From 643bbbb26119ae83bcb9a416b618273b9b65f350 Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Thu, 8 Apr 2021 12:04:45 +0100 Subject: [PATCH] chore: updates all deps and adds types (#11) Updates to the latest version of all deps and adds types. BREAKING CHANGE: There are now types where before there were none --- package.json | 15 ++++--- src/cli/commands/base32.js | 4 ++ src/cli/commands/bases.js | 5 +++ src/cli/commands/codecs.js | 4 ++ src/cli/commands/format.js | 7 +++ src/cli/commands/hashes.js | 4 ++ src/core/base32.js | 4 ++ src/core/bases.js | 10 +++-- src/core/codecs.js | 10 +++-- src/core/format.js | 90 +++++++++++++++++++++++++++++--------- src/core/hashes.js | 10 +++-- src/core/types.d.ts | 8 ++++ src/index.js | 4 ++ tsconfig.json | 9 ++++ 14 files changed, 147 insertions(+), 37 deletions(-) create mode 100644 src/core/types.d.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 51645c1..f34d9a3 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "start": "node src/cli/bin.js", "test": "aegir test -t node", "build": "aegir build", - "lint": "aegir lint", + "lint": "aegir lint && aegir ts --check", "release": "aegir release -t node", "release-minor": "aegir release -t node --type minor", "release-major": "aegir release -t node --type major", @@ -30,15 +30,16 @@ "dependencies": { "cids": "^1.0.0", "explain-error": "^1.0.4", - "multibase": "^3.0.0", - "multihashes": "^3.0.1", + "multibase": "^4.0.2", + "multihashes": "^4.0.2", "split2": "^3.1.1", - "uint8arrays": "^1.1.0", - "yargs": "^15.0.2" + "uint8arrays": "^2.1.3", + "yargs": "^16.2.0" }, "devDependencies": { - "aegir": "^25.1.0", - "execa": "^4.0.0" + "@types/split2": "^2.1.6", + "aegir": "^33.0.0", + "execa": "^5.0.0" }, "contributors": [ "Alan Shaw ", diff --git a/src/cli/commands/base32.js b/src/cli/commands/base32.js index 7d602e8..20f76da 100644 --- a/src/cli/commands/base32.js +++ b/src/cli/commands/base32.js @@ -8,6 +8,10 @@ module.exports = { describe: 'Convert CIDs to base 32 CID version 1.', + /** + * @param {object} argv + * @param {string[]} [argv.cids] + */ handler (argv) { if (argv.cids && argv.cids.length) { return argv.cids.forEach(cid => console.log(CIDTool.base32(cid))) // eslint-disable-line no-console diff --git a/src/cli/commands/bases.js b/src/cli/commands/bases.js index 262ee6d..67ba4a7 100644 --- a/src/cli/commands/bases.js +++ b/src/cli/commands/bases.js @@ -20,6 +20,11 @@ module.exports = { } }, + /** + * @param {object} argv + * @param {boolean} [argv.prefix] + * @param {boolean} [argv.numeric] + */ handler (argv) { CIDTool.bases().forEach(({ name, code }) => { if (argv.prefix && argv.numeric) { diff --git a/src/cli/commands/codecs.js b/src/cli/commands/codecs.js index d1f1613..166c1af 100644 --- a/src/cli/commands/codecs.js +++ b/src/cli/commands/codecs.js @@ -15,6 +15,10 @@ module.exports = { } }, + /** + * @param {object} argv + * @param {boolean} [argv.numeric] + */ handler (argv) { CIDTool.codecs().forEach(({ name, code }) => { if (argv.numeric) { diff --git a/src/cli/commands/format.js b/src/cli/commands/format.js index fe10c65..c59ff0c 100644 --- a/src/cli/commands/format.js +++ b/src/cli/commands/format.js @@ -47,6 +47,13 @@ module.exports = { } }, + /** + * @param {object} argv + * @param {string[]} [argv.cids] + * @param {string} [argv.format] + * @param {import('cids').CIDVersion} [argv.cidVersion] + * @param {import('multibase').BaseNameOrCode} [argv.base] + */ handler (argv) { const options = { format: argv.format, diff --git a/src/cli/commands/hashes.js b/src/cli/commands/hashes.js index 4ee0bb1..640a80d 100644 --- a/src/cli/commands/hashes.js +++ b/src/cli/commands/hashes.js @@ -15,6 +15,10 @@ module.exports = { } }, + /** + * @param {object} argv + * @param {boolean} [argv.numeric] + */ handler (argv) { CIDTool.hashes().forEach(({ name, code }) => { if (argv.numeric) { diff --git a/src/core/base32.js b/src/core/base32.js index 4b2b52c..d6f8f44 100644 --- a/src/core/base32.js +++ b/src/core/base32.js @@ -1,8 +1,12 @@ 'use strict' const CID = require('cids') +// @ts-ignore no types const explain = require('explain-error') +/** + * @param {CID | string | Uint8Array} cid + */ module.exports = function base32 (cid) { try { cid = new CID(cid) diff --git a/src/core/bases.js b/src/core/bases.js index 3b16069..75a538b 100644 --- a/src/core/bases.js +++ b/src/core/bases.js @@ -3,9 +3,11 @@ const multibase = require('multibase') module.exports = function bases () { - return Object.keys(multibase.names).map(name => { - const base = multibase.names[name] + const output = [] - return { name: base.name, code: base.code } - }) + for (const base of Object.values(multibase.names)) { + output.push({ name: base.name, code: base.code }) + } + + return output } diff --git a/src/core/codecs.js b/src/core/codecs.js index 0ccc61a..e598f24 100644 --- a/src/core/codecs.js +++ b/src/core/codecs.js @@ -3,7 +3,11 @@ const CID = require('cids') module.exports = function codecs () { - return Object.keys(CID.codecs).map(name => { - return { name, code: CID.codecs[name] } - }) + const output = [] + + for (const [key, value] of Object.entries(CID.codecs)) { + output.push({ name: key, code: value }) + } + + return output } diff --git a/src/core/format.js b/src/core/format.js index 2d710ea..e16efe4 100644 --- a/src/core/format.js +++ b/src/core/format.js @@ -3,11 +3,21 @@ const CID = require('cids') const bases = require('./bases') const codecs = require('./codecs') +// @ts-ignore no types const explain = require('explain-error') const multibase = require('multibase') const multihash = require('multihashes') const uint8ArrayToString = require('uint8arrays/to-string') +/** + * @typedef {import('multibase').BaseName} BaseName + * @typedef {import('multibase').BaseNameOrCode} BaseNameOrCode + */ + +/** + * @param {CID | string | Uint8Array} cid + * @param {import('./types').FormatOptions} options + */ module.exports = function format (cid, options) { options = options || {} @@ -39,54 +49,62 @@ module.exports = function format (cid, options) { } } - let base + /** + * @type {BaseName} + */ + let base = 'base58btc' if (options.base) { - base = options.base + // Validate passed base name/code + base = findBase(options.base).name } else if (isString(originalCid)) { // Use base of input CID if string - base = multibase.isEncoded(originalCid) - } - - base = base || 'base58btc' - - // Using multibase code instead of name - if (base.length === 1) { - const baseNameCode = bases().find(b => b.code === base) - if (!baseNameCode) throw new Error(`invalid multibase: ${base}`) - base = baseNameCode.name + base = multibase.isEncoded(originalCid) || base } - return formatStr.replace(/%([a-zA-Z%])/g, replacer(cid, base, options)) + return formatStr.replace(/%([a-zA-Z%])/g, replacer(cid, base)) } +/** + * @param {*} obj + * @returns {obj is String} + */ function isString (obj) { return Object.prototype.toString.call(obj) === '[object String]' } -function replacer (cid, base, options) { - return (match, specifier) => { +/** + * @param {CID} cid + * @param {BaseName} base + * @returns {(match: any, specifier: string) => string} + */ +function replacer (cid, base) { + /** + * @param {*} match + * @param {string} specifier + */ + const replace = (match, specifier) => { switch (specifier) { case '%': return '%' case 'b': // base name return base case 'B': // base code - return bases().find(b => b.name === base).code + return findBase(base).code case 'v': // version string return `cidv${cid.version}` case 'V': // version num - return cid.version + return cid.version.toString() case 'c': // codec name return cid.codec case 'C': // codec code - return codecs().find(c => c.name === cid.codec).code + return findCodec(cid).toString() case 'h': // hash fun name return multihash.decode(cid.multihash).name case 'H': // hash fun code - return multihash.decode(cid.multihash).code + return multihash.decode(cid.multihash).code.toString() case 'L': // hash length - return multihash.decode(cid.multihash).length + return multihash.decode(cid.multihash).length.toString() case 'm': // multihash encoded in base %b return uint8ArrayToString(multibase.encode(base, cid.multihash)) case 'M': // multihash encoded in base %b without base prefix @@ -103,12 +121,44 @@ function replacer (cid, base, options) { : uint8ArrayToString(cid.bytes, base) case 'P': // prefix return prefix(cid) + default: throw new Error(`unrecognized specifier in format string: ${specifier}`) } } + + return replace +} + +/** + * @param {BaseNameOrCode} nameOrCode + */ +function findBase (nameOrCode) { + const baseNameCode = bases().find(b => (b.code === nameOrCode) || b.name === nameOrCode) + + if (!baseNameCode) { + throw new Error(`invalid multibase: ${nameOrCode}`) + } + + return baseNameCode +} + +/** + * @param {CID} cid + */ +function findCodec (cid) { + const codec = codecs().find(c => c.name === cid.codec) + + if (!codec) { + throw new Error(`invalid codec: ${cid.codec}`) + } + + return codec.code } +/** + * @param {CID} cid + */ function prefix (cid) { const { name, length } = multihash.decode(cid.multihash) return `cidv${cid.version}-${cid.codec}-${name}-${length}` diff --git a/src/core/hashes.js b/src/core/hashes.js index d6ccd14..6afc206 100644 --- a/src/core/hashes.js +++ b/src/core/hashes.js @@ -4,7 +4,11 @@ const multihash = require('multihashes') // TODO: list only safe hashes https://github.com/ipfs/go-verifcid module.exports = function hashes () { - return Object.keys(multihash.names).map(name => { - return { name, code: multihash.names[name] } - }) + const output = [] + + for (const [name, code] of Object.entries(multihash.names)) { + output.push({ name, code }) + } + + return output } diff --git a/src/core/types.d.ts b/src/core/types.d.ts new file mode 100644 index 0000000..54fd445 --- /dev/null +++ b/src/core/types.d.ts @@ -0,0 +1,8 @@ +import type { CIDVersion } from 'cids' +import type { BaseNameOrCode } from 'multibase' + +export interface FormatOptions { + format?: string + cidVersion?: CIDVersion + base?: BaseNameOrCode +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 1f8d681..a52cb95 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,7 @@ 'use strict' +/** + * @typedef {import('./core/types').FormatOptions} FormatOptions + */ + module.exports = require('./core') diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5fe8ea4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ] +}