From 46de8af8cb9cd6d291a98a40a9261faa423e5842 Mon Sep 17 00:00:00 2001 From: Cayman Date: Fri, 31 Mar 2023 17:00:45 -0400 Subject: [PATCH 01/13] feat: convert codebase to typescript --- ...{block-interface.js => block-interface.ts} | 0 .../{cid-interface.js => cid-interface.ts} | 0 ...c-interface.js => multicodec-interface.ts} | 0 ...sh-interface.js => multihash-interface.ts} | 0 package.json | 80 ++-- src/bases/base.js | 347 ------------------ src/bases/base.ts | 234 ++++++++++++ src/bases/{base10.js => base10.ts} | 0 src/bases/{base16.js => base16.ts} | 2 - src/bases/{base2.js => base2.ts} | 2 - .../{base256emoji.js => base256emoji.ts} | 18 +- src/bases/{base32.js => base32.ts} | 0 src/bases/{base36.js => base36.ts} | 0 src/bases/{base58.js => base58.ts} | 0 src/bases/{base64.js => base64.ts} | 2 - src/bases/{base8.js => base8.ts} | 2 - src/bases/{identity.js => identity.ts} | 2 - src/bases/interface.js | 1 - src/bases/interface.ts | 6 - src/{basics.js => basics.ts} | 2 - src/block.js | 272 -------------- src/block.ts | 211 +++++++++++ src/block/interface.js | 1 - src/block/interface.ts | 8 +- src/bytes.js | 67 ---- src/bytes.ts | 41 +++ src/{cid.js => cid.ts} | 288 ++++----------- src/codecs/interface.js | 1 - src/codecs/json.js | 26 -- src/codecs/json.ts | 11 + src/codecs/raw.js | 23 -- src/codecs/raw.ts | 9 + src/hashes/{digest.js => digest.ts} | 44 +-- src/hashes/hasher.js | 61 --- src/hashes/hasher.ts | 35 ++ src/hashes/identity.js | 16 - src/hashes/identity.ts | 11 + src/hashes/interface.js | 1 - src/hashes/interface.ts | 2 - .../{sha2-browser.js => sha2-browser.ts} | 8 +- src/hashes/{sha2.js => sha2.ts} | 2 - src/{index.js => index.ts} | 0 src/interface.js | 1 - src/link.js | 92 ----- src/link.ts | 63 ++++ src/link/interface.js | 1 - src/traversal.js | 43 --- src/traversal.ts | 26 ++ src/varint.js | 29 -- src/varint.ts | 15 + {vendor => src/vendor}/base-x.d.ts | 1 + {vendor => src/vendor}/base-x.js | 15 + {vendor => src/vendor}/varint.d.ts | 1 + {vendor => src/vendor}/varint.js | 15 +- ...alid-multihash.js => invalid-multihash.ts} | 0 ...{valid-multihash.js => valid-multihash.ts} | 0 ...{test-block.spec.js => test-block.spec.ts} | 0 ...{test-bytes.spec.js => test-bytes.spec.ts} | 0 test/{test-cid.spec.js => test-cid.spec.ts} | 72 ++-- test/{test-link.spec.js => test-link.spec.ts} | 35 +- ...ec.spec.js => test-multibase-spec.spec.ts} | 2 +- ...ltibase.spec.js => test-multibase.spec.ts} | 16 +- ...icodec.spec.js => test-multicodec.spec.ts} | 0 ...ltihash.spec.js => test-multihash.spec.ts} | 22 +- ...aversal.spec.js => test-traversal.spec.ts} | 62 +--- ...est-varint.spec.js => test-varint.spec.ts} | 0 test/ts-use/src/main.ts | 2 +- tsconfig.json | 20 +- 68 files changed, 899 insertions(+), 1470 deletions(-) rename examples/{block-interface.js => block-interface.ts} (100%) rename examples/{cid-interface.js => cid-interface.ts} (100%) rename examples/{multicodec-interface.js => multicodec-interface.ts} (100%) rename examples/{multihash-interface.js => multihash-interface.ts} (100%) delete mode 100644 src/bases/base.js create mode 100644 src/bases/base.ts rename src/bases/{base10.js => base10.ts} (100%) rename src/bases/{base16.js => base16.ts} (95%) rename src/bases/{base2.js => base2.ts} (90%) rename src/bases/{base256emoji.js => base256emoji.ts} (72%) rename src/bases/{base32.js => base32.ts} (100%) rename src/bases/{base36.js => base36.ts} (100%) rename src/bases/{base58.js => base58.ts} (100%) rename src/bases/{base64.js => base64.ts} (98%) rename src/bases/{base8.js => base8.ts} (91%) rename src/bases/{identity.js => identity.ts} (94%) delete mode 100644 src/bases/interface.js rename src/{basics.js => basics.ts} (98%) delete mode 100644 src/block.js create mode 100644 src/block.ts delete mode 100644 src/block/interface.js delete mode 100644 src/bytes.js create mode 100644 src/bytes.ts rename src/{cid.js => cid.ts} (56%) delete mode 100644 src/codecs/interface.js delete mode 100644 src/codecs/json.js create mode 100644 src/codecs/json.ts delete mode 100644 src/codecs/raw.js create mode 100644 src/codecs/raw.ts rename src/hashes/{digest.js => digest.ts} (63%) delete mode 100644 src/hashes/hasher.js create mode 100644 src/hashes/hasher.ts delete mode 100644 src/hashes/identity.js create mode 100644 src/hashes/identity.ts delete mode 100644 src/hashes/interface.js rename src/hashes/{sha2-browser.js => sha2-browser.ts} (74%) rename src/hashes/{sha2.js => sha2.ts} (96%) rename src/{index.js => index.ts} (100%) delete mode 100644 src/interface.js delete mode 100644 src/link.js create mode 100644 src/link.ts delete mode 100644 src/link/interface.js delete mode 100644 src/traversal.js create mode 100644 src/traversal.ts delete mode 100644 src/varint.js create mode 100644 src/varint.ts rename {vendor => src/vendor}/base-x.d.ts (92%) rename {vendor => src/vendor}/base-x.js (94%) rename {vendor => src/vendor}/varint.d.ts (99%) rename {vendor => src/vendor}/varint.js (85%) rename test/fixtures/{invalid-multihash.js => invalid-multihash.ts} (100%) rename test/fixtures/{valid-multihash.js => valid-multihash.ts} (100%) rename test/{test-block.spec.js => test-block.spec.ts} (100%) rename test/{test-bytes.spec.js => test-bytes.spec.ts} (100%) rename test/{test-cid.spec.js => test-cid.spec.ts} (93%) rename test/{test-link.spec.js => test-link.spec.ts} (74%) rename test/{test-multibase-spec.spec.js => test-multibase-spec.spec.ts} (99%) rename test/{test-multibase.spec.js => test-multibase.spec.ts} (94%) rename test/{test-multicodec.spec.js => test-multicodec.spec.ts} (100%) rename test/{test-multihash.spec.js => test-multihash.spec.ts} (88%) rename test/{test-traversal.spec.js => test-traversal.spec.ts} (80%) rename test/{test-varint.spec.js => test-varint.spec.ts} (100%) diff --git a/examples/block-interface.js b/examples/block-interface.ts similarity index 100% rename from examples/block-interface.js rename to examples/block-interface.ts diff --git a/examples/cid-interface.js b/examples/cid-interface.ts similarity index 100% rename from examples/cid-interface.js rename to examples/cid-interface.ts diff --git a/examples/multicodec-interface.js b/examples/multicodec-interface.ts similarity index 100% rename from examples/multicodec-interface.js rename to examples/multicodec-interface.ts diff --git a/examples/multihash-interface.js b/examples/multihash-interface.ts similarity index 100% rename from examples/multihash-interface.js rename to examples/multihash-interface.ts diff --git a/package.json b/package.json index 7cf8a2af..ecdd0270 100644 --- a/package.json +++ b/package.json @@ -22,20 +22,20 @@ "npm": ">=7.0.0" }, "type": "module", - "types": "./dist/types/src/index.d.ts", + "types": "./dist/src/index.d.ts", "typesVersions": { "*": { "*": [ "*", - "dist/types/*", - "dist/types/src/*", - "dist/types/src/*/index" + "dist/*", + "dist/src/*", + "dist/src/*/index" ], "src/*": [ "*", - "dist/types/*", - "dist/types/src/*", - "dist/types/src/*/index" + "dist/*", + "dist/src/*", + "dist/src/*/index" ] } }, @@ -54,125 +54,125 @@ "exports": { ".": { "types": "./dist/types/src/index.d.ts", - "import": "./src/index.js" + "import": "./dist/src/index.js" }, "./bases/base10": { "types": "./dist/types/src/bases/base10.d.ts", - "import": "./src/bases/base10.js" + "import": "./dist/src/bases/base10.js" }, "./bases/base16": { "types": "./dist/types/src/bases/base16.d.ts", - "import": "./src/bases/base16.js" + "import": "./dist/src/bases/base16.js" }, "./bases/base2": { "types": "./dist/types/src/bases/base2.d.ts", - "import": "./src/bases/base2.js" + "import": "./dist/src/bases/base2.js" }, "./bases/base256emoji": { "types": "./dist/types/src/bases/base256emoji.d.ts", - "import": "./src/bases/base256emoji.js" + "import": "./dist/src/bases/base256emoji.js" }, "./bases/base32": { "types": "./dist/types/src/bases/base32.d.ts", - "import": "./src/bases/base32.js" + "import": "./dist/src/bases/base32.js" }, "./bases/base36": { "types": "./dist/types/src/bases/base36.d.ts", - "import": "./src/bases/base36.js" + "import": "./dist/src/bases/base36.js" }, "./bases/base58": { "types": "./dist/types/src/bases/base58.d.ts", - "import": "./src/bases/base58.js" + "import": "./dist/src/bases/base58.js" }, "./bases/base64": { "types": "./dist/types/src/bases/base64.d.ts", - "import": "./src/bases/base64.js" + "import": "./dist/src/bases/base64.js" }, "./bases/base8": { "types": "./dist/types/src/bases/base8.d.ts", - "import": "./src/bases/base8.js" + "import": "./dist/src/bases/base8.js" }, "./bases/identity": { "types": "./dist/types/src/bases/identity.d.ts", - "import": "./src/bases/identity.js" + "import": "./dist/src/bases/identity.js" }, "./bases/interface": { "types": "./dist/types/src/bases/interface.d.ts", - "import": "./src/bases/interface.js" + "import": "./dist/src/bases/interface.js" }, "./basics": { "types": "./dist/types/src/basics.d.ts", - "import": "./src/basics.js" + "import": "./dist/src/basics.js" }, "./block": { "types": "./dist/types/src/block.d.ts", - "import": "./src/block.js" + "import": "./dist/src/block.js" }, "./block/interface": { "types": "./dist/types/src/block/interface.d.ts", - "import": "./src/block/interface.js" + "import": "./dist/src/block/interface.js" }, "./bytes": { "types": "./dist/types/src/bytes.d.ts", - "import": "./src/bytes.js" + "import": "./dist/src/bytes.js" }, "./cid": { "types": "./dist/types/src/cid.d.ts", - "import": "./src/cid.js" + "import": "./dist/src/cid.js" }, "./codecs/interface": { "types": "./dist/types/src/codecs/interface.d.ts", - "import": "./src/codecs/interface.js" + "import": "./dist/src/codecs/interface.js" }, "./codecs/json": { "types": "./dist/types/src/codecs/json.d.ts", - "import": "./src/codecs/json.js" + "import": "./dist/src/codecs/json.js" }, "./codecs/raw": { "types": "./dist/types/src/codecs/raw.d.ts", - "import": "./src/codecs/raw.js" + "import": "./dist/src/codecs/raw.js" }, "./hashes/digest": { "types": "./dist/types/src/hashes/digest.d.ts", - "import": "./src/hashes/digest.js" + "import": "./dist/src/hashes/digest.js" }, "./hashes/hasher": { "types": "./dist/types/src/hashes/hasher.d.ts", - "import": "./src/hashes/hasher.js" + "import": "./dist/src/hashes/hasher.js" }, "./hashes/identity": { "types": "./dist/types/src/hashes/identity.d.ts", - "import": "./src/hashes/identity.js" + "import": "./dist/src/hashes/identity.js" }, "./hashes/interface": { "types": "./dist/types/src/hashes/interface.d.ts", - "import": "./src/hashes/interface.js" + "import": "./dist/src/hashes/interface.js" }, "./hashes/sha2": { "types": "./dist/types/src/hashes/sha2.d.ts", - "browser": "./src/hashes/sha2-browser.js", - "import": "./src/hashes/sha2.js" + "browser": "./dist/src/hashes/sha2-browser.js", + "import": "./dist/src/hashes/sha2.js" }, "./interface": { "types": "./dist/types/src/interface.d.ts", - "import": "./src/interface.js" + "import": "./dist/src/interface.js" }, "./link": { "types": "./dist/types/src/link.d.ts", - "import": "./src/link.js" + "import": "./dist/src/link.js" }, "./link/interface": { "types": "./dist/types/src/interface.d.ts", - "import": "./src/interface.js" + "import": "./dist/src/interface.js" }, "./traversal": { "types": "./dist/types/src/traversal.d.ts", - "import": "./src/traversal.js" + "import": "./dist/src/traversal.js" } }, "browser": { - "./hashes/sha2": "./src/hashes/sha2-browser.js", - "./src/hashes/sha2.js": "./src/hashes/sha2-browser.js" + "./hashes/sha2": "./dist/src/hashes/sha2-browser.js", + "./dist/src/hashes/sha2.js": "./dist/src/hashes/sha2-browser.js" }, "eslintConfig": { "extends": "ipfs", @@ -284,7 +284,7 @@ "@stablelib/sha256": "^1.0.1", "@stablelib/sha512": "^1.0.1", "@types/node": "^18.0.0", - "aegir": "^37.7.5", + "aegir": "^38.1.8", "buffer": "^6.0.3", "cids": "^1.1.9" }, diff --git a/src/bases/base.js b/src/bases/base.js deleted file mode 100644 index 4ace5ff4..00000000 --- a/src/bases/base.js +++ /dev/null @@ -1,347 +0,0 @@ -import basex from '../../vendor/base-x.js' -import { coerce } from '../bytes.js' -// Linter can't see that API is used in types. -// eslint-disable-next-line -import * as API from './interface.js' - -/** - * Class represents both BaseEncoder and MultibaseEncoder meaning it - * can be used to encode to multibase or base encode without multibase - * prefix. - * - * @class - * @template {string} Base - * @template {string} Prefix - * @implements {API.MultibaseEncoder} - * @implements {API.BaseEncoder} - */ -class Encoder { - /** - * @param {Base} name - * @param {Prefix} prefix - * @param {(bytes:Uint8Array) => string} baseEncode - */ - constructor (name, prefix, baseEncode) { - this.name = name - this.prefix = prefix - this.baseEncode = baseEncode - } - - /** - * @param {Uint8Array} bytes - * @returns {API.Multibase} - */ - encode (bytes) { - if (bytes instanceof Uint8Array) { - return `${this.prefix}${this.baseEncode(bytes)}` - } else { - throw Error('Unknown type, must be binary type') - } - } -} - -/** - * @template {string} Prefix - */ -/** - * Class represents both BaseDecoder and MultibaseDecoder so it could be used - * to decode multibases (with matching prefix) or just base decode strings - * with corresponding base encoding. - * - * @class - * @template {string} Base - * @template {string} Prefix - * @implements {API.MultibaseDecoder} - * @implements {API.UnibaseDecoder} - * @implements {API.BaseDecoder} - */ -class Decoder { - /** - * @param {Base} name - * @param {Prefix} prefix - * @param {(text:string) => Uint8Array} baseDecode - */ - constructor (name, prefix, baseDecode) { - this.name = name - this.prefix = prefix - /* c8 ignore next 3 */ - if (prefix.codePointAt(0) === undefined) { - throw new Error('Invalid prefix character') - } - /** @private */ - this.prefixCodePoint = /** @type {number} */ (prefix.codePointAt(0)) - this.baseDecode = baseDecode - } - - /** - * @param {string} text - */ - decode (text) { - if (typeof text === 'string') { - if (text.codePointAt(0) !== this.prefixCodePoint) { - throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`) - } - return this.baseDecode(text.slice(this.prefix.length)) - } else { - throw Error('Can only multibase decode strings') - } - } - - /** - * @template {string} OtherPrefix - * @param {API.UnibaseDecoder|ComposedDecoder} decoder - * @returns {ComposedDecoder} - */ - or (decoder) { - return or(this, decoder) - } -} - -/** - * @template {string} Prefix - * @typedef {Record>} Decoders - */ - -/** - * @template {string} Prefix - * @implements {API.MultibaseDecoder} - * @implements {API.CombobaseDecoder} - */ -class ComposedDecoder { - /** - * @param {Decoders} decoders - */ - constructor (decoders) { - this.decoders = decoders - } - - /** - * @template {string} OtherPrefix - * @param {API.UnibaseDecoder|ComposedDecoder} decoder - * @returns {ComposedDecoder} - */ - or (decoder) { - return or(this, decoder) - } - - /** - * @param {string} input - * @returns {Uint8Array} - */ - decode (input) { - const prefix = /** @type {Prefix} */ (input[0]) - const decoder = this.decoders[prefix] - if (decoder) { - return decoder.decode(input) - } else { - throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`) - } - } -} - -/** - * @template {string} L - * @template {string} R - * @param {API.UnibaseDecoder|API.CombobaseDecoder} left - * @param {API.UnibaseDecoder|API.CombobaseDecoder} right - * @returns {ComposedDecoder} - */ -export const or = (left, right) => new ComposedDecoder(/** @type {Decoders} */({ - ...(left.decoders || { [/** @type API.UnibaseDecoder */(left).prefix]: left }), - ...(right.decoders || { [/** @type API.UnibaseDecoder */(right).prefix]: right }) -})) - -/** - * @class - * @template {string} Base - * @template {string} Prefix - * @implements {API.MultibaseCodec} - * @implements {API.MultibaseEncoder} - * @implements {API.MultibaseDecoder} - * @implements {API.BaseCodec} - * @implements {API.BaseEncoder} - * @implements {API.BaseDecoder} - */ -export class Codec { - /** - * @param {Base} name - * @param {Prefix} prefix - * @param {(bytes:Uint8Array) => string} baseEncode - * @param {(text:string) => Uint8Array} baseDecode - */ - constructor (name, prefix, baseEncode, baseDecode) { - this.name = name - this.prefix = prefix - this.baseEncode = baseEncode - this.baseDecode = baseDecode - this.encoder = new Encoder(name, prefix, baseEncode) - this.decoder = new Decoder(name, prefix, baseDecode) - } - - /** - * @param {Uint8Array} input - */ - encode (input) { - return this.encoder.encode(input) - } - - /** - * @param {string} input - */ - decode (input) { - return this.decoder.decode(input) - } -} - -/** - * @template {string} Base - * @template {string} Prefix - * @param {object} options - * @param {Base} options.name - * @param {Prefix} options.prefix - * @param {(bytes:Uint8Array) => string} options.encode - * @param {(input:string) => Uint8Array} options.decode - * @returns {Codec} - */ -export const from = ({ name, prefix, encode, decode }) => - new Codec(name, prefix, encode, decode) - -/** - * @template {string} Base - * @template {string} Prefix - * @param {object} options - * @param {Base} options.name - * @param {Prefix} options.prefix - * @param {string} options.alphabet - * @returns {Codec} - */ -export const baseX = ({ prefix, name, alphabet }) => { - const { encode, decode } = basex(alphabet, name) - return from({ - prefix, - name, - encode, - /** - * @param {string} text - */ - decode: text => coerce(decode(text)) - }) -} - -/** - * @param {string} string - * @param {string} alphabet - * @param {number} bitsPerChar - * @param {string} name - * @returns {Uint8Array} - */ -const decode = (string, alphabet, bitsPerChar, name) => { - // Build the character lookup table: - /** @type {Record} */ - const codes = {} - for (let i = 0; i < alphabet.length; ++i) { - codes[alphabet[i]] = i - } - - // Count the padding bytes: - let end = string.length - while (string[end - 1] === '=') { - --end - } - - // Allocate the output: - const out = new Uint8Array((end * bitsPerChar / 8) | 0) - - // Parse the data: - let bits = 0 // Number of bits currently in the buffer - let buffer = 0 // Bits waiting to be written out, MSB first - let written = 0 // Next byte to write - for (let i = 0; i < end; ++i) { - // Read one character from the string: - const value = codes[string[i]] - if (value === undefined) { - throw new SyntaxError(`Non-${name} character`) - } - - // Append the bits to the buffer: - buffer = (buffer << bitsPerChar) | value - bits += bitsPerChar - - // Write out some bits if the buffer has a byte's worth: - if (bits >= 8) { - bits -= 8 - out[written++] = 0xff & (buffer >> bits) - } - } - - // Verify that we have received just enough bits: - if (bits >= bitsPerChar || 0xff & (buffer << (8 - bits))) { - throw new SyntaxError('Unexpected end of data') - } - - return out -} - -/** - * @param {Uint8Array} data - * @param {string} alphabet - * @param {number} bitsPerChar - * @returns {string} - */ -const encode = (data, alphabet, bitsPerChar) => { - const pad = alphabet[alphabet.length - 1] === '=' - const mask = (1 << bitsPerChar) - 1 - let out = '' - - let bits = 0 // Number of bits currently in the buffer - let buffer = 0 // Bits waiting to be written out, MSB first - for (let i = 0; i < data.length; ++i) { - // Slurp data into the buffer: - buffer = (buffer << 8) | data[i] - bits += 8 - - // Write out as much as we can: - while (bits > bitsPerChar) { - bits -= bitsPerChar - out += alphabet[mask & (buffer >> bits)] - } - } - - // Partial character: - if (bits) { - out += alphabet[mask & (buffer << (bitsPerChar - bits))] - } - - // Add padding characters until we hit a byte boundary: - if (pad) { - while ((out.length * bitsPerChar) & 7) { - out += '=' - } - } - - return out -} - -/** - * RFC4648 Factory - * - * @template {string} Base - * @template {string} Prefix - * @param {object} options - * @param {Base} options.name - * @param {Prefix} options.prefix - * @param {string} options.alphabet - * @param {number} options.bitsPerChar - */ -export const rfc4648 = ({ name, prefix, bitsPerChar, alphabet }) => { - return from({ - prefix, - name, - encode (input) { - return encode(input, alphabet, bitsPerChar) - }, - decode (input) { - return decode(input, alphabet, bitsPerChar, name) - } - }) -} diff --git a/src/bases/base.ts b/src/bases/base.ts new file mode 100644 index 00000000..98b284a7 --- /dev/null +++ b/src/bases/base.ts @@ -0,0 +1,234 @@ +import basex from '../vendor/base-x.js' +import { coerce } from '../bytes.js' +import type { BaseCodec, BaseDecoder, BaseEncoder, CombobaseDecoder, Multibase, MultibaseCodec, MultibaseDecoder, MultibaseEncoder, UnibaseDecoder } from './interface.js' + +interface EncodeFn { (bytes: Uint8Array): string } +interface DecodeFn { (text: string): Uint8Array } + +/** + * Class represents both BaseEncoder and MultibaseEncoder meaning it + * can be used to encode to multibase or base encode without multibase + * prefix. + */ +class Encoder implements MultibaseEncoder, BaseEncoder { + readonly name: Base + readonly prefix: Prefix + readonly baseEncode: EncodeFn + + constructor (name: Base, prefix: Prefix, baseEncode: EncodeFn) { + this.name = name + this.prefix = prefix + this.baseEncode = baseEncode + } + + encode (bytes: Uint8Array): Multibase { + if (bytes instanceof Uint8Array) { + return `${this.prefix}${this.baseEncode(bytes)}` + } else { + throw Error('Unknown type, must be binary type') + } + } +} + +/** + * Class represents both BaseDecoder and MultibaseDecoder so it could be used + * to decode multibases (with matching prefix) or just base decode strings + * with corresponding base encoding. + */ +class Decoder implements MultibaseDecoder, UnibaseDecoder, BaseDecoder { + readonly name: Base + readonly prefix: Prefix + readonly baseDecode: DecodeFn + private readonly prefixCodePoint: number + + constructor (name: Base, prefix: Prefix, baseDecode: DecodeFn) { + this.name = name + this.prefix = prefix + /* c8 ignore next 3 */ + if (prefix.codePointAt(0) === undefined) { + throw new Error('Invalid prefix character') + } + this.prefixCodePoint = (prefix.codePointAt(0)) as number + this.baseDecode = baseDecode + } + + decode (text: string): Uint8Array { + if (typeof text === 'string') { + if (text.codePointAt(0) !== this.prefixCodePoint) { + throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`) + } + return this.baseDecode(text.slice(this.prefix.length)) + } else { + throw Error('Can only multibase decode strings') + } + } + + or (decoder: UnibaseDecoder | ComposedDecoder): ComposedDecoder { + return or(this, decoder) + } +} + +type Decoders = Record> + +class ComposedDecoder implements MultibaseDecoder, CombobaseDecoder { + readonly decoders: Decoders + + constructor (decoders: Decoders) { + this.decoders = decoders + } + + or (decoder: UnibaseDecoder | ComposedDecoder): ComposedDecoder { + return or(this, decoder) + } + + decode (input: string): Uint8Array { + const prefix = (input[0]) as Prefix + const decoder = this.decoders[prefix] + if (decoder != null) { + return decoder.decode(input) + } else { + throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`) + } + } +} + +// eslint-disable-next-line @typescript-eslint/consistent-type-assertions +export const or = (left: UnibaseDecoder | CombobaseDecoder, right: UnibaseDecoder | CombobaseDecoder): ComposedDecoder => new ComposedDecoder(({ + ...(left.decoders ?? { [(left as UnibaseDecoder).prefix]: left }), + ...(right.decoders ?? { [(right as UnibaseDecoder).prefix]: right }) +} as Decoders)) + +export class Codec implements MultibaseCodec, MultibaseEncoder, MultibaseDecoder, BaseCodec, BaseEncoder, BaseDecoder { + readonly name: Base + readonly prefix: Prefix + readonly baseEncode: EncodeFn + readonly baseDecode: DecodeFn + readonly encoder: Encoder + readonly decoder: Decoder + + constructor (name: Base, prefix: Prefix, baseEncode: EncodeFn, baseDecode: DecodeFn) { + this.name = name + this.prefix = prefix + this.baseEncode = baseEncode + this.baseDecode = baseDecode + this.encoder = new Encoder(name, prefix, baseEncode) + this.decoder = new Decoder(name, prefix, baseDecode) + } + + encode (input: Uint8Array): string { + return this.encoder.encode(input) + } + + decode (input: string): Uint8Array { + return this.decoder.decode(input) + } +} + +export const from = ({ name, prefix, encode, decode }: { name: Base, prefix: Prefix, encode: EncodeFn, decode: DecodeFn }): Codec => + new Codec(name, prefix, encode, decode) + +export const baseX = ({ name, prefix, alphabet }: { name: Base, prefix: Prefix, alphabet: string }): Codec => { + const { encode, decode } = basex(alphabet, name) + return from({ + prefix, + name, + encode, + decode: (text: string): Uint8Array => coerce(decode(text)) + }) +} + +const decode = (string: string, alphabet: string, bitsPerChar: number, name: string): Uint8Array => { + // Build the character lookup table: + const codes: Record = {} + for (let i = 0; i < alphabet.length; ++i) { + codes[alphabet[i]] = i + } + + // Count the padding bytes: + let end = string.length + while (string[end - 1] === '=') { + --end + } + + // Allocate the output: + const out = new Uint8Array((end * bitsPerChar / 8) | 0) + + // Parse the data: + let bits = 0 // Number of bits currently in the buffer + let buffer = 0 // Bits waiting to be written out, MSB first + let written = 0 // Next byte to write + for (let i = 0; i < end; ++i) { + // Read one character from the string: + const value = codes[string[i]] + if (value === undefined) { + throw new SyntaxError(`Non-${name} character`) + } + + // Append the bits to the buffer: + buffer = (buffer << bitsPerChar) | value + bits += bitsPerChar + + // Write out some bits if the buffer has a byte's worth: + if (bits >= 8) { + bits -= 8 + out[written++] = 0xff & (buffer >> bits) + } + } + + // Verify that we have received just enough bits: + if (bits >= bitsPerChar || (0xff & (buffer << (8 - bits))) !== 0) { + throw new SyntaxError('Unexpected end of data') + } + + return out +} + +const encode = (data: Uint8Array, alphabet: string, bitsPerChar: number): string => { + const pad = alphabet[alphabet.length - 1] === '=' + const mask = (1 << bitsPerChar) - 1 + let out = '' + + let bits = 0 // Number of bits currently in the buffer + let buffer = 0 // Bits waiting to be written out, MSB first + for (let i = 0; i < data.length; ++i) { + // Slurp data into the buffer: + buffer = (buffer << 8) | data[i] + bits += 8 + + // Write out as much as we can: + while (bits > bitsPerChar) { + bits -= bitsPerChar + out += alphabet[mask & (buffer >> bits)] + } + } + + // Partial character: + if (bits !== 0) { + out += alphabet[mask & (buffer << (bitsPerChar - bits))] + } + + // Add padding characters until we hit a byte boundary: + if (pad) { + while (((out.length * bitsPerChar) & 7) !== 0) { + out += '=' + } + } + + return out +} + +/** + * RFC4648 Factory + */ +export const rfc4648 = ({ name, prefix, bitsPerChar, alphabet }: { name: Base, prefix: Prefix, bitsPerChar: number, alphabet: string }): Codec => { + return from({ + prefix, + name, + encode (input: Uint8Array): string { + return encode(input, alphabet, bitsPerChar) + }, + decode (input: string): Uint8Array { + return decode(input, alphabet, bitsPerChar, name) + } + }) +} diff --git a/src/bases/base10.js b/src/bases/base10.ts similarity index 100% rename from src/bases/base10.js rename to src/bases/base10.ts diff --git a/src/bases/base16.js b/src/bases/base16.ts similarity index 95% rename from src/bases/base16.js rename to src/bases/base16.ts index 394a8ca3..8e7b2380 100644 --- a/src/bases/base16.js +++ b/src/bases/base16.ts @@ -1,5 +1,3 @@ -// @ts-check - import { rfc4648 } from './base.js' export const base16 = rfc4648({ diff --git a/src/bases/base2.js b/src/bases/base2.ts similarity index 90% rename from src/bases/base2.js rename to src/bases/base2.ts index e32baa32..2ff4977d 100644 --- a/src/bases/base2.js +++ b/src/bases/base2.ts @@ -1,5 +1,3 @@ -// @ts-check - import { rfc4648 } from './base.js' export const base2 = rfc4648({ diff --git a/src/bases/base256emoji.js b/src/bases/base256emoji.ts similarity index 72% rename from src/bases/base256emoji.js rename to src/bases/base256emoji.ts index 957c81f8..e61d0bd2 100644 --- a/src/bases/base256emoji.js +++ b/src/bases/base256emoji.ts @@ -1,28 +1,20 @@ import { from } from './base.js' const alphabet = Array.from('๐Ÿš€๐Ÿชโ˜„๐Ÿ›ฐ๐ŸŒŒ๐ŸŒ‘๐ŸŒ’๐ŸŒ“๐ŸŒ”๐ŸŒ•๐ŸŒ–๐ŸŒ—๐ŸŒ˜๐ŸŒ๐ŸŒ๐ŸŒŽ๐Ÿ‰โ˜€๐Ÿ’ป๐Ÿ–ฅ๐Ÿ’พ๐Ÿ’ฟ๐Ÿ˜‚โค๐Ÿ˜๐Ÿคฃ๐Ÿ˜Š๐Ÿ™๐Ÿ’•๐Ÿ˜ญ๐Ÿ˜˜๐Ÿ‘๐Ÿ˜…๐Ÿ‘๐Ÿ˜๐Ÿ”ฅ๐Ÿฅฐ๐Ÿ’”๐Ÿ’–๐Ÿ’™๐Ÿ˜ข๐Ÿค”๐Ÿ˜†๐Ÿ™„๐Ÿ’ช๐Ÿ˜‰โ˜บ๐Ÿ‘Œ๐Ÿค—๐Ÿ’œ๐Ÿ˜”๐Ÿ˜Ž๐Ÿ˜‡๐ŸŒน๐Ÿคฆ๐ŸŽ‰๐Ÿ’žโœŒโœจ๐Ÿคท๐Ÿ˜ฑ๐Ÿ˜Œ๐ŸŒธ๐Ÿ™Œ๐Ÿ˜‹๐Ÿ’—๐Ÿ’š๐Ÿ˜๐Ÿ’›๐Ÿ™‚๐Ÿ’“๐Ÿคฉ๐Ÿ˜„๐Ÿ˜€๐Ÿ–ค๐Ÿ˜ƒ๐Ÿ’ฏ๐Ÿ™ˆ๐Ÿ‘‡๐ŸŽถ๐Ÿ˜’๐Ÿคญโฃ๐Ÿ˜œ๐Ÿ’‹๐Ÿ‘€๐Ÿ˜ช๐Ÿ˜‘๐Ÿ’ฅ๐Ÿ™‹๐Ÿ˜ž๐Ÿ˜ฉ๐Ÿ˜ก๐Ÿคช๐Ÿ‘Š๐Ÿฅณ๐Ÿ˜ฅ๐Ÿคค๐Ÿ‘‰๐Ÿ’ƒ๐Ÿ˜ณโœ‹๐Ÿ˜š๐Ÿ˜๐Ÿ˜ด๐ŸŒŸ๐Ÿ˜ฌ๐Ÿ™ƒ๐Ÿ€๐ŸŒท๐Ÿ˜ป๐Ÿ˜“โญโœ…๐Ÿฅบ๐ŸŒˆ๐Ÿ˜ˆ๐Ÿค˜๐Ÿ’ฆโœ”๐Ÿ˜ฃ๐Ÿƒ๐Ÿ’โ˜น๐ŸŽŠ๐Ÿ’˜๐Ÿ˜ โ˜๐Ÿ˜•๐ŸŒบ๐ŸŽ‚๐ŸŒป๐Ÿ˜๐Ÿ–•๐Ÿ’๐Ÿ™Š๐Ÿ˜น๐Ÿ—ฃ๐Ÿ’ซ๐Ÿ’€๐Ÿ‘‘๐ŸŽต๐Ÿคž๐Ÿ˜›๐Ÿ”ด๐Ÿ˜ค๐ŸŒผ๐Ÿ˜ซโšฝ๐Ÿค™โ˜•๐Ÿ†๐Ÿคซ๐Ÿ‘ˆ๐Ÿ˜ฎ๐Ÿ™†๐Ÿป๐Ÿƒ๐Ÿถ๐Ÿ’๐Ÿ˜ฒ๐ŸŒฟ๐Ÿงก๐ŸŽโšก๐ŸŒž๐ŸŽˆโŒโœŠ๐Ÿ‘‹๐Ÿ˜ฐ๐Ÿคจ๐Ÿ˜ถ๐Ÿค๐Ÿšถ๐Ÿ’ฐ๐Ÿ“๐Ÿ’ข๐ŸคŸ๐Ÿ™๐Ÿšจ๐Ÿ’จ๐Ÿคฌโœˆ๐ŸŽ€๐Ÿบ๐Ÿค“๐Ÿ˜™๐Ÿ’Ÿ๐ŸŒฑ๐Ÿ˜–๐Ÿ‘ถ๐Ÿฅดโ–ถโžกโ“๐Ÿ’Ž๐Ÿ’ธโฌ‡๐Ÿ˜จ๐ŸŒš๐Ÿฆ‹๐Ÿ˜ท๐Ÿ•บโš ๐Ÿ™…๐Ÿ˜Ÿ๐Ÿ˜ต๐Ÿ‘Ž๐Ÿคฒ๐Ÿค ๐Ÿคง๐Ÿ“Œ๐Ÿ”ต๐Ÿ’…๐Ÿง๐Ÿพ๐Ÿ’๐Ÿ˜—๐Ÿค‘๐ŸŒŠ๐Ÿคฏ๐Ÿทโ˜Ž๐Ÿ’ง๐Ÿ˜ฏ๐Ÿ’†๐Ÿ‘†๐ŸŽค๐Ÿ™‡๐Ÿ‘โ„๐ŸŒด๐Ÿ’ฃ๐Ÿธ๐Ÿ’Œ๐Ÿ“๐Ÿฅ€๐Ÿคข๐Ÿ‘…๐Ÿ’ก๐Ÿ’ฉ๐Ÿ‘๐Ÿ“ธ๐Ÿ‘ป๐Ÿค๐Ÿคฎ๐ŸŽผ๐Ÿฅต๐Ÿšฉ๐ŸŽ๐ŸŠ๐Ÿ‘ผ๐Ÿ’๐Ÿ“ฃ๐Ÿฅ‚') -const alphabetBytesToChars = /** @type {string[]} */ (alphabet.reduce((p, c, i) => { p[i] = c; return p }, /** @type {string[]} */([]))) -const alphabetCharsToBytes = /** @type {number[]} */ (alphabet.reduce((p, c, i) => { p[/** @type {number} */ (c.codePointAt(0))] = i; return p }, /** @type {number[]} */([]))) +const alphabetBytesToChars: string[] = (alphabet.reduce((p, c, i) => { p[i] = c; return p }, ([]))) +const alphabetCharsToBytes: number[] = (alphabet.reduce((p, c, i) => { p[(c.codePointAt(0) as number)] = i; return p }, ([]))) -/** - * @param {Uint8Array} data - * @returns {string} - */ -function encode (data) { +function encode (data: Uint8Array): string { return data.reduce((p, c) => { p += alphabetBytesToChars[c] return p }, '') } -/** - * @param {string} str - * @returns {Uint8Array} - */ -function decode (str) { +function decode (str: string): Uint8Array { const byts = [] for (const char of str) { - const byt = alphabetCharsToBytes[/** @type {number} */ (char.codePointAt(0))] + const byt = alphabetCharsToBytes[(char.codePointAt(0) as number)] if (byt === undefined) { throw new Error(`Non-base256emoji character: ${char}`) } diff --git a/src/bases/base32.js b/src/bases/base32.ts similarity index 100% rename from src/bases/base32.js rename to src/bases/base32.ts diff --git a/src/bases/base36.js b/src/bases/base36.ts similarity index 100% rename from src/bases/base36.js rename to src/bases/base36.ts diff --git a/src/bases/base58.js b/src/bases/base58.ts similarity index 100% rename from src/bases/base58.js rename to src/bases/base58.ts diff --git a/src/bases/base64.js b/src/bases/base64.ts similarity index 98% rename from src/bases/base64.js rename to src/bases/base64.ts index 4fe40f9e..6e66d933 100644 --- a/src/bases/base64.js +++ b/src/bases/base64.ts @@ -1,5 +1,3 @@ -// @ts-check - import { rfc4648 } from './base.js' export const base64 = rfc4648({ diff --git a/src/bases/base8.js b/src/bases/base8.ts similarity index 91% rename from src/bases/base8.js rename to src/bases/base8.ts index caa50f7c..7c584a57 100644 --- a/src/bases/base8.js +++ b/src/bases/base8.ts @@ -1,5 +1,3 @@ -// @ts-check - import { rfc4648 } from './base.js' export const base8 = rfc4648({ diff --git a/src/bases/identity.js b/src/bases/identity.ts similarity index 94% rename from src/bases/identity.js rename to src/bases/identity.ts index 758bba6b..b591f703 100644 --- a/src/bases/identity.js +++ b/src/bases/identity.ts @@ -1,5 +1,3 @@ -// @ts-check - import { from } from './base.js' import { fromString, toString } from '../bytes.js' diff --git a/src/bases/interface.js b/src/bases/interface.js deleted file mode 100644 index d9b3f4f7..00000000 --- a/src/bases/interface.js +++ /dev/null @@ -1 +0,0 @@ -// this is dummy module overlayed by interface.ts diff --git a/src/bases/interface.ts b/src/bases/interface.ts index fd8617ca..f6d99df3 100644 --- a/src/bases/interface.ts +++ b/src/bases/interface.ts @@ -8,8 +8,6 @@ export interface BaseEncoder { /** * Base encodes to a **plain** (and not a multibase) string. Unlike * `encode` no multibase prefix is added. - * - * @param bytes */ baseEncode: (bytes: Uint8Array) => string } @@ -21,8 +19,6 @@ export interface BaseDecoder { /** * Decodes **plain** (and not a multibase) string. Unlike * decode - * - * @param text */ baseDecode: (text: string) => Uint8Array } @@ -73,8 +69,6 @@ export interface MultibaseDecoder { /** * Decodes **multibase** string (which must have a multibase prefix added). * If prefix does not match - * - * @param multibase */ decode: (multibase: Multibase) => Uint8Array } diff --git a/src/basics.js b/src/basics.ts similarity index 98% rename from src/basics.js rename to src/basics.ts index 1fbc254a..893c9cf4 100644 --- a/src/basics.js +++ b/src/basics.ts @@ -1,5 +1,3 @@ -// @ts-check - import * as identityBase from './bases/identity.js' import * as base2 from './bases/base2.js' import * as base8 from './bases/base8.js' diff --git a/src/block.js b/src/block.js deleted file mode 100644 index 16adbec5..00000000 --- a/src/block.js +++ /dev/null @@ -1,272 +0,0 @@ -import { bytes as binary, CID } from './index.js' -// Linter can see that API is used in types. -// eslint-disable-next-line -import * as API from './interface.js' - -function readonly ({ enumerable = true, configurable = false } = {}) { - return { enumerable, configurable, writable: false } -} - -/** - * @param {[string|number, string]} path - * @param {any} value - * @returns {Iterable<[string, CID]>} - */ -function * linksWithin (path, value) { - if (value != null && typeof value === 'object') { - if (Array.isArray(value)) { - for (const [index, element] of value.entries()) { - const elementPath = [...path, index] - const cid = CID.asCID(element) - if (cid) { - yield [elementPath.join('/'), cid] - } else if (typeof element === 'object') { - yield * links(element, elementPath) - } - } - } else { - const cid = CID.asCID(value) - if (cid) { - yield [path.join('/'), cid] - } else { - yield * links(value, path) - } - } - } -} - -/** - * @template T - * @param {T} source - * @param {Array} base - * @returns {Iterable<[string, CID]>} - */ -function * links (source, base) { - if (source == null || source instanceof Uint8Array) { - return - } - const cid = CID.asCID(source) - if (cid) { - yield [base.join('/'), cid] - } - for (const [key, value] of Object.entries(source)) { - const path = /** @type {[string|number, string]} */ ([...base, key]) - yield * linksWithin(path, value) - } -} - -/** - * @param {[string|number, string]} path - * @param {any} value - * @returns {Iterable} - */ -function * treeWithin (path, value) { - if (Array.isArray(value)) { - for (const [index, element] of value.entries()) { - const elementPath = [...path, index] - yield elementPath.join('/') - if (typeof element === 'object' && !CID.asCID(element)) { - yield * tree(element, elementPath) - } - } - } else { - yield * tree(value, path) - } -} - -/** - * @template T - * @param {T} source - * @param {Array} base - * @returns {Iterable} - */ -function * tree (source, base) { - if (source == null || typeof source !== 'object') { - return - } - for (const [key, value] of Object.entries(source)) { - const path = /** @type {[string|number, string]} */ ([...base, key]) - yield path.join('/') - if (value != null && !(value instanceof Uint8Array) && typeof value === 'object' && !CID.asCID(value)) { - yield * treeWithin(path, value) - } - } -} - -/** - * - * @template T - * @param {T} source - * @param {string[]} path - * @returns {API.BlockCursorView} - */ -function get (source, path) { - let node = /** @type {Record} */(source) - for (const [index, key] of path.entries()) { - node = node[key] - if (node == null) { - throw new Error(`Object has no property at ${path.slice(0, index + 1).map(part => `[${JSON.stringify(part)}]`).join('')}`) - } - const cid = CID.asCID(node) - if (cid) { - return { value: cid, remaining: path.slice(index + 1).join('/') } - } - } - return { value: node } -} - -/** - * @template {unknown} T - Logical type of the data encoded in the block - * @template {number} C - multicodec code corresponding to codec used to encode the block - * @template {number} A - multicodec code corresponding to the hashing algorithm used in CID creation. - * @template {API.Version} V - CID version - * @implements {API.BlockView} - */ -class Block { - /** - * @param {object} options - * @param {CID} options.cid - * @param {API.ByteView} options.bytes - * @param {T} options.value - */ - constructor ({ cid, bytes, value }) { - if (!cid || !bytes || typeof value === 'undefined') { throw new Error('Missing required argument') } - - this.cid = cid - this.bytes = bytes - this.value = value - this.asBlock = this - - // Mark all the properties immutable - Object.defineProperties(this, { - cid: readonly(), - bytes: readonly(), - value: readonly(), - asBlock: readonly() - }) - } - - links () { - return links(this.value, []) - } - - tree () { - return tree(this.value, []) - } - - /** - * - * @param {string} [path] - * @returns {API.BlockCursorView} - */ - get (path = '/') { - return get(this.value, path.split('/').filter(Boolean)) - } -} - -/** - * @template {unknown} T - Logical type of the data encoded in the block - * @template {number} Code - multicodec code corresponding to codec used to encode the block - * @template {number} Alg - multicodec code corresponding to the hashing algorithm used in CID creation. - * @param {object} options - * @param {T} options.value - * @param {API.BlockEncoder} options.codec - * @param {API.MultihashHasher} options.hasher - * @returns {Promise>} - */ -async function encode ({ value, codec, hasher }) { - if (typeof value === 'undefined') throw new Error('Missing required argument "value"') - if (!codec || !hasher) throw new Error('Missing required argument: codec or hasher') - - const bytes = codec.encode(value) - const hash = await hasher.digest(bytes) - /** @type {CID} */ - const cid = CID.create( - 1, - codec.code, - hash - ) - - return new Block({ value, bytes, cid }) -} - -/** - * @template {unknown} T - Logical type of the data encoded in the block - * @template {number} Code - multicodec code corresponding to codec used to encode the block - * @template {number} Alg - multicodec code corresponding to the hashing algorithm used in CID creation. - * @param {object} options - * @param {API.ByteView} options.bytes - * @param {API.BlockDecoder} options.codec - * @param {API.MultihashHasher} options.hasher - * @returns {Promise>} - */ -async function decode ({ bytes, codec, hasher }) { - if (!bytes) throw new Error('Missing required argument "bytes"') - if (!codec || !hasher) throw new Error('Missing required argument: codec or hasher') - - const value = codec.decode(bytes) - const hash = await hasher.digest(bytes) - /** @type {CID} */ - const cid = CID.create(1, codec.code, hash) - - return new Block({ value, bytes, cid }) -} - -/** - * @typedef {object} RequiredCreateOptions - * @property {CID} options.cid - */ - -/** - * @template {unknown} T - Logical type of the data encoded in the block - * @template {number} Code - multicodec code corresponding to codec used to encode the block - * @template {number} Alg - multicodec code corresponding to the hashing algorithm used in CID creation. - * @template {API.Version} V - CID version - * @param {{ cid: API.Link, value:T, codec?: API.BlockDecoder, bytes: API.ByteView }|{cid:API.Link, bytes:API.ByteView, value?:void, codec:API.BlockDecoder}} options - * @returns {API.BlockView} - */ -function createUnsafe ({ bytes, cid, value: maybeValue, codec }) { - const value = maybeValue !== undefined - ? maybeValue - : (codec && codec.decode(bytes)) - - if (value === undefined) throw new Error('Missing required argument, must either provide "value" or "codec"') - - return new Block({ - // eslint-disable-next-line object-shorthand - cid: /** @type {CID} */ (cid), - bytes, - value - }) -} - -/** - * @template {unknown} T - Logical type of the data encoded in the block - * @template {number} Code - multicodec code corresponding to codec used to encode the block - * @template {number} Alg - multicodec code corresponding to the hashing algorithm used in CID creation. - * @template {API.Version} V - CID version - * @param {object} options - * @param {API.Link} options.cid - * @param {API.ByteView} options.bytes - * @param {API.BlockDecoder} options.codec - * @param {API.MultihashHasher} options.hasher - * @returns {Promise>} - */ -async function create ({ bytes, cid, hasher, codec }) { - if (!bytes) throw new Error('Missing required argument "bytes"') - if (!hasher) throw new Error('Missing required argument "hasher"') - const value = codec.decode(bytes) - const hash = await hasher.digest(bytes) - if (!binary.equals(cid.multihash.bytes, hash.bytes)) { - throw new Error('CID hash does not match bytes') - } - - return createUnsafe({ - bytes, - cid, - value, - codec - }) -} - -export { encode, decode, create, createUnsafe, Block } diff --git a/src/block.ts b/src/block.ts new file mode 100644 index 00000000..e24fdcdc --- /dev/null +++ b/src/block.ts @@ -0,0 +1,211 @@ +import { bytes as binary, CID } from './index.js' +import type * as API from './interface.js' + +function readonly ({ enumerable = true, configurable = false } = {}): { enumerable: boolean, configurable: boolean, writable: false } { + return { enumerable, configurable, writable: false } +} + +function * linksWithin (path: [string | number, string], value: any): Iterable<[string, CID]> { + if (value != null && typeof value === 'object') { + if (Array.isArray(value)) { + for (const [index, element] of value.entries()) { + const elementPath = [...path, index] + const cid = CID.asCID(element) + if (cid != null) { + yield [elementPath.join('/'), cid] + } else if (typeof element === 'object') { + yield * links(element, elementPath) + } + } + } else { + const cid = CID.asCID(value) + if (cid != null) { + yield [path.join('/'), cid] + } else { + yield * links(value, path) + } + } + } +} + +function * links (source: T, base: Array): Iterable<[string, CID]> { + if (source == null || source instanceof Uint8Array) { + return + } + const cid = CID.asCID(source) + if (cid != null) { + yield [base.join('/'), cid] + } + for (const [key, value] of Object.entries(source)) { + const path = ([...base, key]) as [string | number, string] + yield * linksWithin(path, value) + } +} + +function * treeWithin (path: [string | number, string], value: any): Iterable { + if (Array.isArray(value)) { + for (const [index, element] of value.entries()) { + const elementPath = [...path, index] + yield elementPath.join('/') + if (typeof element === 'object' && (CID.asCID(element) == null)) { + yield * tree(element, elementPath) + } + } + } else { + yield * tree(value, path) + } +} + +function * tree (source: T, base: Array): Iterable { + if (source == null || typeof source !== 'object') { + return + } + for (const [key, value] of Object.entries(source)) { + const path = ([...base, key] as [string | number, string]) + yield path.join('/') + if (value != null && !(value instanceof Uint8Array) && typeof value === 'object' && (CID.asCID(value) == null)) { + yield * treeWithin(path, value) + } + } +} + +function get (source: T, path: string[]): API.BlockCursorView { + let node = (source as Record) + for (const [index, key] of path.entries()) { + node = node[key] + if (node == null) { + throw new Error(`Object has no property at ${path.slice(0, index + 1).map(part => `[${JSON.stringify(part)}]`).join('')}`) + } + const cid = CID.asCID(node) + if (cid != null) { + return { value: cid, remaining: path.slice(index + 1).join('/') } + } + } + return { value: node } +} + +/** + * @template T - Logical type of the data encoded in the block + * @template C - multicodec code corresponding to codec used to encode the block + * @template A - multicodec code corresponding to the hashing algorithm used in CID creation. + * @template V - CID version + */ +class Block implements API.BlockView { + readonly cid: CID + readonly bytes: API.ByteView + readonly value: T + readonly asBlock: this + + constructor ({ cid, bytes, value }: { cid: CID, bytes: API.ByteView, value: T }) { + if (cid == null || bytes == null || typeof value === 'undefined') { throw new Error('Missing required argument') } + + this.cid = cid + this.bytes = bytes + this.value = value + this.asBlock = this + + // Mark all the properties immutable + Object.defineProperties(this, { + cid: readonly(), + bytes: readonly(), + value: readonly(), + asBlock: readonly() + }) + } + + links (): Iterable<[string, CID]> { + return links(this.value, []) + } + + tree (): Iterable { + return tree(this.value, []) + } + + get (path = '/'): API.BlockCursorView { + return get(this.value, path.split('/').filter(Boolean)) + } +} + +/** + * @template T - Logical type of the data encoded in the block + * @template Code - multicodec code corresponding to codec used to encode the block + * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. + */ +async function encode ({ value, codec, hasher }: { value: T, codec: API.BlockEncoder, hasher: API.MultihashHasher }): Promise> { + if (typeof value === 'undefined') throw new Error('Missing required argument "value"') + if (codec == null || hasher == null) throw new Error('Missing required argument: codec or hasher') + + const bytes = codec.encode(value) + const hash = await hasher.digest(bytes) + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const cid = CID.create( + 1, + codec.code, + hash + ) as CID + + return new Block({ value, bytes, cid }) +} + +/** + * @template T - Logical type of the data encoded in the block + * @template Code - multicodec code corresponding to codec used to encode the block + * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. + */ +async function decode ({ bytes, codec, hasher }: { bytes: API.ByteView, codec: API.BlockDecoder, hasher: API.MultihashHasher }): Promise> { + if (bytes == null) throw new Error('Missing required argument "bytes"') + if (codec == null || hasher == null) throw new Error('Missing required argument: codec or hasher') + + const value = codec.decode(bytes) + const hash = await hasher.digest(bytes) + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const cid = CID.create(1, codec.code, hash) as CID + + return new Block({ value, bytes, cid }) +} + +/** + * @template T - Logical type of the data encoded in the block + * @template Code - multicodec code corresponding to codec used to encode the block + * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. + * @template V - CID version + */ +function createUnsafe ({ bytes, cid, value: maybeValue, codec }: { cid: API.Link, value: T, codec?: API.BlockDecoder, bytes: API.ByteView } | { cid: API.Link, bytes: API.ByteView, value?: undefined, codec: API.BlockDecoder }): API.BlockView { + const value = maybeValue !== undefined + ? maybeValue + : (codec?.decode(bytes)) + + if (value === undefined) throw new Error('Missing required argument, must either provide "value" or "codec"') + + return new Block({ + // eslint-disable-next-line object-shorthand + cid: (cid as CID), + bytes, + value + }) +} + +/** + * @template T - Logical type of the data encoded in the block + * @template Code - multicodec code corresponding to codec used to encode the block + * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. + * @template V - CID version + */ +async function create ({ bytes, cid, hasher, codec }: { bytes: API.ByteView, cid: API.Link, hasher: API.MultihashHasher, codec: API.BlockDecoder }): Promise> { + if (bytes == null) throw new Error('Missing required argument "bytes"') + if (hasher == null) throw new Error('Missing required argument "hasher"') + const value = codec.decode(bytes) + const hash = await hasher.digest(bytes) + if (!binary.equals(cid.multihash.bytes, hash.bytes)) { + throw new Error('CID hash does not match bytes') + } + + return createUnsafe({ + bytes, + cid, + value, + codec + }) +} + +export { encode, decode, create, createUnsafe, Block } diff --git a/src/block/interface.js b/src/block/interface.js deleted file mode 100644 index d9b3f4f7..00000000 --- a/src/block/interface.js +++ /dev/null @@ -1 +0,0 @@ -// this is dummy module overlayed by interface.ts diff --git a/src/block/interface.ts b/src/block/interface.ts index df583589..656b7372 100644 --- a/src/block/interface.ts +++ b/src/block/interface.ts @@ -1,7 +1,5 @@ -/* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */ -/* eslint-disable no-use-before-define */ -import { Link, Version } from '../link/interface.js' -import { CID } from '../cid.js' +import type { Link, Version } from '../link/interface.js' +import type { CID } from '../cid.js' /** * A byte-encoded representation of some type of `Data`. @@ -54,7 +52,7 @@ export interface Block< cid: Link } -export type BlockCursorView = +export type BlockCursorView = | { value: T, remaining?: undefined } | { value: CID, remaining: string } diff --git a/src/bytes.js b/src/bytes.js deleted file mode 100644 index a10ce3ec..00000000 --- a/src/bytes.js +++ /dev/null @@ -1,67 +0,0 @@ -const empty = new Uint8Array(0) - -/** - * @param {Uint8Array} d - */ -const toHex = d => d.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '') - -/** - * @param {string} hex - */ -const fromHex = hex => { - const hexes = hex.match(/../g) - return hexes ? new Uint8Array(hexes.map(b => parseInt(b, 16))) : empty -} - -/** - * @param {Uint8Array} aa - * @param {Uint8Array} bb - */ -const equals = (aa, bb) => { - if (aa === bb) return true - if (aa.byteLength !== bb.byteLength) { - return false - } - - for (let ii = 0; ii < aa.byteLength; ii++) { - if (aa[ii] !== bb[ii]) { - return false - } - } - - return true -} - -/** - * @param {ArrayBufferView|ArrayBuffer|Uint8Array} o - * @returns {Uint8Array} - */ -const coerce = o => { - if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') return o - if (o instanceof ArrayBuffer) return new Uint8Array(o) - if (ArrayBuffer.isView(o)) { - return new Uint8Array(o.buffer, o.byteOffset, o.byteLength) - } - throw new Error('Unknown type, must be binary type') -} - -/** - * @param {any} o - * @returns {o is ArrayBuffer|ArrayBufferView} - */ -const isBinary = o => - o instanceof ArrayBuffer || ArrayBuffer.isView(o) - -/** - * @param {string} str - * @returns {Uint8Array} - */ -const fromString = str => (new TextEncoder()).encode(str) - -/** - * @param {Uint8Array} b - * @returns {string} - */ -const toString = b => (new TextDecoder()).decode(b) - -export { equals, coerce, isBinary, fromHex, toHex, fromString, toString, empty } diff --git a/src/bytes.ts b/src/bytes.ts new file mode 100644 index 00000000..e66a1cf0 --- /dev/null +++ b/src/bytes.ts @@ -0,0 +1,41 @@ +const empty = new Uint8Array(0) + +const toHex = (d: Uint8Array): string => d.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '') + +const fromHex = (hex: string): Uint8Array => { + const hexes = hex.match(/../g) + return hexes != null ? new Uint8Array(hexes.map(b => parseInt(b, 16))) : empty +} + +const equals = (aa: Uint8Array, bb: Uint8Array): boolean => { + if (aa === bb) return true + if (aa.byteLength !== bb.byteLength) { + return false + } + + for (let ii = 0; ii < aa.byteLength; ii++) { + if (aa[ii] !== bb[ii]) { + return false + } + } + + return true +} + +const coerce = (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array => { + if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') return o + if (o instanceof ArrayBuffer) return new Uint8Array(o) + if (ArrayBuffer.isView(o)) { + return new Uint8Array(o.buffer, o.byteOffset, o.byteLength) + } + throw new Error('Unknown type, must be binary type') +} + +const isBinary = (o: unknown): o is ArrayBuffer | ArrayBufferView => + o instanceof ArrayBuffer || ArrayBuffer.isView(o) + +const fromString = (str: string): Uint8Array => (new TextEncoder()).encode(str) + +const toString = (b: Uint8Array): string => (new TextDecoder()).decode(b) + +export { equals, coerce, isBinary, fromHex, toHex, fromString, toString, empty } diff --git a/src/cid.js b/src/cid.ts similarity index 56% rename from src/cid.js rename to src/cid.ts index 852b3d53..9de15dc3 100644 --- a/src/cid.js +++ b/src/cid.ts @@ -3,62 +3,39 @@ import * as Digest from './hashes/digest.js' import { base58btc } from './bases/base58.js' import { base32 } from './bases/base32.js' import { coerce } from './bytes.js' -// Linter can see that API is used in types. -// eslint-disable-next-line -import * as API from "./link/interface.js" +import type * as API from './link/interface.js' // This way TS will also expose all the types from module export * from './link/interface.js' -/** - * @template {API.Link} T - * @template {string} Prefix - * @param {T} link - * @param {API.MultibaseEncoder} [base] - * @returns {API.ToString} - */ -export const format = (link, base) => { +export const format = , Prefix extends string>(link: T, base?: API.MultibaseEncoder): API.ToString => { const { bytes, version } = link switch (version) { case 0: return toStringV0( bytes, baseCache(link), - /** @type {API.MultibaseEncoder<"z">} */ (base) || base58btc.encoder + (base as API.MultibaseEncoder<'z'>) ?? base58btc.encoder ) default: return toStringV1( bytes, baseCache(link), - /** @type {API.MultibaseEncoder} */ (base || base32.encoder) + (base ?? base32.encoder) as API.MultibaseEncoder ) } } -/** - * @template {API.UnknownLink} Link - * @param {Link} link - * @returns {API.LinkJSON} - */ -export const toJSON = (link) => ({ +export const toJSON = (link: Link): API.LinkJSON => ({ '/': format(link) }) -/** - * @template {API.UnknownLink} Link - * @param {API.LinkJSON} json - */ -export const fromJSON = (json) => +export const fromJSON = (json: API.LinkJSON): CID => CID.parse(json['/']) -/** @type {WeakMap>} */ -const cache = new WeakMap() +const cache: WeakMap> = new WeakMap() -/** - * @param {API.UnknownLink} cid - * @returns {Map} - */ -const baseCache = cid => { +const baseCache = (cid: API.UnknownLink): Map => { const baseCache = cache.get(cid) if (baseCache == null) { const baseCache = new Map() @@ -68,35 +45,26 @@ const baseCache = cid => { return baseCache } -/** - * @template {unknown} [Data=unknown] - * @template {number} [Format=number] - * @template {number} [Alg=number] - * @template {API.Version} [Version=API.Version] - * @implements {API.Link} - */ +export class CID implements API.Link { + readonly code: Format + readonly version: Version + readonly multihash: API.MultihashDigest + readonly bytes: Uint8Array + readonly '/': Uint8Array -export class CID { /** - * @param {Version} version - Version of the CID - * @param {Format} code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv - * @param {API.MultihashDigest} multihash - (Multi)hash of the of the content. - * @param {Uint8Array} bytes - * + * @param version - Version of the CID + * @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv + * @param multihash - (Multi)hash of the of the content. */ - constructor (version, code, multihash, bytes) { - /** @readonly */ + constructor (version: Version, code: Format, multihash: API.MultihashDigest, bytes: Uint8Array) { this.code = code - /** @readonly */ this.version = version - /** @readonly */ this.multihash = multihash - /** @readonly */ this.bytes = bytes // flag to serializers that this is a CID and // should be treated specially - /** @readonly */ this['/'] = bytes } @@ -106,27 +74,24 @@ export class CID { * * @deprecated */ - get asCID () { + get asCID (): this { return this } // ArrayBufferView - get byteOffset () { + get byteOffset (): number { return this.bytes.byteOffset } // ArrayBufferView - get byteLength () { + get byteLength (): number { return this.bytes.byteLength } - /** - * @returns {CID} - */ - toV0 () { + toV0 (): CID { switch (this.version) { case 0: { - return /** @type {CID} */ (this) + return (this as CID) } case 1: { const { code, multihash } = this @@ -140,9 +105,9 @@ export class CID { throw new Error('Cannot convert non sha2-256 multihash CID to CIDv0') } - return /** @type {CID} */ ( + return ( CID.createV0( - /** @type {API.MultihashDigest} */ (multihash) + (multihash as API.MultihashDigest) ) ) } @@ -154,20 +119,17 @@ export class CID { } } - /** - * @returns {CID} - */ - toV1 () { + toV1 (): CID { switch (this.version) { case 0: { const { code, digest } = this.multihash const multihash = Digest.create(code, digest) - return /** @type {CID} */ ( + return ( CID.createV1(this.code, multihash) ) } case 1: { - return /** @type {CID} */ (this) + return (this as CID) } default: { throw Error( @@ -177,59 +139,42 @@ export class CID { } } - /** - * @param {unknown} other - * @returns {other is CID} - */ - equals (other) { + equals (other: unknown): other is CID { return CID.equals(this, other) } - /** - * @template {unknown} Data - * @template {number} Format - * @template {number} Alg - * @template {API.Version} Version - * @param {API.Link} self - * @param {unknown} other - * @returns {other is CID} - */ - static equals (self, other) { + static equals (self: API.Link, other: unknown): other is CID { const unknown = - /** @type {{code?:unknown, version?:unknown, multihash?:unknown}} */ ( - other + ( + other as { code?: unknown, version?: unknown, multihash?: unknown } ) return ( - unknown && + unknown != null && self.code === unknown.code && self.version === unknown.version && Digest.equals(self.multihash, unknown.multihash) ) } - /** - * @param {API.MultibaseEncoder} [base] - * @returns {string} - */ - toString (base) { + toString (base?: API.MultibaseEncoder): string { return format(this, base) } - toJSON () { + toJSON (): { '/': API.ToString, string> } { return { '/': format(this) } } - link () { + link (): this { return this } - get [Symbol.toStringTag] () { + get [Symbol.toStringTag] (): string { return 'CID' } // Legacy - [Symbol.for('nodejs.util.inspect.custom')] () { + [Symbol.for('nodejs.util.inspect.custom')] (): string { return `CID(${this.toString()})` } @@ -242,21 +187,13 @@ export class CID { * * This allows two different incompatible versions of CID library to * co-exist and interop as long as binary interface is compatible. - * - * @template {unknown} Data - * @template {number} Format - * @template {number} Alg - * @template {API.Version} Version - * @template {unknown} U - * @param {API.Link|U} input - * @returns {CID|null} */ - static asCID (input) { + static asCID (input: API.Link | U): CID | null { if (input == null) { return null } - const value = /** @type {any} */ (input) + const value = (input as any) if (value instanceof CID) { // If value is instance of CID then we're all set. return value @@ -270,8 +207,8 @@ export class CID { return new CID( version, code, - /** @type {API.MultihashDigest} */ (multihash), - bytes || encodeCID(version, code, multihash.bytes) + (multihash as API.MultihashDigest), + bytes ?? encodeCID(version, code, multihash.bytes) ) } else if (value[cidSymbol] === true) { // If value is a CID from older implementation that used to be tagged via @@ -279,8 +216,7 @@ export class CID { // delegating that to a constructor. const { version, multihash, code } = value const digest = - /** @type {API.MultihashDigest} */ - (Digest.decode(multihash)) + (Digest.decode(multihash) as API.MultihashDigest) return CID.create(version, code, digest) } else { // Otherwise value is not a CID (or an incompatible version of it) in @@ -290,17 +226,11 @@ export class CID { } /** - * - * @template {unknown} Data - * @template {number} Format - * @template {number} Alg - * @template {API.Version} Version - * @param {Version} version - Version of the CID - * @param {Format} code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv - * @param {API.MultihashDigest} digest - (Multi)hash of the of the content. - * @returns {CID} + * @param version - Version of the CID + * @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv + * @param digest - (Multi)hash of the of the content. */ - static create (version, code, digest) { + static create (version: Version, code: Format, digest: API.MultihashDigest): CID { if (typeof code !== 'number') { throw new Error('String codecs are no longer supported') } @@ -331,26 +261,18 @@ export class CID { /** * Simplified version of `create` for CIDv0. - * - * @template {unknown} [T=unknown] - * @param {API.MultihashDigest} digest - Multihash. - * @returns {CID} */ - static createV0 (digest) { + static createV0 (digest: API.MultihashDigest): CID { return CID.create(0, DAG_PB_CODE, digest) } /** * Simplified version of `create` for CIDv1. * - * @template {unknown} Data - * @template {number} Code - * @template {number} Alg - * @param {Code} code - Content encoding format code. - * @param {API.MultihashDigest} digest - Miltihash of the content. - * @returns {CID} + * @param code - Content encoding format code. + * @param digest - Multihash of the content. */ - static createV1 (code, digest) { + static createV1 (code: Code, digest: API.MultihashDigest): CID { return CID.create(1, code, digest) } @@ -360,17 +282,10 @@ export class CID { * * An error will be thrown if the bytes provided do not contain a valid * binary representation of a CID. - * - * @template {unknown} Data - * @template {number} Code - * @template {number} Alg - * @template {API.Version} Ver - * @param {API.ByteView>} bytes - * @returns {CID} */ - static decode (bytes) { + static decode (bytes: API.ByteView>): CID { const [cid, remainder] = CID.decodeFirst(bytes) - if (remainder.length) { + if (remainder.length !== 0) { throw new Error('Incorrect length') } return cid @@ -384,15 +299,8 @@ export class CID { * element containing the remainder of the original byte array. The remainder * will be a zero-length byte array if the provided bytes only contained a * binary CID representation. - * - * @template {unknown} T - * @template {number} C - * @template {number} A - * @template {API.Version} V - * @param {API.ByteView>} bytes - * @returns {[CID, Uint8Array]} */ - static decodeFirst (bytes) { + static decodeFirst (bytes: API.ByteView>): [CID, Uint8Array] { const specs = CID.inspectBytes(bytes) const prefixSize = specs.size - specs.multihashSize const multihashBytes = coerce( @@ -412,9 +320,9 @@ export class CID { ) const cid = specs.version === 0 - ? CID.createV0(/** @type {API.MultihashDigest} */ (digest)) + ? CID.createV0((digest as API.MultihashDigest)) : CID.createV1(specs.codec, digest) - return [/** @type {CID} */(cid), bytes.subarray(specs.size)] + return [(cid as CID), bytes.subarray(specs.size)] } /** @@ -425,30 +333,23 @@ export class CID { * lengths these varints can be quite large. It is recommended that at least * 10 bytes be made available in the `initialBytes` argument for a complete * inspection. - * - * @template {unknown} T - * @template {number} C - * @template {number} A - * @template {API.Version} V - * @param {API.ByteView>} initialBytes - * @returns {{ version:V, codec:C, multihashCode:A, digestSize:number, multihashSize:number, size:number }} */ - static inspectBytes (initialBytes) { + static inspectBytes (initialBytes: API.ByteView>): { version: V, codec: C, multihashCode: A, digestSize: number, multihashSize: number, size: number } { let offset = 0 - const next = () => { + const next = (): number => { const [i, length] = varint.decode(initialBytes.subarray(offset)) offset += length return i } - let version = /** @type {V} */ (next()) - let codec = /** @type {C} */ (DAG_PB_CODE) - if (/** @type {number} */(version) === 18) { + let version = (next() as V) + let codec = (DAG_PB_CODE as C) + if ((version as number) === 18) { // CIDv0 - version = /** @type {V} */ (0) + version = (0 as V) offset = 0 } else { - codec = /** @type {C} */ (next()) + codec = (next() as C) } if (version !== 0 && version !== 1) { @@ -456,7 +357,7 @@ export class CID { } const prefixSize = offset - const multihashCode = /** @type {A} */ (next()) // multihash code + const multihashCode = (next() as A) // multihash code const digestSize = next() // multihash length const size = offset + digestSize const multihashSize = size - prefixSize @@ -469,17 +370,8 @@ export class CID { * decoder is not provided will use a default from the configuration. It will * throw an error if encoding of the CID is not compatible with supplied (or * a default decoder). - * - * @template {string} Prefix - * @template {unknown} Data - * @template {number} Code - * @template {number} Alg - * @template {API.Version} Ver - * @param {API.ToString, Prefix>} source - * @param {API.MultibaseDecoder} [base] - * @returns {CID} */ - static parse (source, base) { + static parse (source: API.ToString, Prefix>, base?: API.MultibaseDecoder): CID { const [prefix, bytes] = parseCIDtoBytes(source, base) const cid = CID.decode(bytes) @@ -495,33 +387,23 @@ export class CID { } } -/** - * @template {string} Prefix - * @template {unknown} Data - * @template {number} Code - * @template {number} Alg - * @template {API.Version} Ver - * @param {API.ToString, Prefix>} source - * @param {API.MultibaseDecoder} [base] - * @returns {[Prefix, API.ByteView>]} - */ -const parseCIDtoBytes = (source, base) => { +const parseCIDtoBytes = (source: API.ToString, Prefix>, base?: API.MultibaseDecoder): [Prefix, API.ByteView>] => { switch (source[0]) { // CIDv0 is parsed differently case 'Q': { - const decoder = base || base58btc + const decoder = base ?? base58btc return [ - /** @type {Prefix} */ (base58btc.prefix), + (base58btc.prefix as Prefix), decoder.decode(`${base58btc.prefix}${source}`) ] } case base58btc.prefix: { - const decoder = base || base58btc - return [/** @type {Prefix} */(base58btc.prefix), decoder.decode(source)] + const decoder = base ?? base58btc + return [(base58btc.prefix as Prefix), decoder.decode(source)] } case base32.prefix: { - const decoder = base || base32 - return [/** @type {Prefix} */(base32.prefix), decoder.decode(source)] + const decoder = base ?? base32 + return [(base32.prefix as Prefix), decoder.decode(source)] } default: { if (base == null) { @@ -529,18 +411,12 @@ const parseCIDtoBytes = (source, base) => { 'To parse non base32 or base58btc encoded CID multibase decoder must be provided' ) } - return [/** @type {Prefix} */(source[0]), base.decode(source)] + return [(source[0] as Prefix), base.decode(source)] } } } -/** - * - * @param {Uint8Array} bytes - * @param {Map} cache - * @param {API.MultibaseEncoder<'z'>} base - */ -const toStringV0 = (bytes, cache, base) => { +const toStringV0 = (bytes: Uint8Array, cache: Map, base: API.MultibaseEncoder<'z'>): string => { const { prefix } = base if (prefix !== base58btc.prefix) { throw Error(`Cannot string encode V0 in ${base.name} encoding`) @@ -556,13 +432,7 @@ const toStringV0 = (bytes, cache, base) => { } } -/** - * @template {string} Prefix - * @param {Uint8Array} bytes - * @param {Map} cache - * @param {API.MultibaseEncoder} base - */ -const toStringV1 = (bytes, cache, base) => { +const toStringV1 = (bytes: Uint8Array, cache: Map, base: API.MultibaseEncoder): string => { const { prefix } = base const cid = cache.get(prefix) if (cid == null) { @@ -577,13 +447,7 @@ const toStringV1 = (bytes, cache, base) => { const DAG_PB_CODE = 0x70 const SHA_256_CODE = 0x12 -/** - * @param {API.Version} version - * @param {number} code - * @param {Uint8Array} multihash - * @returns {Uint8Array} - */ -const encodeCID = (version, code, multihash) => { +const encodeCID = (version: API.Version, code: number, multihash: Uint8Array): Uint8Array => { const codeOffset = varint.encodingLength(version) const hashOffset = codeOffset + varint.encodingLength(code) const bytes = new Uint8Array(hashOffset + multihash.byteLength) diff --git a/src/codecs/interface.js b/src/codecs/interface.js deleted file mode 100644 index d9b3f4f7..00000000 --- a/src/codecs/interface.js +++ /dev/null @@ -1 +0,0 @@ -// this is dummy module overlayed by interface.ts diff --git a/src/codecs/json.js b/src/codecs/json.js deleted file mode 100644 index c3028430..00000000 --- a/src/codecs/json.js +++ /dev/null @@ -1,26 +0,0 @@ -// @ts-check - -/** - * @template T - * @typedef {import('./interface.js').ByteView} ByteView - */ - -const textEncoder = new TextEncoder() -const textDecoder = new TextDecoder() - -export const name = 'json' -export const code = 0x0200 - -/** - * @template T - * @param {T} node - * @returns {ByteView} - */ -export const encode = (node) => textEncoder.encode(JSON.stringify(node)) - -/** - * @template T - * @param {ByteView} data - * @returns {T} - */ -export const decode = (data) => JSON.parse(textDecoder.decode(data)) diff --git a/src/codecs/json.ts b/src/codecs/json.ts new file mode 100644 index 00000000..7dd8a7ec --- /dev/null +++ b/src/codecs/json.ts @@ -0,0 +1,11 @@ +import type { ByteView } from './interface.js' + +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() + +export const name = 'json' +export const code = 0x0200 + +export const encode = (node: T): ByteView => textEncoder.encode(JSON.stringify(node)) + +export const decode = (data: ByteView): T => JSON.parse(textDecoder.decode(data)) diff --git a/src/codecs/raw.js b/src/codecs/raw.js deleted file mode 100644 index 7a9c7815..00000000 --- a/src/codecs/raw.js +++ /dev/null @@ -1,23 +0,0 @@ -// @ts-check - -import { coerce } from '../bytes.js' - -/** - * @template T - * @typedef {import('./interface.js').ByteView} ByteView - */ - -export const name = 'raw' -export const code = 0x55 - -/** - * @param {Uint8Array} node - * @returns {ByteView} - */ -export const encode = (node) => coerce(node) - -/** - * @param {ByteView} data - * @returns {Uint8Array} - */ -export const decode = (data) => coerce(data) diff --git a/src/codecs/raw.ts b/src/codecs/raw.ts new file mode 100644 index 00000000..db7fdddd --- /dev/null +++ b/src/codecs/raw.ts @@ -0,0 +1,9 @@ +import { coerce } from '../bytes.js' +import type { ByteView } from './interface.js' + +export const name = 'raw' +export const code = 0x55 + +export const encode = (node: Uint8Array): ByteView => coerce(node) + +export const decode = (data: ByteView): Uint8Array => coerce(data) diff --git a/src/hashes/digest.js b/src/hashes/digest.ts similarity index 63% rename from src/hashes/digest.js rename to src/hashes/digest.ts index 0653b685..c7215256 100644 --- a/src/hashes/digest.js +++ b/src/hashes/digest.ts @@ -1,14 +1,11 @@ import { coerce, equals as equalBytes } from '../bytes.js' import * as varint from '../varint.js' +import type { MultihashDigest } from './interface.js' /** * Creates a multihash digest. - * - * @template {number} Code - * @param {Code} code - * @param {Uint8Array} digest */ -export const create = (code, digest) => { +export const create = (code: Code, digest: Uint8Array): Digest => { const size = digest.byteLength const sizeOffset = varint.encodingLength(code) const digestOffset = sizeOffset + varint.encodingLength(size) @@ -23,11 +20,8 @@ export const create = (code, digest) => { /** * Turns bytes representation of multihash digest into an instance. - * - * @param {Uint8Array} multihash - * @returns {MultihashDigest} */ -export const decode = (multihash) => { +export const decode = (multihash: Uint8Array): MultihashDigest => { const bytes = coerce(multihash) const [code, sizeOffset] = varint.decode(bytes) const [size, digestOffset] = varint.decode(bytes.subarray(sizeOffset)) @@ -40,16 +34,11 @@ export const decode = (multihash) => { return new Digest(code, size, digest, bytes) } -/** - * @param {MultihashDigest} a - * @param {unknown} b - * @returns {b is MultihashDigest} - */ -export const equals = (a, b) => { +export const equals = (a: MultihashDigest, b: unknown): b is MultihashDigest => { if (a === b) { return true } else { - const data = /** @type {{code?:unknown, size?:unknown, bytes?:unknown}} */(b) + const data = (b as { code?: unknown, size?: unknown, bytes?: unknown }) return ( a.code === data.code && @@ -60,29 +49,20 @@ export const equals = (a, b) => { } } -/** - * @typedef {import('./interface.js').MultihashDigest} MultihashDigest - */ - /** * Represents a multihash digest which carries information about the * hashing algorithm and an actual hash digest. - * - * @template {number} Code - * @template {number} Size - * @class - * @implements {MultihashDigest} */ -export class Digest { +export class Digest implements MultihashDigest { + readonly code: Code + readonly size: Size + readonly digest: Uint8Array + readonly bytes: Uint8Array + /** * Creates a multihash digest. - * - * @param {Code} code - * @param {Size} size - * @param {Uint8Array} digest - * @param {Uint8Array} bytes */ - constructor (code, size, digest, bytes) { + constructor (code: Code, size: Size, digest: Uint8Array, bytes: Uint8Array) { this.code = code this.size = size this.digest = digest diff --git a/src/hashes/hasher.js b/src/hashes/hasher.js deleted file mode 100644 index ac095857..00000000 --- a/src/hashes/hasher.js +++ /dev/null @@ -1,61 +0,0 @@ -import * as Digest from './digest.js' - -/** - * @template {string} Name - * @template {number} Code - * @param {object} options - * @param {Name} options.name - * @param {Code} options.code - * @param {(input: Uint8Array) => Await} options.encode - */ -export const from = ({ name, code, encode }) => new Hasher(name, code, encode) - -/** - * Hasher represents a hashing algorithm implementation that produces as - * `MultihashDigest`. - * - * @template {string} Name - * @template {number} Code - * @class - * @implements {MultihashHasher} - */ -export class Hasher { - /** - * - * @param {Name} name - * @param {Code} code - * @param {(input: Uint8Array) => Await} encode - */ - constructor (name, code, encode) { - this.name = name - this.code = code - this.encode = encode - } - - /** - * @param {Uint8Array} input - * @returns {Await>} - */ - digest (input) { - if (input instanceof Uint8Array) { - const result = this.encode(input) - return result instanceof Uint8Array - ? Digest.create(this.code, result) - /* c8 ignore next 1 */ - : result.then(digest => Digest.create(this.code, digest)) - } else { - throw Error('Unknown type, must be binary type') - /* c8 ignore next 1 */ - } - } -} - -/** - * @template {number} Alg - * @typedef {import('./interface.js').MultihashHasher} MultihashHasher - */ - -/** - * @template T - * @typedef {Promise|T} Await - */ diff --git a/src/hashes/hasher.ts b/src/hashes/hasher.ts new file mode 100644 index 00000000..e19d63bc --- /dev/null +++ b/src/hashes/hasher.ts @@ -0,0 +1,35 @@ +import * as Digest from './digest.js' +import type { MultihashHasher } from './interface.js' + +type Await = Promise | T + +export const from = ({ name, code, encode }: { name: Name, code: Code, encode: (input: Uint8Array) => Await }): Hasher => new Hasher(name, code, encode) + +/** + * Hasher represents a hashing algorithm implementation that produces as + * `MultihashDigest`. + */ +export class Hasher implements MultihashHasher { + readonly name: Name + readonly code: Code + readonly encode: (input: Uint8Array) => Await + + constructor (name: Name, code: Code, encode: (input: Uint8Array) => Await) { + this.name = name + this.code = code + this.encode = encode + } + + digest (input: Uint8Array): Await> { + if (input instanceof Uint8Array) { + const result = this.encode(input) + return result instanceof Uint8Array + ? Digest.create(this.code, result) + /* c8 ignore next 1 */ + : result.then(digest => Digest.create(this.code, digest)) + } else { + throw Error('Unknown type, must be binary type') + /* c8 ignore next 1 */ + } + } +} diff --git a/src/hashes/identity.js b/src/hashes/identity.js deleted file mode 100644 index 45e82458..00000000 --- a/src/hashes/identity.js +++ /dev/null @@ -1,16 +0,0 @@ -import { coerce } from '../bytes.js' -import * as Digest from './digest.js' - -const code = 0x0 -const name = 'identity' - -/** @type {(input:Uint8Array) => Uint8Array} */ -const encode = coerce - -/** - * @param {Uint8Array} input - * @returns {Digest.Digest} - */ -const digest = (input) => Digest.create(code, encode(input)) - -export const identity = { code, name, encode, digest } diff --git a/src/hashes/identity.ts b/src/hashes/identity.ts new file mode 100644 index 00000000..d61d795b --- /dev/null +++ b/src/hashes/identity.ts @@ -0,0 +1,11 @@ +import { coerce } from '../bytes.js' +import * as Digest from './digest.js' + +const code = 0x0 +const name = 'identity' + +const encode: (input: Uint8Array) => Uint8Array = coerce + +const digest = (input: Uint8Array): Digest.Digest => Digest.create(code, encode(input)) + +export const identity = { code, name, encode, digest } diff --git a/src/hashes/interface.js b/src/hashes/interface.js deleted file mode 100644 index d9b3f4f7..00000000 --- a/src/hashes/interface.js +++ /dev/null @@ -1 +0,0 @@ -// this is dummy module overlayed by interface.ts diff --git a/src/hashes/interface.ts b/src/hashes/interface.ts index b7e9edf6..c3f872f4 100644 --- a/src/hashes/interface.ts +++ b/src/hashes/interface.ts @@ -41,8 +41,6 @@ export interface MultihashHasher { * either promise of a digest or a digest. This way general use can `await` * while performance critical code may asses return value to decide whether * await is needed. - * - * @param {Uint8Array} input */ digest: (input: Uint8Array) => Promise> | MultihashDigest diff --git a/src/hashes/sha2-browser.js b/src/hashes/sha2-browser.ts similarity index 74% rename from src/hashes/sha2-browser.js rename to src/hashes/sha2-browser.ts index 7f7de04a..30cade61 100644 --- a/src/hashes/sha2-browser.js +++ b/src/hashes/sha2-browser.ts @@ -2,13 +2,7 @@ import { from } from './hasher.js' -/** - * @param {AlgorithmIdentifier} name - */ -const sha = name => - /** - * @param {Uint8Array} data - */ +const sha = (name: AlgorithmIdentifier): (data: Uint8Array) => Promise => async data => new Uint8Array(await crypto.subtle.digest(name, data)) export const sha256 = from({ diff --git a/src/hashes/sha2.js b/src/hashes/sha2.ts similarity index 96% rename from src/hashes/sha2.js rename to src/hashes/sha2.ts index 20f88b6e..74542a80 100644 --- a/src/hashes/sha2.js +++ b/src/hashes/sha2.ts @@ -1,5 +1,3 @@ -// @ts-check - import crypto from 'crypto' import { from } from './hasher.js' import { coerce } from '../bytes.js' diff --git a/src/index.js b/src/index.ts similarity index 100% rename from src/index.js rename to src/index.ts diff --git a/src/interface.js b/src/interface.js deleted file mode 100644 index d9b3f4f7..00000000 --- a/src/interface.js +++ /dev/null @@ -1 +0,0 @@ -// this is dummy module overlayed by interface.ts diff --git a/src/link.js b/src/link.js deleted file mode 100644 index 0cd0a849..00000000 --- a/src/link.js +++ /dev/null @@ -1,92 +0,0 @@ -// Linter can see that API is used in types. -// eslint-disable-next-line -import * as API from "./link/interface.js" -import { CID, format, toJSON, fromJSON } from './cid.js' -// This way TS will also expose all the types from module -export * from './link/interface.js' - -const DAG_PB_CODE = 0x70 -// eslint-disable-next-line -const SHA_256_CODE = 0x12 - -/** - * Simplified version of `create` for CIDv0. - * - * @param {API.MultihashDigest} digest - Multihash. - * @returns {API.LegacyLink} - */ -export const createLegacy = digest => CID.create(0, DAG_PB_CODE, digest) - -/** - * Simplified version of `create` for CIDv1. - * - * @template {unknown} Data - * @template {number} Code - * @template {number} Alg - * @param {Code} code - Content encoding format code. - * @param {API.MultihashDigest} digest - Miltihash of the content. - * @returns {API.Link} - */ -export const create = (code, digest) => CID.create(1, code, digest) - -/** - * Type predicate returns true if value is the link. - * - * @template {API.Link} L - * @param {unknown|L} value - * @returns {value is L & CID} - */ -export const isLink = value => { - if (value == null) { - return false - } - - const withSlash = /** @type {{'/'?: Uint8Array, bytes: Uint8Array}} */ (value) - - if (withSlash['/'] != null && withSlash['/'] === withSlash.bytes) { - return true - } - - const withAsCID = /** @type {{'asCID'?: unknown}} */ (value) - - if (withAsCID.asCID === value) { - return true - } - - return false -} - -/** - * Takes cid in a string representation and creates an instance. If `base` - * decoder is not provided will use a default from the configuration. It will - * throw an error if encoding of the CID is not compatible with supplied (or - * a default decoder). - * - * @template {string} Prefix - * @template {unknown} Data - * @template {number} Code - * @template {number} Alg - * @template {API.Version} Ver - * @param {API.ToString, Prefix>} source - * @param {API.MultibaseDecoder} [base] - * @returns {API.Link} - */ -export const parse = (source, base) => CID.parse(source, base) - -export { format, toJSON, fromJSON } - -/** - * Decoded a CID from its binary representation. The byte array must contain - * only the CID with no additional bytes. - * - * An error will be thrown if the bytes provided do not contain a valid - * binary representation of a CID. - * - * @template {unknown} Data - * @template {number} Code - * @template {number} Alg - * @template {API.Version} Ver - * @param {API.ByteView>} bytes - * @returns {API.Link} - */ -export const decode = bytes => CID.decode(bytes) diff --git a/src/link.ts b/src/link.ts new file mode 100644 index 00000000..b9942ba1 --- /dev/null +++ b/src/link.ts @@ -0,0 +1,63 @@ +import type * as API from './link/interface.js' +import { CID, format, toJSON, fromJSON } from './cid.js' +// This way TS will also expose all the types from module +export * from './link/interface.js' + +const DAG_PB_CODE = 0x70 +// eslint-disable-next-line +const SHA_256_CODE = 0x12 + +/** + * Simplified version of `create` for CIDv0. + */ +export const createLegacy = (digest: API.MultihashDigest): API.LegacyLink => CID.create(0, DAG_PB_CODE, digest) + +/** + * Simplified version of `create` for CIDv1. + * + * @param code - Content encoding format code. + * @param digest - Miltihash of the content. + */ +export const create = (code: Code, digest: API.MultihashDigest): API.Link => CID.create(1, code, digest) + +/** + * Type predicate returns true if value is the link. + */ +export const isLink = >(value: unknown | L): value is L & CID => { + if (value == null) { + return false + } + + const withSlash = (value as { '/'?: Uint8Array, bytes: Uint8Array }) + + if (withSlash['/'] != null && withSlash['/'] === withSlash.bytes) { + return true + } + + const withAsCID = (value as { 'asCID'?: unknown }) + + if (withAsCID.asCID === value) { + return true + } + + return false +} + +/** + * Takes cid in a string representation and creates an instance. If `base` + * decoder is not provided will use a default from the configuration. It will + * throw an error if encoding of the CID is not compatible with supplied (or + * a default decoder). + */ +export const parse = (source: API.ToString, Prefix>, base?: API.MultibaseDecoder): API.Link => CID.parse(source, base) + +export { format, toJSON, fromJSON } + +/** + * Decoded a CID from its binary representation. The byte array must contain + * only the CID with no additional bytes. + * + * An error will be thrown if the bytes provided do not contain a valid + * binary representation of a CID. + */ +export const decode = (bytes: API.ByteView>): API.Link => CID.decode(bytes) diff --git a/src/link/interface.js b/src/link/interface.js deleted file mode 100644 index d9b3f4f7..00000000 --- a/src/link/interface.js +++ /dev/null @@ -1 +0,0 @@ -// this is dummy module overlayed by interface.ts diff --git a/src/traversal.js b/src/traversal.js deleted file mode 100644 index 0b46b086..00000000 --- a/src/traversal.js +++ /dev/null @@ -1,43 +0,0 @@ -import { base58btc } from './bases/base58.js' - -/** - * @template [C=number] - multicodec code corresponding to codec used to encode the block - * @template [A=number] - multicodec code corresponding to the hashing algorithm used in CID creation. - * @template [V=0|1] - CID version - * @typedef {import('./cid').CID} CID - */ - -/** - * @template [T=unknown] - Logical type of the data encoded in the block - * @template [C=number] - multicodec code corresponding to codec used to encode the block - * @template [A=number] - multicodec code corresponding to the hashing algorithm used in CID creation. - * @template [V=0|1] - CID version - * @typedef {import('./block/interface.js').BlockView} BlockView - */ - -/** - * @param {object} options - * @param {CID} options.cid - * @param {(cid: CID) => Promise} options.load - * @param {Set} [options.seen] - */ -const walk = async ({ cid, load, seen }) => { - seen = seen || new Set() - const b58Cid = cid.toString(base58btc) - if (seen.has(b58Cid)) { - return - } - - const block = await load(cid) - seen.add(b58Cid) - - if (block === null) { // the loader signals with `null` that we should skip this block - return - } - - for (const [, cid] of block.links()) { - await walk({ cid, load, seen }) - } -} - -export { walk } diff --git a/src/traversal.ts b/src/traversal.ts new file mode 100644 index 00000000..dc64062e --- /dev/null +++ b/src/traversal.ts @@ -0,0 +1,26 @@ +import { base58btc } from './bases/base58.js' +import type { BlockView as _BlockView } from './block/interface.js' +import type { CID, Version } from './cid.js' + +type BlockView = _BlockView + +const walk = async ({ cid, load, seen }: { cid: CID, load: (cid: CID) => Promise, seen?: Set }): Promise => { + seen = seen ?? new Set() + const b58Cid = cid.toString(base58btc) + if (seen.has(b58Cid)) { + return + } + + const block = await load(cid) + seen.add(b58Cid) + + if (block === null) { // the loader signals with `null` that we should skip this block + return + } + + for (const [, cid] of block.links()) { + await walk({ cid, load, seen }) + } +} + +export { walk } diff --git a/src/varint.js b/src/varint.js deleted file mode 100644 index d0c71eac..00000000 --- a/src/varint.js +++ /dev/null @@ -1,29 +0,0 @@ -import varint from '../vendor/varint.js' - -/** - * @param {Uint8Array} data - * @param {number} [offset=0] - * @returns {[number, number]} - */ -export const decode = (data, offset = 0) => { - const code = varint.decode(data, offset) - return [code, varint.decode.bytes] -} - -/** - * @param {number} int - * @param {Uint8Array} target - * @param {number} [offset=0] - */ -export const encodeTo = (int, target, offset = 0) => { - varint.encode(int, target, offset) - return target -} - -/** - * @param {number} int - * @returns {number} - */ -export const encodingLength = (int) => { - return varint.encodingLength(int) -} diff --git a/src/varint.ts b/src/varint.ts new file mode 100644 index 00000000..b195e961 --- /dev/null +++ b/src/varint.ts @@ -0,0 +1,15 @@ +import varint from './vendor/varint.js' + +export const decode = (data: Uint8Array, offset = 0): [number, number] => { + const code = varint.decode(data, offset) + return [code, varint.decode.bytes] +} + +export const encodeTo = (int: number, target: Uint8Array, offset = 0): Uint8Array => { + varint.encode(int, target, offset) + return target +} + +export const encodingLength = (int: number): number => { + return varint.encodingLength(int) +} diff --git a/vendor/base-x.d.ts b/src/vendor/base-x.d.ts similarity index 92% rename from vendor/base-x.d.ts rename to src/vendor/base-x.d.ts index a8665dc9..94ada8af 100644 --- a/vendor/base-x.d.ts +++ b/src/vendor/base-x.d.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ export interface BaseConverter { encode(buffer: Uint8Array | number[]): string; diff --git a/vendor/base-x.js b/src/vendor/base-x.js similarity index 94% rename from vendor/base-x.js rename to src/vendor/base-x.js index d9627414..dd396ab2 100644 --- a/vendor/base-x.js +++ b/src/vendor/base-x.js @@ -1,8 +1,13 @@ +/* eslint-disable */ // base-x encoding / decoding // Copyright (c) 2018 base-x contributors // Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp) // Distributed under the MIT software license, see the accompanying // file LICENSE or http://www.opensource.org/licenses/mit-license.php. +/** + * @param {string} ALPHABET + * @param {any} name + */ function base (ALPHABET, name) { if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') } var BASE_MAP = new Uint8Array(256); @@ -19,7 +24,11 @@ function base (ALPHABET, name) { var LEADER = ALPHABET.charAt(0); var FACTOR = Math.log(BASE) / Math.log(256); // log(BASE) / log(256), rounded up var iFACTOR = Math.log(256) / Math.log(BASE); // log(256) / log(BASE), rounded up + /** + * @param {any[] | Iterable} source + */ function encode (source) { + // @ts-ignore if (source instanceof Uint8Array) ; else if (ArrayBuffer.isView(source)) { source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); } else if (Array.isArray(source)) { @@ -63,6 +72,9 @@ function base (ALPHABET, name) { for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]); } return str } + /** + * @param {string | string[]} source + */ function decodeUnsafe (source) { if (typeof source !== 'string') { throw new TypeError('Expected String') } if (source.length === 0) { return new Uint8Array() } @@ -109,6 +121,9 @@ function base (ALPHABET, name) { } return vch } + /** + * @param {string | string[]} string + */ function decode (string) { var buffer = decodeUnsafe(string); if (buffer) { return buffer } diff --git a/vendor/varint.d.ts b/src/vendor/varint.d.ts similarity index 99% rename from vendor/varint.d.ts rename to src/vendor/varint.d.ts index f5a8a021..5d2ce74f 100644 --- a/vendor/varint.d.ts +++ b/src/vendor/varint.d.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ // Type definitions for varint 5.0 // Project: https://github.com/chrisdickinson/varint#readme // Definitions by: David Brockman Smoliansky diff --git a/vendor/varint.js b/src/vendor/varint.js similarity index 85% rename from vendor/varint.js rename to src/vendor/varint.js index fdc9f1f6..0c5e7b22 100644 --- a/vendor/varint.js +++ b/src/vendor/varint.js @@ -1,3 +1,4 @@ +/* eslint-disable */ var encode_1 = encode; var MSB = 0x80 @@ -5,6 +6,11 @@ var MSB = 0x80 , MSBALL = ~REST , INT = Math.pow(2, 31); +/** + * @param {number} num + * @param {number[]} out + * @param {number} offset + */ function encode(num, out, offset) { out = out || []; offset = offset || 0; @@ -20,6 +26,7 @@ function encode(num, out, offset) { } out[offset] = num | 0; + // @ts-ignore encode.bytes = offset - oldOffset + 1; return out @@ -30,6 +37,10 @@ var decode = read; var MSB$1 = 0x80 , REST$1 = 0x7F; +/** + * @param {string | any[]} buf + * @param {number} offset + */ function read(buf, offset) { var res = 0 , offset = offset || 0 @@ -40,6 +51,7 @@ function read(buf, offset) { do { if (counter >= l) { + // @ts-ignore read.bytes = 0; throw new RangeError('Could not decode varint') } @@ -50,6 +62,7 @@ function read(buf, offset) { shift += 7; } while (b >= MSB$1) + // @ts-ignore read.bytes = counter - offset; return res @@ -65,7 +78,7 @@ var N7 = Math.pow(2, 49); var N8 = Math.pow(2, 56); var N9 = Math.pow(2, 63); -var length = function (value) { +var length = function (/** @type {number} */ value) { return ( value < N1 ? 1 : value < N2 ? 2 diff --git a/test/fixtures/invalid-multihash.js b/test/fixtures/invalid-multihash.ts similarity index 100% rename from test/fixtures/invalid-multihash.js rename to test/fixtures/invalid-multihash.ts diff --git a/test/fixtures/valid-multihash.js b/test/fixtures/valid-multihash.ts similarity index 100% rename from test/fixtures/valid-multihash.js rename to test/fixtures/valid-multihash.ts diff --git a/test/test-block.spec.js b/test/test-block.spec.ts similarity index 100% rename from test/test-block.spec.js rename to test/test-block.spec.ts diff --git a/test/test-bytes.spec.js b/test/test-bytes.spec.ts similarity index 100% rename from test/test-bytes.spec.js rename to test/test-bytes.spec.ts diff --git a/test/test-cid.spec.js b/test/test-cid.spec.ts similarity index 93% rename from test/test-cid.spec.js rename to test/test-cid.spec.ts index e6a6b806..a3b52b42 100644 --- a/test/test-cid.spec.js +++ b/test/test-cid.spec.ts @@ -1,7 +1,7 @@ /* globals describe, it */ import { fromHex, toHex, equals } from '../src/bytes.js' -import { varint, CID } from '../src/index.js' +import { varint, CID, MultihashDigest } from '../src/index.js' import { base58btc } from '../src/bases/base58.js' import { base32 } from '../src/bases/base32.js' import { base64 } from '../src/bases/base64.js' @@ -9,9 +9,6 @@ import { sha256, sha512 } from '../src/hashes/sha2.js' import invalidMultihash from './fixtures/invalid-multihash.js' import OLDCID from 'cids' import { assert } from 'aegir/chai' -// Linter can see that API is used in types. -// eslint-disable-next-line -import * as API from 'multiformats' const textEncoder = new TextEncoder() @@ -107,7 +104,7 @@ describe('CID', () => { it('should construct from an old CID', () => { const cidStr = 'QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n' const oldCid = CID.parse(cidStr) - const newCid = /** @type {CID} */ (CID.asCID(oldCid)) + const newCid = (CID.asCID(oldCid) as CID) assert.deepStrictEqual(newCid.toString(), cidStr) }) @@ -228,7 +225,7 @@ describe('CID', () => { const cidStr = 'bafybeidskjjd4zmr7oh6ku6wp72vvbxyibcli2r6if3ocdcy7jjjusvl2u' const oldCid = CID.parse(cidStr) - const newCid = /** @type {CID} */ (CID.asCID(oldCid)) + const newCid = (CID.asCID(oldCid) as CID) assert.deepStrictEqual(newCid.toString(), cidStr) }) @@ -295,7 +292,7 @@ describe('CID', () => { for (const i of parse) { const name = `CID.parse(${JSON.stringify(i)})` - it(name, async () => assert.throws(() => CID.parse(i))) + it(name, async () => { assert.throws(() => CID.parse(i)) }) } const decode = [ @@ -307,7 +304,7 @@ describe('CID', () => { const name = `CID.decode(textEncoder.encode(${JSON.stringify( i.toString() )}))` - it(name, async () => assert.throws(() => CID.decode(i))) + it(name, async () => { assert.throws(() => CID.decode(i)) }) } const create = [ @@ -322,7 +319,7 @@ describe('CID', () => { hash instanceof Uint8Array ? `textEncoder.encode(${form})` : form const name = `CID.create(${version}, ${code}, ${mh})` // @ts-expect-error - version issn't always 0|1 - it(name, async () => assert.throws(() => CID.create(version, code, hash))) + it(name, async () => { assert.throws(() => CID.create(version, code, hash)) }) } it('invalid fixtures', async () => { @@ -428,10 +425,7 @@ describe('CID', () => { const b32 = { ...base32, callCount: 0, - /** - * @param {Uint8Array} bytes - */ - encode (bytes) { + encode (bytes: Uint8Array): string { this.callCount += 1 return base32.encode(bytes) + '!' } @@ -440,10 +434,7 @@ describe('CID', () => { const b64 = { ...base64, callCount: 0, - /** - * @param {Uint8Array} bytes - */ - encode (bytes) { + encode (bytes: Uint8Array): string { this.callCount += 1 return base64.encode(bytes) } @@ -497,19 +488,19 @@ describe('CID', () => { it('asCID', async () => { const hash = await sha256.digest(textEncoder.encode('abc')) class IncompatibleCID { - /** - * @param {number} version - * @param {number} code - * @param {import('multiformats/hashes/interface').MultihashDigest} multihash - */ - constructor (version, code, multihash) { + readonly version: number + readonly code: number + readonly multihash: MultihashDigest + readonly asCID: this + + constructor (version: number, code: number, multihash: MultihashDigest) { this.version = version this.code = code this.multihash = multihash this.asCID = this } - get [Symbol.for('@ipld/js-cid/CID')] () { + get [Symbol.for('@ipld/js-cid/CID')] (): boolean { return true } } @@ -518,11 +509,12 @@ describe('CID', () => { const code = 112 const incompatibleCID = new IncompatibleCID(version, code, hash) + // eslint-disable-next-line @typescript-eslint/no-base-to-string assert.strictEqual(incompatibleCID.toString(), '[object Object]') // @ts-expect-error - no such method assert.strictEqual(typeof incompatibleCID.toV0, 'undefined') - const cid1 = /** @type {CID} */ (CID.asCID(incompatibleCID)) + const cid1 = (CID.asCID(incompatibleCID) as CID) assert.ok(cid1 instanceof CID) assert.strictEqual(cid1.code, code) assert.strictEqual(cid1.version, version) @@ -534,7 +526,7 @@ describe('CID', () => { const duckCID = { version, code, multihash: hash } // @ts-expect-error - no such property duckCID.asCID = duckCID - const cid3 = /** @type {CID} */ (CID.asCID(duckCID)) + const cid3 = (CID.asCID(duckCID) as CID) assert.ok(cid3 instanceof CID) assert.strictEqual(cid3.code, code) assert.strictEqual(cid3.version, version) @@ -543,8 +535,8 @@ describe('CID', () => { const cid4 = CID.asCID(cid3) assert.strictEqual(cid3, cid4) - const cid5 = /** @type {CID} */ ( - CID.asCID(new OLDCID(1, 'raw', Uint8Array.from(hash.bytes))) + const cid5 = ( + CID.asCID(new OLDCID(1, 'raw', Uint8Array.from(hash.bytes))) as CID ) assert.ok(cid5 instanceof CID) assert.strictEqual(cid5.version, 1) @@ -552,32 +544,24 @@ describe('CID', () => { assert.strictEqual(cid5.code, 85) }) - /** - * @param {API.CID} x - * @param {API.CID} y - */ - const digestsame = (x, y) => { - // @ts-ignore - not sure what this supposed to be + const digestsame = (x: CID, y: CID): void => { + // @ts-expect-error not sure what this supposed to be assert.deepStrictEqual(x.hash, y.hash) assert.deepStrictEqual(x.bytes, y.bytes) - if (x.multihash) { + if (x.multihash != null) { equalDigest(x.multihash, y.multihash) } const empty = { hash: null, bytes: null, digest: null, multihash: null } assert.deepStrictEqual({ ...x, ...empty }, { ...y, ...empty }) } - /** - * @typedef {import('multiformats/hashes/interface').MultihashDigest} MultihashDigest - * @param {MultihashDigest} x - * @param {MultihashDigest} y - */ - const equalDigest = (x, y) => { + const equalDigest = (x: MultihashDigest, y: MultihashDigest): void => { assert.deepStrictEqual(x.digest, y.digest) assert.deepStrictEqual(x.code, y.code) assert.deepStrictEqual(x.digest, y.digest) } + // eslint-disable-next-line @typescript-eslint/no-misused-promises describe('CID.parse', async () => { it('parse 32 encoded CIDv1', async () => { const hash = await sha256.digest(textEncoder.encode('abc')) @@ -667,8 +651,8 @@ describe('CID', () => { it('new CID from old CID', async () => { const hash = await sha256.digest(textEncoder.encode('abc')) - const cid = /** @type {CID} */ ( - CID.asCID(new OLDCID(1, 'raw', Uint8Array.from(hash.bytes))) + const cid = ( + CID.asCID(new OLDCID(1, 'raw', Uint8Array.from(hash.bytes))) as CID ) assert.deepStrictEqual(cid.version, 1) @@ -700,7 +684,7 @@ describe('CID', () => { const cid = CID.parse('bafybeif2pall7dybz7vecqka3zo24irdwabwdi4wc55jznaq75q7eaavvu') const { port1: sender, port2: receiver } = new MessageChannel() sender.postMessage(cid) - const cid2 = await new Promise((resolve) => { + const cid2 = await new Promise((resolve) => { receiver.onmessage = (event) => { resolve(event.data) } }) sender.close() diff --git a/test/test-link.spec.js b/test/test-link.spec.ts similarity index 74% rename from test/test-link.spec.js rename to test/test-link.spec.ts index 7fdc1f05..f6098469 100644 --- a/test/test-link.spec.js +++ b/test/test-link.spec.ts @@ -9,11 +9,10 @@ const utf8 = new TextEncoder() const h1 = 'QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n' const h4 = 'bafyreidykglsfhoixmivffc5uwhcgshx4j465xwqntbmu43nb2dzqwfvae' const CBOR = 0x71 -// eslint-disable-next-line const SHA256 = sha256.code -const sh1 = /** @type {Link.MultihashDigest} */ ( - Link.parse(h4).multihash +const sh1 = ( + Link.parse(h4).multihash as Link.MultihashDigest ) describe('Link', () => { @@ -26,15 +25,12 @@ describe('Link', () => { it('create v1', async () => { const hash = await sha256.digest(utf8.encode('abc')) const link = Link.create(0x71, hash) - /** @type {0x71} */ - const code = link.code + const code = link.code as 0x71 assert.deepStrictEqual(code, 0x71) - /** @type {1} */ - const version = link.version + const version = link.version as 1 assert.deepEqual(version, 1) - /** @type {Link.MultihashDigest}> */ const multihash = link.multihash assert.deepStrictEqual(multihash, hash) }) @@ -43,15 +39,12 @@ describe('Link', () => { const hash = await sha256.digest(utf8.encode('abc')) const link = Link.createLegacy(hash) - /** @type {0x70} */ - const code = link.code + const code = link.code as 0x70 assert.deepStrictEqual(code, 0x70) - /** @type {0} */ - const version = link.version + const version = link.version as 0 assert.deepEqual(version, 0) - /** @type {Link.MultihashDigest}> */ const multihash = link.multihash assert.deepStrictEqual(multihash, hash) }) @@ -61,13 +54,11 @@ describe('Link', () => { it('can parse any string', () => { const link = Link.parse(h1) - /** @type {Link.Link} */ - // @ts-expect-error - types can not be inferred - const t1 = link + const t1 = link as Link.Link assert.ok(t1) // it is possible to manually cast - const t2 = /** @type {Link.LegacyLink} */ (link) + const t2 = (link as Link.LegacyLink) assert.ok(t2) }) @@ -78,14 +69,13 @@ describe('Link', () => { assert.equal(original.equals(link), true, 'format -> parse roundtrips') // ensure that type info is retained - /** @type {Link.Link} */ const t1 = link assert.ok(t1) // ensurate that you can't cast incorrectly const t2 = // @ts-expect-error - version is 1 not 0 - /** @type {Link.Link} */ (link) + (link as Link.Link) assert.ok(t2) }) }) @@ -134,15 +124,12 @@ describe('decode', () => { const link = Link.decode(bytes) - /** @type {0x71} */ - const code = link.code + const code = link.code as 0x71 assert.deepStrictEqual(code, 0x71) - /** @type {1} */ - const version = link.version + const version = link.version as 1 assert.deepEqual(version, 1) - /** @type {Link.MultihashDigest}> */ const multihash = link.multihash assert.deepStrictEqual(multihash, hash) }) diff --git a/test/test-multibase-spec.spec.js b/test/test-multibase-spec.spec.ts similarity index 99% rename from test/test-multibase-spec.spec.js rename to test/test-multibase-spec.spec.ts index f30101af..158f4b3e 100644 --- a/test/test-multibase-spec.spec.js +++ b/test/test-multibase-spec.spec.ts @@ -157,7 +157,7 @@ describe('spec test', () => { for (const { input, tests } of encoded) { describe(`multibase spec ${index++}`, () => { for (const [name, output] of tests) { - const base = bases[/** @type {keyof bases} */(name)] + const base = bases[name as keyof typeof bases] describe(name, () => { it('should encode buffer', () => { diff --git a/test/test-multibase.spec.js b/test/test-multibase.spec.ts similarity index 94% rename from test/test-multibase.spec.js rename to test/test-multibase.spec.ts index bdb93293..68666a1c 100644 --- a/test/test-multibase.spec.js +++ b/test/test-multibase.spec.ts @@ -63,12 +63,9 @@ describe('multibase', () => { const buff = bytes.fromString('test') const nonPrintableBuff = Uint8Array.from([239, 250, 254]) - /** - * @param {typeof b2|b8|b10|b16|b32|b36|b58|b64} bases - */ - const baseTest = bases => { + const baseTest = (bases: typeof b2 | typeof b8 | typeof b10 | typeof b16 | typeof b32 | typeof b36 | typeof b58 | typeof b64): void => { for (const base of Object.values(bases)) { - if (base && base.name) { + if (((base as { name: string })?.name) !== '') { it(`encode/decode ${base.name}`, () => { const encoded = base.encode(buff) const decoded = base.decode(encoded) @@ -161,15 +158,12 @@ describe('multibase', () => { }) it('infers prefix and name corretly', () => { - /** @type {'base32'} */ - const name = base32.name + const name = base32.name as 'base32' - /** @type {'base16'} */ // @ts-expect-error - TS catches mismatch - const name2 = base32.name + const name2: 'base16' = base32.name - /** @type {'b'} */ - const prefix = base32.prefix + const prefix = base32.prefix as 'b' assert.equal(prefix, 'b') assert.equal(name, 'base32') assert.equal(name2, name) diff --git a/test/test-multicodec.spec.js b/test/test-multicodec.spec.ts similarity index 100% rename from test/test-multicodec.spec.js rename to test/test-multicodec.spec.ts diff --git a/test/test-multihash.spec.js b/test/test-multihash.spec.ts similarity index 88% rename from test/test-multihash.spec.js rename to test/test-multihash.spec.ts index 87126137..d0642ad7 100644 --- a/test/test-multihash.spec.js +++ b/test/test-multihash.spec.ts @@ -9,16 +9,8 @@ import { hash as slSha256 } from '@stablelib/sha256' import { hash as slSha512 } from '@stablelib/sha512' import { assert } from 'aegir/chai' -/** - * @param {number|string} code - * @param {number} size - * @param {string} hex - */ -const sample = (code, size, hex) => { - /** - * @param {number|string} i - */ - const toHex = (i) => { +const sample = (code: number | string, size: number, hex: string): Uint8Array => { + const toHex = (i: number | string): string => { if (typeof i === 'string') return i const h = i.toString(16) return h.length % 2 === 1 ? `0${h}` : h @@ -34,8 +26,8 @@ describe('multihash', () => { for (const test of valid) { const { encoding, hex, size } = test const { code, varint } = encoding - const buf = sample(varint || code, size, hex) - assert.deepStrictEqual(createDigest(code, hex ? fromHex(hex) : empty).bytes, buf) + const buf = sample(varint ?? code, size, hex) + assert.deepStrictEqual(createDigest(code, (hex !== '') ? fromHex(hex) : empty).bytes, buf) } }) @@ -76,6 +68,7 @@ describe('multihash', () => { }) it('hash identity async', async () => { + // eslint-disable-next-line @typescript-eslint/await-thenable const hash = await identity.digest(fromString('test')) assert.deepStrictEqual(hash.code, identity.code) assert.deepStrictEqual(identity.code, 0) @@ -101,8 +94,8 @@ describe('multihash', () => { for (const { encoding, hex, size } of valid) { it(`valid fixture ${hex}`, () => { const { code, varint } = encoding - const bytes = sample(varint || code, size, hex) - const digest = hex ? fromHex(hex) : empty + const bytes = sample(varint ?? code, size, hex) + const digest = (hex !== '') ? fromHex(hex) : empty const hash = decodeDigest(bytes) assert.deepStrictEqual(hash.bytes, bytes) @@ -118,6 +111,7 @@ describe('multihash', () => { assert.deepStrictEqual(hash.code, 18) }) }) + // eslint-disable-next-line @typescript-eslint/no-misused-promises describe('validate', async () => { it('invalid fixtures', async () => { for (const test of invalid) { diff --git a/test/test-traversal.spec.js b/test/test-traversal.spec.ts similarity index 80% rename from test/test-traversal.spec.js rename to test/test-traversal.spec.ts index 494e11c5..74cd5a54 100644 --- a/test/test-traversal.spec.js +++ b/test/test-traversal.spec.ts @@ -5,30 +5,20 @@ import * as main from '../src/block.js' import { walk } from '../src/traversal.js' import { fromString } from '../src/bytes.js' import { assert } from 'aegir/chai' - -/** @typedef {import('../src/cid.js').CID} CID */ +import type { CID } from '../src/cid.js' +import type { BlockView } from '../src/block/interface.js' // from dag-pb, simplified -/** - * @param {Uint8Array} data - * @param {{Hash:CID, Name:string, Tsize:number}[]} links - * @returns {{Data:Uint8Array, Links:{Hash:CID, Name:string, Tsize:number}[]}} - */ -function createNode (data, links) { +function createNode (data: Uint8Array, links: Array<{ Hash: CID, Name: string, Tsize: number }>): { Data: Uint8Array, Links: Array<{ Hash: CID, Name: string, Tsize: number }> } { return { Data: data, Links: links } } -/** - * @param {string} name - * @param {number} size - * @param {CID} cid - * @returns {{Hash:CID, Name:string, Tsize:number}} - */ -function createLink (name, size, cid) { +function createLink (name: string, size: number, cid: CID): { Hash: CID, Name: string, Tsize: number } { return { Hash: cid, Name: name, Tsize: size } } describe('traversal', () => { + // eslint-disable-next-line @typescript-eslint/no-misused-promises describe('walk', async () => { // Forming the following DAG for testing // A @@ -36,12 +26,12 @@ describe('traversal', () => { // B C // / \ / \ // D D D E - const linksE = /** @type {[]} */([]) + const linksE = ([] as []) const valueE = createNode(fromString('string E qacdswa'), linksE) const blockE = await main.encode({ value: valueE, codec, hasher }) const cidE = blockE.cid - const linksD = /** @type {[]} */([]) + const linksD = ([] as []) const valueD = createNode(fromString('string D zasa'), linksD) const blockD = await main.encode({ value: valueD, codec, hasher }) const cidD = blockD.cid @@ -61,10 +51,7 @@ describe('traversal', () => { const blockA = await main.encode({ value: valueA, codec, hasher }) const cidA = blockA.cid - /** - * @param {CID} cid - */ - const load = async (cid) => { + const load = async (cid: CID): Promise | null> => { if (cid.equals(cidE)) { return blockE } @@ -83,17 +70,12 @@ describe('traversal', () => { return null } - /** - * @param {typeof load} load - * @param {string[]} arr - */ - const loadWrapper = (load, arr = []) => - /** - * @param {CID} cid - */ - (cid) => { + type loadFn = typeof load + + const loadWrapper = (load: loadFn, arr: string[] = []) => + async (cid: CID): Promise | null> => { arr.push(cid.toString()) - return load(cid) + return await load(cid) } it('block with no links', async () => { @@ -103,8 +85,7 @@ describe('traversal', () => { // // Expect load to be called with D const expectedCallArray = [cidD.toString()] - /** @type {string[]} */ - const callArray = [] + const callArray: string[] = [] await walk({ cid: cidD, load: loadWrapper(load, callArray) }) @@ -122,8 +103,7 @@ describe('traversal', () => { // // Expect load to be called with C, then D, then E const expectedCallArray = [cidC.toString(), cidD.toString(), cidE.toString()] - /** @type {string[]} */ - const callArray = [] + const callArray: string[] = [] await walk({ cid: cidC, load: loadWrapper(load, callArray) }) @@ -141,8 +121,7 @@ describe('traversal', () => { // // Expect load to be called with B, then D const expectedCallArray = [cidB.toString(), cidD.toString()] - /** @type {string[]} */ - const callArray = [] + const callArray: string[] = [] await walk({ cid: cidB, load: loadWrapper(load, callArray) }) @@ -168,8 +147,7 @@ describe('traversal', () => { cidC.toString(), cidE.toString() ] - /** @type {string[]} */ - const callArray = [] + const callArray: string[] = [] await walk({ cid: cidA, load: loadWrapper(load, callArray) }) @@ -179,14 +157,12 @@ describe('traversal', () => { }) it('null return', async () => { - /** @type {[]} */ - const links = [] + const links = [] as [] const value = createNode(fromString('test'), links) const block = await main.encode({ value, codec, hasher }) const cid = block.cid const expectedCallArray = [cid.toString()] - /** @type {string[]} */ - const callArray = [] + const callArray: string[] = [] await walk({ cid, load: loadWrapper(load, callArray) }) diff --git a/test/test-varint.spec.js b/test/test-varint.spec.ts similarity index 100% rename from test/test-varint.spec.js rename to test/test-varint.spec.ts diff --git a/test/ts-use/src/main.ts b/test/ts-use/src/main.ts index ff7de729..fd68aac0 100644 --- a/test/ts-use/src/main.ts +++ b/test/ts-use/src/main.ts @@ -2,7 +2,7 @@ import * as Block from 'multiformats/block' import { sha256 } from 'multiformats/hashes/sha2' import * as json from 'multiformats/codecs/json' -const main = async () => { +const main = async (): Promise => { const block = await Block.encode({ value: { hello: 'world' }, hasher: sha256, diff --git a/tsconfig.json b/tsconfig.json index d8dbe630..383a638d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,26 +1,10 @@ { "extends": "aegir/src/config/tsconfig.aegir.json", "compilerOptions": { - "outDir": "dist/types", - "emitDeclarationOnly": true, - "importsNotUsedAsValues": "preserve", - "paths": { - "multiformats": [ - "./src/index.js" - ], - "multiformats/interface": [ - "./src/interface" - ], - "multiformats/hashes/interface": [ - "./src/hashes/interface" - ], - "multiformats/*": [ - "./src/*.js" - ] - } + "outDir": "dist" }, "include": [ "src", "test" - ] +, "vendor" ] } \ No newline at end of file From e03b91765e4f3093c6869581cf2de4a108d1db6e Mon Sep 17 00:00:00 2001 From: Cayman Date: Wed, 24 May 2023 12:32:05 -0400 Subject: [PATCH 02/13] fix: fix types export and tsconfig --- package.json | 59 +++++++++++++++++++++++++-------------------------- tsconfig.json | 4 ++-- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index ecdd0270..0c06bd23 100644 --- a/package.json +++ b/package.json @@ -47,126 +47,125 @@ "test", "tsconfig.json", "dist", - "vendor", "!**/*.tsbuildinfo", "!test/ts-use/node_modules" ], "exports": { ".": { - "types": "./dist/types/src/index.d.ts", + "types": "./dist/src/index.d.ts", "import": "./dist/src/index.js" }, "./bases/base10": { - "types": "./dist/types/src/bases/base10.d.ts", + "types": "./dist/src/bases/base10.d.ts", "import": "./dist/src/bases/base10.js" }, "./bases/base16": { - "types": "./dist/types/src/bases/base16.d.ts", + "types": "./dist/src/bases/base16.d.ts", "import": "./dist/src/bases/base16.js" }, "./bases/base2": { - "types": "./dist/types/src/bases/base2.d.ts", + "types": "./dist/src/bases/base2.d.ts", "import": "./dist/src/bases/base2.js" }, "./bases/base256emoji": { - "types": "./dist/types/src/bases/base256emoji.d.ts", + "types": "./dist/src/bases/base256emoji.d.ts", "import": "./dist/src/bases/base256emoji.js" }, "./bases/base32": { - "types": "./dist/types/src/bases/base32.d.ts", + "types": "./dist/src/bases/base32.d.ts", "import": "./dist/src/bases/base32.js" }, "./bases/base36": { - "types": "./dist/types/src/bases/base36.d.ts", + "types": "./dist/src/bases/base36.d.ts", "import": "./dist/src/bases/base36.js" }, "./bases/base58": { - "types": "./dist/types/src/bases/base58.d.ts", + "types": "./dist/src/bases/base58.d.ts", "import": "./dist/src/bases/base58.js" }, "./bases/base64": { - "types": "./dist/types/src/bases/base64.d.ts", + "types": "./dist/src/bases/base64.d.ts", "import": "./dist/src/bases/base64.js" }, "./bases/base8": { - "types": "./dist/types/src/bases/base8.d.ts", + "types": "./dist/src/bases/base8.d.ts", "import": "./dist/src/bases/base8.js" }, "./bases/identity": { - "types": "./dist/types/src/bases/identity.d.ts", + "types": "./dist/src/bases/identity.d.ts", "import": "./dist/src/bases/identity.js" }, "./bases/interface": { - "types": "./dist/types/src/bases/interface.d.ts", + "types": "./dist/src/bases/interface.d.ts", "import": "./dist/src/bases/interface.js" }, "./basics": { - "types": "./dist/types/src/basics.d.ts", + "types": "./dist/src/basics.d.ts", "import": "./dist/src/basics.js" }, "./block": { - "types": "./dist/types/src/block.d.ts", + "types": "./dist/src/block.d.ts", "import": "./dist/src/block.js" }, "./block/interface": { - "types": "./dist/types/src/block/interface.d.ts", + "types": "./dist/src/block/interface.d.ts", "import": "./dist/src/block/interface.js" }, "./bytes": { - "types": "./dist/types/src/bytes.d.ts", + "types": "./dist/src/bytes.d.ts", "import": "./dist/src/bytes.js" }, "./cid": { - "types": "./dist/types/src/cid.d.ts", + "types": "./dist/src/cid.d.ts", "import": "./dist/src/cid.js" }, "./codecs/interface": { - "types": "./dist/types/src/codecs/interface.d.ts", + "types": "./dist/src/codecs/interface.d.ts", "import": "./dist/src/codecs/interface.js" }, "./codecs/json": { - "types": "./dist/types/src/codecs/json.d.ts", + "types": "./dist/src/codecs/json.d.ts", "import": "./dist/src/codecs/json.js" }, "./codecs/raw": { - "types": "./dist/types/src/codecs/raw.d.ts", + "types": "./dist/src/codecs/raw.d.ts", "import": "./dist/src/codecs/raw.js" }, "./hashes/digest": { - "types": "./dist/types/src/hashes/digest.d.ts", + "types": "./dist/src/hashes/digest.d.ts", "import": "./dist/src/hashes/digest.js" }, "./hashes/hasher": { - "types": "./dist/types/src/hashes/hasher.d.ts", + "types": "./dist/src/hashes/hasher.d.ts", "import": "./dist/src/hashes/hasher.js" }, "./hashes/identity": { - "types": "./dist/types/src/hashes/identity.d.ts", + "types": "./dist/src/hashes/identity.d.ts", "import": "./dist/src/hashes/identity.js" }, "./hashes/interface": { - "types": "./dist/types/src/hashes/interface.d.ts", + "types": "./dist/src/hashes/interface.d.ts", "import": "./dist/src/hashes/interface.js" }, "./hashes/sha2": { - "types": "./dist/types/src/hashes/sha2.d.ts", + "types": "./dist/src/hashes/sha2.d.ts", "browser": "./dist/src/hashes/sha2-browser.js", "import": "./dist/src/hashes/sha2.js" }, "./interface": { - "types": "./dist/types/src/interface.d.ts", + "types": "./dist/src/interface.d.ts", "import": "./dist/src/interface.js" }, "./link": { - "types": "./dist/types/src/link.d.ts", + "types": "./dist/src/link.d.ts", "import": "./dist/src/link.js" }, "./link/interface": { - "types": "./dist/types/src/interface.d.ts", + "types": "./dist/src/interface.d.ts", "import": "./dist/src/interface.js" }, "./traversal": { - "types": "./dist/types/src/traversal.d.ts", + "types": "./dist/src/traversal.d.ts", "import": "./dist/src/traversal.js" } }, diff --git a/tsconfig.json b/tsconfig.json index 383a638d..13a35996 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,5 +6,5 @@ "include": [ "src", "test" -, "vendor" ] -} \ No newline at end of file + ] +} From 410564c9c16e03cc0561ca16d6bf52d5f5067f38 Mon Sep 17 00:00:00 2001 From: Cayman Date: Thu, 6 Jul 2023 10:24:50 -0400 Subject: [PATCH 03/13] Rename examples to .js --- examples/{block-interface.ts => block-interface.js} | 0 examples/{cid-interface.ts => cid-interface.js} | 0 examples/{multicodec-interface.ts => multicodec-interface.js} | 0 examples/{multihash-interface.ts => multihash-interface.js} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename examples/{block-interface.ts => block-interface.js} (100%) rename examples/{cid-interface.ts => cid-interface.js} (100%) rename examples/{multicodec-interface.ts => multicodec-interface.js} (100%) rename examples/{multihash-interface.ts => multihash-interface.js} (100%) diff --git a/examples/block-interface.ts b/examples/block-interface.js similarity index 100% rename from examples/block-interface.ts rename to examples/block-interface.js diff --git a/examples/cid-interface.ts b/examples/cid-interface.js similarity index 100% rename from examples/cid-interface.ts rename to examples/cid-interface.js diff --git a/examples/multicodec-interface.ts b/examples/multicodec-interface.js similarity index 100% rename from examples/multicodec-interface.ts rename to examples/multicodec-interface.js diff --git a/examples/multihash-interface.ts b/examples/multihash-interface.js similarity index 100% rename from examples/multihash-interface.ts rename to examples/multihash-interface.js From bd6554cf8305a1ff6ea6a27ded49d60bcb6f75e6 Mon Sep 17 00:00:00 2001 From: Cayman Date: Thu, 6 Jul 2023 11:29:37 -0400 Subject: [PATCH 04/13] Consistent use of function declarations --- src/bases/base.ts | 25 ++++++++++++++----------- src/bytes.ts | 23 +++++++++++++++-------- src/cid.ts | 25 ++++++++++++++----------- src/codecs/json.ts | 8 ++++++-- src/codecs/raw.ts | 8 ++++++-- src/hashes/digest.ts | 6 +++--- src/hashes/hasher.ts | 4 +++- src/hashes/identity.ts | 4 +++- src/hashes/sha2-browser.ts | 5 +++-- src/link.ts | 18 +++++++++++++----- src/traversal.ts | 2 +- src/varint.ts | 6 +++--- 12 files changed, 84 insertions(+), 50 deletions(-) diff --git a/src/bases/base.ts b/src/bases/base.ts index 98b284a7..ff102cab 100644 --- a/src/bases/base.ts +++ b/src/bases/base.ts @@ -92,11 +92,13 @@ class ComposedDecoder implements MultibaseDecoder } } -// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -export const or = (left: UnibaseDecoder | CombobaseDecoder, right: UnibaseDecoder | CombobaseDecoder): ComposedDecoder => new ComposedDecoder(({ - ...(left.decoders ?? { [(left as UnibaseDecoder).prefix]: left }), - ...(right.decoders ?? { [(right as UnibaseDecoder).prefix]: right }) -} as Decoders)) +export function or (left: UnibaseDecoder | CombobaseDecoder, right: UnibaseDecoder | CombobaseDecoder): ComposedDecoder { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + return new ComposedDecoder(({ + ...(left.decoders ?? { [(left as UnibaseDecoder).prefix]: left }), + ...(right.decoders ?? { [(right as UnibaseDecoder).prefix]: right }) + } as Decoders)) +} export class Codec implements MultibaseCodec, MultibaseEncoder, MultibaseDecoder, BaseCodec, BaseEncoder, BaseDecoder { readonly name: Base @@ -124,10 +126,11 @@ export class Codec implements Multib } } -export const from = ({ name, prefix, encode, decode }: { name: Base, prefix: Prefix, encode: EncodeFn, decode: DecodeFn }): Codec => - new Codec(name, prefix, encode, decode) +export function from ({ name, prefix, encode, decode }: { name: Base, prefix: Prefix, encode: EncodeFn, decode: DecodeFn }): Codec { + return new Codec(name, prefix, encode, decode) +} -export const baseX = ({ name, prefix, alphabet }: { name: Base, prefix: Prefix, alphabet: string }): Codec => { +export function baseX ({ name, prefix, alphabet }: { name: Base, prefix: Prefix, alphabet: string }): Codec { const { encode, decode } = basex(alphabet, name) return from({ prefix, @@ -137,7 +140,7 @@ export const baseX = ({ name, prefix }) } -const decode = (string: string, alphabet: string, bitsPerChar: number, name: string): Uint8Array => { +function decode (string: string, alphabet: string, bitsPerChar: number, name: string): Uint8Array { // Build the character lookup table: const codes: Record = {} for (let i = 0; i < alphabet.length; ++i) { @@ -183,7 +186,7 @@ const decode = (string: string, alphabet: string, bitsPerChar: number, name: str return out } -const encode = (data: Uint8Array, alphabet: string, bitsPerChar: number): string => { +function encode (data: Uint8Array, alphabet: string, bitsPerChar: number): string { const pad = alphabet[alphabet.length - 1] === '=' const mask = (1 << bitsPerChar) - 1 let out = '' @@ -220,7 +223,7 @@ const encode = (data: Uint8Array, alphabet: string, bitsPerChar: number): string /** * RFC4648 Factory */ -export const rfc4648 = ({ name, prefix, bitsPerChar, alphabet }: { name: Base, prefix: Prefix, bitsPerChar: number, alphabet: string }): Codec => { +export function rfc4648 ({ name, prefix, bitsPerChar, alphabet }: { name: Base, prefix: Prefix, bitsPerChar: number, alphabet: string }): Codec { return from({ prefix, name, diff --git a/src/bytes.ts b/src/bytes.ts index e66a1cf0..ac8a86e6 100644 --- a/src/bytes.ts +++ b/src/bytes.ts @@ -1,13 +1,15 @@ const empty = new Uint8Array(0) -const toHex = (d: Uint8Array): string => d.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '') +function toHex (d: Uint8Array): string { + return d.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '') +} -const fromHex = (hex: string): Uint8Array => { +function fromHex (hex: string): Uint8Array { const hexes = hex.match(/../g) return hexes != null ? new Uint8Array(hexes.map(b => parseInt(b, 16))) : empty } -const equals = (aa: Uint8Array, bb: Uint8Array): boolean => { +function equals (aa: Uint8Array, bb: Uint8Array): boolean { if (aa === bb) return true if (aa.byteLength !== bb.byteLength) { return false @@ -22,7 +24,7 @@ const equals = (aa: Uint8Array, bb: Uint8Array): boolean => { return true } -const coerce = (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array => { +function coerce (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array { if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') return o if (o instanceof ArrayBuffer) return new Uint8Array(o) if (ArrayBuffer.isView(o)) { @@ -31,11 +33,16 @@ const coerce = (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array => { throw new Error('Unknown type, must be binary type') } -const isBinary = (o: unknown): o is ArrayBuffer | ArrayBufferView => - o instanceof ArrayBuffer || ArrayBuffer.isView(o) +function isBinary (o: unknown): o is ArrayBuffer | ArrayBufferView { + return o instanceof ArrayBuffer || ArrayBuffer.isView(o) +} -const fromString = (str: string): Uint8Array => (new TextEncoder()).encode(str) +function fromString (str: string): Uint8Array { + return new TextEncoder().encode(str) +} -const toString = (b: Uint8Array): string => (new TextDecoder()).decode(b) +function toString (b: Uint8Array): string { + return new TextDecoder().decode(b) +} export { equals, coerce, isBinary, fromHex, toHex, fromString, toString, empty } diff --git a/src/cid.ts b/src/cid.ts index 9de15dc3..5199e781 100644 --- a/src/cid.ts +++ b/src/cid.ts @@ -8,7 +8,7 @@ import type * as API from './link/interface.js' // This way TS will also expose all the types from module export * from './link/interface.js' -export const format = , Prefix extends string>(link: T, base?: API.MultibaseEncoder): API.ToString => { +export function format , Prefix extends string> (link: T, base?: API.MultibaseEncoder): API.ToString { const { bytes, version } = link switch (version) { case 0: @@ -26,16 +26,19 @@ export const format = , } } -export const toJSON = (link: Link): API.LinkJSON => ({ - '/': format(link) -}) +export function toJSON (link: Link): API.LinkJSON { + return { + '/': format(link) + } +} -export const fromJSON = (json: API.LinkJSON): CID => - CID.parse(json['/']) +export function fromJSON (json: API.LinkJSON): CID { + return CID.parse(json['/']) +} const cache: WeakMap> = new WeakMap() -const baseCache = (cid: API.UnknownLink): Map => { +function baseCache (cid: API.UnknownLink): Map { const baseCache = cache.get(cid) if (baseCache == null) { const baseCache = new Map() @@ -387,7 +390,7 @@ export class CID(source: API.ToString, Prefix>, base?: API.MultibaseDecoder): [Prefix, API.ByteView>] => { +function parseCIDtoBytes (source: API.ToString, Prefix>, base?: API.MultibaseDecoder): [Prefix, API.ByteView>] { switch (source[0]) { // CIDv0 is parsed differently case 'Q': { @@ -416,7 +419,7 @@ const parseCIDtoBytes = , base: API.MultibaseEncoder<'z'>): string => { +function toStringV0 (bytes: Uint8Array, cache: Map, base: API.MultibaseEncoder<'z'>): string { const { prefix } = base if (prefix !== base58btc.prefix) { throw Error(`Cannot string encode V0 in ${base.name} encoding`) @@ -432,7 +435,7 @@ const toStringV0 = (bytes: Uint8Array, cache: Map, base: API.Mul } } -const toStringV1 = (bytes: Uint8Array, cache: Map, base: API.MultibaseEncoder): string => { +function toStringV1 (bytes: Uint8Array, cache: Map, base: API.MultibaseEncoder): string { const { prefix } = base const cid = cache.get(prefix) if (cid == null) { @@ -447,7 +450,7 @@ const toStringV1 = (bytes: Uint8Array, cache: Map { +function encodeCID (version: API.Version, code: number, multihash: Uint8Array): Uint8Array { const codeOffset = varint.encodingLength(version) const hashOffset = codeOffset + varint.encodingLength(code) const bytes = new Uint8Array(hashOffset + multihash.byteLength) diff --git a/src/codecs/json.ts b/src/codecs/json.ts index 7dd8a7ec..77151e7b 100644 --- a/src/codecs/json.ts +++ b/src/codecs/json.ts @@ -6,6 +6,10 @@ const textDecoder = new TextDecoder() export const name = 'json' export const code = 0x0200 -export const encode = (node: T): ByteView => textEncoder.encode(JSON.stringify(node)) +export function encode (node: T): ByteView { + return textEncoder.encode(JSON.stringify(node)) +} -export const decode = (data: ByteView): T => JSON.parse(textDecoder.decode(data)) +export function decode (data: ByteView): T { + return JSON.parse(textDecoder.decode(data)) +} diff --git a/src/codecs/raw.ts b/src/codecs/raw.ts index db7fdddd..2d76a422 100644 --- a/src/codecs/raw.ts +++ b/src/codecs/raw.ts @@ -4,6 +4,10 @@ import type { ByteView } from './interface.js' export const name = 'raw' export const code = 0x55 -export const encode = (node: Uint8Array): ByteView => coerce(node) +export function encode (node: Uint8Array): ByteView { + return coerce(node) +} -export const decode = (data: ByteView): Uint8Array => coerce(data) +export function decode (data: ByteView): Uint8Array { + return coerce(data) +} diff --git a/src/hashes/digest.ts b/src/hashes/digest.ts index c7215256..5ba8941f 100644 --- a/src/hashes/digest.ts +++ b/src/hashes/digest.ts @@ -5,7 +5,7 @@ import type { MultihashDigest } from './interface.js' /** * Creates a multihash digest. */ -export const create = (code: Code, digest: Uint8Array): Digest => { +export function create (code: Code, digest: Uint8Array): Digest { const size = digest.byteLength const sizeOffset = varint.encodingLength(code) const digestOffset = sizeOffset + varint.encodingLength(size) @@ -21,7 +21,7 @@ export const create = (code: Code, digest: Uint8Array): Dig /** * Turns bytes representation of multihash digest into an instance. */ -export const decode = (multihash: Uint8Array): MultihashDigest => { +export function decode (multihash: Uint8Array): MultihashDigest { const bytes = coerce(multihash) const [code, sizeOffset] = varint.decode(bytes) const [size, digestOffset] = varint.decode(bytes.subarray(sizeOffset)) @@ -34,7 +34,7 @@ export const decode = (multihash: Uint8Array): MultihashDigest => { return new Digest(code, size, digest, bytes) } -export const equals = (a: MultihashDigest, b: unknown): b is MultihashDigest => { +export function equals (a: MultihashDigest, b: unknown): b is MultihashDigest { if (a === b) { return true } else { diff --git a/src/hashes/hasher.ts b/src/hashes/hasher.ts index e19d63bc..553a61a1 100644 --- a/src/hashes/hasher.ts +++ b/src/hashes/hasher.ts @@ -3,7 +3,9 @@ import type { MultihashHasher } from './interface.js' type Await = Promise | T -export const from = ({ name, code, encode }: { name: Name, code: Code, encode: (input: Uint8Array) => Await }): Hasher => new Hasher(name, code, encode) +export function from ({ name, code, encode }: { name: Name, code: Code, encode: (input: Uint8Array) => Await }): Hasher { + return new Hasher(name, code, encode) +} /** * Hasher represents a hashing algorithm implementation that produces as diff --git a/src/hashes/identity.ts b/src/hashes/identity.ts index d61d795b..69886c75 100644 --- a/src/hashes/identity.ts +++ b/src/hashes/identity.ts @@ -6,6 +6,8 @@ const name = 'identity' const encode: (input: Uint8Array) => Uint8Array = coerce -const digest = (input: Uint8Array): Digest.Digest => Digest.create(code, encode(input)) +function digest (input: Uint8Array): Digest.Digest { + return Digest.create(code, encode(input)) +} export const identity = { code, name, encode, digest } diff --git a/src/hashes/sha2-browser.ts b/src/hashes/sha2-browser.ts index 30cade61..cbf0b7b8 100644 --- a/src/hashes/sha2-browser.ts +++ b/src/hashes/sha2-browser.ts @@ -2,8 +2,9 @@ import { from } from './hasher.js' -const sha = (name: AlgorithmIdentifier): (data: Uint8Array) => Promise => - async data => new Uint8Array(await crypto.subtle.digest(name, data)) +function sha (name: AlgorithmIdentifier): (data: Uint8Array) => Promise { + return async data => new Uint8Array(await crypto.subtle.digest(name, data)) +} export const sha256 = from({ name: 'sha2-256', diff --git a/src/link.ts b/src/link.ts index b9942ba1..f577dd5b 100644 --- a/src/link.ts +++ b/src/link.ts @@ -10,7 +10,9 @@ const SHA_256_CODE = 0x12 /** * Simplified version of `create` for CIDv0. */ -export const createLegacy = (digest: API.MultihashDigest): API.LegacyLink => CID.create(0, DAG_PB_CODE, digest) +export function createLegacy (digest: API.MultihashDigest): API.LegacyLink { + return CID.create(0, DAG_PB_CODE, digest) +} /** * Simplified version of `create` for CIDv1. @@ -18,12 +20,14 @@ export const createLegacy = (digest: API.MultihashDigest): * @param code - Content encoding format code. * @param digest - Miltihash of the content. */ -export const create = (code: Code, digest: API.MultihashDigest): API.Link => CID.create(1, code, digest) +export function create (code: Code, digest: API.MultihashDigest): API.Link { + return CID.create(1, code, digest) +} /** * Type predicate returns true if value is the link. */ -export const isLink = >(value: unknown | L): value is L & CID => { +export function isLink > (value: unknown | L): value is L & CID { if (value == null) { return false } @@ -49,7 +53,9 @@ export const isLink = >(value * throw an error if encoding of the CID is not compatible with supplied (or * a default decoder). */ -export const parse = (source: API.ToString, Prefix>, base?: API.MultibaseDecoder): API.Link => CID.parse(source, base) +export function parse (source: API.ToString, Prefix>, base?: API.MultibaseDecoder): API.Link { + return CID.parse(source, base) +} export { format, toJSON, fromJSON } @@ -60,4 +66,6 @@ export { format, toJSON, fromJSON } * An error will be thrown if the bytes provided do not contain a valid * binary representation of a CID. */ -export const decode = (bytes: API.ByteView>): API.Link => CID.decode(bytes) +export function decode (bytes: API.ByteView>): API.Link { + return CID.decode(bytes) +} diff --git a/src/traversal.ts b/src/traversal.ts index dc64062e..6cdb3304 100644 --- a/src/traversal.ts +++ b/src/traversal.ts @@ -4,7 +4,7 @@ import type { CID, Version } from './cid.js' type BlockView = _BlockView -const walk = async ({ cid, load, seen }: { cid: CID, load: (cid: CID) => Promise, seen?: Set }): Promise => { +async function walk ({ cid, load, seen }: { cid: CID, load: (cid: CID) => Promise, seen?: Set }): Promise { seen = seen ?? new Set() const b58Cid = cid.toString(base58btc) if (seen.has(b58Cid)) { diff --git a/src/varint.ts b/src/varint.ts index b195e961..49f4e91e 100644 --- a/src/varint.ts +++ b/src/varint.ts @@ -1,15 +1,15 @@ import varint from './vendor/varint.js' -export const decode = (data: Uint8Array, offset = 0): [number, number] => { +export function decode (data: Uint8Array, offset = 0): [number, number] { const code = varint.decode(data, offset) return [code, varint.decode.bytes] } -export const encodeTo = (int: number, target: Uint8Array, offset = 0): Uint8Array => { +export function encodeTo (int: number, target: Uint8Array, offset = 0): Uint8Array { varint.encode(int, target, offset) return target } -export const encodingLength = (int: number): number => { +export function encodingLength (int: number): number { return varint.encodingLength(int) } From 877fcbe395ca60e1eebb24f6ce33b1bdd780c805 Mon Sep 17 00:00:00 2001 From: Cayman Date: Thu, 6 Jul 2023 11:41:47 -0400 Subject: [PATCH 05/13] Remove unnecessary parens --- src/bases/base.ts | 8 +++---- src/bases/base256emoji.ts | 4 ++-- src/block.ts | 9 ++++---- src/cid.ts | 44 ++++++++++++++++++--------------------- src/hashes/digest.ts | 2 +- src/link.ts | 4 ++-- 6 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/bases/base.ts b/src/bases/base.ts index ff102cab..9885412a 100644 --- a/src/bases/base.ts +++ b/src/bases/base.ts @@ -48,7 +48,7 @@ class Decoder implements MultibaseDe if (prefix.codePointAt(0) === undefined) { throw new Error('Invalid prefix character') } - this.prefixCodePoint = (prefix.codePointAt(0)) as number + this.prefixCodePoint = prefix.codePointAt(0) as number this.baseDecode = baseDecode } @@ -82,7 +82,7 @@ class ComposedDecoder implements MultibaseDecoder } decode (input: string): Uint8Array { - const prefix = (input[0]) as Prefix + const prefix = input[0] as Prefix const decoder = this.decoders[prefix] if (decoder != null) { return decoder.decode(input) @@ -94,10 +94,10 @@ class ComposedDecoder implements MultibaseDecoder export function or (left: UnibaseDecoder | CombobaseDecoder, right: UnibaseDecoder | CombobaseDecoder): ComposedDecoder { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return new ComposedDecoder(({ + return new ComposedDecoder({ ...(left.decoders ?? { [(left as UnibaseDecoder).prefix]: left }), ...(right.decoders ?? { [(right as UnibaseDecoder).prefix]: right }) - } as Decoders)) + } as Decoders) } export class Codec implements MultibaseCodec, MultibaseEncoder, MultibaseDecoder, BaseCodec, BaseEncoder, BaseDecoder { diff --git a/src/bases/base256emoji.ts b/src/bases/base256emoji.ts index e61d0bd2..d17a44c2 100644 --- a/src/bases/base256emoji.ts +++ b/src/bases/base256emoji.ts @@ -2,7 +2,7 @@ import { from } from './base.js' const alphabet = Array.from('๐Ÿš€๐Ÿชโ˜„๐Ÿ›ฐ๐ŸŒŒ๐ŸŒ‘๐ŸŒ’๐ŸŒ“๐ŸŒ”๐ŸŒ•๐ŸŒ–๐ŸŒ—๐ŸŒ˜๐ŸŒ๐ŸŒ๐ŸŒŽ๐Ÿ‰โ˜€๐Ÿ’ป๐Ÿ–ฅ๐Ÿ’พ๐Ÿ’ฟ๐Ÿ˜‚โค๐Ÿ˜๐Ÿคฃ๐Ÿ˜Š๐Ÿ™๐Ÿ’•๐Ÿ˜ญ๐Ÿ˜˜๐Ÿ‘๐Ÿ˜…๐Ÿ‘๐Ÿ˜๐Ÿ”ฅ๐Ÿฅฐ๐Ÿ’”๐Ÿ’–๐Ÿ’™๐Ÿ˜ข๐Ÿค”๐Ÿ˜†๐Ÿ™„๐Ÿ’ช๐Ÿ˜‰โ˜บ๐Ÿ‘Œ๐Ÿค—๐Ÿ’œ๐Ÿ˜”๐Ÿ˜Ž๐Ÿ˜‡๐ŸŒน๐Ÿคฆ๐ŸŽ‰๐Ÿ’žโœŒโœจ๐Ÿคท๐Ÿ˜ฑ๐Ÿ˜Œ๐ŸŒธ๐Ÿ™Œ๐Ÿ˜‹๐Ÿ’—๐Ÿ’š๐Ÿ˜๐Ÿ’›๐Ÿ™‚๐Ÿ’“๐Ÿคฉ๐Ÿ˜„๐Ÿ˜€๐Ÿ–ค๐Ÿ˜ƒ๐Ÿ’ฏ๐Ÿ™ˆ๐Ÿ‘‡๐ŸŽถ๐Ÿ˜’๐Ÿคญโฃ๐Ÿ˜œ๐Ÿ’‹๐Ÿ‘€๐Ÿ˜ช๐Ÿ˜‘๐Ÿ’ฅ๐Ÿ™‹๐Ÿ˜ž๐Ÿ˜ฉ๐Ÿ˜ก๐Ÿคช๐Ÿ‘Š๐Ÿฅณ๐Ÿ˜ฅ๐Ÿคค๐Ÿ‘‰๐Ÿ’ƒ๐Ÿ˜ณโœ‹๐Ÿ˜š๐Ÿ˜๐Ÿ˜ด๐ŸŒŸ๐Ÿ˜ฌ๐Ÿ™ƒ๐Ÿ€๐ŸŒท๐Ÿ˜ป๐Ÿ˜“โญโœ…๐Ÿฅบ๐ŸŒˆ๐Ÿ˜ˆ๐Ÿค˜๐Ÿ’ฆโœ”๐Ÿ˜ฃ๐Ÿƒ๐Ÿ’โ˜น๐ŸŽŠ๐Ÿ’˜๐Ÿ˜ โ˜๐Ÿ˜•๐ŸŒบ๐ŸŽ‚๐ŸŒป๐Ÿ˜๐Ÿ–•๐Ÿ’๐Ÿ™Š๐Ÿ˜น๐Ÿ—ฃ๐Ÿ’ซ๐Ÿ’€๐Ÿ‘‘๐ŸŽต๐Ÿคž๐Ÿ˜›๐Ÿ”ด๐Ÿ˜ค๐ŸŒผ๐Ÿ˜ซโšฝ๐Ÿค™โ˜•๐Ÿ†๐Ÿคซ๐Ÿ‘ˆ๐Ÿ˜ฎ๐Ÿ™†๐Ÿป๐Ÿƒ๐Ÿถ๐Ÿ’๐Ÿ˜ฒ๐ŸŒฟ๐Ÿงก๐ŸŽโšก๐ŸŒž๐ŸŽˆโŒโœŠ๐Ÿ‘‹๐Ÿ˜ฐ๐Ÿคจ๐Ÿ˜ถ๐Ÿค๐Ÿšถ๐Ÿ’ฐ๐Ÿ“๐Ÿ’ข๐ŸคŸ๐Ÿ™๐Ÿšจ๐Ÿ’จ๐Ÿคฌโœˆ๐ŸŽ€๐Ÿบ๐Ÿค“๐Ÿ˜™๐Ÿ’Ÿ๐ŸŒฑ๐Ÿ˜–๐Ÿ‘ถ๐Ÿฅดโ–ถโžกโ“๐Ÿ’Ž๐Ÿ’ธโฌ‡๐Ÿ˜จ๐ŸŒš๐Ÿฆ‹๐Ÿ˜ท๐Ÿ•บโš ๐Ÿ™…๐Ÿ˜Ÿ๐Ÿ˜ต๐Ÿ‘Ž๐Ÿคฒ๐Ÿค ๐Ÿคง๐Ÿ“Œ๐Ÿ”ต๐Ÿ’…๐Ÿง๐Ÿพ๐Ÿ’๐Ÿ˜—๐Ÿค‘๐ŸŒŠ๐Ÿคฏ๐Ÿทโ˜Ž๐Ÿ’ง๐Ÿ˜ฏ๐Ÿ’†๐Ÿ‘†๐ŸŽค๐Ÿ™‡๐Ÿ‘โ„๐ŸŒด๐Ÿ’ฃ๐Ÿธ๐Ÿ’Œ๐Ÿ“๐Ÿฅ€๐Ÿคข๐Ÿ‘…๐Ÿ’ก๐Ÿ’ฉ๐Ÿ‘๐Ÿ“ธ๐Ÿ‘ป๐Ÿค๐Ÿคฎ๐ŸŽผ๐Ÿฅต๐Ÿšฉ๐ŸŽ๐ŸŠ๐Ÿ‘ผ๐Ÿ’๐Ÿ“ฃ๐Ÿฅ‚') const alphabetBytesToChars: string[] = (alphabet.reduce((p, c, i) => { p[i] = c; return p }, ([]))) -const alphabetCharsToBytes: number[] = (alphabet.reduce((p, c, i) => { p[(c.codePointAt(0) as number)] = i; return p }, ([]))) +const alphabetCharsToBytes: number[] = (alphabet.reduce((p, c, i) => { p[c.codePointAt(0) as number] = i; return p }, ([]))) function encode (data: Uint8Array): string { return data.reduce((p, c) => { @@ -14,7 +14,7 @@ function encode (data: Uint8Array): string { function decode (str: string): Uint8Array { const byts = [] for (const char of str) { - const byt = alphabetCharsToBytes[(char.codePointAt(0) as number)] + const byt = alphabetCharsToBytes[char.codePointAt(0) as number] if (byt === undefined) { throw new Error(`Non-base256emoji character: ${char}`) } diff --git a/src/block.ts b/src/block.ts index e24fdcdc..540abb6c 100644 --- a/src/block.ts +++ b/src/block.ts @@ -37,7 +37,7 @@ function * links (source: T, base: Array): Iterable<[string yield [base.join('/'), cid] } for (const [key, value] of Object.entries(source)) { - const path = ([...base, key]) as [string | number, string] + const path = [...base, key] as [string | number, string] yield * linksWithin(path, value) } } @@ -61,7 +61,7 @@ function * tree (source: T, base: Array): Iterable return } for (const [key, value] of Object.entries(source)) { - const path = ([...base, key] as [string | number, string]) + const path = [...base, key] as [string | number, string] yield path.join('/') if (value != null && !(value instanceof Uint8Array) && typeof value === 'object' && (CID.asCID(value) == null)) { yield * treeWithin(path, value) @@ -70,7 +70,7 @@ function * tree (source: T, base: Array): Iterable } function get (source: T, path: string[]): API.BlockCursorView { - let node = (source as Record) + let node = source as Record for (const [index, key] of path.entries()) { node = node[key] if (node == null) { @@ -178,8 +178,7 @@ function createUnsafe ), + cid: cid as CID, bytes, value }) diff --git a/src/cid.ts b/src/cid.ts index 5199e781..5df8f08a 100644 --- a/src/cid.ts +++ b/src/cid.ts @@ -15,7 +15,7 @@ export function format return toStringV0( bytes, baseCache(link), - (base as API.MultibaseEncoder<'z'>) ?? base58btc.encoder + base as API.MultibaseEncoder<'z'> ?? base58btc.encoder ) default: return toStringV1( @@ -94,7 +94,7 @@ export class CID { switch (this.version) { case 0: { - return (this as CID) + return this as CID } case 1: { const { code, multihash } = this @@ -110,7 +110,7 @@ export class CID) + multihash as API.MultihashDigest ) ) } @@ -132,7 +132,7 @@ export class CID) + return this as CID } default: { throw Error( @@ -147,10 +147,7 @@ export class CID(self: API.Link, other: unknown): other is CID { - const unknown = - ( - other as { code?: unknown, version?: unknown, multihash?: unknown } - ) + const unknown = other as { code?: unknown, version?: unknown, multihash?: unknown } return ( unknown != null && self.code === unknown.code && @@ -196,7 +193,7 @@ export class CID), + multihash as API.MultihashDigest, bytes ?? encodeCID(version, code, multihash.bytes) ) } else if (value[cidSymbol] === true) { @@ -218,8 +215,7 @@ export class CID) + const digest = Digest.decode(multihash) as API.MultihashDigest return CID.create(version, code, digest) } else { // Otherwise value is not a CID (or an incompatible version of it) in @@ -323,9 +319,9 @@ export class CID)) + ? CID.createV0(digest as API.MultihashDigest) : CID.createV1(specs.codec, digest) - return [(cid as CID), bytes.subarray(specs.size)] + return [cid as CID, bytes.subarray(specs.size)] } /** @@ -345,14 +341,14 @@ export class CID> (val return false } - const withSlash = (value as { '/'?: Uint8Array, bytes: Uint8Array }) + const withSlash = value as { '/'?: Uint8Array, bytes: Uint8Array } if (withSlash['/'] != null && withSlash['/'] === withSlash.bytes) { return true } - const withAsCID = (value as { 'asCID'?: unknown }) + const withAsCID = value as { 'asCID'?: unknown } if (withAsCID.asCID === value) { return true From 9ec46e716ba2fb0fe9e14cede7eacf2d95609d92 Mon Sep 17 00:00:00 2001 From: Cayman Date: Fri, 6 Oct 2023 17:46:38 -0400 Subject: [PATCH 06/13] chore: convert sha1 to typescript --- src/hashes/sha1-browser.js | 18 ------------------ src/hashes/sha1-browser.ts | 12 ++++++++++++ src/hashes/{sha1.js => sha1.ts} | 2 -- 3 files changed, 12 insertions(+), 20 deletions(-) delete mode 100644 src/hashes/sha1-browser.js create mode 100644 src/hashes/sha1-browser.ts rename src/hashes/{sha1.js => sha1.ts} (94%) diff --git a/src/hashes/sha1-browser.js b/src/hashes/sha1-browser.js deleted file mode 100644 index 187ba543..00000000 --- a/src/hashes/sha1-browser.js +++ /dev/null @@ -1,18 +0,0 @@ -/* global crypto */ - -import { from } from './hasher.js' - -/** - * @param {AlgorithmIdentifier} name - */ -const sha = name => - /** - * @param {Uint8Array} data - */ - async data => new Uint8Array(await crypto.subtle.digest(name, data)) - -export const sha1 = from({ - name: 'sha-1', - code: 0x11, - encode: sha('SHA-1') -}) diff --git a/src/hashes/sha1-browser.ts b/src/hashes/sha1-browser.ts new file mode 100644 index 00000000..6764ba8e --- /dev/null +++ b/src/hashes/sha1-browser.ts @@ -0,0 +1,12 @@ +/* global crypto */ + +import { from } from './hasher.js' + +const sha = (name: AlgorithmIdentifier) => + async (data: Uint8Array) => new Uint8Array(await crypto.subtle.digest(name, data)) + +export const sha1 = from({ + name: 'sha-1', + code: 0x11, + encode: sha('SHA-1') +}) diff --git a/src/hashes/sha1.js b/src/hashes/sha1.ts similarity index 94% rename from src/hashes/sha1.js rename to src/hashes/sha1.ts index d552fea5..f8480519 100644 --- a/src/hashes/sha1.js +++ b/src/hashes/sha1.ts @@ -1,5 +1,3 @@ -// @ts-check - import crypto from 'crypto' import { coerce } from '../bytes.js' import { from } from './hasher.js' From 607453ac1390f8ff18502c37388d7c025664e385 Mon Sep 17 00:00:00 2001 From: Cayman Date: Fri, 6 Oct 2023 17:56:36 -0400 Subject: [PATCH 07/13] chore: fix linter errors --- src/bases/base.ts | 2 +- src/cid.ts | 8 +++----- src/hashes/hasher.ts | 2 +- src/link.ts | 2 +- src/traversal.ts | 2 +- test/test-block.spec.ts | 14 +++++++------- test/test-cid.spec.ts | 11 ++++++----- test/test-link.spec.ts | 2 +- test/test-traversal.spec.ts | 6 ++---- 9 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/bases/base.ts b/src/bases/base.ts index 9885412a..03be1c84 100644 --- a/src/bases/base.ts +++ b/src/bases/base.ts @@ -1,5 +1,5 @@ -import basex from '../vendor/base-x.js' import { coerce } from '../bytes.js' +import basex from '../vendor/base-x.js' import type { BaseCodec, BaseDecoder, BaseEncoder, CombobaseDecoder, Multibase, MultibaseCodec, MultibaseDecoder, MultibaseEncoder, UnibaseDecoder } from './interface.js' interface EncodeFn { (bytes: Uint8Array): string } diff --git a/src/cid.ts b/src/cid.ts index 0a533959..6baa4a10 100644 --- a/src/cid.ts +++ b/src/cid.ts @@ -36,7 +36,7 @@ export function fromJSON (json: API.LinkJSON> = new WeakMap() +const cache = new WeakMap>() function baseCache (cid: API.UnknownLink): Map { const baseCache = cache.get(cid) @@ -160,7 +160,7 @@ export class CID { + toJSON (): API.LinkJSON { return { '/': format(this) } } @@ -168,9 +168,7 @@ export class CID = Promise | T -export function from ({ name, code, encode }: { name: Name, code: Code, encode: (input: Uint8Array) => Await }): Hasher { +export function from ({ name, code, encode }: { name: Name, code: Code, encode(input: Uint8Array): Await }): Hasher { return new Hasher(name, code, encode) } diff --git a/src/link.ts b/src/link.ts index 1bea6cc0..8d3fb9a6 100644 --- a/src/link.ts +++ b/src/link.ts @@ -1,5 +1,5 @@ -import type * as API from './link/interface.js' import { CID, format, toJSON, fromJSON } from './cid.js' +import type * as API from './link/interface.js' // This way TS will also expose all the types from module export * from './link/interface.js' diff --git a/src/traversal.ts b/src/traversal.ts index 6cdb3304..ee68e04c 100644 --- a/src/traversal.ts +++ b/src/traversal.ts @@ -4,7 +4,7 @@ import type { CID, Version } from './cid.js' type BlockView = _BlockView -async function walk ({ cid, load, seen }: { cid: CID, load: (cid: CID) => Promise, seen?: Set }): Promise { +async function walk ({ cid, load, seen }: { cid: CID, load(cid: CID): Promise, seen?: Set }): Promise { seen = seen ?? new Set() const b58Cid = cid.toString(base58btc) if (seen.has(b58Cid)) { diff --git a/test/test-block.spec.ts b/test/test-block.spec.ts index 65a79225..120be93c 100644 --- a/test/test-block.spec.ts +++ b/test/test-block.spec.ts @@ -118,28 +118,28 @@ describe('block', () => { }) it('encode', async () => { - // @ts-expect-error + // @ts-expect-error testing invalid usage await assert.isRejected(main.encode({}), 'Missing required argument "value"') - // @ts-expect-error + // @ts-expect-error testing invalid usage await assert.isRejected(main.encode({ value: true }), 'Missing required argument: codec or hasher') }) it('decode', async () => { - // @ts-expect-error + // @ts-expect-error testing invalid usage await assert.isRejected(main.decode({}), 'Missing required argument "bytes"') - // @ts-expect-error + // @ts-expect-error testing invalid usage await assert.isRejected(main.decode({ bytes: true }), 'Missing required argument: codec or hasher') }) it('createUnsafe', async () => { - // @ts-expect-error + // @ts-expect-error testing invalid usage assert.throws(() => main.createUnsafe({}), 'Missing required argument, must either provide "value" or "codec"') }) it('create', async () => { - // @ts-expect-error + // @ts-expect-error testing invalid usage await assert.isRejected(main.create({}), 'Missing required argument "bytes"') - // @ts-expect-error + // @ts-expect-error testing invalid usage await assert.isRejected(main.create({ bytes: true }), 'Missing required argument "hasher"') const block = await main.encode({ value: fixture, codec, hasher }) const block2 = await main.encode({ value: { ...fixture, test: 'blah' }, codec, hasher }) diff --git a/test/test-cid.spec.ts b/test/test-cid.spec.ts index a3b52b42..5b409a59 100644 --- a/test/test-cid.spec.ts +++ b/test/test-cid.spec.ts @@ -1,14 +1,14 @@ /* globals describe, it */ -import { fromHex, toHex, equals } from '../src/bytes.js' -import { varint, CID, MultihashDigest } from '../src/index.js' -import { base58btc } from '../src/bases/base58.js' +import { assert } from 'aegir/chai' +import OLDCID from 'cids' import { base32 } from '../src/bases/base32.js' +import { base58btc } from '../src/bases/base58.js' import { base64 } from '../src/bases/base64.js' +import { fromHex, toHex, equals } from '../src/bytes.js' import { sha256, sha512 } from '../src/hashes/sha2.js' +import { varint, CID, type MultihashDigest } from '../src/index.js' import invalidMultihash from './fixtures/invalid-multihash.js' -import OLDCID from 'cids' -import { assert } from 'aegir/chai' const textEncoder = new TextEncoder() @@ -500,6 +500,7 @@ describe('CID', () => { this.asCID = this } + // eslint-disable-next-line @typescript-eslint/class-literal-property-style get [Symbol.for('@ipld/js-cid/CID')] (): boolean { return true } diff --git a/test/test-link.spec.ts b/test/test-link.spec.ts index a406e2a9..94fd4d2f 100644 --- a/test/test-link.spec.ts +++ b/test/test-link.spec.ts @@ -97,7 +97,7 @@ describe('Link', () => { assert.deepStrictEqual(Link.parse(h1), Link.fromJSON({ '/': h1, - // @ts-expect-error + // @ts-expect-error foo doesn't exist foo: 1 })) diff --git a/test/test-traversal.spec.ts b/test/test-traversal.spec.ts index efb0744c..e0ae2c59 100644 --- a/test/test-traversal.spec.ts +++ b/test/test-traversal.spec.ts @@ -6,10 +6,8 @@ import { fromString } from '../src/bytes.js' import * as codec from '../src/codecs/json.js' import { sha256 as hasher } from '../src/hashes/sha2.js' import { walk } from '../src/traversal.js' -import { fromString } from '../src/bytes.js' -import { assert } from 'aegir/chai' -import type { CID } from '../src/cid.js' import type { BlockView } from '../src/block/interface.js' +import type { CID } from '../src/cid.js' // from dag-pb, simplified function createNode (data: Uint8Array, links: Array<{ Hash: CID, Name: string, Tsize: number }>): { Data: Uint8Array, Links: Array<{ Hash: CID, Name: string, Tsize: number }> } { @@ -78,7 +76,7 @@ describe('traversal', () => { const loadWrapper = (load: loadFn, arr: string[] = []) => async (cid: CID): Promise | null> => { arr.push(cid.toString()) - return await load(cid) + return load(cid) } it('block with no links', async () => { From bc0378ed458d293ebf971e2b49410ffb629a20f5 Mon Sep 17 00:00:00 2001 From: Cayman Date: Fri, 6 Oct 2023 18:07:08 -0400 Subject: [PATCH 08/13] chore: fix merge conflict errors --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 902ae29b..b0facfc3 100644 --- a/package.json +++ b/package.json @@ -149,8 +149,8 @@ }, "./hashes/sha1": { "types": "./dist/types/src/hashes/sha1.d.ts", - "browser": "./src/hashes/sha1-browser.js", - "import": "./src/hashes/sha1.js" + "browser": "./dist/src/hashes/sha1-browser.js", + "import": "./dist/src/hashes/sha1.js" }, "./hashes/sha2": { "types": "./dist/src/hashes/sha2.d.ts", @@ -176,9 +176,9 @@ }, "browser": { "./hashes/sha1": "./dist/src/hashes/sha1-browser.js", - "./src/hashes/sha1.js": "./dist/src/hashes/sha1-browser.js", + "./dist/src/hashes/sha1.js": "./dist/src/hashes/sha1-browser.js", "./hashes/sha2": "./dist/src/hashes/sha2-browser.js", - "./src/hashes/sha2.js": "./dist/src/hashes/sha2-browser.js" + "./dist/src/hashes/sha2.js": "./dist/src/hashes/sha2-browser.js" }, "eslintConfig": { "extends": "ipfs", From 303fa8476c0655fff457ce15e954ef79060d114c Mon Sep 17 00:00:00 2001 From: Cayman Date: Mon, 9 Oct 2023 14:29:05 -0400 Subject: [PATCH 09/13] chore: remove ts-use test package --- .gitignore | 1 - package.json | 6 ++---- test/ts-use/package.json | 20 -------------------- test/ts-use/src/main.ts | 16 ---------------- test/ts-use/tsconfig.json | 8 -------- test/ts-use/tsconfig.tsbuildinfo | 1 + 6 files changed, 3 insertions(+), 49 deletions(-) delete mode 100644 test/ts-use/package.json delete mode 100644 test/ts-use/src/main.ts delete mode 100644 test/ts-use/tsconfig.json create mode 100644 test/ts-use/tsconfig.tsbuildinfo diff --git a/.gitignore b/.gitignore index dec11b7f..a5f2d9cb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ node_modules .DS_Store yarn.lock types -test/ts-use/tsconfig.tsbuildinfo types/tsconfig.tsbuildinfo *.log dist diff --git a/package.json b/package.json index b0facfc3..81bbe9d8 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,7 @@ "test", "tsconfig.json", "dist", - "!**/*.tsbuildinfo", - "!test/ts-use/node_modules" + "!**/*.tsbuildinfo" ], "exports": { ".": { @@ -277,8 +276,7 @@ "build": "aegir build", "release": "aegir release", "docs": "aegir docs", - "test": "npm run lint && npm run test:node && npm run test:chrome && npm run test:ts", - "test:ts": "npm run test --prefix test/ts-use", + "test": "npm run lint && npm run test:node && npm run test:chrome", "test:node": "aegir test -t node --cov", "test:chrome": "aegir test -t browser --cov", "test:chrome-webworker": "aegir test -t webworker", diff --git a/test/ts-use/package.json b/test/ts-use/package.json deleted file mode 100644 index 64a68bf1..00000000 --- a/test/ts-use/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "ts-use", - "private": true, - "type": "module", - "dependencies": { - "multiformats": "file:../../" - }, - "scripts": { - "test": "npm install && ../../node_modules/.bin/tsc --noEmit" - }, - "eslintConfig": { - "extends": "ipfs", - "parserOptions": { - "sourceType": "module", - "project": [ - "./test/ts-use/tsconfig.json" - ] - } - } -} \ No newline at end of file diff --git a/test/ts-use/src/main.ts b/test/ts-use/src/main.ts deleted file mode 100644 index dc678c84..00000000 --- a/test/ts-use/src/main.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as Block from 'multiformats/block' -import * as json from 'multiformats/codecs/json' -import { sha256 } from 'multiformats/hashes/sha2' - -const main = async (): Promise => { - const block = await Block.encode({ - value: { hello: 'world' }, - hasher: sha256, - codec: json - }) - - /* eslint-disable no-console */ - console.log(block) -} - -export default main diff --git a/test/ts-use/tsconfig.json b/test/ts-use/tsconfig.json deleted file mode 100644 index 2588ec61..00000000 --- a/test/ts-use/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "strict": true, - "module": "NodeNext", - "noImplicitAny": true, - "incremental": true - } -} diff --git a/test/ts-use/tsconfig.tsbuildinfo b/test/ts-use/tsconfig.tsbuildinfo new file mode 100644 index 00000000..7354d82c --- /dev/null +++ b/test/ts-use/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.full.d.ts","../../dist/src/hashes/interface.d.ts","../../dist/src/bases/interface.d.ts","../../dist/src/block/interface.d.ts","../../dist/src/link/interface.d.ts","../../dist/src/cid.d.ts","../../dist/src/varint.d.ts","../../dist/src/bytes.d.ts","../../dist/src/hashes/digest.d.ts","../../dist/src/hashes/hasher.d.ts","../../dist/src/codecs/interface.d.ts","../../dist/src/interface.d.ts","../../dist/src/index.d.ts","../../dist/src/block.d.ts","../../dist/src/hashes/sha2.d.ts","../../dist/src/codecs/json.d.ts","./src/main.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/dom-events.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/globals.global.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/keyv/src/index.d.ts","../../node_modules/@types/http-cache-semantics/index.d.ts","../../node_modules/@types/responselike/index.d.ts","../../node_modules/@types/cacheable-request/index.d.ts","../../node_modules/@types/chai/index.d.ts","../../node_modules/@types/chai-as-promised/index.d.ts","../../node_modules/@types/chai-string/index.d.ts","../../node_modules/@types/chai-subset/index.d.ts","../../node_modules/@types/ms/index.d.ts","../../node_modules/@types/debug/index.d.ts","../../node_modules/@types/extend/index.d.ts","../../node_modules/@types/istanbul-lib-coverage/index.d.ts","../../node_modules/@types/json-schema/index.d.ts","../../node_modules/@types/json5/index.d.ts","../../node_modules/@types/keyv/index.d.ts","../../node_modules/@types/unist/index.d.ts","../../node_modules/@types/mdast/index.d.ts","../../node_modules/@types/minimatch/index.d.ts","../../node_modules/@types/minimist/index.d.ts","../../node_modules/@types/mocha/index.d.ts","../../node_modules/@types/normalize-package-data/index.d.ts","../../node_modules/@types/parse-json/index.d.ts","../../node_modules/@types/retry/index.d.ts","../../node_modules/@types/semver/classes/semver.d.ts","../../node_modules/@types/semver/functions/parse.d.ts","../../node_modules/@types/semver/functions/valid.d.ts","../../node_modules/@types/semver/functions/clean.d.ts","../../node_modules/@types/semver/functions/inc.d.ts","../../node_modules/@types/semver/functions/diff.d.ts","../../node_modules/@types/semver/functions/major.d.ts","../../node_modules/@types/semver/functions/minor.d.ts","../../node_modules/@types/semver/functions/patch.d.ts","../../node_modules/@types/semver/functions/prerelease.d.ts","../../node_modules/@types/semver/functions/compare.d.ts","../../node_modules/@types/semver/functions/rcompare.d.ts","../../node_modules/@types/semver/functions/compare-loose.d.ts","../../node_modules/@types/semver/functions/compare-build.d.ts","../../node_modules/@types/semver/functions/sort.d.ts","../../node_modules/@types/semver/functions/rsort.d.ts","../../node_modules/@types/semver/functions/gt.d.ts","../../node_modules/@types/semver/functions/lt.d.ts","../../node_modules/@types/semver/functions/eq.d.ts","../../node_modules/@types/semver/functions/neq.d.ts","../../node_modules/@types/semver/functions/gte.d.ts","../../node_modules/@types/semver/functions/lte.d.ts","../../node_modules/@types/semver/functions/cmp.d.ts","../../node_modules/@types/semver/functions/coerce.d.ts","../../node_modules/@types/semver/classes/comparator.d.ts","../../node_modules/@types/semver/classes/range.d.ts","../../node_modules/@types/semver/functions/satisfies.d.ts","../../node_modules/@types/semver/ranges/max-satisfying.d.ts","../../node_modules/@types/semver/ranges/min-satisfying.d.ts","../../node_modules/@types/semver/ranges/to-comparators.d.ts","../../node_modules/@types/semver/ranges/min-version.d.ts","../../node_modules/@types/semver/ranges/valid.d.ts","../../node_modules/@types/semver/ranges/outside.d.ts","../../node_modules/@types/semver/ranges/gtr.d.ts","../../node_modules/@types/semver/ranges/ltr.d.ts","../../node_modules/@types/semver/ranges/intersects.d.ts","../../node_modules/@types/semver/ranges/simplify.d.ts","../../node_modules/@types/semver/ranges/subset.d.ts","../../node_modules/@types/semver/internals/identifiers.d.ts","../../node_modules/@types/semver/index.d.ts","../../node_modules/@types/sinonjs__fake-timers/index.d.ts","../../node_modules/@types/sinon/index.d.ts","../../node_modules/@types/strip-bom/index.d.ts","../../node_modules/@types/strip-json-comments/index.d.ts","../../node_modules/@types/yargs-parser/index.d.ts","../../node_modules/@types/yargs/index.d.ts","../../node_modules/@types/yauzl/index.d.ts"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","impliedFormat":1},{"version":"7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","impliedFormat":1},{"version":"8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","impliedFormat":1},{"version":"5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","impliedFormat":1},{"version":"4b421cbfb3a38a27c279dec1e9112c3d1da296f77a1a85ddadf7e7a425d45d18","impliedFormat":1},{"version":"1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9","impliedFormat":1},{"version":"746d62152361558ea6d6115cf0da4dd10ede041d14882ede3568bce5dc4b4f1f","impliedFormat":1},{"version":"d11a03592451da2d1065e09e61f4e2a9bf68f780f4f6623c18b57816a9679d17","impliedFormat":1},{"version":"aea179452def8a6152f98f63b191b84e7cbd69b0e248c91e61fb2e52328abe8c","impliedFormat":1},{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true,"impliedFormat":1},{"version":"f3d4da15233e593eacb3965cde7960f3fddf5878528d882bcedd5cbaba0193c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true,"impliedFormat":1},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true,"impliedFormat":1},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true,"impliedFormat":1},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true,"impliedFormat":1},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true,"impliedFormat":1},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true,"impliedFormat":1},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true,"impliedFormat":1},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true,"impliedFormat":1},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true,"impliedFormat":1},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true,"impliedFormat":1},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true,"impliedFormat":1},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true,"impliedFormat":1},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true,"impliedFormat":1},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true,"impliedFormat":1},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true,"impliedFormat":1},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true,"impliedFormat":1},{"version":"5e5e095c4470c8bab227dbbc61374878ecead104c74ab9960d3adcccfee23205","affectsGlobalScope":true,"impliedFormat":1},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true,"impliedFormat":1},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true,"impliedFormat":1},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true,"impliedFormat":1},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true,"impliedFormat":1},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true,"impliedFormat":1},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c55633c733c8378db65ac3da7a767c3cf2cf3057f0565a9124a16a3a2019e87","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb4416144c1bf0323ccbc9afb0ab289c07312214e8820ad17d709498c865a3fe","affectsGlobalScope":true,"impliedFormat":1},{"version":"5b0ca94ec819d68d33da516306c15297acec88efeb0ae9e2b39f71dbd9685ef7","affectsGlobalScope":true,"impliedFormat":1},{"version":"34c839eaaa6d78c8674ae2c37af2236dee6831b13db7b4ef4df3ec889a04d4f2","affectsGlobalScope":true,"impliedFormat":1},{"version":"34478567f8a80171f88f2f30808beb7da15eac0538ae91282dd33dce928d98ed","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab7d58e6161a550ff92e5aff755dc37fe896245348332cd5f1e1203479fe0ed1","affectsGlobalScope":true,"impliedFormat":1},{"version":"6bda95ea27a59a276e46043b7065b55bd4b316c25e70e29b572958fa77565d43","affectsGlobalScope":true,"impliedFormat":1},{"version":"aedb8de1abb2ff1095c153854a6df7deae4a5709c37297f9d6e9948b6806fa66","affectsGlobalScope":true,"impliedFormat":1},{"version":"a4da0551fd39b90ca7ce5f68fb55d4dc0c1396d589b612e1902f68ee090aaada","affectsGlobalScope":true,"impliedFormat":1},{"version":"11ffe3c281f375fff9ffdde8bbec7669b4dd671905509079f866f2354a788064","affectsGlobalScope":true,"impliedFormat":1},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"d96fa8a56871904776165ceb8e00bd56127e1a017bb2664cae76223b5f815141","impliedFormat":1},{"version":"71f910bbc1010c99bc9a63723ba53a0fd74a75f7d8ef5f40f92dda1ff0fe7d6f","impliedFormat":99},{"version":"bdcb1c2272aa71a2f95a86aa81923ecf7292ff5515870d78d214bd958a5c258b","impliedFormat":99},{"version":"02affddde4b76e7b5445a1bb77838a6b9b42151f97fe9c7432df78714737353e","impliedFormat":99},{"version":"862eacc247d6c92524d7879feac6da363f55428cc78270bce7b14f2d3d0b0cef","impliedFormat":99},{"version":"ad90f6028cb9ede302c3be37055e335212398efc06d98213eccfcf7736442fbe","impliedFormat":99},{"version":"594618846a4e54f8e5c1bb06bacc80ad9e4afb49487bd26c6e579c17a544005c","impliedFormat":99},{"version":"6aed8660a3d62ff16adde4407e98f81eb2841394612addb0535bef12c7206fc3","impliedFormat":99},{"version":"162ff5a36d53f972d2b9a92b32568ba9acef365d314de3f1591f7f49faa0e30f","impliedFormat":99},{"version":"4997e1160c0f77e6276348448cafdb5146fbf6773c076aae7cedcd23b98866d0","impliedFormat":99},{"version":"8ad13afb5324460426b210f7c5040d3d19375accd24e22bb52a534c728aca73e","impliedFormat":99},{"version":"e1fe04ff1ffecfb18420f0895d0cd2652f98a27def5c33aae5ef328f186c905b","impliedFormat":99},{"version":"92ed344fade4a16b75edff7e9d2cac3208c23f7dbf524f156d697c96c6c4b738","impliedFormat":99},{"version":"962a8e09151bf0eac85b0cc2e9bbc9ac43c5ea1a589dc28435c29611f13ba3ad","impliedFormat":99},{"version":"827621a9e55b32118ebdf1985c569d8af39090ed7dfdf8f2123995b7580cf8d8","impliedFormat":99},{"version":"cbd340eeef4f6654aca2fe7687b2507270c01ac9d51b7824fff73ea6e320af90","impliedFormat":99},{"version":"25a387a67dd09022cf12074e64aa8d5ba926e97b630709433303d8e2dcf3e3a3","impliedFormat":99},{"version":"ba8691cf6bea9d53e6bf6cbc22af964a9633a21793981a1be3dce65e7a714d8b","impliedFormat":1},{"version":"a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a","impliedFormat":1},{"version":"bce910d9164785c9f0d4dcea4be359f5f92130c7c7833dea6138ab1db310a1f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"7d2e3fea24c712c99c03ad8f556abedbfe105f87f1be10b95dbd409d24bc05a3","impliedFormat":1},{"version":"c7a976828c7acb8ada184935195aef0f389c4e37d87daa52eb4f2f3df3edcdea","affectsGlobalScope":true,"impliedFormat":1},{"version":"3719525a8f6ab731e3dfd585d9f87df55ec7d50d461df84f74eb4d68bb165244","impliedFormat":1},{"version":"5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713","impliedFormat":1},{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true,"impliedFormat":1},{"version":"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","impliedFormat":1},{"version":"b787b5b54349a24f07d089b612a9fb8ff024dbbe991ff52ea2b188a6b1230644","impliedFormat":1},{"version":"bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","impliedFormat":1},{"version":"1cdcfc1f624d6c08aa12c73935f6e13f095919cd99edf95752951796eb225729","impliedFormat":1},{"version":"4eaff3d8e10676fd7913d8c108890e71c688e1e7d52f6d1d55c39514f493dc47","impliedFormat":1},{"version":"14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","impliedFormat":1},{"version":"5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea","impliedFormat":1},{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true,"impliedFormat":1},{"version":"00dee7cdca8b8420c47ea4a31a34b8e8294013ebc4f463fd941e867e7bf05029","affectsGlobalScope":true,"impliedFormat":1},{"version":"7abd2623cdd8148233c0c6b9da0289e124f1718bc58dcb8da4262432e9ce0f0a","impliedFormat":1},{"version":"f4a3088770ba56a4c72e9907bc9798706ab1575097cd024503f57966df2d3d3a","impliedFormat":1},{"version":"7f138842074d0a40681775af008c8452093b68c383c94de31759e853c6d06b5c","impliedFormat":1},{"version":"a3d541d303ee505053f5dcbf9fafb65cac3d5631037501cd616195863a6c5740","impliedFormat":1},{"version":"8d3c583a07e0c37e876908c2d5da575019f689df8d9fa4c081d99119d53dba22","impliedFormat":1},{"version":"2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58","impliedFormat":1},{"version":"e630e5528e899219ae319e83bef54bf3bcb91b01d76861ecf881e8e614b167f0","affectsGlobalScope":true,"impliedFormat":1},{"version":"bcebb922784739bdb34c18ee51095d25a92b560c78ccd2eaacd6bd00f7443d83","impliedFormat":1},{"version":"7ee6ed878c4528215c82b664fe0cfe80e8b4da6c0d4cc80869367868774db8b1","impliedFormat":1},{"version":"b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30","impliedFormat":1},{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true,"impliedFormat":1},{"version":"0715e4cd28ad471b2a93f3e552ff51a3ae423417a01a10aa1d3bc7c6b95059d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","impliedFormat":1},{"version":"210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","impliedFormat":1},{"version":"36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","impliedFormat":1},{"version":"0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","impliedFormat":1},{"version":"25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","impliedFormat":1},{"version":"4f3fdeba4e28e21aa719c081b8dc8f91d47e12e773389b9d35679c08151c9d37","impliedFormat":1},{"version":"1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","impliedFormat":1},{"version":"69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","impliedFormat":1},{"version":"44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","impliedFormat":1},{"version":"23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","impliedFormat":1},{"version":"5629c03c44d1e07698c31d04318c9950d78940461269c0f692a42091cedea142","impliedFormat":1},{"version":"3c4ba1dd9b12ffa284b565063108f2f031d150ea15b8fafbdc17f5d2a07251f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"e10177274a35a9d07c825615340b2fcde2f610f53f3fb40269fd196b4288dda6","impliedFormat":1},{"version":"1422cd9e705adcc09088fda85a900c2b70e3ad36ea85846f68bd1a884cdf4e2b","impliedFormat":1},{"version":"3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","impliedFormat":1},{"version":"5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2","impliedFormat":1},{"version":"c6b124041039647ff446e19ea0e90a7a83256593d64f23c66b4fda6e0c5b968e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a9fc1469744055a3435f203123246b96c094e7ff8c4e1c3863829d9b705b7a34","affectsGlobalScope":true,"impliedFormat":1},{"version":"868831cab82b65dfe1d68180e898af1f2101e89ba9b754d1db6fb8cc2fac1921","impliedFormat":1},{"version":"0fe8985a28f82c450a04a6edf1279d7181c0893f37da7d2a27f8efd4fd5edb03","impliedFormat":1},{"version":"e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa","impliedFormat":1},{"version":"52120bb7e4583612225bdf08e7c12559548170f11e660d33a33623bae9bbdbba","affectsGlobalScope":true,"impliedFormat":1},{"version":"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e","impliedFormat":1},{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6dd3dba8e665ac43d279e0fdf5219edda0eed69b5e9a5061f46cd6a65c4f7a1","impliedFormat":1},{"version":"92edb6e257fa64d3baae647490e041912684f5dc1f243d0aedd60b4b383ff50b","impliedFormat":1},{"version":"cab425b5559edac18327eb2c3c0f47e7e9f71b667290b7689faafd28aac69eae","impliedFormat":1},{"version":"3cfb0cb51cc2c2e1b313d7c4df04dbf7e5bda0a133c6b309bf6af77cf614b971","impliedFormat":1},{"version":"f992cd6cc0bcbaa4e6c810468c90f2d8595f8c6c3cf050c806397d3de8585562","impliedFormat":1},{"version":"c3bc5d095c3c22fd20b5a6550b9c9a6d56c3ffbb87ef057ccce7764b6bed4428","affectsGlobalScope":true,"impliedFormat":1},{"version":"63e2182615c513e89bb8a3e749d08f7c379e86490fcdbf6d35f2c14b3507a6e8","affectsGlobalScope":true,"impliedFormat":1},{"version":"41071d2f1a39386d10bf36d1ba4712ad42a900047f16a109936df9e48f13673e","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4c0db3a49cea9babd5d224ba14243a6a6119bf65a65198994033aaea3a60a71","affectsGlobalScope":true,"impliedFormat":1},{"version":"6a9c5127096b35264eb7cd21b2417bfc1d42cceca9ba4ce2bb0c3410b7816042","impliedFormat":1},{"version":"93b7325b49dfbf613d940ed0e471216657b2d77459dac34f1b5b1678f08f884c","impliedFormat":1},{"version":"80d50bca45b12deb542118e51aa1c5e6c779f2b387e589d475297c07de0b342d","impliedFormat":1},{"version":"8b06ac3faeacb8484d84ddb44571d8f410697f98d7bfa86c0fda60373a9f5215","impliedFormat":1},{"version":"dca41e86e89dfb2e85e6935260250f02eb6683b86c2fa16bec729ddd1bcd9b4b","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1},{"version":"fec943fdb3275eb6e006b35e04a8e2e99e9adf3f4b969ddf15315ac7575a93e4","impliedFormat":1},{"version":"cddf5c26907c0b8378bc05543161c11637b830da9fadf59e02a11e675d11e180","impliedFormat":1},{"version":"5774751340e987a6a9e4a5dcc03ff68a6515adc2b91423e1af2f660fc8f30e81","impliedFormat":1},{"version":"8841e2aa774b89bd23302dede20663306dc1b9902431ac64b24be8b8d0e3f649","impliedFormat":1},{"version":"209e814e8e71aec74f69686a9506dd7610b97ab59dcee9446266446f72a76d05","impliedFormat":1},{"version":"677646e2620795c98a539fb12fb531f10331c217cef1492132b2518f894fa92d","affectsGlobalScope":true,"impliedFormat":1},{"version":"6fa0008bf91a4cc9c8963bace4bba0bd6865cbfa29c3e3ccc461155660fb113a","impliedFormat":1},{"version":"2b8264b2fefd7367e0f20e2c04eed5d3038831fe00f5efbc110ff0131aab899b","impliedFormat":1},{"version":"58a3914b1cce4560d9ad6eee2b716caaa030eda0a90b21ca2457ea9e2783eaa3","impliedFormat":1},{"version":"2b93035328f7778d200252681c1d86285d501ed424825a18f81e4c3028aa51d9","impliedFormat":1},{"version":"2ac9c8332c5f8510b8bdd571f8271e0f39b0577714d5e95c1e79a12b2616f069","impliedFormat":1},{"version":"42c21aa963e7b86fa00801d96e88b36803188018d5ad91db2a9101bccd40b3ff","impliedFormat":1},{"version":"d31eb848cdebb4c55b4893b335a7c0cca95ad66dee13cbb7d0893810c0a9c301","impliedFormat":1},{"version":"b9f96255e1048ed2ea33ec553122716f0e57fc1c3ad778e9aa15f5b46547bd23","impliedFormat":1},{"version":"7a9e0a564fee396cacf706523b5aeed96e04c6b871a8bebefad78499fbffc5bc","impliedFormat":1},{"version":"906c751ef5822ec0dadcea2f0e9db64a33fb4ee926cc9f7efa38afe5d5371b2a","impliedFormat":1},{"version":"5387c049e9702f2d2d7ece1a74836a14b47fbebe9bbeb19f94c580a37c855351","impliedFormat":1},{"version":"c68391fb9efad5d99ff332c65b1606248c4e4a9f1dd9a087204242b56c7126d6","impliedFormat":1},{"version":"e9cf02252d3a0ced987d24845dcb1f11c1be5541f17e5daa44c6de2d18138d0c","impliedFormat":1},{"version":"e8b02b879754d85f48489294f99147aeccc352c760d95a6fe2b6e49cd400b2fe","impliedFormat":1},{"version":"9f6908ab3d8a86c68b86e38578afc7095114e66b2fc36a2a96e9252aac3998e0","impliedFormat":1},{"version":"0eedb2344442b143ddcd788f87096961cd8572b64f10b4afc3356aa0460171c6","impliedFormat":1},{"version":"71405cc70f183d029cc5018375f6c35117ffdaf11846c35ebf85ee3956b1b2a6","impliedFormat":1},{"version":"c68baff4d8ba346130e9753cefe2e487a16731bf17e05fdacc81e8c9a26aae9d","impliedFormat":1},{"version":"2cd15528d8bb5d0453aa339b4b52e0696e8b07e790c153831c642c3dea5ac8af","impliedFormat":1},{"version":"479d622e66283ffa9883fbc33e441f7fc928b2277ff30aacbec7b7761b4e9579","impliedFormat":1},{"version":"ade307876dc5ca267ca308d09e737b611505e015c535863f22420a11fffc1c54","impliedFormat":1},{"version":"f8cdefa3e0dee639eccbe9794b46f90291e5fd3989fcba60d2f08fde56179fb9","impliedFormat":1},{"version":"86c5a62f99aac7053976e317dbe9acb2eaf903aaf3d2e5bb1cafe5c2df7b37a8","impliedFormat":1},{"version":"2b300954ce01a8343866f737656e13243e86e5baef51bd0631b21dcef1f6e954","impliedFormat":1},{"version":"a2d409a9ffd872d6b9d78ead00baa116bbc73cfa959fce9a2f29d3227876b2a1","impliedFormat":1},{"version":"b288936f560cd71f4a6002953290de9ff8dfbfbf37f5a9391be5c83322324898","impliedFormat":1},{"version":"61178a781ef82e0ff54f9430397e71e8f365fc1e3725e0e5346f2de7b0d50dfa","impliedFormat":1},{"version":"6a6ccb37feb3aad32d9be026a3337db195979cd5727a616fc0f557e974101a54","impliedFormat":1},{"version":"c649ea79205c029a02272ef55b7ab14ada0903db26144d2205021f24727ac7a3","impliedFormat":1},{"version":"38e2b02897c6357bbcff729ef84c736727b45cc152abe95a7567caccdfad2a1d","impliedFormat":1},{"version":"d6610ea7e0b1a7686dba062a1e5544dd7d34140f4545305b7c6afaebfb348341","impliedFormat":1},{"version":"3dee35db743bdba2c8d19aece7ac049bde6fa587e195d86547c882784e6ba34c","impliedFormat":1},{"version":"b15e55c5fa977c2f25ca0b1db52cfa2d1fd4bf0baf90a8b90d4a7678ca462ff1","impliedFormat":1},{"version":"f41d30972724714763a2698ae949fbc463afb203b5fa7c4ad7e4de0871129a17","impliedFormat":1},{"version":"843dd7b6a7c6269fd43827303f5cbe65c1fecabc30b4670a50d5a15d57daeeb9","impliedFormat":1},{"version":"f06d8b8567ee9fd799bf7f806efe93b67683ef24f4dea5b23ef12edff4434d9d","impliedFormat":1},{"version":"6017384f697ff38bc3ef6a546df5b230c3c31329db84cbfe686c83bec011e2b2","impliedFormat":1},{"version":"e1a5b30d9248549ca0c0bb1d653bafae20c64c4aa5928cc4cd3017b55c2177b0","impliedFormat":1},{"version":"a593632d5878f17295bd53e1c77f27bf4c15212822f764a2bfc1702f4b413fa0","impliedFormat":1},{"version":"a868a534ba1c2ca9060b8a13b0ffbbbf78b4be7b0ff80d8c75b02773f7192c29","impliedFormat":1},{"version":"da7545aba8f54a50fde23e2ede00158dc8112560d934cee58098dfb03aae9b9d","impliedFormat":1},{"version":"34baf65cfee92f110d6653322e2120c2d368ee64b3c7981dff08ed105c4f19b0","impliedFormat":1},{"version":"a1a261624efb3a00ff346b13580f70f3463b8cdcc58b60f5793ff11785d52cab","impliedFormat":1},{"version":"f83b320cceccfc48457a818d18fc9a006ab18d0bdd727aa2c2e73dc1b4a45e98","impliedFormat":1},{"version":"cffac9db07bba0b35754412e48215d1bc5153c03c46409bbeaf315848359822b","impliedFormat":1},{"version":"4006c872e38a2c4e09c593bc0cdd32b7b4f5c4843910bea0def631c483fff6c5","impliedFormat":1},{"version":"ab6aa3a65d473871ee093e3b7b71ed0f9c69e07d1d4295f45c9efd91a771241d","impliedFormat":1},{"version":"70e9a18da08294f75bf23e46c7d69e67634c0765d355887b9b41f0d959e1426e","impliedFormat":1},{"version":"e9eb1b173aa166892f3eddab182e49cfe59aa2e14d33aedb6b49d175ed6a3750","impliedFormat":1},{"version":"65dfa4bc49ccd1355789abb6ae215b302a5b050fdee9651124fe7e826f33113c","impliedFormat":1}],"options":{"module":199,"noImplicitAny":true,"strict":true},"fileIdsList":[[122],[70,71,122],[63,64,122],[63,122],[62,122],[69,122],[60,122],[60,67,122],[68,122],[64,65,66,67,68,70,122],[60,61,62,63,69,122],[60,61,62,122],[92,95,121,122,129,130,131,132],[122,134],[122,138],[92,122,129],[122,145],[76,122],[79,122],[80,85,113,122],[81,92,93,100,110,121,122],[81,82,92,100,122],[83,122],[84,85,93,101,122],[85,110,118,122],[86,88,92,100,122],[87,122],[88,89,122],[92,122],[90,92,122],[92,93,94,110,121,122],[92,93,94,107,110,113,122],[122,126],[88,92,95,100,110,121,122],[92,93,95,96,100,110,118,121,122],[95,97,110,118,121,122],[76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128],[92,98,122],[99,121,122],[88,92,100,110,122],[101,122],[102,122],[79,103,122],[104,120,122,126],[105,122],[106,122],[92,107,108,122],[107,109,122,124],[80,92,110,111,112,113,122],[80,110,112,122],[110,111,122],[113,122],[114,122],[92,116,117,122],[116,117,122],[85,100,110,118,122],[119,122],[100,120,122],[80,95,106,121,122],[85,122],[110,122,123],[122,124],[122,125],[80,85,92,94,103,110,121,122,124,126],[110,122,127],[95,110,122,129],[122,153,192],[122,153,177,192],[122,192],[122,153],[122,153,178,192],[122,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191],[122,178,192],[122,193],[122,197],[92,110,122,129],[72,73,74,122]],"referencedMap":[[61,1],[72,2],[62,3],[66,1],[64,4],[69,5],[74,6],[67,7],[68,8],[60,1],[73,9],[71,10],[70,11],[63,12],[65,1],[133,13],[135,14],[136,14],[137,14],[134,1],[139,15],[140,1],[131,1],[141,1],[142,1],[143,1],[144,16],[146,17],[147,1],[148,1],[149,1],[138,1],[76,18],[77,18],[79,19],[80,20],[81,21],[82,22],[83,23],[84,24],[85,25],[86,26],[87,27],[88,28],[89,28],[91,29],[90,30],[92,29],[93,31],[94,32],[78,33],[128,1],[95,34],[96,35],[97,36],[129,37],[98,38],[99,39],[100,40],[101,41],[102,42],[103,43],[104,44],[105,45],[106,46],[107,47],[108,47],[109,48],[110,49],[112,50],[111,51],[113,52],[114,53],[115,1],[116,54],[117,55],[118,56],[119,57],[120,58],[121,59],[122,60],[123,61],[124,62],[125,63],[126,64],[127,65],[150,1],[151,1],[132,66],[152,1],[177,67],[178,68],[153,69],[156,69],[175,67],[176,67],[166,67],[165,70],[163,67],[158,67],[171,67],[169,67],[173,67],[157,67],[170,67],[174,67],[159,67],[160,67],[172,67],[154,67],[161,67],[162,67],[164,67],[168,67],[179,71],[167,67],[155,67],[192,72],[191,1],[186,71],[188,73],[187,71],[180,71],[181,71],[183,71],[185,71],[189,73],[190,73],[182,73],[184,73],[194,74],[193,1],[195,1],[196,1],[145,1],[197,1],[198,75],[199,76],[130,29],[11,1],[12,1],[16,1],[15,1],[2,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[3,1],[4,1],[28,1],[25,1],[26,1],[27,1],[29,1],[30,1],[31,1],[5,1],[32,1],[33,1],[34,1],[35,1],[6,1],[39,1],[36,1],[37,1],[38,1],[40,1],[7,1],[41,1],[46,1],[47,1],[42,1],[43,1],[44,1],[45,1],[8,1],[51,1],[48,1],[49,1],[50,1],[52,1],[9,1],[53,1],[54,1],[55,1],[56,1],[57,1],[1,1],[10,1],[59,1],[58,1],[14,1],[13,1],[75,77]],"exportedModulesMap":[[61,1],[72,2],[62,3],[66,1],[64,4],[69,5],[74,6],[67,7],[68,8],[60,1],[73,9],[71,10],[70,11],[63,12],[65,1],[133,13],[135,14],[136,14],[137,14],[134,1],[139,15],[140,1],[131,1],[141,1],[142,1],[143,1],[144,16],[146,17],[147,1],[148,1],[149,1],[138,1],[76,18],[77,18],[79,19],[80,20],[81,21],[82,22],[83,23],[84,24],[85,25],[86,26],[87,27],[88,28],[89,28],[91,29],[90,30],[92,29],[93,31],[94,32],[78,33],[128,1],[95,34],[96,35],[97,36],[129,37],[98,38],[99,39],[100,40],[101,41],[102,42],[103,43],[104,44],[105,45],[106,46],[107,47],[108,47],[109,48],[110,49],[112,50],[111,51],[113,52],[114,53],[115,1],[116,54],[117,55],[118,56],[119,57],[120,58],[121,59],[122,60],[123,61],[124,62],[125,63],[126,64],[127,65],[150,1],[151,1],[132,66],[152,1],[177,67],[178,68],[153,69],[156,69],[175,67],[176,67],[166,67],[165,70],[163,67],[158,67],[171,67],[169,67],[173,67],[157,67],[170,67],[174,67],[159,67],[160,67],[172,67],[154,67],[161,67],[162,67],[164,67],[168,67],[179,71],[167,67],[155,67],[192,72],[191,1],[186,71],[188,73],[187,71],[180,71],[181,71],[183,71],[185,71],[189,73],[190,73],[182,73],[184,73],[194,74],[193,1],[195,1],[196,1],[145,1],[197,1],[198,75],[199,76],[130,29],[11,1],[12,1],[16,1],[15,1],[2,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[3,1],[4,1],[28,1],[25,1],[26,1],[27,1],[29,1],[30,1],[31,1],[5,1],[32,1],[33,1],[34,1],[35,1],[6,1],[39,1],[36,1],[37,1],[38,1],[40,1],[7,1],[41,1],[46,1],[47,1],[42,1],[43,1],[44,1],[45,1],[8,1],[51,1],[48,1],[49,1],[50,1],[52,1],[9,1],[53,1],[54,1],[55,1],[56,1],[57,1],[1,1],[10,1],[59,1],[58,1],[14,1],[13,1],[75,77]],"semanticDiagnosticsPerFile":[61,72,62,66,64,69,74,67,68,60,73,71,70,63,65,133,135,136,137,134,139,140,131,141,142,143,144,146,147,148,149,138,76,77,79,80,81,82,83,84,85,86,87,88,89,91,90,92,93,94,78,128,95,96,97,129,98,99,100,101,102,103,104,105,106,107,108,109,110,112,111,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,150,151,132,152,177,178,153,156,175,176,166,165,163,158,171,169,173,157,170,174,159,160,172,154,161,162,164,168,179,167,155,192,191,186,188,187,180,181,183,185,189,190,182,184,194,193,195,196,145,197,198,199,130,11,12,16,15,2,17,18,19,20,21,22,23,24,3,4,28,25,26,27,29,30,31,5,32,33,34,35,6,39,36,37,38,40,7,41,46,47,42,43,44,45,8,51,48,49,50,52,9,53,54,55,56,57,1,10,59,58,14,13,75],"affectedFilesPendingEmit":[[61,1],[72,1],[62,1],[66,1],[64,1],[69,1],[74,1],[67,1],[68,1],[60,1],[73,1],[71,1],[70,1],[63,1],[65,1],[133,1],[135,1],[136,1],[137,1],[134,1],[139,1],[140,1],[131,1],[141,1],[142,1],[143,1],[144,1],[146,1],[147,1],[148,1],[149,1],[138,1],[76,1],[77,1],[79,1],[80,1],[81,1],[82,1],[83,1],[84,1],[85,1],[86,1],[87,1],[88,1],[89,1],[91,1],[90,1],[92,1],[93,1],[94,1],[78,1],[128,1],[95,1],[96,1],[97,1],[129,1],[98,1],[99,1],[100,1],[101,1],[102,1],[103,1],[104,1],[105,1],[106,1],[107,1],[108,1],[109,1],[110,1],[112,1],[111,1],[113,1],[114,1],[115,1],[116,1],[117,1],[118,1],[119,1],[120,1],[121,1],[122,1],[123,1],[124,1],[125,1],[126,1],[127,1],[150,1],[151,1],[132,1],[152,1],[177,1],[178,1],[153,1],[156,1],[175,1],[176,1],[166,1],[165,1],[163,1],[158,1],[171,1],[169,1],[173,1],[157,1],[170,1],[174,1],[159,1],[160,1],[172,1],[154,1],[161,1],[162,1],[164,1],[168,1],[179,1],[167,1],[155,1],[192,1],[191,1],[186,1],[188,1],[187,1],[180,1],[181,1],[183,1],[185,1],[189,1],[190,1],[182,1],[184,1],[194,1],[193,1],[195,1],[196,1],[145,1],[197,1],[198,1],[199,1],[130,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1],[10,1],[59,1],[75,1]]},"version":"4.9.5"} \ No newline at end of file From 721654b17e30b01e9ee63eb76a1e3c462812593c Mon Sep 17 00:00:00 2001 From: achingbrain Date: Mon, 30 Oct 2023 14:26:57 +0000 Subject: [PATCH 10/13] chore: tidy up project config --- .github/workflows/semantic-pull-request.yml | 12 +++++ .github/workflows/stale.yml | 13 ++++++ .github/workflows/typecheck.yml | 29 ------------ .gitignore | 13 +++--- README.md | 51 ++++++--------------- package.json | 23 ++++------ test/ts-use/tsconfig.tsbuildinfo | 1 - typedoc.json | 35 ++++++++++++++ 8 files changed, 89 insertions(+), 88 deletions(-) create mode 100644 .github/workflows/semantic-pull-request.yml create mode 100644 .github/workflows/stale.yml delete mode 100644 .github/workflows/typecheck.yml delete mode 100644 test/ts-use/tsconfig.tsbuildinfo create mode 100644 typedoc.json diff --git a/.github/workflows/semantic-pull-request.yml b/.github/workflows/semantic-pull-request.yml new file mode 100644 index 00000000..bd00f090 --- /dev/null +++ b/.github/workflows/semantic-pull-request.yml @@ -0,0 +1,12 @@ +name: Semantic PR + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + uses: pl-strflt/.github/.github/workflows/reusable-semantic-pull-request.yml@v0.3 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..16d65d72 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,13 @@ +name: Close and mark stale issue + +on: + schedule: + - cron: '0 0 * * *' + +permissions: + issues: write + pull-requests: write + +jobs: + stale: + uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3 diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml deleted file mode 100644 index 78d48e93..00000000 --- a/.github/workflows/typecheck.yml +++ /dev/null @@ -1,29 +0,0 @@ -on: - push: - branches: - - master - - main - - default - pull_request: - branches: - - "**" - -name: Typecheck -jobs: - check: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [12.x] - steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3.8.2 - with: - node-version: ${{ matrix.node-version }} - - name: Install dependencies - run: npm install - - name: Typecheck - uses: gozala/typescript-error-reporter-action@v1.0.9 - with: - project: tsconfig.json diff --git a/.gitignore b/.gitignore index a5f2d9cb..7ad9e674 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ -.coverage -package-lock.json node_modules -.DS_Store -yarn.lock -types -types/tsconfig.tsbuildinfo -*.log +build dist .docs +.coverage +node_modules +package-lock.json +yarn.lock +.vscode diff --git a/README.md b/README.md index 1ed02dda..9f0c512e 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,16 @@ -# multiformats - [![multiformats.io](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://multiformats.io) [![codecov](https://img.shields.io/codecov/c/github/multiformats/js-multiformats.svg?style=flat-square)](https://codecov.io/gh/multiformats/js-multiformats) [![CI](https://img.shields.io/github/actions/workflow/status/multiformats/js-multiformats/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/multiformats/js-multiformats/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) > Interface for multihash, multicodec, multibase and CID -## Table of contents - -- [Install](#install) - - [Browser ` ``` -## Interfaces +# Interfaces This library defines common interfaces and low level building blocks for various interrelated multiformat technologies (multicodec, multihash, multibase, and CID). They can be used to implement custom base encoders / decoders / codecs, codec encoders /decoders and multihash hashers that comply to the interface that layers above assume. @@ -80,7 +59,7 @@ block = await Block.decode({ bytes: block.bytes, codec, hasher }) block = await Block.create({ bytes: block.bytes, cid: block.cid, codec, hasher }) ``` -### Multibase Encoders / Decoders / Codecs +## Multibase Encoders / Decoders / Codecs CIDs can be serialized to string representation using multibase encoders that implement [`MultibaseEncoder`](https://github.com/multiformats/js-multiformats/blob/master/src/bases/interface.ts) interface. This library provides quite a few implementations that can be imported: @@ -123,7 +102,7 @@ v0.toV1().toString() //> 'bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku' ``` -### Multicodec Encoders / Decoders / Codecs +## Multicodec Encoders / Decoders / Codecs This library defines [`BlockEncoder`, `BlockDecoder` and `BlockCodec` interfaces](https://github.com/multiformats/js-multiformats/blob/master/src/codecs/interface.ts). Codec implementations should conform to the `BlockCodec` interface which implements both `BlockEncoder` and `BlockDecoder`. @@ -142,7 +121,7 @@ export const { name, code, encode, decode } = { } ``` -### Multihash Hashers +## Multihash Hashers This library defines [`MultihashHasher` and `MultihashDigest` interfaces](https://github.com/multiformats/js-multiformats/blob/master/src/hashes/interface.ts) and convinient function for implementing them: @@ -164,7 +143,7 @@ CID.create(1, json.code, hash) //> CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) ``` -### Traversal +## Traversal This library contains higher-order functions for traversing graphs of data easily. @@ -200,18 +179,18 @@ console.log(blocks) //> [CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea)] ``` -## Legacy interface +# Legacy interface [`blockcodec-to-ipld-format`](https://github.com/ipld/js-blockcodec-to-ipld-format) converts a multiformats [`BlockCodec`](https://github.com/multiformats/js-multiformats/blob/master/src/codecs/interface.ts#L21) into an [`interface-ipld-format`](https://github.com/ipld/interface-ipld-format) for use with the [`ipld`](https://github.com/ipld/ipld) package. This can help bridge IPLD codecs implemented using the structure and interfaces defined here to existing code that assumes, or requires `interface-ipld-format`. This bridge also includes the relevant TypeScript definitions. -## Implementations +# Implementations By default, no base encodings (other than base32 & base58btc), hash functions, or codec implementations are exposed by `multiformats`, you need to import the ones you need yourself. -### Multibase codecs +## Multibase codecs | bases | import | repo | | ------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------- | @@ -222,7 +201,7 @@ import the ones you need yourself. Other (less useful) bases implemented in [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/bases) include: `base2`, `base8`, `base10`, `base36` and `base256emoji`. -### Multihash hashers +## Multihash hashers | hashes | import | repo | | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ | @@ -232,7 +211,7 @@ Other (less useful) bases implemented in [multiformats/js-multiformats](https:// | `murmur3-128`, `murmur3-32` | `@multiformats/murmur3` | [multiformats/js-murmur3](https://github.com/multiformats/js-murmur3) | | `blake2b-*`, `blake2s-*` | `@multiformats/blake2` | [multiformats/js-blake2](https://github.com/multiformats/js-blake2) | -### IPLD codecs (multicodec) +## IPLD codecs (multicodec) | codec | import | repo | | ---------- | -------------------------- | ------------------------------------------------------------------------------------------------------ | @@ -243,17 +222,17 @@ Other (less useful) bases implemented in [multiformats/js-multiformats](https:// | `dag-pb` | `@ipld/dag-pb` | [ipld/js-dag-pb](https://github.com/ipld/js-dag-pb) | | `dag-jose` | `dag-jose` | [ceramicnetwork/js-dag-jose](https://github.com/ceramicnetwork/js-dag-jose) | -## API Docs +# API Docs - -## License +# License Licensed under either of - Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) - MIT ([LICENSE-MIT](LICENSE-MIT) / ) -## Contribution +# Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. diff --git a/package.json b/package.json index dc547742..0edc8014 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,6 @@ "ipld", "multiformats" ], - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - }, "type": "module", "types": "./dist/src/index.d.ts", "typesVersions": { @@ -40,13 +36,9 @@ } }, "files": [ - "CHANGELOG.md", - "examples", - "LICENSE*", "src", - "test", - "tsconfig.json", "dist", + "!dist/test", "!**/*.tsbuildinfo" ], "exports": { @@ -173,15 +165,10 @@ "import": "./dist/src/traversal.js" } }, - "browser": { - "./hashes/sha1": "./dist/src/hashes/sha1-browser.js", - "./dist/src/hashes/sha1.js": "./dist/src/hashes/sha1-browser.js", - "./hashes/sha2": "./dist/src/hashes/sha2-browser.js", - "./dist/src/hashes/sha2.js": "./dist/src/hashes/sha2-browser.js" - }, "eslintConfig": { "extends": "ipfs", "parserOptions": { + "project": true, "sourceType": "module" } }, @@ -300,5 +287,11 @@ "browser" ] } + }, + "browser": { + "./hashes/sha1": "./dist/src/hashes/sha1-browser.js", + "./dist/src/hashes/sha1.js": "./dist/src/hashes/sha1-browser.js", + "./hashes/sha2": "./dist/src/hashes/sha2-browser.js", + "./dist/src/hashes/sha2.js": "./dist/src/hashes/sha2-browser.js" } } diff --git a/test/ts-use/tsconfig.tsbuildinfo b/test/ts-use/tsconfig.tsbuildinfo deleted file mode 100644 index 7354d82c..00000000 --- a/test/ts-use/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.full.d.ts","../../dist/src/hashes/interface.d.ts","../../dist/src/bases/interface.d.ts","../../dist/src/block/interface.d.ts","../../dist/src/link/interface.d.ts","../../dist/src/cid.d.ts","../../dist/src/varint.d.ts","../../dist/src/bytes.d.ts","../../dist/src/hashes/digest.d.ts","../../dist/src/hashes/hasher.d.ts","../../dist/src/codecs/interface.d.ts","../../dist/src/interface.d.ts","../../dist/src/index.d.ts","../../dist/src/block.d.ts","../../dist/src/hashes/sha2.d.ts","../../dist/src/codecs/json.d.ts","./src/main.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/dom-events.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/globals.global.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/keyv/src/index.d.ts","../../node_modules/@types/http-cache-semantics/index.d.ts","../../node_modules/@types/responselike/index.d.ts","../../node_modules/@types/cacheable-request/index.d.ts","../../node_modules/@types/chai/index.d.ts","../../node_modules/@types/chai-as-promised/index.d.ts","../../node_modules/@types/chai-string/index.d.ts","../../node_modules/@types/chai-subset/index.d.ts","../../node_modules/@types/ms/index.d.ts","../../node_modules/@types/debug/index.d.ts","../../node_modules/@types/extend/index.d.ts","../../node_modules/@types/istanbul-lib-coverage/index.d.ts","../../node_modules/@types/json-schema/index.d.ts","../../node_modules/@types/json5/index.d.ts","../../node_modules/@types/keyv/index.d.ts","../../node_modules/@types/unist/index.d.ts","../../node_modules/@types/mdast/index.d.ts","../../node_modules/@types/minimatch/index.d.ts","../../node_modules/@types/minimist/index.d.ts","../../node_modules/@types/mocha/index.d.ts","../../node_modules/@types/normalize-package-data/index.d.ts","../../node_modules/@types/parse-json/index.d.ts","../../node_modules/@types/retry/index.d.ts","../../node_modules/@types/semver/classes/semver.d.ts","../../node_modules/@types/semver/functions/parse.d.ts","../../node_modules/@types/semver/functions/valid.d.ts","../../node_modules/@types/semver/functions/clean.d.ts","../../node_modules/@types/semver/functions/inc.d.ts","../../node_modules/@types/semver/functions/diff.d.ts","../../node_modules/@types/semver/functions/major.d.ts","../../node_modules/@types/semver/functions/minor.d.ts","../../node_modules/@types/semver/functions/patch.d.ts","../../node_modules/@types/semver/functions/prerelease.d.ts","../../node_modules/@types/semver/functions/compare.d.ts","../../node_modules/@types/semver/functions/rcompare.d.ts","../../node_modules/@types/semver/functions/compare-loose.d.ts","../../node_modules/@types/semver/functions/compare-build.d.ts","../../node_modules/@types/semver/functions/sort.d.ts","../../node_modules/@types/semver/functions/rsort.d.ts","../../node_modules/@types/semver/functions/gt.d.ts","../../node_modules/@types/semver/functions/lt.d.ts","../../node_modules/@types/semver/functions/eq.d.ts","../../node_modules/@types/semver/functions/neq.d.ts","../../node_modules/@types/semver/functions/gte.d.ts","../../node_modules/@types/semver/functions/lte.d.ts","../../node_modules/@types/semver/functions/cmp.d.ts","../../node_modules/@types/semver/functions/coerce.d.ts","../../node_modules/@types/semver/classes/comparator.d.ts","../../node_modules/@types/semver/classes/range.d.ts","../../node_modules/@types/semver/functions/satisfies.d.ts","../../node_modules/@types/semver/ranges/max-satisfying.d.ts","../../node_modules/@types/semver/ranges/min-satisfying.d.ts","../../node_modules/@types/semver/ranges/to-comparators.d.ts","../../node_modules/@types/semver/ranges/min-version.d.ts","../../node_modules/@types/semver/ranges/valid.d.ts","../../node_modules/@types/semver/ranges/outside.d.ts","../../node_modules/@types/semver/ranges/gtr.d.ts","../../node_modules/@types/semver/ranges/ltr.d.ts","../../node_modules/@types/semver/ranges/intersects.d.ts","../../node_modules/@types/semver/ranges/simplify.d.ts","../../node_modules/@types/semver/ranges/subset.d.ts","../../node_modules/@types/semver/internals/identifiers.d.ts","../../node_modules/@types/semver/index.d.ts","../../node_modules/@types/sinonjs__fake-timers/index.d.ts","../../node_modules/@types/sinon/index.d.ts","../../node_modules/@types/strip-bom/index.d.ts","../../node_modules/@types/strip-json-comments/index.d.ts","../../node_modules/@types/yargs-parser/index.d.ts","../../node_modules/@types/yargs/index.d.ts","../../node_modules/@types/yauzl/index.d.ts"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","impliedFormat":1},{"version":"7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","impliedFormat":1},{"version":"8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","impliedFormat":1},{"version":"5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","impliedFormat":1},{"version":"4b421cbfb3a38a27c279dec1e9112c3d1da296f77a1a85ddadf7e7a425d45d18","impliedFormat":1},{"version":"1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9","impliedFormat":1},{"version":"746d62152361558ea6d6115cf0da4dd10ede041d14882ede3568bce5dc4b4f1f","impliedFormat":1},{"version":"d11a03592451da2d1065e09e61f4e2a9bf68f780f4f6623c18b57816a9679d17","impliedFormat":1},{"version":"aea179452def8a6152f98f63b191b84e7cbd69b0e248c91e61fb2e52328abe8c","impliedFormat":1},{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true,"impliedFormat":1},{"version":"f3d4da15233e593eacb3965cde7960f3fddf5878528d882bcedd5cbaba0193c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true,"impliedFormat":1},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true,"impliedFormat":1},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true,"impliedFormat":1},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true,"impliedFormat":1},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true,"impliedFormat":1},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true,"impliedFormat":1},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true,"impliedFormat":1},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true,"impliedFormat":1},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true,"impliedFormat":1},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true,"impliedFormat":1},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true,"impliedFormat":1},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true,"impliedFormat":1},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true,"impliedFormat":1},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true,"impliedFormat":1},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true,"impliedFormat":1},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true,"impliedFormat":1},{"version":"5e5e095c4470c8bab227dbbc61374878ecead104c74ab9960d3adcccfee23205","affectsGlobalScope":true,"impliedFormat":1},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true,"impliedFormat":1},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true,"impliedFormat":1},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true,"impliedFormat":1},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true,"impliedFormat":1},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true,"impliedFormat":1},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c55633c733c8378db65ac3da7a767c3cf2cf3057f0565a9124a16a3a2019e87","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb4416144c1bf0323ccbc9afb0ab289c07312214e8820ad17d709498c865a3fe","affectsGlobalScope":true,"impliedFormat":1},{"version":"5b0ca94ec819d68d33da516306c15297acec88efeb0ae9e2b39f71dbd9685ef7","affectsGlobalScope":true,"impliedFormat":1},{"version":"34c839eaaa6d78c8674ae2c37af2236dee6831b13db7b4ef4df3ec889a04d4f2","affectsGlobalScope":true,"impliedFormat":1},{"version":"34478567f8a80171f88f2f30808beb7da15eac0538ae91282dd33dce928d98ed","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab7d58e6161a550ff92e5aff755dc37fe896245348332cd5f1e1203479fe0ed1","affectsGlobalScope":true,"impliedFormat":1},{"version":"6bda95ea27a59a276e46043b7065b55bd4b316c25e70e29b572958fa77565d43","affectsGlobalScope":true,"impliedFormat":1},{"version":"aedb8de1abb2ff1095c153854a6df7deae4a5709c37297f9d6e9948b6806fa66","affectsGlobalScope":true,"impliedFormat":1},{"version":"a4da0551fd39b90ca7ce5f68fb55d4dc0c1396d589b612e1902f68ee090aaada","affectsGlobalScope":true,"impliedFormat":1},{"version":"11ffe3c281f375fff9ffdde8bbec7669b4dd671905509079f866f2354a788064","affectsGlobalScope":true,"impliedFormat":1},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"d96fa8a56871904776165ceb8e00bd56127e1a017bb2664cae76223b5f815141","impliedFormat":1},{"version":"71f910bbc1010c99bc9a63723ba53a0fd74a75f7d8ef5f40f92dda1ff0fe7d6f","impliedFormat":99},{"version":"bdcb1c2272aa71a2f95a86aa81923ecf7292ff5515870d78d214bd958a5c258b","impliedFormat":99},{"version":"02affddde4b76e7b5445a1bb77838a6b9b42151f97fe9c7432df78714737353e","impliedFormat":99},{"version":"862eacc247d6c92524d7879feac6da363f55428cc78270bce7b14f2d3d0b0cef","impliedFormat":99},{"version":"ad90f6028cb9ede302c3be37055e335212398efc06d98213eccfcf7736442fbe","impliedFormat":99},{"version":"594618846a4e54f8e5c1bb06bacc80ad9e4afb49487bd26c6e579c17a544005c","impliedFormat":99},{"version":"6aed8660a3d62ff16adde4407e98f81eb2841394612addb0535bef12c7206fc3","impliedFormat":99},{"version":"162ff5a36d53f972d2b9a92b32568ba9acef365d314de3f1591f7f49faa0e30f","impliedFormat":99},{"version":"4997e1160c0f77e6276348448cafdb5146fbf6773c076aae7cedcd23b98866d0","impliedFormat":99},{"version":"8ad13afb5324460426b210f7c5040d3d19375accd24e22bb52a534c728aca73e","impliedFormat":99},{"version":"e1fe04ff1ffecfb18420f0895d0cd2652f98a27def5c33aae5ef328f186c905b","impliedFormat":99},{"version":"92ed344fade4a16b75edff7e9d2cac3208c23f7dbf524f156d697c96c6c4b738","impliedFormat":99},{"version":"962a8e09151bf0eac85b0cc2e9bbc9ac43c5ea1a589dc28435c29611f13ba3ad","impliedFormat":99},{"version":"827621a9e55b32118ebdf1985c569d8af39090ed7dfdf8f2123995b7580cf8d8","impliedFormat":99},{"version":"cbd340eeef4f6654aca2fe7687b2507270c01ac9d51b7824fff73ea6e320af90","impliedFormat":99},{"version":"25a387a67dd09022cf12074e64aa8d5ba926e97b630709433303d8e2dcf3e3a3","impliedFormat":99},{"version":"ba8691cf6bea9d53e6bf6cbc22af964a9633a21793981a1be3dce65e7a714d8b","impliedFormat":1},{"version":"a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a","impliedFormat":1},{"version":"bce910d9164785c9f0d4dcea4be359f5f92130c7c7833dea6138ab1db310a1f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"7d2e3fea24c712c99c03ad8f556abedbfe105f87f1be10b95dbd409d24bc05a3","impliedFormat":1},{"version":"c7a976828c7acb8ada184935195aef0f389c4e37d87daa52eb4f2f3df3edcdea","affectsGlobalScope":true,"impliedFormat":1},{"version":"3719525a8f6ab731e3dfd585d9f87df55ec7d50d461df84f74eb4d68bb165244","impliedFormat":1},{"version":"5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713","impliedFormat":1},{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true,"impliedFormat":1},{"version":"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","impliedFormat":1},{"version":"b787b5b54349a24f07d089b612a9fb8ff024dbbe991ff52ea2b188a6b1230644","impliedFormat":1},{"version":"bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","impliedFormat":1},{"version":"1cdcfc1f624d6c08aa12c73935f6e13f095919cd99edf95752951796eb225729","impliedFormat":1},{"version":"4eaff3d8e10676fd7913d8c108890e71c688e1e7d52f6d1d55c39514f493dc47","impliedFormat":1},{"version":"14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","impliedFormat":1},{"version":"5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea","impliedFormat":1},{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true,"impliedFormat":1},{"version":"00dee7cdca8b8420c47ea4a31a34b8e8294013ebc4f463fd941e867e7bf05029","affectsGlobalScope":true,"impliedFormat":1},{"version":"7abd2623cdd8148233c0c6b9da0289e124f1718bc58dcb8da4262432e9ce0f0a","impliedFormat":1},{"version":"f4a3088770ba56a4c72e9907bc9798706ab1575097cd024503f57966df2d3d3a","impliedFormat":1},{"version":"7f138842074d0a40681775af008c8452093b68c383c94de31759e853c6d06b5c","impliedFormat":1},{"version":"a3d541d303ee505053f5dcbf9fafb65cac3d5631037501cd616195863a6c5740","impliedFormat":1},{"version":"8d3c583a07e0c37e876908c2d5da575019f689df8d9fa4c081d99119d53dba22","impliedFormat":1},{"version":"2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58","impliedFormat":1},{"version":"e630e5528e899219ae319e83bef54bf3bcb91b01d76861ecf881e8e614b167f0","affectsGlobalScope":true,"impliedFormat":1},{"version":"bcebb922784739bdb34c18ee51095d25a92b560c78ccd2eaacd6bd00f7443d83","impliedFormat":1},{"version":"7ee6ed878c4528215c82b664fe0cfe80e8b4da6c0d4cc80869367868774db8b1","impliedFormat":1},{"version":"b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30","impliedFormat":1},{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true,"impliedFormat":1},{"version":"0715e4cd28ad471b2a93f3e552ff51a3ae423417a01a10aa1d3bc7c6b95059d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","impliedFormat":1},{"version":"210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","impliedFormat":1},{"version":"36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","impliedFormat":1},{"version":"0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","impliedFormat":1},{"version":"25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","impliedFormat":1},{"version":"4f3fdeba4e28e21aa719c081b8dc8f91d47e12e773389b9d35679c08151c9d37","impliedFormat":1},{"version":"1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","impliedFormat":1},{"version":"69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","impliedFormat":1},{"version":"44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","impliedFormat":1},{"version":"23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","impliedFormat":1},{"version":"5629c03c44d1e07698c31d04318c9950d78940461269c0f692a42091cedea142","impliedFormat":1},{"version":"3c4ba1dd9b12ffa284b565063108f2f031d150ea15b8fafbdc17f5d2a07251f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"e10177274a35a9d07c825615340b2fcde2f610f53f3fb40269fd196b4288dda6","impliedFormat":1},{"version":"1422cd9e705adcc09088fda85a900c2b70e3ad36ea85846f68bd1a884cdf4e2b","impliedFormat":1},{"version":"3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","impliedFormat":1},{"version":"5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2","impliedFormat":1},{"version":"c6b124041039647ff446e19ea0e90a7a83256593d64f23c66b4fda6e0c5b968e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a9fc1469744055a3435f203123246b96c094e7ff8c4e1c3863829d9b705b7a34","affectsGlobalScope":true,"impliedFormat":1},{"version":"868831cab82b65dfe1d68180e898af1f2101e89ba9b754d1db6fb8cc2fac1921","impliedFormat":1},{"version":"0fe8985a28f82c450a04a6edf1279d7181c0893f37da7d2a27f8efd4fd5edb03","impliedFormat":1},{"version":"e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa","impliedFormat":1},{"version":"52120bb7e4583612225bdf08e7c12559548170f11e660d33a33623bae9bbdbba","affectsGlobalScope":true,"impliedFormat":1},{"version":"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e","impliedFormat":1},{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6dd3dba8e665ac43d279e0fdf5219edda0eed69b5e9a5061f46cd6a65c4f7a1","impliedFormat":1},{"version":"92edb6e257fa64d3baae647490e041912684f5dc1f243d0aedd60b4b383ff50b","impliedFormat":1},{"version":"cab425b5559edac18327eb2c3c0f47e7e9f71b667290b7689faafd28aac69eae","impliedFormat":1},{"version":"3cfb0cb51cc2c2e1b313d7c4df04dbf7e5bda0a133c6b309bf6af77cf614b971","impliedFormat":1},{"version":"f992cd6cc0bcbaa4e6c810468c90f2d8595f8c6c3cf050c806397d3de8585562","impliedFormat":1},{"version":"c3bc5d095c3c22fd20b5a6550b9c9a6d56c3ffbb87ef057ccce7764b6bed4428","affectsGlobalScope":true,"impliedFormat":1},{"version":"63e2182615c513e89bb8a3e749d08f7c379e86490fcdbf6d35f2c14b3507a6e8","affectsGlobalScope":true,"impliedFormat":1},{"version":"41071d2f1a39386d10bf36d1ba4712ad42a900047f16a109936df9e48f13673e","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4c0db3a49cea9babd5d224ba14243a6a6119bf65a65198994033aaea3a60a71","affectsGlobalScope":true,"impliedFormat":1},{"version":"6a9c5127096b35264eb7cd21b2417bfc1d42cceca9ba4ce2bb0c3410b7816042","impliedFormat":1},{"version":"93b7325b49dfbf613d940ed0e471216657b2d77459dac34f1b5b1678f08f884c","impliedFormat":1},{"version":"80d50bca45b12deb542118e51aa1c5e6c779f2b387e589d475297c07de0b342d","impliedFormat":1},{"version":"8b06ac3faeacb8484d84ddb44571d8f410697f98d7bfa86c0fda60373a9f5215","impliedFormat":1},{"version":"dca41e86e89dfb2e85e6935260250f02eb6683b86c2fa16bec729ddd1bcd9b4b","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1},{"version":"fec943fdb3275eb6e006b35e04a8e2e99e9adf3f4b969ddf15315ac7575a93e4","impliedFormat":1},{"version":"cddf5c26907c0b8378bc05543161c11637b830da9fadf59e02a11e675d11e180","impliedFormat":1},{"version":"5774751340e987a6a9e4a5dcc03ff68a6515adc2b91423e1af2f660fc8f30e81","impliedFormat":1},{"version":"8841e2aa774b89bd23302dede20663306dc1b9902431ac64b24be8b8d0e3f649","impliedFormat":1},{"version":"209e814e8e71aec74f69686a9506dd7610b97ab59dcee9446266446f72a76d05","impliedFormat":1},{"version":"677646e2620795c98a539fb12fb531f10331c217cef1492132b2518f894fa92d","affectsGlobalScope":true,"impliedFormat":1},{"version":"6fa0008bf91a4cc9c8963bace4bba0bd6865cbfa29c3e3ccc461155660fb113a","impliedFormat":1},{"version":"2b8264b2fefd7367e0f20e2c04eed5d3038831fe00f5efbc110ff0131aab899b","impliedFormat":1},{"version":"58a3914b1cce4560d9ad6eee2b716caaa030eda0a90b21ca2457ea9e2783eaa3","impliedFormat":1},{"version":"2b93035328f7778d200252681c1d86285d501ed424825a18f81e4c3028aa51d9","impliedFormat":1},{"version":"2ac9c8332c5f8510b8bdd571f8271e0f39b0577714d5e95c1e79a12b2616f069","impliedFormat":1},{"version":"42c21aa963e7b86fa00801d96e88b36803188018d5ad91db2a9101bccd40b3ff","impliedFormat":1},{"version":"d31eb848cdebb4c55b4893b335a7c0cca95ad66dee13cbb7d0893810c0a9c301","impliedFormat":1},{"version":"b9f96255e1048ed2ea33ec553122716f0e57fc1c3ad778e9aa15f5b46547bd23","impliedFormat":1},{"version":"7a9e0a564fee396cacf706523b5aeed96e04c6b871a8bebefad78499fbffc5bc","impliedFormat":1},{"version":"906c751ef5822ec0dadcea2f0e9db64a33fb4ee926cc9f7efa38afe5d5371b2a","impliedFormat":1},{"version":"5387c049e9702f2d2d7ece1a74836a14b47fbebe9bbeb19f94c580a37c855351","impliedFormat":1},{"version":"c68391fb9efad5d99ff332c65b1606248c4e4a9f1dd9a087204242b56c7126d6","impliedFormat":1},{"version":"e9cf02252d3a0ced987d24845dcb1f11c1be5541f17e5daa44c6de2d18138d0c","impliedFormat":1},{"version":"e8b02b879754d85f48489294f99147aeccc352c760d95a6fe2b6e49cd400b2fe","impliedFormat":1},{"version":"9f6908ab3d8a86c68b86e38578afc7095114e66b2fc36a2a96e9252aac3998e0","impliedFormat":1},{"version":"0eedb2344442b143ddcd788f87096961cd8572b64f10b4afc3356aa0460171c6","impliedFormat":1},{"version":"71405cc70f183d029cc5018375f6c35117ffdaf11846c35ebf85ee3956b1b2a6","impliedFormat":1},{"version":"c68baff4d8ba346130e9753cefe2e487a16731bf17e05fdacc81e8c9a26aae9d","impliedFormat":1},{"version":"2cd15528d8bb5d0453aa339b4b52e0696e8b07e790c153831c642c3dea5ac8af","impliedFormat":1},{"version":"479d622e66283ffa9883fbc33e441f7fc928b2277ff30aacbec7b7761b4e9579","impliedFormat":1},{"version":"ade307876dc5ca267ca308d09e737b611505e015c535863f22420a11fffc1c54","impliedFormat":1},{"version":"f8cdefa3e0dee639eccbe9794b46f90291e5fd3989fcba60d2f08fde56179fb9","impliedFormat":1},{"version":"86c5a62f99aac7053976e317dbe9acb2eaf903aaf3d2e5bb1cafe5c2df7b37a8","impliedFormat":1},{"version":"2b300954ce01a8343866f737656e13243e86e5baef51bd0631b21dcef1f6e954","impliedFormat":1},{"version":"a2d409a9ffd872d6b9d78ead00baa116bbc73cfa959fce9a2f29d3227876b2a1","impliedFormat":1},{"version":"b288936f560cd71f4a6002953290de9ff8dfbfbf37f5a9391be5c83322324898","impliedFormat":1},{"version":"61178a781ef82e0ff54f9430397e71e8f365fc1e3725e0e5346f2de7b0d50dfa","impliedFormat":1},{"version":"6a6ccb37feb3aad32d9be026a3337db195979cd5727a616fc0f557e974101a54","impliedFormat":1},{"version":"c649ea79205c029a02272ef55b7ab14ada0903db26144d2205021f24727ac7a3","impliedFormat":1},{"version":"38e2b02897c6357bbcff729ef84c736727b45cc152abe95a7567caccdfad2a1d","impliedFormat":1},{"version":"d6610ea7e0b1a7686dba062a1e5544dd7d34140f4545305b7c6afaebfb348341","impliedFormat":1},{"version":"3dee35db743bdba2c8d19aece7ac049bde6fa587e195d86547c882784e6ba34c","impliedFormat":1},{"version":"b15e55c5fa977c2f25ca0b1db52cfa2d1fd4bf0baf90a8b90d4a7678ca462ff1","impliedFormat":1},{"version":"f41d30972724714763a2698ae949fbc463afb203b5fa7c4ad7e4de0871129a17","impliedFormat":1},{"version":"843dd7b6a7c6269fd43827303f5cbe65c1fecabc30b4670a50d5a15d57daeeb9","impliedFormat":1},{"version":"f06d8b8567ee9fd799bf7f806efe93b67683ef24f4dea5b23ef12edff4434d9d","impliedFormat":1},{"version":"6017384f697ff38bc3ef6a546df5b230c3c31329db84cbfe686c83bec011e2b2","impliedFormat":1},{"version":"e1a5b30d9248549ca0c0bb1d653bafae20c64c4aa5928cc4cd3017b55c2177b0","impliedFormat":1},{"version":"a593632d5878f17295bd53e1c77f27bf4c15212822f764a2bfc1702f4b413fa0","impliedFormat":1},{"version":"a868a534ba1c2ca9060b8a13b0ffbbbf78b4be7b0ff80d8c75b02773f7192c29","impliedFormat":1},{"version":"da7545aba8f54a50fde23e2ede00158dc8112560d934cee58098dfb03aae9b9d","impliedFormat":1},{"version":"34baf65cfee92f110d6653322e2120c2d368ee64b3c7981dff08ed105c4f19b0","impliedFormat":1},{"version":"a1a261624efb3a00ff346b13580f70f3463b8cdcc58b60f5793ff11785d52cab","impliedFormat":1},{"version":"f83b320cceccfc48457a818d18fc9a006ab18d0bdd727aa2c2e73dc1b4a45e98","impliedFormat":1},{"version":"cffac9db07bba0b35754412e48215d1bc5153c03c46409bbeaf315848359822b","impliedFormat":1},{"version":"4006c872e38a2c4e09c593bc0cdd32b7b4f5c4843910bea0def631c483fff6c5","impliedFormat":1},{"version":"ab6aa3a65d473871ee093e3b7b71ed0f9c69e07d1d4295f45c9efd91a771241d","impliedFormat":1},{"version":"70e9a18da08294f75bf23e46c7d69e67634c0765d355887b9b41f0d959e1426e","impliedFormat":1},{"version":"e9eb1b173aa166892f3eddab182e49cfe59aa2e14d33aedb6b49d175ed6a3750","impliedFormat":1},{"version":"65dfa4bc49ccd1355789abb6ae215b302a5b050fdee9651124fe7e826f33113c","impliedFormat":1}],"options":{"module":199,"noImplicitAny":true,"strict":true},"fileIdsList":[[122],[70,71,122],[63,64,122],[63,122],[62,122],[69,122],[60,122],[60,67,122],[68,122],[64,65,66,67,68,70,122],[60,61,62,63,69,122],[60,61,62,122],[92,95,121,122,129,130,131,132],[122,134],[122,138],[92,122,129],[122,145],[76,122],[79,122],[80,85,113,122],[81,92,93,100,110,121,122],[81,82,92,100,122],[83,122],[84,85,93,101,122],[85,110,118,122],[86,88,92,100,122],[87,122],[88,89,122],[92,122],[90,92,122],[92,93,94,110,121,122],[92,93,94,107,110,113,122],[122,126],[88,92,95,100,110,121,122],[92,93,95,96,100,110,118,121,122],[95,97,110,118,121,122],[76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128],[92,98,122],[99,121,122],[88,92,100,110,122],[101,122],[102,122],[79,103,122],[104,120,122,126],[105,122],[106,122],[92,107,108,122],[107,109,122,124],[80,92,110,111,112,113,122],[80,110,112,122],[110,111,122],[113,122],[114,122],[92,116,117,122],[116,117,122],[85,100,110,118,122],[119,122],[100,120,122],[80,95,106,121,122],[85,122],[110,122,123],[122,124],[122,125],[80,85,92,94,103,110,121,122,124,126],[110,122,127],[95,110,122,129],[122,153,192],[122,153,177,192],[122,192],[122,153],[122,153,178,192],[122,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191],[122,178,192],[122,193],[122,197],[92,110,122,129],[72,73,74,122]],"referencedMap":[[61,1],[72,2],[62,3],[66,1],[64,4],[69,5],[74,6],[67,7],[68,8],[60,1],[73,9],[71,10],[70,11],[63,12],[65,1],[133,13],[135,14],[136,14],[137,14],[134,1],[139,15],[140,1],[131,1],[141,1],[142,1],[143,1],[144,16],[146,17],[147,1],[148,1],[149,1],[138,1],[76,18],[77,18],[79,19],[80,20],[81,21],[82,22],[83,23],[84,24],[85,25],[86,26],[87,27],[88,28],[89,28],[91,29],[90,30],[92,29],[93,31],[94,32],[78,33],[128,1],[95,34],[96,35],[97,36],[129,37],[98,38],[99,39],[100,40],[101,41],[102,42],[103,43],[104,44],[105,45],[106,46],[107,47],[108,47],[109,48],[110,49],[112,50],[111,51],[113,52],[114,53],[115,1],[116,54],[117,55],[118,56],[119,57],[120,58],[121,59],[122,60],[123,61],[124,62],[125,63],[126,64],[127,65],[150,1],[151,1],[132,66],[152,1],[177,67],[178,68],[153,69],[156,69],[175,67],[176,67],[166,67],[165,70],[163,67],[158,67],[171,67],[169,67],[173,67],[157,67],[170,67],[174,67],[159,67],[160,67],[172,67],[154,67],[161,67],[162,67],[164,67],[168,67],[179,71],[167,67],[155,67],[192,72],[191,1],[186,71],[188,73],[187,71],[180,71],[181,71],[183,71],[185,71],[189,73],[190,73],[182,73],[184,73],[194,74],[193,1],[195,1],[196,1],[145,1],[197,1],[198,75],[199,76],[130,29],[11,1],[12,1],[16,1],[15,1],[2,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[3,1],[4,1],[28,1],[25,1],[26,1],[27,1],[29,1],[30,1],[31,1],[5,1],[32,1],[33,1],[34,1],[35,1],[6,1],[39,1],[36,1],[37,1],[38,1],[40,1],[7,1],[41,1],[46,1],[47,1],[42,1],[43,1],[44,1],[45,1],[8,1],[51,1],[48,1],[49,1],[50,1],[52,1],[9,1],[53,1],[54,1],[55,1],[56,1],[57,1],[1,1],[10,1],[59,1],[58,1],[14,1],[13,1],[75,77]],"exportedModulesMap":[[61,1],[72,2],[62,3],[66,1],[64,4],[69,5],[74,6],[67,7],[68,8],[60,1],[73,9],[71,10],[70,11],[63,12],[65,1],[133,13],[135,14],[136,14],[137,14],[134,1],[139,15],[140,1],[131,1],[141,1],[142,1],[143,1],[144,16],[146,17],[147,1],[148,1],[149,1],[138,1],[76,18],[77,18],[79,19],[80,20],[81,21],[82,22],[83,23],[84,24],[85,25],[86,26],[87,27],[88,28],[89,28],[91,29],[90,30],[92,29],[93,31],[94,32],[78,33],[128,1],[95,34],[96,35],[97,36],[129,37],[98,38],[99,39],[100,40],[101,41],[102,42],[103,43],[104,44],[105,45],[106,46],[107,47],[108,47],[109,48],[110,49],[112,50],[111,51],[113,52],[114,53],[115,1],[116,54],[117,55],[118,56],[119,57],[120,58],[121,59],[122,60],[123,61],[124,62],[125,63],[126,64],[127,65],[150,1],[151,1],[132,66],[152,1],[177,67],[178,68],[153,69],[156,69],[175,67],[176,67],[166,67],[165,70],[163,67],[158,67],[171,67],[169,67],[173,67],[157,67],[170,67],[174,67],[159,67],[160,67],[172,67],[154,67],[161,67],[162,67],[164,67],[168,67],[179,71],[167,67],[155,67],[192,72],[191,1],[186,71],[188,73],[187,71],[180,71],[181,71],[183,71],[185,71],[189,73],[190,73],[182,73],[184,73],[194,74],[193,1],[195,1],[196,1],[145,1],[197,1],[198,75],[199,76],[130,29],[11,1],[12,1],[16,1],[15,1],[2,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[3,1],[4,1],[28,1],[25,1],[26,1],[27,1],[29,1],[30,1],[31,1],[5,1],[32,1],[33,1],[34,1],[35,1],[6,1],[39,1],[36,1],[37,1],[38,1],[40,1],[7,1],[41,1],[46,1],[47,1],[42,1],[43,1],[44,1],[45,1],[8,1],[51,1],[48,1],[49,1],[50,1],[52,1],[9,1],[53,1],[54,1],[55,1],[56,1],[57,1],[1,1],[10,1],[59,1],[58,1],[14,1],[13,1],[75,77]],"semanticDiagnosticsPerFile":[61,72,62,66,64,69,74,67,68,60,73,71,70,63,65,133,135,136,137,134,139,140,131,141,142,143,144,146,147,148,149,138,76,77,79,80,81,82,83,84,85,86,87,88,89,91,90,92,93,94,78,128,95,96,97,129,98,99,100,101,102,103,104,105,106,107,108,109,110,112,111,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,150,151,132,152,177,178,153,156,175,176,166,165,163,158,171,169,173,157,170,174,159,160,172,154,161,162,164,168,179,167,155,192,191,186,188,187,180,181,183,185,189,190,182,184,194,193,195,196,145,197,198,199,130,11,12,16,15,2,17,18,19,20,21,22,23,24,3,4,28,25,26,27,29,30,31,5,32,33,34,35,6,39,36,37,38,40,7,41,46,47,42,43,44,45,8,51,48,49,50,52,9,53,54,55,56,57,1,10,59,58,14,13,75],"affectedFilesPendingEmit":[[61,1],[72,1],[62,1],[66,1],[64,1],[69,1],[74,1],[67,1],[68,1],[60,1],[73,1],[71,1],[70,1],[63,1],[65,1],[133,1],[135,1],[136,1],[137,1],[134,1],[139,1],[140,1],[131,1],[141,1],[142,1],[143,1],[144,1],[146,1],[147,1],[148,1],[149,1],[138,1],[76,1],[77,1],[79,1],[80,1],[81,1],[82,1],[83,1],[84,1],[85,1],[86,1],[87,1],[88,1],[89,1],[91,1],[90,1],[92,1],[93,1],[94,1],[78,1],[128,1],[95,1],[96,1],[97,1],[129,1],[98,1],[99,1],[100,1],[101,1],[102,1],[103,1],[104,1],[105,1],[106,1],[107,1],[108,1],[109,1],[110,1],[112,1],[111,1],[113,1],[114,1],[115,1],[116,1],[117,1],[118,1],[119,1],[120,1],[121,1],[122,1],[123,1],[124,1],[125,1],[126,1],[127,1],[150,1],[151,1],[132,1],[152,1],[177,1],[178,1],[153,1],[156,1],[175,1],[176,1],[166,1],[165,1],[163,1],[158,1],[171,1],[169,1],[173,1],[157,1],[170,1],[174,1],[159,1],[160,1],[172,1],[154,1],[161,1],[162,1],[164,1],[168,1],[179,1],[167,1],[155,1],[192,1],[191,1],[186,1],[188,1],[187,1],[180,1],[181,1],[183,1],[185,1],[189,1],[190,1],[182,1],[184,1],[194,1],[193,1],[195,1],[196,1],[145,1],[197,1],[198,1],[199,1],[130,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1],[10,1],[59,1],[75,1]]},"version":"4.9.5"} \ No newline at end of file diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 00000000..87e4675c --- /dev/null +++ b/typedoc.json @@ -0,0 +1,35 @@ +{ + "entryPoints": [ + "./src/index.ts", + "./src/bases/base10.ts", + "./src/bases/base16.ts", + "./src/bases/base2.ts", + "./src/bases/base256emoji.ts", + "./src/bases/base32.ts", + "./src/bases/base36.ts", + "./src/bases/base58.ts", + "./src/bases/base64.ts", + "./src/bases/base8.ts", + "./src/bases/identity.ts", + "./src/bases/interface.ts", + "./src/basics.ts", + "./src/block.ts", + "./src/block/interface.ts", + "./src/bytes.ts", + "./src/cid.ts", + "./src/codecs/interface.ts", + "./src/codecs/json.ts", + "./src/codecs/raw.ts", + "./src/hashes/digest.ts", + "./src/hashes/hasher.ts", + "./src/hashes/identity.ts", + "./src/hashes/interface.ts", + "./src/hashes/sha1.ts", + "./src/hashes/sha2.ts", + "./src/interface.ts", + "./src/link.ts", + "./src/link/interface.ts", + "./src/traversal.ts" + ], + "includeVersion": true +} From ca7bc7a779e587cf4af9ee191b433152f05656ca Mon Sep 17 00:00:00 2001 From: Cayman Date: Wed, 6 Dec 2023 14:37:54 -0500 Subject: [PATCH 11/13] chore: long function signatures to multiple lines --- src/block.ts | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/block.ts b/src/block.ts index 540abb6c..c1e7a6c2 100644 --- a/src/block.ts +++ b/src/block.ts @@ -126,12 +126,18 @@ class Block implem } } +interface EncodeInput { + value: T + codec: API.BlockEncoder + hasher: API.MultihashHasher +} + /** * @template T - Logical type of the data encoded in the block * @template Code - multicodec code corresponding to codec used to encode the block * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. */ -async function encode ({ value, codec, hasher }: { value: T, codec: API.BlockEncoder, hasher: API.MultihashHasher }): Promise> { +async function encode ({ value, codec, hasher }: EncodeInput): Promise> { if (typeof value === 'undefined') throw new Error('Missing required argument "value"') if (codec == null || hasher == null) throw new Error('Missing required argument: codec or hasher') @@ -147,12 +153,18 @@ async function encode ({ value, cod return new Block({ value, bytes, cid }) } +interface DecodeInput { + bytes: API.ByteView + codec: API.BlockDecoder + hasher: API.MultihashHasher +} + /** * @template T - Logical type of the data encoded in the block * @template Code - multicodec code corresponding to codec used to encode the block * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. */ -async function decode ({ bytes, codec, hasher }: { bytes: API.ByteView, codec: API.BlockDecoder, hasher: API.MultihashHasher }): Promise> { +async function decode ({ bytes, codec, hasher }: DecodeInput): Promise> { if (bytes == null) throw new Error('Missing required argument "bytes"') if (codec == null || hasher == null) throw new Error('Missing required argument: codec or hasher') @@ -164,13 +176,25 @@ async function decode ({ bytes, cod return new Block({ value, bytes, cid }) } +type CreateUnsafeInput = { + cid: API.Link + value: T + codec?: API.BlockDecoder + bytes: API.ByteView +} | { + cid: API.Link + value?: undefined + codec: API.BlockDecoder + bytes: API.ByteView +} + /** * @template T - Logical type of the data encoded in the block * @template Code - multicodec code corresponding to codec used to encode the block * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. * @template V - CID version */ -function createUnsafe ({ bytes, cid, value: maybeValue, codec }: { cid: API.Link, value: T, codec?: API.BlockDecoder, bytes: API.ByteView } | { cid: API.Link, bytes: API.ByteView, value?: undefined, codec: API.BlockDecoder }): API.BlockView { +function createUnsafe ({ bytes, cid, value: maybeValue, codec }: CreateUnsafeInput): API.BlockView { const value = maybeValue !== undefined ? maybeValue : (codec?.decode(bytes)) @@ -184,13 +208,20 @@ function createUnsafe { + bytes: API.ByteView + cid: API.Link + hasher: API.MultihashHasher + codec: API.BlockDecoder +} + /** * @template T - Logical type of the data encoded in the block * @template Code - multicodec code corresponding to codec used to encode the block * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. * @template V - CID version */ -async function create ({ bytes, cid, hasher, codec }: { bytes: API.ByteView, cid: API.Link, hasher: API.MultihashHasher, codec: API.BlockDecoder }): Promise> { +async function create ({ bytes, cid, hasher, codec }: CreateInput): Promise> { if (bytes == null) throw new Error('Missing required argument "bytes"') if (hasher == null) throw new Error('Missing required argument "hasher"') const value = codec.decode(bytes) From 0db24546bd29c7735d29c4114262f33bf5013784 Mon Sep 17 00:00:00 2001 From: Cayman Date: Wed, 6 Dec 2023 14:42:34 -0500 Subject: [PATCH 12/13] chore: prefer individual exports over grouped --- src/basics.ts | 8 ++++---- src/block.ts | 12 +++++------- src/bytes.ts | 18 ++++++++---------- src/traversal.ts | 4 +--- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/basics.ts b/src/basics.ts index 114afba8..11b45ed1 100644 --- a/src/basics.ts +++ b/src/basics.ts @@ -14,8 +14,8 @@ import * as identity from './hashes/identity.js' import * as sha2 from './hashes/sha2.js' import { CID, hasher, digest, varint, bytes } from './index.js' -const bases = { ...identityBase, ...base2, ...base8, ...base10, ...base16, ...base32, ...base36, ...base58, ...base64, ...base256emoji } -const hashes = { ...sha2, ...identity } -const codecs = { raw, json } +export const bases = { ...identityBase, ...base2, ...base8, ...base10, ...base16, ...base32, ...base36, ...base58, ...base64, ...base256emoji } +export const hashes = { ...sha2, ...identity } +export const codecs = { raw, json } -export { CID, hasher, digest, varint, bytes, hashes, bases, codecs } +export { CID, hasher, digest, varint, bytes } diff --git a/src/block.ts b/src/block.ts index c1e7a6c2..ae59ff13 100644 --- a/src/block.ts +++ b/src/block.ts @@ -90,7 +90,7 @@ function get (source: T, path: string[]): API.BlockCursorView { * @template A - multicodec code corresponding to the hashing algorithm used in CID creation. * @template V - CID version */ -class Block implements API.BlockView { +export class Block implements API.BlockView { readonly cid: CID readonly bytes: API.ByteView readonly value: T @@ -137,7 +137,7 @@ interface EncodeInput { * @template Code - multicodec code corresponding to codec used to encode the block * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. */ -async function encode ({ value, codec, hasher }: EncodeInput): Promise> { +export async function encode ({ value, codec, hasher }: EncodeInput): Promise> { if (typeof value === 'undefined') throw new Error('Missing required argument "value"') if (codec == null || hasher == null) throw new Error('Missing required argument: codec or hasher') @@ -164,7 +164,7 @@ interface DecodeInput { * @template Code - multicodec code corresponding to codec used to encode the block * @template Alg - multicodec code corresponding to the hashing algorithm used in CID creation. */ -async function decode ({ bytes, codec, hasher }: DecodeInput): Promise> { +export async function decode ({ bytes, codec, hasher }: DecodeInput): Promise> { if (bytes == null) throw new Error('Missing required argument "bytes"') if (codec == null || hasher == null) throw new Error('Missing required argument: codec or hasher') @@ -194,7 +194,7 @@ type CreateUnsafeInput ({ bytes, cid, value: maybeValue, codec }: CreateUnsafeInput): API.BlockView { +export function createUnsafe ({ bytes, cid, value: maybeValue, codec }: CreateUnsafeInput): API.BlockView { const value = maybeValue !== undefined ? maybeValue : (codec?.decode(bytes)) @@ -221,7 +221,7 @@ interface CreateInput ({ bytes, cid, hasher, codec }: CreateInput): Promise> { +export async function create ({ bytes, cid, hasher, codec }: CreateInput): Promise> { if (bytes == null) throw new Error('Missing required argument "bytes"') if (hasher == null) throw new Error('Missing required argument "hasher"') const value = codec.decode(bytes) @@ -237,5 +237,3 @@ async function create hex + byte.toString(16).padStart(2, '0'), '') } -function fromHex (hex: string): Uint8Array { +export function fromHex (hex: string): Uint8Array { const hexes = hex.match(/../g) return hexes != null ? new Uint8Array(hexes.map(b => parseInt(b, 16))) : empty } -function equals (aa: Uint8Array, bb: Uint8Array): boolean { +export function equals (aa: Uint8Array, bb: Uint8Array): boolean { if (aa === bb) return true if (aa.byteLength !== bb.byteLength) { return false @@ -24,7 +24,7 @@ function equals (aa: Uint8Array, bb: Uint8Array): boolean { return true } -function coerce (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array { +export function coerce (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array { if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') return o if (o instanceof ArrayBuffer) return new Uint8Array(o) if (ArrayBuffer.isView(o)) { @@ -33,16 +33,14 @@ function coerce (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array { throw new Error('Unknown type, must be binary type') } -function isBinary (o: unknown): o is ArrayBuffer | ArrayBufferView { +export function isBinary (o: unknown): o is ArrayBuffer | ArrayBufferView { return o instanceof ArrayBuffer || ArrayBuffer.isView(o) } -function fromString (str: string): Uint8Array { +export function fromString (str: string): Uint8Array { return new TextEncoder().encode(str) } -function toString (b: Uint8Array): string { +export function toString (b: Uint8Array): string { return new TextDecoder().decode(b) } - -export { equals, coerce, isBinary, fromHex, toHex, fromString, toString, empty } diff --git a/src/traversal.ts b/src/traversal.ts index ee68e04c..abb07663 100644 --- a/src/traversal.ts +++ b/src/traversal.ts @@ -4,7 +4,7 @@ import type { CID, Version } from './cid.js' type BlockView = _BlockView -async function walk ({ cid, load, seen }: { cid: CID, load(cid: CID): Promise, seen?: Set }): Promise { +export async function walk ({ cid, load, seen }: { cid: CID, load(cid: CID): Promise, seen?: Set }): Promise { seen = seen ?? new Set() const b58Cid = cid.toString(base58btc) if (seen.has(b58Cid)) { @@ -22,5 +22,3 @@ async function walk ({ cid, load, seen }: { cid: CID, load(cid: CID): Promise Date: Wed, 20 Dec 2023 07:35:58 +0000 Subject: [PATCH 13/13] chore: publish with provenance, move readme to package docs --- .github/workflows/js-test-and-release.yml | 2 + README.md | 64 ++++--- package.json | 4 + src/index.ts | 202 ++++++++++++++++++++++ 4 files changed, 238 insertions(+), 34 deletions(-) diff --git a/.github/workflows/js-test-and-release.yml b/.github/workflows/js-test-and-release.yml index 2c7a14bb..359eb975 100644 --- a/.github/workflows/js-test-and-release.yml +++ b/.github/workflows/js-test-and-release.yml @@ -9,7 +9,9 @@ on: permissions: contents: write + id-token: write packages: write + pull-requests: write concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/README.md b/README.md index 9f0c512e..260df917 100644 --- a/README.md +++ b/README.md @@ -4,27 +4,13 @@ > Interface for multihash, multicodec, multibase and CID -# Install - -```console -$ npm i multiformats -``` - -# Browser ` -``` - -# Interfaces +# About This library defines common interfaces and low level building blocks for various interrelated multiformat technologies (multicodec, multihash, multibase, and CID). They can be used to implement custom base encoders / decoders / codecs, codec encoders /decoders and multihash hashers that comply to the interface that layers above assume. This library provides implementations for most basics and many others can be found in linked repositories. -```js +```TypeScript import { CID } from 'multiformats/cid' import * as json from 'multiformats/codecs/json' import { sha256 } from 'multiformats/hashes/sha2' @@ -36,9 +22,9 @@ const cid = CID.create(1, json.code, hash) //> CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) ``` -### Creating Blocks +## Creating Blocks -```js +```TypeScript import * as Block from 'multiformats/block' import * as codec from '@ipld/dag-cbor' import { sha256 as hasher } from 'multiformats/hashes/sha2' @@ -63,7 +49,7 @@ block = await Block.create({ bytes: block.bytes, cid: block.cid, codec, hasher } CIDs can be serialized to string representation using multibase encoders that implement [`MultibaseEncoder`](https://github.com/multiformats/js-multiformats/blob/master/src/bases/interface.ts) interface. This library provides quite a few implementations that can be imported: -```js +```TypeScript import { base64 } from "multiformats/bases/base64" cid.toString(base64.encoder) //> 'mAYAEEiCTojlxqRTl6svwqNJRVM2jCcPBxy+7mRTUfGDzy2gViA' @@ -71,7 +57,7 @@ cid.toString(base64.encoder) Parsing CID string serialized CIDs requires multibase decoder that implements [`MultibaseDecoder`](https://github.com/multiformats/js-multiformats/blob/master/src/bases/interface.ts) interface. This library provides a decoder for every encoder it provides: -```js +```TypeScript CID.parse('mAYAEEiCTojlxqRTl6svwqNJRVM2jCcPBxy+7mRTUfGDzy2gViA', base64.decoder) //> CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) ``` @@ -81,7 +67,7 @@ them as `encoder` and `decoder` properties. For added convenience codecs also implement `MultibaseEncoder` and `MultibaseDecoder` interfaces so they could be used as either or both: -```js +```TypeScript cid.toString(base64) CID.parse(cid.toString(base64), base64) ``` @@ -90,7 +76,7 @@ CID.parse(cid.toString(base64), base64) multibase codecs so that CIDs can be base serialized to (version specific) default base encoding and parsed without having to supply base encoders/decoders: -```js +```TypeScript const v1 = CID.parse('bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea') v1.toString() //> 'bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea' @@ -108,11 +94,7 @@ This library defines [`BlockEncoder`, `BlockDecoder` and `BlockCodec` interfaces Codec implementations should conform to the `BlockCodec` interface which implements both `BlockEncoder` and `BlockDecoder`. Here is an example implementation of JSON `BlockCodec`. -```js -/** - * @template T - * @type {BlockCodec<0x0200, T>} - */ +```TypeScript export const { name, code, encode, decode } = { name: 'json', code: 0x0200, @@ -125,7 +107,7 @@ export const { name, code, encode, decode } = { This library defines [`MultihashHasher` and `MultihashDigest` interfaces](https://github.com/multiformats/js-multiformats/blob/master/src/hashes/interface.ts) and convinient function for implementing them: -```js +```TypeScript import * as hasher from 'multiformats/hashes/hasher' const sha256 = hasher.from({ @@ -149,7 +131,7 @@ This library contains higher-order functions for traversing graphs of data easil `walk()` walks through the links in each block of a DAG calling a user-supplied loader function for each one, in depth-first order with no duplicate block visits. The loader should return a `Block` object and can be used to inspect and collect block ordering for a full DAG walk. The loader should `throw` on error, and return `null` if a block should be skipped by `walk()`. -```js +```TypeScript import { walk } from 'multiformats/traversal' import * as Block from 'multiformats/block' import * as codec from 'multiformats/codecs/json' @@ -179,18 +161,18 @@ console.log(blocks) //> [CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea)] ``` -# Legacy interface +## Legacy interface [`blockcodec-to-ipld-format`](https://github.com/ipld/js-blockcodec-to-ipld-format) converts a multiformats [`BlockCodec`](https://github.com/multiformats/js-multiformats/blob/master/src/codecs/interface.ts#L21) into an [`interface-ipld-format`](https://github.com/ipld/interface-ipld-format) for use with the [`ipld`](https://github.com/ipld/ipld) package. This can help bridge IPLD codecs implemented using the structure and interfaces defined here to existing code that assumes, or requires `interface-ipld-format`. This bridge also includes the relevant TypeScript definitions. -# Implementations +## Implementations By default, no base encodings (other than base32 & base58btc), hash functions, or codec implementations are exposed by `multiformats`, you need to import the ones you need yourself. -## Multibase codecs +### Multibase codecs | bases | import | repo | | ------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------- | @@ -201,7 +183,7 @@ import the ones you need yourself. Other (less useful) bases implemented in [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/bases) include: `base2`, `base8`, `base10`, `base36` and `base256emoji`. -## Multihash hashers +### Multihash hashers | hashes | import | repo | | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ | @@ -211,7 +193,7 @@ Other (less useful) bases implemented in [multiformats/js-multiformats](https:// | `murmur3-128`, `murmur3-32` | `@multiformats/murmur3` | [multiformats/js-murmur3](https://github.com/multiformats/js-murmur3) | | `blake2b-*`, `blake2s-*` | `@multiformats/blake2` | [multiformats/js-blake2](https://github.com/multiformats/js-blake2) | -## IPLD codecs (multicodec) +### IPLD codecs (multicodec) | codec | import | repo | | ---------- | -------------------------- | ------------------------------------------------------------------------------------------------------ | @@ -222,6 +204,20 @@ Other (less useful) bases implemented in [multiformats/js-multiformats](https:// | `dag-pb` | `@ipld/dag-pb` | [ipld/js-dag-pb](https://github.com/ipld/js-dag-pb) | | `dag-jose` | `dag-jose` | [ceramicnetwork/js-dag-jose](https://github.com/ceramicnetwork/js-dag-jose) | +# Install + +```console +$ npm i multiformats +``` + +## Browser ` +``` + # API Docs - diff --git a/package.json b/package.json index 0edc8014..8e9e2df3 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,10 @@ "bugs": { "url": "https://github.com/multiformats/js-multiformats/issues" }, + "publishConfig": { + "access": "public", + "provenance": true + }, "keywords": [ "ipfs", "ipld", diff --git a/src/index.ts b/src/index.ts index 0f676fcd..677ef877 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,205 @@ +/** + * @packageDocumentation + * + * This library defines common interfaces and low level building blocks for various interrelated multiformat technologies (multicodec, multihash, multibase, and CID). They can be used to implement custom base encoders / decoders / codecs, codec encoders /decoders and multihash hashers that comply to the interface that layers above assume. + * + * This library provides implementations for most basics and many others can be found in linked repositories. + * + * ```TypeScript + * import { CID } from 'multiformats/cid' + * import * as json from 'multiformats/codecs/json' + * import { sha256 } from 'multiformats/hashes/sha2' + * + * const bytes = json.encode({ hello: 'world' }) + * + * const hash = await sha256.digest(bytes) + * const cid = CID.create(1, json.code, hash) + * //> CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) + * ``` + * + * ## Creating Blocks + * + * ```TypeScript + * import * as Block from 'multiformats/block' + * import * as codec from '@ipld/dag-cbor' + * import { sha256 as hasher } from 'multiformats/hashes/sha2' + * + * const value = { hello: 'world' } + * + * // encode a block + * let block = await Block.encode({ value, codec, hasher }) + * + * block.value // { hello: 'world' } + * block.bytes // Uint8Array + * block.cid // CID() w/ sha2-256 hash address and dag-cbor codec + * + * // you can also decode blocks from their binary state + * block = await Block.decode({ bytes: block.bytes, codec, hasher }) + * + * // if you have the cid you can also verify the hash on decode + * block = await Block.create({ bytes: block.bytes, cid: block.cid, codec, hasher }) + * ``` + * + * ## Multibase Encoders / Decoders / Codecs + * + * CIDs can be serialized to string representation using multibase encoders that implement [`MultibaseEncoder`](https://github.com/multiformats/js-multiformats/blob/master/src/bases/interface.ts) interface. This library provides quite a few implementations that can be imported: + * + * ```TypeScript + * import { base64 } from "multiformats/bases/base64" + * cid.toString(base64.encoder) + * //> 'mAYAEEiCTojlxqRTl6svwqNJRVM2jCcPBxy+7mRTUfGDzy2gViA' + * ``` + * + * Parsing CID string serialized CIDs requires multibase decoder that implements [`MultibaseDecoder`](https://github.com/multiformats/js-multiformats/blob/master/src/bases/interface.ts) interface. This library provides a decoder for every encoder it provides: + * + * ```TypeScript + * CID.parse('mAYAEEiCTojlxqRTl6svwqNJRVM2jCcPBxy+7mRTUfGDzy2gViA', base64.decoder) + * //> CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) + * ``` + * + * Dual of multibase encoder & decoder is defined as multibase codec and it exposes + * them as `encoder` and `decoder` properties. For added convenience codecs also + * implement `MultibaseEncoder` and `MultibaseDecoder` interfaces so they could be + * used as either or both: + * + * ```TypeScript + * cid.toString(base64) + * CID.parse(cid.toString(base64), base64) + * ``` + * + * **Note:** CID implementation comes bundled with `base32` and `base58btc` + * multibase codecs so that CIDs can be base serialized to (version specific) + * default base encoding and parsed without having to supply base encoders/decoders: + * + * ```TypeScript + * const v1 = CID.parse('bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea') + * v1.toString() + * //> 'bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea' + * + * const v0 = CID.parse('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') + * v0.toString() + * //> 'QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n' + * v0.toV1().toString() + * //> 'bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku' + * ``` + * + * ## Multicodec Encoders / Decoders / Codecs + * + * This library defines [`BlockEncoder`, `BlockDecoder` and `BlockCodec` interfaces](https://github.com/multiformats/js-multiformats/blob/master/src/codecs/interface.ts). + * Codec implementations should conform to the `BlockCodec` interface which implements both `BlockEncoder` and `BlockDecoder`. + * Here is an example implementation of JSON `BlockCodec`. + * + * ```TypeScript + * export const { name, code, encode, decode } = { + * name: 'json', + * code: 0x0200, + * encode: json => new TextEncoder().encode(JSON.stringify(json)), + * decode: bytes => JSON.parse(new TextDecoder().decode(bytes)) + * } + * ``` + * + * ## Multihash Hashers + * + * This library defines [`MultihashHasher` and `MultihashDigest` interfaces](https://github.com/multiformats/js-multiformats/blob/master/src/hashes/interface.ts) and convinient function for implementing them: + * + * ```TypeScript + * import * as hasher from 'multiformats/hashes/hasher' + * + * const sha256 = hasher.from({ + * // As per multiformats table + * // https://github.com/multiformats/multicodec/blob/master/table.csv#L9 + * name: 'sha2-256', + * code: 0x12, + * + * encode: (input) => new Uint8Array(crypto.createHash('sha256').update(input).digest()) + * }) + * + * const hash = await sha256.digest(json.encode({ hello: 'world' })) + * CID.create(1, json.code, hash) + * + * //> CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) + * ``` + * + * ## Traversal + * + * This library contains higher-order functions for traversing graphs of data easily. + * + * `walk()` walks through the links in each block of a DAG calling a user-supplied loader function for each one, in depth-first order with no duplicate block visits. The loader should return a `Block` object and can be used to inspect and collect block ordering for a full DAG walk. The loader should `throw` on error, and return `null` if a block should be skipped by `walk()`. + * + * ```TypeScript + * import { walk } from 'multiformats/traversal' + * import * as Block from 'multiformats/block' + * import * as codec from 'multiformats/codecs/json' + * import { sha256 as hasher } from 'multiformats/hashes/sha2' + * + * // build a DAG (a single block for this simple example) + * const value = { hello: 'world' } + * const block = await Block.encode({ value, codec, hasher }) + * const { cid } = block + * console.log(cid) + * //> CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) + * + * // create a loader function that also collects CIDs of blocks in + * // their traversal order + * const load = (cid, blocks) => async (cid) => { + * // fetch a block using its cid + * // e.g.: const block = await fetchBlockByCID(cid) + * blocks.push(cid) + * return block + * } + * + * // collect blocks in this DAG starting from the root `cid` + * const blocks = [] + * await walk({ cid, load: load(cid, blocks) }) + * + * console.log(blocks) + * //> [CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea)] + * ``` + * + * ## Legacy interface + * + * [`blockcodec-to-ipld-format`](https://github.com/ipld/js-blockcodec-to-ipld-format) converts a multiformats [`BlockCodec`](https://github.com/multiformats/js-multiformats/blob/master/src/codecs/interface.ts#L21) into an + * [`interface-ipld-format`](https://github.com/ipld/interface-ipld-format) for use with the [`ipld`](https://github.com/ipld/ipld) package. This can help bridge IPLD codecs implemented using the structure and interfaces defined here to existing code that assumes, or requires `interface-ipld-format`. This bridge also includes the relevant TypeScript definitions. + * + * ## Implementations + * + * By default, no base encodings (other than base32 & base58btc), hash functions, + * or codec implementations are exposed by `multiformats`, you need to + * import the ones you need yourself. + * + * ### Multibase codecs + * + * | bases | import | repo | + * | ------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------- | + * | `base16` | `multiformats/bases/base16` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/bases) | + * | `base32`, `base32pad`, `base32hex`, `base32hexpad`, `base32z` | `multiformats/bases/base32` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/bases) | + * | `base64`, `base64pad`, `base64url`, `base64urlpad` | `multiformats/bases/base64` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/bases) | + * | `base58btc`, `base58flick4` | `multiformats/bases/base58` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/bases) | + * + * Other (less useful) bases implemented in [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/bases) include: `base2`, `base8`, `base10`, `base36` and `base256emoji`. + * + * ### Multihash hashers + * + * | hashes | import | repo | + * | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ | + * | `sha2-256`, `sha2-512` | `multiformats/hashes/sha2` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/src/hashes) | + * | `sha3-224`, `sha3-256`, `sha3-384`,`sha3-512`, `shake-128`, `shake-256`, `keccak-224`, `keccak-256`, `keccak-384`, `keccak-512` | `@multiformats/sha3` | [multiformats/js-sha3](https://github.com/multiformats/js-sha3) | + * | `identity` | `multiformats/hashes/identity` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/src/hashes/identity.js) | + * | `murmur3-128`, `murmur3-32` | `@multiformats/murmur3` | [multiformats/js-murmur3](https://github.com/multiformats/js-murmur3) | + * | `blake2b-*`, `blake2s-*` | `@multiformats/blake2` | [multiformats/js-blake2](https://github.com/multiformats/js-blake2) | + * + * ### IPLD codecs (multicodec) + * + * | codec | import | repo | + * | ---------- | -------------------------- | ------------------------------------------------------------------------------------------------------ | + * | `raw` | `multiformats/codecs/raw` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/src/codecs) | + * | `json` | `multiformats/codecs/json` | [multiformats/js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/src/codecs) | + * | `dag-cbor` | `@ipld/dag-cbor` | [ipld/js-dag-cbor](https://github.com/ipld/js-dag-cbor) | + * | `dag-json` | `@ipld/dag-json` | [ipld/js-dag-json](https://github.com/ipld/js-dag-json) | + * | `dag-pb` | `@ipld/dag-pb` | [ipld/js-dag-pb](https://github.com/ipld/js-dag-pb) | + * | `dag-jose` | `dag-jose` | [ceramicnetwork/js-dag-jose](https://github.com/ceramicnetwork/js-dag-jose) | + */ + import * as bytes from './bytes.js' import { CID } from './cid.js' import * as digest from './hashes/digest.js'