diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 8266f90..b94c65e 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,6 +14,8 @@ jobs:
- uses: actions/checkout@v2
- run: yarn
- run: yarn lint
+ - run: yarn build
+ - uses: gozala/typescript-error-reporter-action@v1.0.4
- run: yarn aegir dep-check -- -i aegir
- uses: ipfs/aegir/actions/bundle-size@master
name: size
diff --git a/README.md b/README.md
index 098fa05..511e143 100644
--- a/README.md
+++ b/README.md
@@ -1,36 +1,27 @@
-js-multibase
+js-multibase
============
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs)
-[![Dependency Status](https://david-dm.org/multiformats/js-multibase.svg?style=flat-square)](https://david-dm.org/multiformats/js-multibase)
[![codecov](https://img.shields.io/codecov/c/github/multiformats/js-multibase.svg?style=flat-square)](https://codecov.io/gh/multiformats/js-multibase)
-[![Travis CI](https://flat.badgen.net/travis/multiformats/js-multibase)](https://travis-ci.com/multiformats/js-multibase)
+[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/multiformats/js-multibase/ci?label=ci&style=flat-square)](https://github.com/multiformats/js-multibase/actions?query=branch%3Amaster+workflow%3Aci+)
> JavaScript implementation of the [multibase](https://github.com/multiformats/multibase) specification
-## Lead Maintainer
+## Lead Maintainer
[Hugo Dias](https://github.com/hugomrdias)
-## Table of Contents
+## Table of Contents
- [Install](#install)
- [NPM](#npm)
- - [In the Browser through `
@@ -72,55 +57,6 @@ console.log(decodedBytes.toString())
## API
https://multiformats.github.io/js-multibase/
-#### `multibase` - Prefixes an encoded Uint8Array with its multibase code
-
-```
-const multibased = multibase(, encodedBytes)
-```
-
-#### `multibase.encode` - Encodes Uint8Array into one of the supported encodings, prefixing it with the multibase code
-
-```JavaScript
-const encodedBuf = multibase.encode(, )
-```
-
-#### `multibase.decode` - Decodes Uint8Array or string
-
-```JavaScript
-const decodedBuf = multibase.decode(bufOrString)
-```
-
-#### `multibase.isEncoded` - Checks if Uint8Array or string is encoded
-
-```JavaScript
-const value = multibase.isEncoded(bytesOrString)
-// value is the name of the encoding if it is encoded, false otherwise
-```
-
-#### `multibase.encoding` - Get the encoding by name or code
-
-```JavaScript
-const value = multibase.encoding(nameOrCode)
-// value is an instance of the corresponding `Base`
-```
-
-#### `multibase.encodingFromData` - Get the encoding from data either a `string` or `Uint8Array`
-
-```JavaScript
-const value = multibase.encodingFromData(data)
-// value is an instance of the corresponding `Base`
-```
-
-#### `multibase.names`
-
-A frozen `Object` of supported base encoding names mapped to the corresponding `Base` instance.
-
-#### `multibase.codes`
-
-A frozen `Object` of supported base encoding codes mapped to the corresponding `Base` instance.
-
-### Supported Encodings, see [`src/constants.js`](/src/constants.js)
-
## Contribute
Contributions welcome. Please check out [the issues](https://github.com/multiformats/js-multibase/issues).
diff --git a/package.json b/package.json
index a5485df..bb8e0ed 100644
--- a/package.json
+++ b/package.json
@@ -35,10 +35,10 @@
},
"dependencies": {
"@multiformats/base-x": "^4.0.1",
- "web-encoding": "^1.0.2"
+ "web-encoding": "^1.0.4"
},
"devDependencies": {
- "aegir": "^26.0.0",
+ "aegir": "^29.0.1",
"benchmark": "^2.1.4"
},
"engines": {
@@ -46,7 +46,16 @@
"npm": ">=6.0.0"
},
"eslintConfig": {
- "extends": "./node_modules/aegir/src/config/eslintrc.js"
+ "extends": "ipfs"
+ },
+ "types": "dist/src/index.d.ts",
+ "typesVersions": {
+ "*": {
+ "src/*": [
+ "dist/src/*",
+ "dist/src/*/index"
+ ]
+ }
},
"contributors": [
"David Dias ",
diff --git a/src/base.js b/src/base.js
index 8b63b94..635d4ca 100644
--- a/src/base.js
+++ b/src/base.js
@@ -1,29 +1,28 @@
-// @ts-check
'use strict'
const { encodeText } = require('./util')
+/** @typedef {import('./types').CodecFactory} CodecFactory */
+/** @typedef {import("./types").BaseName} BaseName */
+/** @typedef {import("./types").BaseCode} BaseCode */
+
/**
- * @typedef {Object} Codec
- * @property {function(Uint8Array):string} encode
- * @property {function(string):Uint8Array} decode
+ * Class to encode/decode in the supported Bases
*
- * @typedef {function(string):Codec} CodecFactory
*/
-
class Base {
/**
- * @param {string} name
- * @param {string} code
- * @param {CodecFactory} implementation
+ * @param {BaseName} name
+ * @param {BaseCode} code
+ * @param {CodecFactory} factory
* @param {string} alphabet
*/
- constructor (name, code, implementation, alphabet) {
+ constructor (name, code, factory, alphabet) {
this.name = name
this.code = code
this.codeBuf = encodeText(this.code)
this.alphabet = alphabet
- this.engine = implementation(alphabet)
+ this.codec = factory(alphabet)
}
/**
@@ -31,7 +30,7 @@ class Base {
* @returns {string}
*/
encode (buf) {
- return this.engine.encode(buf)
+ return this.codec.encode(buf)
}
/**
@@ -44,7 +43,7 @@ class Base {
throw new Error(`invalid character '${char}' in '${string}'`)
}
}
- return this.engine.decode(string)
+ return this.codec.decode(string)
}
}
diff --git a/src/constants.js b/src/constants.js
index 7ea3058..979a58d 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -1,11 +1,16 @@
-// @ts-check
'use strict'
const baseX = require('@multiformats/base-x')
const Base = require('./base.js')
-const rfc4648 = require('./rfc4648')
+const { rfc4648 } = require('./rfc4648')
const { decodeText, encodeText } = require('./util')
+/** @typedef {import('./types').CodecFactory} CodecFactory */
+/** @typedef {import('./types').Codec} Codec */
+/** @typedef {import('./types').BaseName} BaseName */
+/** @typedef {import('./types').BaseCode} BaseCode */
+
+/** @type {CodecFactory} */
const identity = () => {
return {
encode: decodeText,
@@ -14,10 +19,10 @@ const identity = () => {
}
/**
- * @typedef {import('./base').CodecFactory} CodecFactory
*
* name, code, implementation, alphabet
- * @type {Array<[string, string, CodecFactory, string]>}
+ *
+ * @type {Array<[BaseName, BaseCode, CodecFactory, string]>}
*/
const constants = [
['identity', '\x00', identity, ''],
@@ -45,15 +50,17 @@ const constants = [
['base64urlpad', 'U', rfc4648(6), 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=']
]
+/** @type {Record} */
const names = constants.reduce((prev, tupple) => {
prev[tupple[0]] = new Base(tupple[0], tupple[1], tupple[2], tupple[3])
return prev
-}, {})
+}, /** @type {Record} */({}))
+/** @type {Record} */
const codes = constants.reduce((prev, tupple) => {
prev[tupple[1]] = names[tupple[0]]
return prev
-}, {})
+}, /** @type {Record} */({}))
module.exports = {
names,
diff --git a/src/index.js b/src/index.js
index 4a06f37..310e597 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,20 +1,20 @@
-// @ts-check
/**
* Implementation of the [multibase](https://github.com/multiformats/multibase) specification.
*
- * @module Multibase
*/
'use strict'
const constants = require('./constants')
const { encodeText, decodeText, concat } = require('./util')
-/** @typedef {import("./base")} Base */
+/** @typedef {import('./base')} Base */
+/** @typedef {import("./types").BaseNameOrCode} BaseNameOrCode */
+/** @typedef {import("./types").BaseCode} BaseCode */
/**
* Create a new Uint8Array with the multibase varint+code.
*
- * @param {string|number} nameOrCode - The multibase name or code number.
+ * @param {BaseNameOrCode} nameOrCode - The multibase name or code number.
* @param {Uint8Array} buf - The data to be prefixed with multibase.
* @returns {Uint8Array}
* @throws {Error} Will throw if the encoding is not supported
@@ -32,7 +32,7 @@ function multibase (nameOrCode, buf) {
/**
* Encode data with the specified base and add the multibase prefix.
*
- * @param {string|number} nameOrCode - The multibase name or code number.
+ * @param {BaseNameOrCode} nameOrCode - The multibase name or code number.
* @param {Uint8Array} buf - The data to be encoded.
* @returns {Uint8Array}
* @throws {Error} Will throw if the encoding is not supported
@@ -64,7 +64,7 @@ function decode (data) {
if (['f', 'F', 'v', 'V', 't', 'T', 'b', 'B', 'c', 'C', 'h', 'k', 'K'].includes(prefix)) {
data = data.toLowerCase()
}
- const enc = encoding(data[0])
+ const enc = encoding(/** @type {BaseCode} */(data[0]))
return enc.decode(data.substring(1))
}
@@ -72,7 +72,7 @@ function decode (data) {
* Is the given data multibase encoded?
*
* @param {Uint8Array|string} data
- * @returns {false|string}
+ * @returns {false | string}
*/
function isEncoded (data) {
if (data instanceof Uint8Array) {
@@ -85,7 +85,7 @@ function isEncoded (data) {
}
try {
- const enc = encoding(data[0])
+ const enc = encoding(/** @type {BaseCode} */(data[0]))
return enc.name
} catch (err) {
return false
@@ -95,7 +95,7 @@ function isEncoded (data) {
/**
* Validate encoded data
*
- * @param {string} name
+ * @param {BaseNameOrCode} name
* @param {Uint8Array} buf
* @returns {void}
* @throws {Error} Will throw if the encoding is not supported
@@ -108,7 +108,7 @@ function validEncode (name, buf) {
/**
* Get the encoding by name or code
*
- * @param {string|number} nameOrCode
+ * @param {BaseNameOrCode} nameOrCode
* @returns {Base}
* @throws {Error} Will throw if the encoding is not supported
*/
@@ -134,7 +134,7 @@ function encodingFromData (data) {
data = decodeText(data)
}
- return encoding(data[0])
+ return encoding(/** @type {BaseCode} */(data[0]))
}
exports = module.exports = multibase
diff --git a/src/rfc4648.js b/src/rfc4648.js
index e1e4ba3..89a1aa2 100644
--- a/src/rfc4648.js
+++ b/src/rfc4648.js
@@ -1,7 +1,6 @@
-// @ts-check
'use strict'
-/** @typedef {import('./base').CodecFactory} CodecFactory */
+/** @typedef {import('./types').CodecFactory} CodecFactory */
/**
* @param {string} string
@@ -96,10 +95,12 @@ const encode = (data, alphabet, bitsPerChar) => {
}
/**
+ * RFC4648 Factory
+ *
* @param {number} bitsPerChar
* @returns {CodecFactory}
*/
-module.exports = (bitsPerChar) => (alphabet) => {
+const rfc4648 = (bitsPerChar) => (alphabet) => {
return {
/**
* @param {Uint8Array} input
@@ -117,3 +118,5 @@ module.exports = (bitsPerChar) => (alphabet) => {
}
}
}
+
+module.exports = { rfc4648 }
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..84438f8
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,62 @@
+/**
+ * - Codes of the supported encodings
+ */
+export type BaseCode =
+ | '\x00'
+ | '0'
+ | '7'
+ | '9'
+ | 'f'
+ | 'F'
+ | 'v'
+ | 'V'
+ | 't'
+ | 'T'
+ | 'b'
+ | 'B'
+ | 'c'
+ | 'C'
+ | 'h'
+ | 'k'
+ | 'K'
+ | 'z'
+ | 'Z'
+ | 'm'
+ | 'M'
+ | 'u'
+ | 'U';
+
+/**
+ * - Names of the supported encodings
+ */
+export type BaseName =
+ | 'identity'
+ | 'base2'
+ | 'base8'
+ | 'base10'
+ | 'base16'
+ | 'base16upper'
+ | 'base32hex'
+ | 'base32hexupper'
+ | 'base32hexpad'
+ | 'base32hexpadupper'
+ | 'base32'
+ | 'base32upper'
+ | 'base32pad'
+ | 'base32padupper'
+ | 'base32z'
+ | 'base36'
+ | 'base36upper'
+ | 'base58btc'
+ | 'base58flickr'
+ | 'base64'
+ | 'base64pad'
+ | 'base64url'
+ | 'base64urlpad';
+
+export type BaseNameOrCode = BaseCode | BaseName;
+export type Codec = {
+ encode: (buffer: Uint8Array) => string;
+ decode: (hash: string) => Uint8Array;
+};
+export type CodecFactory = (input: string) => Codec;
diff --git a/src/util.js b/src/util.js
index f63a6fe..653fae1 100644
--- a/src/util.js
+++ b/src/util.js
@@ -1,6 +1,6 @@
-// @ts-check
'use strict'
+// @ts-ignore
const { TextEncoder, TextDecoder } = require('web-encoding')
const textDecoder = new TextDecoder()
@@ -20,8 +20,8 @@ const encodeText = (text) => textEncoder.encode(text)
/**
* Returns a new Uint8Array created by concatenating the passed Arrays
*
- * @param {Array>} arrs
- * @param {Number} length
+ * @param {Array>} arrs
+ * @param {number} length
* @returns {Uint8Array}
*/
function concat (arrs, length) {
diff --git a/test/multibase.spec.js b/test/multibase.spec.js
index 8fb4bd5..9d80cd9 100644
--- a/test/multibase.spec.js
+++ b/test/multibase.spec.js
@@ -8,6 +8,11 @@ const constants = require('../src/constants.js')
const unsupportedBases = []
+/**
+ * @typedef {import('../src/types').BaseName} BaseName
+ */
+
+/** @type {Array<[BaseName, string, string]>} */
const supportedBases = [
['base16', decodeText(Uint8Array.from([0x01])), 'f01'],
@@ -95,18 +100,21 @@ describe('multibase', () => {
it('fails on no buf', () => {
expect(() => {
+ // @ts-expect-error
multibase('base16')
}).to.throw(Error)
})
they('fails on non supported name', (encode) => {
expect(() => {
+ // @ts-expect-error
multibase('base1001', encode('meh'))
}).to.throw(Error)
})
they('fails on non supported code', (encode) => {
expect(() => {
+ // @ts-expect-error
multibase('6', encode('meh'))
}).to.throw(Error)
})
@@ -253,7 +261,9 @@ describe('multibase.isEncoded', () => {
]
invalidInputs.forEach(input => {
+ // @ts-ignore
expect(() => multibase.isEncoded(input)).to.not.throw()
+ // @ts-ignore
expect(multibase.isEncoded(input)).to.be.false()
})
})
diff --git a/test/spec-test1.spec.js b/test/spec-test1.spec.js
index ab3725f..156849f 100644
--- a/test/spec-test1.spec.js
+++ b/test/spec-test1.spec.js
@@ -6,6 +6,11 @@ const { expect } = require('aegir/utils/chai')
const multibase = require('../src')
const constants = require('../src/constants.js')
const input = 'Decentralize everything!!'
+
+/**
+ * @typedef {import('../src/types').BaseName} BaseName
+ */
+/** @type {Array<[BaseName, string]>} */
const encoded = [
['identity', '\x00Decentralize everything!!'],
['base2', '001000100011001010110001101100101011011100111010001110010011000010110110001101001011110100110010100100000011001010111011001100101011100100111100101110100011010000110100101101110011001110010000100100001'],
diff --git a/test/spec-test2.spec.js b/test/spec-test2.spec.js
index f3f3c6e..88b60dd 100644
--- a/test/spec-test2.spec.js
+++ b/test/spec-test2.spec.js
@@ -6,6 +6,11 @@ const { expect } = require('aegir/utils/chai')
const multibase = require('../src')
const constants = require('../src/constants.js')
const input = 'yes mani !'
+
+/**
+ * @typedef {import('../src/types').BaseName} BaseName
+ */
+/** @type {Array<[BaseName, string]>} */
const encoded = [
['identity', '\x00yes mani !'],
['base2', '001111001011001010111001100100000011011010110000101101110011010010010000000100001'],
diff --git a/test/spec-test3.spec.js b/test/spec-test3.spec.js
index df23891..35f6513 100644
--- a/test/spec-test3.spec.js
+++ b/test/spec-test3.spec.js
@@ -6,6 +6,11 @@ const { expect } = require('aegir/utils/chai')
const multibase = require('../src')
const constants = require('../src/constants.js')
const input = 'hello world'
+
+/**
+ * @typedef {import('../src/types').BaseName} BaseName
+ */
+/** @type {Array<[BaseName, string]>} */
const encoded = [
['identity', '\x00hello world'],
['base2', '00110100001100101011011000110110001101111001000000111011101101111011100100110110001100100'],
diff --git a/test/spec-test4.spec.js b/test/spec-test4.spec.js
index 6d2d6db..3dbfa4b 100644
--- a/test/spec-test4.spec.js
+++ b/test/spec-test4.spec.js
@@ -6,6 +6,10 @@ const { expect } = require('aegir/utils/chai')
const multibase = require('../src')
const constants = require('../src/constants.js')
const input = '\x00yes mani !'
+/**
+ * @typedef {import('../src/types').BaseName} BaseName
+ */
+/** @type {Array<[BaseName, string]>} */
const encoded = [
['identity', '\x00\x00yes mani !'],
['base2', '00000000001111001011001010111001100100000011011010110000101101110011010010010000000100001'],
diff --git a/test/spec-test5.spec.js b/test/spec-test5.spec.js
index 7259af2..97f654f 100644
--- a/test/spec-test5.spec.js
+++ b/test/spec-test5.spec.js
@@ -6,6 +6,10 @@ const { expect } = require('aegir/utils/chai')
const multibase = require('../src')
const constants = require('../src/constants.js')
const input = '\x00\x00yes mani !'
+/**
+ * @typedef {import('../src/types').BaseName} BaseName
+ */
+/** @type {Array<[BaseName, string]>} */
const encoded = [
['identity', '\x00\x00\x00yes mani !'],
['base2', '0000000000000000001111001011001010111001100100000011011010110000101101110011010010010000000100001'],
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..5225c42
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "./node_modules/aegir/src/config/tsconfig.aegir.json",
+ "compilerOptions": {
+ "outDir": "dist"
+ },
+ "include": [
+ "src", "test"
+ ]
+}