Skip to content
This repository has been archived by the owner on Aug 24, 2021. It is now read-only.

feat: add ts types #72

Merged
merged 10 commits into from
Nov 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
- uses: actions/checkout@v2
- run: yarn
- run: yarn lint
- run: yarn build
- uses: gozala/[email protected]
- run: yarn aegir dep-check -- -i aegir
- uses: ipfs/aegir/actions/bundle-size@master
name: size
Expand Down
80 changes: 8 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,27 @@
js-multibase
js-multibase <!-- omit in toc -->
============

[![](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 <!-- omit in toc -->

[Hugo Dias](https://github.com/hugomrdias)

## Table of Contents
## Table of Contents <!-- omit in toc -->

- [Install](#install)
- [NPM](#npm)
- [In the Browser through `<script>` tag](#in-the-browser-through-script-tag)
- [Browser through `<script>` tag](#browser-through-script-tag)
- [Usage](#usage)
- [Example](#example)
- [API](#api)
- [`multibase` - Prefixes an encoded Uint8Array with its multibase code](#multibase---prefixes-an-encoded-Uint8Array-with-its-multibase-code)
- [`multibase.encode` - Encodes Uint8Array into one of the supported encodings, prefixing it with the multibase code](#multibaseencode---encodes-Uint8Array-into-one-of-the-supported-encodings-prefixing-it-with-the-multibase-code)
- [`multibase.decode` - Decodes Uint8Array or string](#multibasedecode---decodes-Uint8Array-or-string)
- [`multibase.isEncoded` - Checks if Uint8Array or string is encoded](#multibaseisencoded---checks-if-Uint8Array-or-string-is-encoded)
- [`multibase.names` - Supported base encoding names](#multibasenames)
- [`multibase.codes` - Supported base encoding codes](#multibasecodes)
- [Supported Encodings, see `src/constants.js`](#supported-encodings-see-srcconstantsjs)
- [Architecture and Encoding/Decoding](#architecture-and-encodingdecoding)
- [Adding additional bases](#adding-additional-bases)
- [Contribute](#contribute)
- [License](#license)

## Install
Expand All @@ -41,15 +32,9 @@ js-multibase
$ npm install --save multibase
```

The type definitions for this package are available on http://definitelytyped.org/. To install just use:
### Browser through `<script>` tag

```sh
$ npm install -D @types/multibase
```

### In the Browser through `<script>` tag

Loading this module through a script tag will make the ```Multibase``` obj available in the global namespace.
Loading this module through a script tag will make the `Multibase` obj available in the global namespace.

```html
<script src="https://unpkg.com/multibase/dist/index.min.js"></script>
Expand All @@ -72,55 +57,6 @@ console.log(decodedBytes.toString())
## API
https://multiformats.github.io/js-multibase/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 Maybe we do not need the whole section just for the link ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t know maybe API Docs badge at the top ?


#### `multibase` - Prefixes an encoded Uint8Array with its multibase code

```
const multibased = multibase(<nameOrCode>, encodedBytes)
```

#### `multibase.encode` - Encodes Uint8Array into one of the supported encodings, prefixing it with the multibase code

```JavaScript
const encodedBuf = multibase.encode(<nameOrCode>, <bytes>)
```

#### `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).
Expand Down
15 changes: 12 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,27 @@
},
"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": {
"node": ">=10.0.0",
"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 <[email protected]>",
Expand Down
25 changes: 12 additions & 13 deletions src/base.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
// @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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Seems like breaking change and I’m not sure if it is worth bundling it with typedefs.

Copy link
Contributor

@Gozala Gozala Nov 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭If this / other properties are not supposed to be touched might be worth adding /** @private */ as well.

}

/**
* @param {Uint8Array} buf
* @returns {string}
*/
encode (buf) {
return this.engine.encode(buf)
return this.codec.encode(buf)
}

/**
Expand All @@ -44,7 +43,7 @@ class Base {
throw new Error(`invalid character '${char}' in '${string}'`)
}
}
return this.engine.decode(string)
return this.codec.decode(string)
}
}

Expand Down
19 changes: 13 additions & 6 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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, ''],
Expand Down Expand Up @@ -45,15 +50,17 @@ const constants = [
['base64urlpad', 'U', rfc4648(6), 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=']
]

/** @type {Record<BaseName,Base>} */
const names = constants.reduce((prev, tupple) => {
prev[tupple[0]] = new Base(tupple[0], tupple[1], tupple[2], tupple[3])
return prev
}, {})
}, /** @type {Record<BaseName,Base>} */({}))

/** @type {Record<BaseCode,Base>} */
const codes = constants.reduce((prev, tupple) => {
prev[tupple[1]] = names[tupple[0]]
return prev
}, {})
}, /** @type {Record<BaseCode,Base>} */({}))

module.exports = {
names,
Expand Down
22 changes: 11 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -64,15 +64,15 @@ 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))
}

/**
* Is the given data multibase encoded?
*
* @param {Uint8Array|string} data
* @returns {false|string}
* @returns {false | string}
*/
function isEncoded (data) {
if (data instanceof Uint8Array) {
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
*/
Expand All @@ -134,7 +134,7 @@ function encodingFromData (data) {
data = decodeText(data)
}

return encoding(data[0])
return encoding(/** @type {BaseCode} */(data[0]))
}

exports = module.exports = multibase
Expand Down
9 changes: 6 additions & 3 deletions src/rfc4648.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @ts-check
'use strict'

/** @typedef {import('./base').CodecFactory} CodecFactory */
/** @typedef {import('./types').CodecFactory} CodecFactory */

/**
* @param {string} string
Expand Down Expand Up @@ -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
Expand All @@ -117,3 +118,5 @@ module.exports = (bitsPerChar) => (alphabet) => {
}
}
}

module.exports = { rfc4648 }
Loading