diff --git a/.aegir.js b/.aegir.js
deleted file mode 100644
index 07d86700..00000000
--- a/.aegir.js
+++ /dev/null
@@ -1,7 +0,0 @@
-'use strict'
-
-module.exports = {
- bundlesize: {
- maxSize: '14kB'
- }
-}
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..dd84ea78
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,38 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Smartphone (please complete the following information):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..bbcbbe7d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000..e06e02db
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,78 @@
+name: ci
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+
+jobs:
+ check:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: npm install
+ - run: npx aegir lint
+ - run: npx aegir ts -p check
+ - run: npx aegir build
+ - run: npx aegir dep-check
+ - uses: ipfs/aegir/actions/bundle-size@master
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ test-node:
+ needs: check
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [windows-latest, ubuntu-latest, macos-latest]
+ node: [14, 15]
+ fail-fast: true
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node }}
+ - run: npm install
+ - run: npx aegir test -t node --bail --cov
+ - uses: codecov/codecov-action@v1
+ test-chrome:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: microsoft/playwright-github-action@v1
+ - run: npm install
+ - run: npx aegir test -t browser --bail --cov
+ - run: npx aegir test -t webworker --bail
+ - uses: codecov/codecov-action@v1
+ test-firefox:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: microsoft/playwright-github-action@v1
+ - run: npm install
+ - run: npx aegir test -t browser -t webworker --bail -- --browser firefox
+ test-webkit:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: microsoft/playwright-github-action@v1
+ - run: npm install
+ - run: npx aegir test -t browser -t webworker --bail -- --browser webkit
+ test-electron-main:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: npm install
+ - run: npx xvfb-maybe aegir test -t electron-main --bail
+ test-electron-renderer:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: npm install
+ - run: npx xvfb-maybe aegir test -t electron-renderer --bail
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 81758d88..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-language: node_js
-cache: npm
-stages:
- - check
- - test
- - cov
-
-node_js:
- - 'lts/*'
- - 'stable'
-
-os:
- - linux
- - osx
-
-script: npx nyc -s npm run test:node -- --bail
-after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov
-
-jobs:
- include:
- - os: windows
- cache: false
-
- - stage: check
- script:
- - npx aegir dep-check
- - npm run lint
- - npm run test:types
-
- - stage: test
- name: chrome
- addons:
- chrome: stable
- script: npx aegir test -t browser -t webworker
-
- - stage: test
- name: firefox
- addons:
- firefox: latest
- script: npx aegir test -t browser -t webworker -- --browsers FirefoxHeadless
-
-notifications:
- email: false
-
diff --git a/README.md b/README.md
index cf037f0e..1d4be878 100644
--- a/README.md
+++ b/README.md
@@ -24,10 +24,8 @@ js-multiaddr
- [Background](#background)
- [What is multiaddr?](#what-is-multiaddr)
- [Install](#install)
- - [Setup](#setup)
- - [Node.js](#nodejs)
- - [Browser: Browserify, Webpack, other bundlers](#browser-browserify-webpack-other-bundlers)
- - [Browser: `
-
-
-```
diff --git a/package.json b/package.json
index 637dae53..5471cc5a 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,6 @@
"test": "npm run test:node && npm run test:browser",
"test:node": "aegir test --ts -t node",
"test:browser": "aegir test -t browser",
- "test:types": "npx tsc",
"build": "aegir build",
"release": "aegir release",
"release-minor": "aegir release --type minor",
@@ -32,26 +31,30 @@
"bugs": "https://github.com/multiformats/js-multiaddr/issues",
"homepage": "https://github.com/multiformats/js-multiaddr",
"browser": {
- "dns": false
+ "./src/resolvers/dns.js": "./src/resolvers/dns.browser.js"
},
"dependencies": {
"cids": "^1.0.0",
- "class-is": "^1.1.0",
"dns-over-http-resolver": "^1.0.0",
- "err-code": "^2.0.3",
+ "err-code": "^3.0.1",
"is-ip": "^3.1.0",
- "multibase": "^3.0.0",
- "uint8arrays": "^1.1.0",
- "varint": "^5.0.0"
+ "multibase": "^4.0.2",
+ "uint8arrays": "^2.1.3",
+ "varint": "^6.0.0"
},
"devDependencies": {
- "@types/chai": "^4.2.8",
- "@types/dirty-chai": "^2.0.2",
- "@types/mocha": "^8.0.1",
- "@types/node": "^14.0.11",
- "aegir": "^29.0.1",
- "sinon": "^9.2.0",
- "typescript": "^3.9.5"
+ "@types/varint": "^6.0.0",
+ "aegir": "^33.0.0",
+ "sinon": "^10.0.0",
+ "util": "^0.12.3"
+ },
+ "aegir": {
+ "build": {
+ "bundlesizeMax": "22kB"
+ }
+ },
+ "eslintConfig": {
+ "extends": "ipfs"
},
"contributors": [
"David Dias ",
diff --git a/src/codec.js b/src/codec.js
index 09bbfa0c..85d0edc1 100644
--- a/src/codec.js
+++ b/src/codec.js
@@ -33,6 +33,9 @@ module.exports = {
}
// string -> [[str name, str addr]... ]
+/**
+ * @param {string} str
+ */
function stringToStringTuples (str) {
const tuples = []
const parts = str.split('/').slice(1) // skip first empty elem
@@ -73,22 +76,31 @@ function stringToStringTuples (str) {
}
// [[str name, str addr]... ] -> string
+/**
+ * @param {[number, string?][]} tuples
+ */
function stringTuplesToString (tuples) {
+ /** @type {Array} */
const parts = []
- tuples.map(tup => {
+ tuples.map((tup) => {
const proto = protoFromTuple(tup)
parts.push(proto.name)
if (tup.length > 1) {
parts.push(tup[1])
}
+ return null
})
return cleanPath(parts.join('/'))
}
// [[str name, str addr]... ] -> [[int code, Uint8Array]... ]
+/**
+ * @param {Array} tuples
+ * @returns {[number , Uint8Array?][]}
+ */
function stringTuplesToTuples (tuples) {
- return tuples.map(tup => {
+ return tuples.map((tup) => {
if (!Array.isArray(tup)) {
tup = [tup]
}
@@ -100,11 +112,19 @@ function stringTuplesToTuples (tuples) {
})
}
-// [[int code, Uint8Array]... ] -> [[str name, str addr]... ]
+/**
+ * Convert tuples to string tuples
+ *
+ * [[int code, Uint8Array]... ] -> [[int code, str addr]... ]
+ *
+ * @param {Array<[number, Uint8Array?]>} tuples
+ * @returns {Array<[number, string?]>}
+ */
+
function tuplesToStringTuples (tuples) {
return tuples.map(tup => {
const proto = protoFromTuple(tup)
- if (tup.length > 1) {
+ if (tup[1]) {
return [proto.code, convert.toString(proto.code, tup[1])]
}
return [proto.code]
@@ -112,8 +132,11 @@ function tuplesToStringTuples (tuples) {
}
// [[int code, Uint8Array ]... ] -> Uint8Array
+/**
+ * @param {[number, Uint8Array?][]} tuples
+ */
function tuplesToBytes (tuples) {
- return fromBytes(uint8ArrayConcat(tuples.map(tup => {
+ return fromBytes(uint8ArrayConcat(tuples.map((/** @type {any[]} */ tup) => {
const proto = protoFromTuple(tup)
let buf = Uint8Array.from(varint.encode(proto.code))
@@ -125,6 +148,10 @@ function tuplesToBytes (tuples) {
})))
}
+/**
+ * @param {import("./types").Protocol} p
+ * @param {Uint8Array | number[]} addr
+ */
function sizeForAddr (p, addr) {
if (p.size > 0) {
return p.size / 8
@@ -136,8 +163,13 @@ function sizeForAddr (p, addr) {
}
}
-// Uint8Array -> [[int code, Uint8Array ]... ]
+/**
+ *
+ * @param {Uint8Array} buf
+ * @returns {Array<[number, Uint8Array?]>}
+ */
function bytesToTuples (buf) {
+ /** @type {Array<[number, Uint8Array?]>} */
const tuples = []
let i = 0
while (i < buf.length) {
@@ -170,6 +202,9 @@ function bytesToTuples (buf) {
}
// Uint8Array -> String
+/**
+ * @param {Uint8Array} buf
+ */
function bytesToString (buf) {
const a = bytesToTuples(buf)
const b = tuplesToStringTuples(a)
@@ -177,6 +212,9 @@ function bytesToString (buf) {
}
// String -> Uint8Array
+/**
+ * @param {string} str
+ */
function stringToBytes (str) {
str = cleanPath(str)
const a = stringToStringTuples(str)
@@ -186,17 +224,26 @@ function stringToBytes (str) {
}
// String -> Uint8Array
+/**
+ * @param {string} str
+ */
function fromString (str) {
return stringToBytes(str)
}
// Uint8Array -> Uint8Array
+/**
+ * @param {Uint8Array} buf
+ */
function fromBytes (buf) {
const err = validateBytes(buf)
if (err) throw err
return Uint8Array.from(buf) // copy
}
+/**
+ * @param {Uint8Array} buf
+ */
function validateBytes (buf) {
try {
bytesToTuples(buf) // try to parse. will throw if breaks
@@ -205,18 +252,30 @@ function validateBytes (buf) {
}
}
+/**
+ * @param {Uint8Array} buf
+ */
function isValidBytes (buf) {
return validateBytes(buf) === undefined
}
+/**
+ * @param {string} str
+ */
function cleanPath (str) {
- return '/' + str.trim().split('/').filter(a => a).join('/')
+ return '/' + str.trim().split('/').filter((/** @type {any} */ a) => a).join('/')
}
+/**
+ * @param {string} str
+ */
function ParseError (str) {
return new Error('Error parsing address: ' + str)
}
+/**
+ * @param {any[]} tup
+ */
function protoFromTuple (tup) {
const proto = protocols(tup[0])
return proto
diff --git a/src/convert.js b/src/convert.js
index 7258b50c..4ffa0b10 100644
--- a/src/convert.js
+++ b/src/convert.js
@@ -12,6 +12,10 @@ const uint8ArrayConcat = require('uint8arrays/concat')
module.exports = Convert
// converts (serializes) addresses
+/**
+ * @param {string} proto
+ * @param {string | Uint8Array} a
+ */
function Convert (proto, a) {
if (a instanceof Uint8Array) {
return Convert.toString(proto, a)
@@ -20,9 +24,16 @@ function Convert (proto, a) {
}
}
+/**
+ * Convert [code,Uint8Array] to string
+ *
+ * @param {number|string} proto
+ * @param {Uint8Array} buf
+ * @returns {string}
+ */
Convert.toString = function convertToString (proto, buf) {
- proto = protocols(proto)
- switch (proto.code) {
+ const protocol = protocols(proto)
+ switch (protocol.code) {
case 4: // ipv4
case 41: // ipv6
return bytes2ip(buf)
@@ -31,7 +42,7 @@ Convert.toString = function convertToString (proto, buf) {
case 273: // udp
case 33: // dccp
case 132: // sctp
- return bytes2port(buf)
+ return bytes2port(buf).toString()
case 53: // dns
case 54: // dns4
@@ -52,9 +63,9 @@ Convert.toString = function convertToString (proto, buf) {
}
}
-Convert.toBytes = function convertToBytes (proto, str) {
- proto = protocols(proto)
- switch (proto.code) {
+Convert.toBytes = function convertToBytes (/** @type {string | number } */ proto, /** @type {string} */ str) {
+ const protocol = protocols(proto)
+ switch (protocol.code) {
case 4: // ipv4
return ip2bytes(str)
case 41: // ipv6
@@ -85,6 +96,9 @@ Convert.toBytes = function convertToBytes (proto, str) {
}
}
+/**
+ * @param {string} ipString
+ */
function ip2bytes (ipString) {
if (!ip.isIP(ipString)) {
throw new Error('invalid ip address')
@@ -92,6 +106,9 @@ function ip2bytes (ipString) {
return ip.toBytes(ipString)
}
+/**
+ * @param {Uint8Array} ipBuff
+ */
function bytes2ip (ipBuff) {
const ipString = ip.toString(ipBuff)
if (!ipString || !ip.isIP(ipString)) {
@@ -100,6 +117,9 @@ function bytes2ip (ipBuff) {
return ipString
}
+/**
+ * @param {number} port
+ */
function port2bytes (port) {
const buf = new ArrayBuffer(2)
const view = new DataView(buf)
@@ -108,17 +128,26 @@ function port2bytes (port) {
return new Uint8Array(buf)
}
+/**
+ * @param {Uint8Array} buf
+ */
function bytes2port (buf) {
const view = new DataView(buf.buffer)
return view.getUint16(0)
}
+/**
+ * @param {string} str
+ */
function str2bytes (str) {
const buf = uint8ArrayFromString(str)
const size = Uint8Array.from(varint.encode(buf.length))
return uint8ArrayConcat([size, buf], size.length + buf.length)
}
+/**
+ * @param {Uint8Array} buf
+ */
function bytes2str (buf) {
const size = varint.decode(buf)
buf = buf.slice(varint.decode.bytes)
@@ -130,6 +159,9 @@ function bytes2str (buf) {
return uint8ArrayToString(buf)
}
+/**
+ * @param {string | Uint8Array | CID} hash
+ */
function mh2bytes (hash) {
// the address is a varint prefixed multihash string representation
const mh = new CID(hash).multihash
@@ -137,6 +169,12 @@ function mh2bytes (hash) {
return uint8ArrayConcat([size, mh], size.length + mh.length)
}
+/**
+ * Converts bytes to bas58btc string
+ *
+ * @param {Uint8Array} buf
+ * @returns {string} bas58btc string
+ */
function bytes2mh (buf) {
const size = varint.decode(buf)
const address = buf.slice(varint.decode.bytes)
@@ -148,6 +186,9 @@ function bytes2mh (buf) {
return uint8ArrayToString(address, 'base58btc')
}
+/**
+ * @param {string} str
+ */
function onion2bytes (str) {
const addr = str.split(':')
if (addr.length !== 2) {
@@ -169,6 +210,9 @@ function onion2bytes (str) {
return uint8ArrayConcat([buf, portBuf], buf.length + portBuf.length)
}
+/**
+ * @param {string} str
+ */
function onion32bytes (str) {
const addr = str.split(':')
if (addr.length !== 2) {
@@ -189,6 +233,9 @@ function onion32bytes (str) {
return uint8ArrayConcat([buf, portBuf], buf.length + portBuf.length)
}
+/**
+ * @param {Uint8Array} buf
+ */
function bytes2onion (buf) {
const addrBytes = buf.slice(0, buf.length - 2)
const portBytes = buf.slice(buf.length - 2)
diff --git a/src/index.d.ts b/src/index.d.ts
deleted file mode 100644
index 0fca50e3..00000000
--- a/src/index.d.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-declare type NetOptions = {
- family: "ipv4" | "ipv6";
- host: string;
- transport: "tcp" | "udp";
- port: number;
-};
-
-declare type Protocol = {
- code: number;
- size: number;
- name: string;
- resolvable: boolean | undefined;
- path: boolean | undefined;
-};
-
-declare interface Protocols {
- table: {
- [index: number]: Protocol;
- };
- names: {
- [index: string]: Protocol;
- };
- codes: {
- [index: number]: Protocol;
- };
- object(
- code: number,
- size: number,
- name: string,
- resolvable?: any,
- path?: any
- ): Protocol;
-}
-
-declare type NodeAddress = {
- family: "IPv4" | "IPv6";
- address: string;
- port: string;
-};
-
-declare type MultiaddrInput = string | Uint8Array | Multiaddr | null;
-
-declare class Multiaddr {
- /**
- * Creates a [multiaddr](https://github.com/multiformats/multiaddr) from
- * a Uint8Array, String or another Multiaddr instance
- * public key.
- * @param addr - If String or Uint8Array, needs to adhere
- * to the address format of a [multiaddr](https://github.com/multiformats/multiaddr#string-format)
- */
- constructor(addr?: MultiaddrInput);
-
- bytes: Uint8Array;
-
- /**
- * Returns Multiaddr as a String
- */
- toString(): string;
-
- /**
- * Returns Multiaddr as a JSON encoded object
- */
- toJSON(): string;
-
- /**
- * Returns Multiaddr as a convinient options object to be used with net.createConnection
- */
- toOptions(): NetOptions;
-
- /**
- * Returns Multiaddr as a human-readable string
- */
- inspect(): string;
-
- /**
- * Returns the protocols the Multiaddr is defined with, as an array of objects, in
- * left-to-right order. Each object contains the protocol code, protocol name,
- * and the size of its address space in bits.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- */
- protos(): Protocol[];
-
- /**
- * Returns the codes of the protocols in left-to-right order.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- */
- protoCodes(): number[];
-
- /**
- * Returns the names of the protocols in left-to-right order.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- */
- protoNames(): string[];
-
- /**
- * Returns a tuple of parts
- */
- tuples(): [number, Uint8Array][];
-
- /**
- * Returns a tuple of string/number parts
- */
- stringTuples(): [number, string | number][];
-
- /**
- * Encapsulates a Multiaddr in another Multiaddr
- */
- encapsulate(addr: MultiaddrInput): Multiaddr;
-
- /**
- * Decapsulates a Multiaddr from another Multiaddr
- */
- decapsulate(addr: MultiaddrInput): Multiaddr;
-
- /**
- * A more reliable version of `decapsulate` if you are targeting a
- * specific code, such as 421 (the `p2p` protocol code). The last index of the code
- * will be removed from the `Multiaddr`, and a new instance will be returned.
- * If the code is not present, the original `Multiaddr` is returned.
- */
- decapsulateCode(code: number): Multiaddr;
-
- /**
- * Extract the peerId if the multiaddr contains one
- */
- getPeerId(): string;
-
- /**
- * Extract the path if the multiaddr contains one
- */
- getPath(): string | null;
-
- /**
- * Checks if two Multiaddrs are the same
- */
- equals(addr: Multiaddr): boolean;
-
- /**
- * Gets a Multiaddrs node-friendly address object. Note that protocol information
- * is left out: in Node (and most network systems) the protocol is unknowable
- * given only the address.
- *
- * Has to be a ThinWaist Address, otherwise throws error
- */
- nodeAddress(): NodeAddress;
-
- /**
- * Returns if a Multiaddr is a Thin Waist address or not.
- *
- * Thin Waist is if a Multiaddr adheres to the standard combination of:
- *
- * `{IPv4, IPv6}/{TCP, UDP}`
- */
- isThinWaistAddress(addr?: Multiaddr): boolean;
-
- /**
- * Resolve multiaddr if containing resolvable hostname.
- */
- resolve(): Promise>
-}
-
-declare namespace Multiaddr {
- const resolvers: Map < string, (addr: Multiaddr) => Promise < Array < string >>>
-
- /**
- * Creates a Multiaddr from a node-friendly address object
- */
- function fromNodeAddress(addr: NodeAddress, transport: string): Multiaddr;
-
- /**
- * Object containing table, names and codes of all supported protocols.
- * To get the protocol values from a Multiaddr, you can use
- * [`.protos()`](#multiaddrprotos),
- * [`.protoCodes()`](#multiaddrprotocodes) or
- * [`.protoNames()`](#multiaddrprotonames)
- */
- const protocols: Protocols;
-
- /**
- * Returns if something is a Multiaddr
- */
- function isMultiaddr(addr: unknown): addr is Multiaddr;
-
- /**
- * Returns if something is a Multiaddr that is a name
- */
- function isName(addr: Multiaddr): boolean;
-
- /**
- * Returns an array of multiaddrs, by resolving the multiaddr that is a name
- */
- function resolve(addr: Multiaddr): Promise;
-}
-
-/**
- * Creates a [multiaddr](https://github.com/multiformats/multiaddr) from
- * a Uint8Array, String or another Multiaddr instance
- * public key.
- * @param addr - If String or Uint8Array, needs to adhere
- * to the address format of a [multiaddr](https://github.com/multiformats/multiaddr#string-format)
- */
-declare function Multiaddr(input?: MultiaddrInput): Multiaddr;
-
-export = Multiaddr;
diff --git a/src/index.js b/src/index.js
index fc464bd6..50d328b6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,507 +4,590 @@ const codec = require('./codec')
const protocols = require('./protocols-table')
const varint = require('varint')
const CID = require('cids')
-const withIs = require('class-is')
const errCode = require('err-code')
const inspect = Symbol.for('nodejs.util.inspect.custom')
const uint8ArrayToString = require('uint8arrays/to-string')
const uint8ArrayEquals = require('uint8arrays/equals')
+/**
+ * @typedef {(addr: Multiaddr) => Promise} Resolver
+ * @typedef {string | Multiaddr | Uint8Array | null} MultiaddrInput
+ * @typedef {import('./types').MultiaddrObject} MultiaddrObject
+ * @typedef {import('./types').Protocol} Protocol
+ */
+
+/** @type {Map} */
const resolvers = new Map()
+const symbol = Symbol.for('@multiformats/js-multiaddr/multiaddr')
/**
* Creates a [multiaddr](https://github.com/multiformats/multiaddr) from
* a Uint8Array, String or another Multiaddr instance
* public key.
*
- * @class Multiaddr
- * @param {(string | Uint8Array | Multiaddr)} addr - If String or Uint8Array, needs to adhere
- * to the address format of a [multiaddr](https://github.com/multiformats/multiaddr#string-format)
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001')
- * //
*/
-const Multiaddr = withIs.proto(function (addr) {
- if (!(this instanceof Multiaddr)) {
- return new Multiaddr(addr)
- }
+class Multiaddr {
+ /**
+ * @example
+ * ```js
+ * new Multiaddr('/ip4/127.0.0.1/tcp/4001')
+ * //
+ * ```
+ *
+ * @param {MultiaddrInput} [addr] - If String or Uint8Array, needs to adhere to the address format of a [multiaddr](https://github.com/multiformats/multiaddr#string-format)
+ */
+ constructor (addr) {
+ // default
+ if (addr == null) {
+ addr = ''
+ }
- // default
- if (addr == null) {
- addr = ''
- }
+ // Define symbol
+ Object.defineProperty(this, symbol, { value: true })
- if (addr instanceof Uint8Array) {
- /**
- * @type {Uint8Array} - The raw bytes representing this multiaddress
- */
- this.bytes = codec.fromBytes(addr)
- } else if (typeof addr === 'string' || addr instanceof String) {
- if (addr.length > 0 && addr.charAt(0) !== '/') {
- throw new Error(`multiaddr "${addr}" must start with a "/"`)
+ if (addr instanceof Uint8Array) {
+ /** @type {Uint8Array} - The raw bytes representing this multiaddress */
+ this.bytes = codec.fromBytes(addr)
+ } else if (typeof addr === 'string') {
+ if (addr.length > 0 && addr.charAt(0) !== '/') {
+ throw new Error(`multiaddr "${addr}" must start with a "/"`)
+ }
+ this.bytes = codec.fromString(addr)
+ } else if (Multiaddr.isMultiaddr(addr)) { // Multiaddr
+ this.bytes = codec.fromBytes(addr.bytes) // validate + copy buffer
+ } else {
+ throw new Error('addr must be a string, Buffer, or another Multiaddr')
}
- this.bytes = codec.fromString(addr)
- } else if (addr.bytes && addr.protos && addr.protoCodes) { // Multiaddr
- this.bytes = codec.fromBytes(addr.bytes) // validate + copy buffer
- } else {
- throw new Error('addr must be a string, Buffer, or another Multiaddr')
}
-}, { className: 'Multiaddr', symbolName: '@multiformats/js-multiaddr/multiaddr' })
-/**
- * Returns Multiaddr as a String
- *
- * @returns {string}
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001').toString()
- * // '/ip4/127.0.0.1/tcp/4001'
- */
-Multiaddr.prototype.toString = function toString () {
- return codec.bytesToString(this.bytes)
-}
-
-/**
- * Returns Multiaddr as a JSON encoded object
- *
- * @returns {string}
- * @example
- * JSON.stringify(Multiaddr('/ip4/127.0.0.1/tcp/4001'))
- * // '/ip4/127.0.0.1/tcp/4001'
- */
-Multiaddr.prototype.toJSON = Multiaddr.prototype.toString
-
-/**
- * Returns Multiaddr as a convinient options object to be used with net.createConnection
- *
- * @returns {{family: string, host: string, transport: string, port: number}}
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001').toOptions()
- * // { family: 'ipv4', host: '127.0.0.1', transport: 'tcp', port: 4001 }
- */
-Multiaddr.prototype.toOptions = function toOptions () {
- const opts = {}
- const parsed = this.toString().split('/')
- opts.family = parsed[1] === 'ip4' ? 'ipv4' : 'ipv6'
- opts.host = parsed[2]
- opts.transport = parsed[3]
- opts.port = parseInt(parsed[4])
- return opts
-}
-
-/**
- * Returns Multiaddr as a human-readable string.
- * For post Node.js v10.0.0.
- * https://nodejs.org/api/deprecations.html#deprecations_dep0079_custom_inspection_function_on_objects_via_inspect
- *
- * @returns {string}
- * @example
- * console.log(Multiaddr('/ip4/127.0.0.1/tcp/4001'))
- * // ''
- */
-Multiaddr.prototype[inspect] = function inspectCustom () {
- return ''
-}
-
-/**
- * Returns Multiaddr as a human-readable string.
- * Fallback for pre Node.js v10.0.0.
- * https://nodejs.org/api/deprecations.html#deprecations_dep0079_custom_inspection_function_on_objects_via_inspect
- *
- * @returns {string}
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001').inspect()
- * // ''
- */
-Multiaddr.prototype.inspect = function inspect () {
- return ''
-}
+ /**
+ * Returns Multiaddr as a String
+ *
+ * @example
+ * ```js
+ * new Multiaddr('/ip4/127.0.0.1/tcp/4001').toString()
+ * // '/ip4/127.0.0.1/tcp/4001'
+ * ```
+ */
+ toString () {
+ return codec.bytesToString(this.bytes)
+ }
-/**
- * @typedef {object} protocol
- * @property {number} code
- * @property {number} size
- * @property {string} name
- * @property {boolean} [resolvable]
- * @property {boolean} [path]
- */
+ /**
+ * Returns Multiaddr as a JSON encoded object
+ *
+ * @example
+ * ```js
+ * JSON.stringify(new Multiaddr('/ip4/127.0.0.1/tcp/4001'))
+ * // '/ip4/127.0.0.1/tcp/4001'
+ * ```
+ */
+ toJSON () {
+ return this.toString()
+ }
-/**
- * Returns the protocols the Multiaddr is defined with, as an array of objects, in
- * left-to-right order. Each object contains the protocol code, protocol name,
- * and the size of its address space in bits.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- *
- * @returns {protocol[]} protocols - All the protocols the address is composed of
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001').protos()
- * // [ { code: 4, size: 32, name: 'ip4' },
- * // { code: 6, size: 16, name: 'tcp' } ]
- */
-Multiaddr.prototype.protos = function protos () {
- return this.protoCodes().map(code => Object.assign({}, protocols(code)))
-}
+ /**
+ * Returns Multiaddr as a convinient options object to be used with net.createConnection
+ *
+ * @example
+ * ```js
+ * new Multiaddr('/ip4/127.0.0.1/tcp/4001').toOptions()
+ * // { family: 4, host: '127.0.0.1', transport: 'tcp', port: 4001 }
+ * ```
+ */
+ toOptions () {
+ /** @type {MultiaddrObject} */
+ const opts = {}
+ const parsed = this.toString().split('/')
+ opts.family = parsed[1] === 'ip4' ? 4 : 6
+ opts.host = parsed[2]
+ opts.transport = parsed[3]
+ opts.port = parseInt(parsed[4])
+ return opts
+ }
-/**
- * Returns the codes of the protocols in left-to-right order.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- *
- * @returns {Array} protocol codes
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001').protoCodes()
- * // [ 4, 6 ]
- */
-Multiaddr.prototype.protoCodes = function protoCodes () {
- const codes = []
- const buf = this.bytes
- let i = 0
- while (i < buf.length) {
- const code = varint.decode(buf, i)
- const n = varint.decode.bytes
-
- const p = protocols(code)
- const size = codec.sizeForAddr(p, buf.slice(i + n))
-
- i += (size + n)
- codes.push(code)
+ /**
+ * Returns the protocols the Multiaddr is defined with, as an array of objects, in
+ * left-to-right order. Each object contains the protocol code, protocol name,
+ * and the size of its address space in bits.
+ * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
+ *
+ * @example
+ * ```js
+ * new Multiaddr('/ip4/127.0.0.1/tcp/4001').protos()
+ * // [ { code: 4, size: 32, name: 'ip4' },
+ * // { code: 6, size: 16, name: 'tcp' } ]
+ * ```
+ *
+ * @returns {Protocol[]} protocols - All the protocols the address is composed of
+ */
+ protos () {
+ return this.protoCodes().map(code => Object.assign({}, protocols(code)))
}
- return codes
-}
+ /**
+ * Returns the codes of the protocols in left-to-right order.
+ * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
+ *
+ * @example
+ * ```js
+ * Multiaddr('/ip4/127.0.0.1/tcp/4001').protoCodes()
+ * // [ 4, 6 ]
+ * ```
+ *
+ * @returns {number[]} protocol codes
+ */
+ protoCodes () {
+ const codes = []
+ const buf = this.bytes
+ let i = 0
+ while (i < buf.length) {
+ const code = varint.decode(buf, i)
+ const n = varint.decode.bytes
+
+ const p = protocols(code)
+ const size = codec.sizeForAddr(p, buf.slice(i + n))
+
+ i += (size + n)
+ codes.push(code)
+ }
-/**
- * Returns the names of the protocols in left-to-right order.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- *
- * @returns {Array.} protocol names
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001').protoNames()
- * // [ 'ip4', 'tcp' ]
- */
-Multiaddr.prototype.protoNames = function protoNames () {
- return this.protos().map(proto => proto.name)
-}
+ return codes
+ }
-/**
- * Returns a tuple of parts
- *
- * @returns {[number, Uint8Array][]} tuples
- * @example
- * Multiaddr("/ip4/127.0.0.1/tcp/4001").tuples()
- * // [ [ 4, ], [ 6, ] ]
- */
-Multiaddr.prototype.tuples = function tuples () {
- return codec.bytesToTuples(this.bytes)
-}
+ /**
+ * Returns the names of the protocols in left-to-right order.
+ * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
+ *
+ * @example
+ * ```js
+ * new Multiaddr('/ip4/127.0.0.1/tcp/4001').protoNames()
+ * // [ 'ip4', 'tcp' ]
+ * ```
+ *
+ * @returns {string[]} protocol names
+ */
+ protoNames () {
+ return this.protos().map(proto => proto.name)
+ }
-/**
- * Returns a tuple of string/number parts
- * - tuples[][0] = code of protocol
- * - tuples[][1] = contents of address
- *
- * @returns {[number, string|number][]} tuples
- * @example
- * Multiaddr("/ip4/127.0.0.1/tcp/4001").stringTuples()
- * // [ [ 4, '127.0.0.1' ], [ 6, 4001 ] ]
- */
-Multiaddr.prototype.stringTuples = function stringTuples () {
- const t = codec.bytesToTuples(this.bytes)
- return codec.tuplesToStringTuples(t)
-}
+ /**
+ * Returns a tuple of parts
+ *
+ * @example
+ * ```js
+ * new Multiaddr("/ip4/127.0.0.1/tcp/4001").tuples()
+ * // [ [ 4, ], [ 6, ] ]
+ * ```
+ */
+ tuples () {
+ return codec.bytesToTuples(this.bytes)
+ }
-/**
- * Encapsulates a Multiaddr in another Multiaddr
- *
- * @param {Multiaddr} addr - Multiaddr to add into this Multiaddr
- * @returns {Multiaddr}
- * @example
- * const mh1 = Multiaddr('/ip4/8.8.8.8/tcp/1080')
- * //
- *
- * const mh2 = Multiaddr('/ip4/127.0.0.1/tcp/4001')
- * //
- *
- * const mh3 = mh1.encapsulate(mh2)
- * //
- *
- * mh3.toString()
- * // '/ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001'
- */
-Multiaddr.prototype.encapsulate = function encapsulate (addr) {
- addr = Multiaddr(addr)
- return Multiaddr(this.toString() + addr.toString())
-}
+ /**
+ * Returns a tuple of string/number parts
+ * - tuples[][0] = code of protocol
+ * - tuples[][1] = contents of address
+ *
+ * @example
+ * ```js
+ * new Multiaddr("/ip4/127.0.0.1/tcp/4001").stringTuples()
+ * // [ [ 4, '127.0.0.1' ], [ 6, '4001' ] ]
+ * ```
+ */
+ stringTuples () {
+ const t = codec.bytesToTuples(this.bytes)
+ return codec.tuplesToStringTuples(t)
+ }
-/**
- * Decapsulates a Multiaddr from another Multiaddr
- *
- * @param {Multiaddr} addr - Multiaddr to remove from this Multiaddr
- * @returns {Multiaddr}
- * @example
- * const mh1 = Multiaddr('/ip4/8.8.8.8/tcp/1080')
- * //
- *
- * const mh2 = Multiaddr('/ip4/127.0.0.1/tcp/4001')
- * //
- *
- * const mh3 = mh1.encapsulate(mh2)
- * //
- *
- * mh3.decapsulate(mh2).toString()
- * // '/ip4/8.8.8.8/tcp/1080'
- */
-Multiaddr.prototype.decapsulate = function decapsulate (addr) {
- addr = addr.toString()
- const s = this.toString()
- const i = s.lastIndexOf(addr)
- if (i < 0) {
- throw new Error('Address ' + this + ' does not contain subaddress: ' + addr)
+ /**
+ * Encapsulates a Multiaddr in another Multiaddr
+ *
+ * @example
+ * ```js
+ * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080')
+ * //
+ *
+ * const mh2 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
+ * //
+ *
+ * const mh3 = mh1.encapsulate(mh2)
+ * //
+ *
+ * mh3.toString()
+ * // '/ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001'
+ * ```
+ *
+ * @param {MultiaddrInput} addr - Multiaddr to add into this Multiaddr
+ */
+ encapsulate (addr) {
+ addr = new Multiaddr(addr)
+ return new Multiaddr(this.toString() + addr.toString())
}
- return Multiaddr(s.slice(0, i))
-}
-/**
- * A more reliable version of `decapsulate` if you are targeting a
- * specific code, such as 421 (the `p2p` protocol code). The last index of the code
- * will be removed from the `Multiaddr`, and a new instance will be returned.
- * If the code is not present, the original `Multiaddr` is returned.
- *
- * @param {number} code - The code of the protocol to decapsulate from this Multiaddr
- * @returns {Multiaddr}
- * @example
- * const addr = Multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
- * //
- *
- * addr.decapsulateCode(421).toString()
- * // '/ip4/0.0.0.0/tcp/8080'
- *
- * Multiaddr('/ip4/127.0.0.1/tcp/8080').decapsulateCode(421).toString()
- * // '/ip4/127.0.0.1/tcp/8080'
- */
-Multiaddr.prototype.decapsulateCode = function decapsulateCode (code) {
- const tuples = this.tuples()
- for (let i = tuples.length - 1; i >= 0; i--) {
- if (tuples[i][0] === code) {
- return Multiaddr(codec.tuplesToBytes(tuples.slice(0, i)))
+ /**
+ * Decapsulates a Multiaddr from another Multiaddr
+ *
+ * @example
+ * ```js
+ * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080')
+ * //
+ *
+ * const mh2 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
+ * //
+ *
+ * const mh3 = mh1.encapsulate(mh2)
+ * //
+ *
+ * mh3.decapsulate(mh2).toString()
+ * // '/ip4/8.8.8.8/tcp/1080'
+ * ```
+ *
+ * @param {Multiaddr | string} addr - Multiaddr to remove from this Multiaddr
+ * @returns {Multiaddr}
+ */
+ decapsulate (addr) {
+ const addrString = addr.toString()
+ const s = this.toString()
+ const i = s.lastIndexOf(addrString)
+ if (i < 0) {
+ throw new Error('Address ' + this + ' does not contain subaddress: ' + addr)
}
+ return new Multiaddr(s.slice(0, i))
}
- return this
-}
-/**
- * Extract the peerId if the multiaddr contains one
- *
- * @returns {string | null} peerId - The id of the peer or null if invalid or missing from the ma
- * @example
- * const mh1 = Multiaddr('/ip4/8.8.8.8/tcp/1080/ipfs/QmValidBase58string')
- * //
- *
- * // should return QmValidBase58string or null if the id is missing or invalid
- * const peerId = mh1.getPeerId()
- */
-Multiaddr.prototype.getPeerId = function getPeerId () {
- let b58str = null
- try {
- const tuples = this.stringTuples().filter((tuple) => {
- if (tuple[0] === protocols.names.ipfs.code) {
- return true
+ /**
+ * A more reliable version of `decapsulate` if you are targeting a
+ * specific code, such as 421 (the `p2p` protocol code). The last index of the code
+ * will be removed from the `Multiaddr`, and a new instance will be returned.
+ * If the code is not present, the original `Multiaddr` is returned.
+ *
+ * @example
+ * ```js
+ * const addr = new Multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
+ * //
+ *
+ * addr.decapsulateCode(421).toString()
+ * // '/ip4/0.0.0.0/tcp/8080'
+ *
+ * new Multiaddr('/ip4/127.0.0.1/tcp/8080').decapsulateCode(421).toString()
+ * // '/ip4/127.0.0.1/tcp/8080'
+ * ```
+ *
+ * @param {number} code - The code of the protocol to decapsulate from this Multiaddr
+ * @returns {Multiaddr}
+ */
+ decapsulateCode (code) {
+ const tuples = this.tuples()
+ for (let i = tuples.length - 1; i >= 0; i--) {
+ if (tuples[i][0] === code) {
+ return new Multiaddr(codec.tuplesToBytes(tuples.slice(0, i)))
}
- })
-
- // Get the last id
- b58str = tuples.pop()[1]
- // Get multihash, unwrap from CID if needed
- b58str = uint8ArrayToString(new CID(b58str).multihash, 'base58btc')
- } catch (e) {
- b58str = null
+ }
+ return this
}
- return b58str
-}
+ /**
+ * Extract the peerId if the multiaddr contains one
+ *
+ * @example
+ * ```js
+ * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080/ipfs/QmValidBase58string')
+ * //
+ *
+ * // should return QmValidBase58string or null if the id is missing or invalid
+ * const peerId = mh1.getPeerId()
+ * ```
+ *
+ * @returns {string | null} peerId - The id of the peer or null if invalid or missing from the ma
+ */
+ getPeerId () {
+ try {
+ const tuples = this.stringTuples().filter((tuple) => {
+ if (tuple[0] === protocols.names.ipfs.code) {
+ return true
+ }
+ return false
+ })
+
+ // Get the last ipfs tuple ['ipfs', 'peerid string']
+ const tuple = tuples.pop()
+ if (tuple && tuple[1]) {
+ // Get multihash, unwrap from CID if needed
+ return uint8ArrayToString(new CID(tuple[1]).multihash, 'base58btc')
+ } else {
+ return null
+ }
+ } catch (e) {
+ return null
+ }
+ }
-/**
- * Extract the path if the multiaddr contains one
- *
- * @returns {string | null} path - The path of the multiaddr, or null if no path protocol is present
- * @example
- * const mh1 = Multiaddr('/ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock')
- * //
- *
- * // should return utf8 string or null if the id is missing or invalid
- * const path = mh1.getPath()
- */
-Multiaddr.prototype.getPath = function getPath () {
- let path = null
- try {
- path = this.stringTuples().filter((tuple) => {
- const proto = protocols(tuple[0])
- if (proto.path) {
- return true
+ /**
+ * Extract the path if the multiaddr contains one
+ *
+ * @example
+ * ```js
+ * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock')
+ * //
+ *
+ * // should return utf8 string or null if the id is missing or invalid
+ * const path = mh1.getPath()
+ * ```js
+ *
+ * @returns {string | null} path - The path of the multiaddr, or null if no path protocol is present
+ */
+ getPath () {
+ let path = null
+ try {
+ path = this.stringTuples().filter((tuple) => {
+ const proto = protocols(tuple[0])
+ if (proto.path) {
+ return true
+ }
+ return false
+ })[0][1]
+
+ if (!path) {
+ path = null
}
- })[0][1]
- } catch (e) {
- path = null
+ } catch (e) {
+ path = null
+ }
+ return path
}
- return path
-}
+ /**
+ * Checks if two Multiaddrs are the same
+ *
+ * @example
+ * ```js
+ * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080')
+ * //
+ *
+ * const mh2 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
+ * //
+ *
+ * mh1.equals(mh1)
+ * // true
+ *
+ * mh1.equals(mh2)
+ * // false
+ * ```
+ *
+ * @param {Multiaddr} addr
+ * @returns {boolean}
+ */
+ equals (addr) {
+ return uint8ArrayEquals(this.bytes, addr.bytes)
+ }
-/**
- * Checks if two Multiaddrs are the same
- *
- * @param {Multiaddr} addr
- * @returns {Bool}
- * @example
- * const mh1 = Multiaddr('/ip4/8.8.8.8/tcp/1080')
- * //
- *
- * const mh2 = Multiaddr('/ip4/127.0.0.1/tcp/4001')
- * //
- *
- * mh1.equals(mh1)
- * // true
- *
- * mh1.equals(mh2)
- * // false
- */
-Multiaddr.prototype.equals = function equals (addr) {
- return uint8ArrayEquals(this.bytes, addr.bytes)
-}
+ /**
+ * Resolve multiaddr if containing resolvable hostname.
+ *
+ * @example
+ * ```js
+ * Multiaddr.resolvers.set('dnsaddr', resolverFunction)
+ * const mh1 = new Multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
+ * const resolvedMultiaddrs = await mh1.resolve()
+ * // [
+ * // ,
+ * // ,
+ * //
+ * // ]
+ * ```
+ *
+ * @returns {Promise>}
+ */
+ async resolve () {
+ const resolvableProto = this.protos().find((p) => p.resolvable)
-/**
- * Resolve multiaddr if containing resolvable hostname.
- *
- * @returns {Promise>}
- * @example
- * Multiaddr.resolvers.set('dnsaddr', resolverFunction)
- * const mh1 = Multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
- * const resolvedMultiaddrs = await mh1.resolve()
- * // [
- * // ,
- * // ,
- * //
- * // ]
- */
-Multiaddr.prototype.resolve = async function resolve () {
- const resolvableProto = this.protos().find((p) => p.resolvable)
+ // Multiaddr is not resolvable?
+ if (!resolvableProto) {
+ return [this]
+ }
- // Multiaddr is not resolvable?
- if (!resolvableProto) {
- return [this]
- }
+ const resolver = resolvers.get(resolvableProto.name)
+ if (!resolver) {
+ throw errCode(new Error(`no available resolver for ${resolvableProto.name}`), 'ERR_NO_AVAILABLE_RESOLVER')
+ }
- const resolver = resolvers.get(resolvableProto.name)
- if (!resolver) {
- throw errCode(new Error(`no available resolver for ${resolvableProto.name}`), 'ERR_NO_AVAILABLE_RESOLVER')
+ const addresses = await resolver(this)
+ return addresses.map((a) => new Multiaddr(a))
}
- const addresses = await resolver(this)
- return addresses.map(a => Multiaddr(a))
-}
+ /**
+ * Gets a Multiaddrs node-friendly address object. Note that protocol information
+ * is left out: in Node (and most network systems) the protocol is unknowable
+ * given only the address.
+ *
+ * Has to be a ThinWaist Address, otherwise throws error
+ *
+ * @example
+ * ```js
+ * new Multiaddr('/ip4/127.0.0.1/tcp/4001').nodeAddress()
+ * // {family: 4, address: '127.0.0.1', port: 4001}
+ * ```
+ *
+ * @returns {{family: 4 | 6, address: string, port: number}}
+ * @throws {Error} Throws error if Multiaddr is not a Thin Waist address
+ */
+ nodeAddress () {
+ const codes = this.protoCodes()
+ const names = this.protoNames()
+ const parts = this.toString().split('/').slice(1)
+
+ if (parts.length < 4) {
+ throw new Error('multiaddr must have a valid format: "/{ip4, ip6, dns4, dns6}/{address}/{tcp, udp}/{port}".')
+ } else if (codes[0] !== 4 && codes[0] !== 41 && codes[0] !== 54 && codes[0] !== 55) {
+ throw new Error(`no protocol with name: "'${names[0]}'". Must have a valid family name: "{ip4, ip6, dns4, dns6}".`)
+ } else if (parts[2] !== 'tcp' && parts[2] !== 'udp') {
+ throw new Error(`no protocol with name: "'${names[1]}'". Must have a valid transport protocol: "{tcp, udp}".`)
+ }
-/**
- * Gets a Multiaddrs node-friendly address object. Note that protocol information
- * is left out: in Node (and most network systems) the protocol is unknowable
- * given only the address.
- *
- * Has to be a ThinWaist Address, otherwise throws error
- *
- * @returns {{family: string, address: string, port: number}}
- * @throws {Error} Throws error if Multiaddr is not a Thin Waist address
- * @example
- * Multiaddr('/ip4/127.0.0.1/tcp/4001').nodeAddress()
- * // {family: 'IPv4', address: '127.0.0.1', port: '4001'}
- */
-Multiaddr.prototype.nodeAddress = function nodeAddress () {
- const codes = this.protoCodes()
- const names = this.protoNames()
- const parts = this.toString().split('/').slice(1)
-
- if (parts.length < 4) {
- throw new Error('multiaddr must have a valid format: "/{ip4, ip6, dns4, dns6}/{address}/{tcp, udp}/{port}".')
- } else if (codes[0] !== 4 && codes[0] !== 41 && codes[0] !== 54 && codes[0] !== 55) {
- throw new Error(`no protocol with name: "'${names[0]}'". Must have a valid family name: "{ip4, ip6, dns4, dns6}".`)
- } else if (parts[2] !== 'tcp' && parts[2] !== 'udp') {
- throw new Error(`no protocol with name: "'${names[1]}'". Must have a valid transport protocol: "{tcp, udp}".`)
+ return {
+ family: (codes[0] === 41 || codes[0] === 55) ? 6 : 4,
+ address: parts[1],
+ port: parseInt(parts[3]) // tcp or udp port
+ }
}
- return {
- family: (codes[0] === 41 || codes[0] === 55) ? 6 : 4,
- address: parts[1], // ip addr
- port: parseInt(parts[3]) // tcp or udp port
+ /**
+ * Returns if a Multiaddr is a Thin Waist address or not.
+ *
+ * Thin Waist is if a Multiaddr adheres to the standard combination of:
+ *
+ * `{IPv4, IPv6}/{TCP, UDP}`
+ *
+ * @example
+ * ```js
+ * const mh1 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
+ * //
+ * const mh2 = new Multiaddr('/ip4/192.168.2.1/tcp/5001')
+ * //
+ * const mh3 = mh1.encapsulate(mh2)
+ * //
+ * const mh4 = new Multiaddr('/ip4/127.0.0.1/tcp/2000/wss/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')
+ * //
+ * mh1.isThinWaistAddress()
+ * // true
+ * mh2.isThinWaistAddress()
+ * // true
+ * mh3.isThinWaistAddress()
+ * // false
+ * mh4.isThinWaistAddress()
+ * // false
+ * ```
+ *
+ * @param {Multiaddr} [addr] - Defaults to using `this` instance
+ */
+ isThinWaistAddress (addr) {
+ const protos = (addr || this).protos()
+
+ if (protos.length !== 2) {
+ return false
+ }
+
+ if (protos[0].code !== 4 && protos[0].code !== 41) {
+ return false
+ }
+ if (protos[1].code !== 6 && protos[1].code !== 273) {
+ return false
+ }
+ return true
}
-}
-/**
- * Creates a Multiaddr from a node-friendly address object
- *
- * @param {{family: string, address: string, port: number}} addr
- * @param {string} transport
- * @returns {Multiaddr} multiaddr
- * @throws {Error} Throws error if addr is not truthy
- * @throws {Error} Throws error if transport is not truthy
- * @example
- * Multiaddr.fromNodeAddress({address: '127.0.0.1', port: '4001'}, 'tcp')
- * //
- */
-Multiaddr.fromNodeAddress = function fromNodeAddress (addr, transport) {
- if (!addr) throw new Error('requires node address object')
- if (!transport) throw new Error('requires transport protocol')
- let ip
- switch (addr.family) {
- case 'IPv4':
- ip = 'ip4'
- break
- case 'IPv6':
- ip = 'ip6'
- break
- default:
- throw Error(`Invalid addr family. Got '${addr.family}' instead of 'IPv4' or 'IPv6'`)
+ /**
+ * Creates a Multiaddr from a node-friendly address object
+ *
+ * @example
+ * ```js
+ * Multiaddr.fromNodeAddress({address: '127.0.0.1', port: '4001'}, 'tcp')
+ * //
+ * ```
+ *
+ * @param {{family: 4 | 6, address: string, port: number}} addr
+ * @param {string} transport
+ */
+ static fromNodeAddress (addr, transport) {
+ if (!addr) { throw new Error('requires node address object') }
+ if (!transport) { throw new Error('requires transport protocol') }
+ let ip
+ switch (addr.family) {
+ case 4:
+ ip = 'ip4'
+ break
+ case 6:
+ ip = 'ip6'
+ break
+ default:
+ throw Error(`Invalid addr family. Got '${addr.family}' instead of 4 or 6`)
+ }
+ return new Multiaddr('/' + [ip, addr.address, transport, addr.port].join('/'))
}
- return Multiaddr('/' + [ip, addr.address, transport, addr.port].join('/'))
-}
-// TODO find a better example, not sure about it's good enough
-/**
- * Returns if a Multiaddr is a Thin Waist address or not.
- *
- * Thin Waist is if a Multiaddr adheres to the standard combination of:
- *
- * `{IPv4, IPv6}/{TCP, UDP}`
- *
- * @param {Multiaddr} [addr] - Defaults to using `this` instance
- * @returns {boolean} isThinWaistAddress
- * @example
- * const mh1 = Multiaddr('/ip4/127.0.0.1/tcp/4001')
- * //
- * const mh2 = Multiaddr('/ip4/192.168.2.1/tcp/5001')
- * //
- * const mh3 = mh1.encapsulate(mh2)
- * //
- * mh1.isThinWaistAddress()
- * // true
- * mh2.isThinWaistAddress()
- * // true
- * mh3.isThinWaistAddress()
- * // false
- */
-Multiaddr.prototype.isThinWaistAddress = function isThinWaistAddress (addr) {
- const protos = (addr || this).protos()
+ /**
+ * Returns if something is a Multiaddr that is a name
+ *
+ * @param {Multiaddr} addr
+ * @returns {boolean} isName
+ */
+ static isName (addr) {
+ if (!Multiaddr.isMultiaddr(addr)) {
+ return false
+ }
- if (protos.length !== 2) {
- return false
+ // if a part of the multiaddr is resolvable, then return true
+ return addr.protos().some((proto) => proto.resolvable)
}
- if (protos[0].code !== 4 && protos[0].code !== 41) {
- return false
+ /**
+ * Check if object is a CID instance
+ *
+ * @param {any} value
+ * @returns {value is Multiaddr}
+ */
+ static isMultiaddr (value) {
+ return value instanceof Multiaddr || Boolean(value && value[symbol])
}
- if (protos[1].code !== 6 && protos[1].code !== 273) {
- return false
+
+ /**
+ * Returns Multiaddr as a human-readable string.
+ * For post Node.js v10.0.0.
+ * https://nodejs.org/api/deprecations.html#deprecations_dep0079_custom_inspection_function_on_objects_via_inspect
+ *
+ * @example
+ * ```js
+ * console.log(new Multiaddr('/ip4/127.0.0.1/tcp/4001'))
+ * // ''
+ * ```
+ *
+ * @returns {string}
+ */
+ [inspect] () {
+ return ''
+ }
+
+ /**
+ * Returns Multiaddr as a human-readable string.
+ * Fallback for pre Node.js v10.0.0.
+ * https://nodejs.org/api/deprecations.html#deprecations_dep0079_custom_inspection_function_on_objects_via_inspect
+ *
+ * @example
+ * ```js
+ * new Multiaddr('/ip4/127.0.0.1/tcp/4001').inspect()
+ * // ''
+ * ```
+ *
+ * @returns {string}
+ */
+ inspect () {
+ return ''
}
- return true
}
/**
@@ -514,46 +597,19 @@ Multiaddr.prototype.isThinWaistAddress = function isThinWaistAddress (addr) {
* [`.protoCodes()`](#multiaddrprotocodes) or
* [`.protoNames()`](#multiaddrprotonames)
*
- * @instance
* @returns {{table: Array, names: Object, codes: Object}}
- *
*/
Multiaddr.protocols = protocols
-/**
- * Returns if something is a Multiaddr that is a name
- *
- * @param {Multiaddr} addr
- * @returns {Bool} isName
- */
-Multiaddr.isName = function isName (addr) {
- if (!Multiaddr.isMultiaddr(addr)) {
- return false
- }
-
- // if a part of the multiaddr is resolvable, then return true
- return addr.protos().some((proto) => proto.resolvable)
-}
+Multiaddr.resolvers = resolvers
/**
- * Returns an array of multiaddrs, by resolving the multiaddr that is a name
+ * Static factory
*
- * @async
- * @param {Multiaddr} addr
- * @returns {Multiaddr[]}
+ * @param {MultiaddrInput} addr
*/
-Multiaddr.resolve = function resolve (addr) {
- if (!Multiaddr.isMultiaddr(addr) || !Multiaddr.isName(addr)) {
- return Promise.reject(Error('not a valid name'))
- }
-
- /*
- * Needs more consideration from spec design:
- * - what to return
- * - how to achieve it in the browser?
- */
- return Promise.reject(new Error('not implemented yet'))
+function multiaddr (addr) {
+ return new Multiaddr(addr)
}
-Multiaddr.resolvers = resolvers
-exports = module.exports = Multiaddr
+module.exports = { Multiaddr, multiaddr, protocols, resolvers }
diff --git a/src/ip.js b/src/ip.js
index c1ffb273..958423ba 100644
--- a/src/ip.js
+++ b/src/ip.js
@@ -8,22 +8,25 @@ const isV4 = isIp.v4
const isV6 = isIp.v6
// Copied from https://github.com/indutny/node-ip/blob/master/lib/ip.js#L7
+// @ts-ignore - this is copied from the link above better to keep it the same
const toBytes = function (ip, buff, offset) {
offset = ~~offset
- var result
+ let result
if (isV4(ip)) {
result = buff || new Uint8Array(offset + 4)
+ // @ts-ignore
+ // eslint-disable-next-line array-callback-return
ip.split(/\./g).map(function (byte) {
result[offset++] = parseInt(byte, 10) & 0xff
})
} else if (isV6(ip)) {
- var sections = ip.split(':', 8)
+ const sections = ip.split(':', 8)
- var i
+ let i
for (i = 0; i < sections.length; i++) {
- var isv4 = isV4(sections[i])
+ const isv4 = isV4(sections[i])
var v4Buffer
if (isv4) {
@@ -42,7 +45,7 @@ const toBytes = function (ip, buff, offset) {
while (sections.length < 8) sections.push('0')
} else if (sections.length < 8) {
for (i = 0; i < sections.length && sections[i] !== ''; i++);
- var argv = [i, '1']
+ const argv = [i, '1']
for (i = 9 - sections.length; i > 0; i--) {
argv.push('0')
}
@@ -51,7 +54,7 @@ const toBytes = function (ip, buff, offset) {
result = buff || new Uint8Array(offset + 16)
for (i = 0; i < sections.length; i++) {
- var word = parseInt(sections[i], 16)
+ const word = parseInt(sections[i], 16)
result[offset++] = (word >> 8) & 0xff
result[offset++] = word & 0xff
}
@@ -65,12 +68,13 @@ const toBytes = function (ip, buff, offset) {
}
// Copied from https://github.com/indutny/node-ip/blob/master/lib/ip.js#L63
+// @ts-ignore - this is copied from the link above better to keep it the same
const toString = function (buff, offset, length) {
offset = ~~offset
length = length || (buff.length - offset)
- var result = []
- var string
+ const result = []
+ let string
const view = new DataView(buff.buffer)
if (length === 4) {
// IPv4
diff --git a/src/protocols-table.js b/src/protocols-table.js
index 4578e436..3431af59 100644
--- a/src/protocols-table.js
+++ b/src/protocols-table.js
@@ -1,5 +1,12 @@
'use strict'
+/** @typedef {import("./types").Protocol} Protocol */
+/**
+ * Protocols
+ *
+ * @param {number | string} proto
+ * @returns {Protocol}
+ */
function Protocols (proto) {
if (typeof (proto) === 'number') {
if (Protocols.codes[proto]) {
@@ -7,7 +14,7 @@ function Protocols (proto) {
}
throw new Error('no protocol with code: ' + proto)
- } else if (typeof (proto) === 'string' || proto instanceof String) {
+ } else if (typeof (proto) === 'string') {
if (Protocols.names[proto]) {
return Protocols.names[proto]
}
@@ -22,6 +29,7 @@ const V = -1
Protocols.lengthPrefixedVarSize = V
Protocols.V = V
+/** @type {Array<[number, number, string, (string|boolean)?, string?]>} */
Protocols.table = [
[4, 32, 'ip4'],
[6, 16, 'tcp'],
@@ -58,8 +66,9 @@ Protocols.table = [
[480, 0, 'http'],
[777, V, 'memory']
]
-
+/** @type {Record} */
Protocols.names = {}
+/** @type {Record} */
Protocols.codes = {}
// populate tables
@@ -67,10 +76,22 @@ Protocols.table.map(row => {
const proto = p.apply(null, row)
Protocols.codes[proto.code] = proto
Protocols.names[proto.name] = proto
+ return null
})
Protocols.object = p
+/**
+ *
+ * Create a protocol
+ *
+ * @param {number} code
+ * @param {number} size
+ * @param {string} name
+ * @param {any} [resolvable]
+ * @param {any} [path]
+ * @returns {Protocol}
+ */
function p (code, size, name, resolvable, path) {
return {
code,
diff --git a/src/resolvers/dns.browser.js b/src/resolvers/dns.browser.js
new file mode 100644
index 00000000..b5d16980
--- /dev/null
+++ b/src/resolvers/dns.browser.js
@@ -0,0 +1,7 @@
+'use strict'
+
+/** @type {import('dns').promises.Resolver} */
+// @ts-ignore - has no types
+const dns = require('dns-over-http-resolver')
+
+module.exports = dns
diff --git a/src/resolvers/dns.js b/src/resolvers/dns.js
index e85a5bd2..32bde6bf 100644
--- a/src/resolvers/dns.js
+++ b/src/resolvers/dns.js
@@ -1,14 +1,3 @@
'use strict'
-let dns
-
-try {
- dns = require('dns').promises
- if (!dns) {
- throw new Error('no dns available')
- }
-} catch (err) {
- dns = require('dns-over-http-resolver')
-}
-
-module.exports = dns
+module.exports = require('dns').promises.Resolver
diff --git a/src/resolvers/index.js b/src/resolvers/index.js
index d14c5c99..da082b24 100644
--- a/src/resolvers/index.js
+++ b/src/resolvers/index.js
@@ -1,25 +1,27 @@
'use strict'
-const Multiaddr = require('..') // eslint-disable-line no-unused-vars
const protocols = require('../protocols-table')
const { code: dnsaddrCode } = protocols('dnsaddr')
+/**
+ * @typedef {import('..').Multiaddr} Multiaddr
+ */
+
/**
* Resolver for dnsaddr addresses.
*
* @param {Multiaddr} addr
- * @returns {Promise>}
+ * @returns {Promise}
*/
async function dnsaddrResolver (addr) {
- const { Resolver } = require('./dns')
+ const Resolver = require('./dns')
const resolver = new Resolver()
const peerId = addr.getPeerId()
const [, hostname] = addr.stringTuples().find(([proto]) => proto === dnsaddrCode) || []
const records = await resolver.resolveTxt(`_dnsaddr.${hostname}`)
- // @ts-ignore
let addresses = records.flat().map((a) => a.split('=')[1])
if (peerId) {
diff --git a/src/types.d.ts b/src/types.d.ts
new file mode 100644
index 00000000..5f3185fd
--- /dev/null
+++ b/src/types.d.ts
@@ -0,0 +1,14 @@
+export interface Protocol {
+ code: number
+ size: number
+ name: string
+ resolvable?: boolean | undefined
+ path?: boolean | undefined
+}
+
+export interface MultiaddrObject {
+ family: 4 | 6
+ host: string
+ transport: string
+ port: number
+}
diff --git a/test/index.spec.js b/test/index.spec.js
index c154eb4a..09999111 100644
--- a/test/index.spec.js
+++ b/test/index.spec.js
@@ -2,106 +2,108 @@
/* eslint-env mocha */
'use strict'
-const multiaddr = require('../src')
+const { Multiaddr } = require('../src')
const { expect } = require('aegir/utils/chai')
const uint8ArrayFromString = require('uint8arrays/from-string')
describe('construction', () => {
+ /** @type {Multiaddr} */
let udpAddr
it('create multiaddr', () => {
- udpAddr = multiaddr('/ip4/127.0.0.1/udp/1234')
- expect(udpAddr instanceof multiaddr).to.equal(true)
+ udpAddr = new Multiaddr('/ip4/127.0.0.1/udp/1234')
+ expect(udpAddr instanceof Multiaddr).to.equal(true)
})
it('clone multiaddr', () => {
- const udpAddrClone = multiaddr(udpAddr)
+ const udpAddrClone = new Multiaddr(udpAddr)
expect(udpAddrClone !== udpAddr).to.equal(true)
})
it('reconstruct with buffer', () => {
- expect(multiaddr(udpAddr.bytes).bytes === udpAddr.bytes).to.equal(false)
- expect(multiaddr(udpAddr.bytes).bytes).to.deep.equal(udpAddr.bytes)
+ expect(new Multiaddr(udpAddr.bytes).bytes === udpAddr.bytes).to.equal(false)
+ expect(new Multiaddr(udpAddr.bytes).bytes).to.deep.equal(udpAddr.bytes)
})
it('reconstruct with string', () => {
- expect(multiaddr(udpAddr.toString()).bytes === udpAddr.bytes).to.equal(false)
- expect(multiaddr(udpAddr.toString()).bytes).to.deep.equal(udpAddr.bytes)
+ expect(new Multiaddr(udpAddr.toString()).bytes === udpAddr.bytes).to.equal(false)
+ expect(new Multiaddr(udpAddr.toString()).bytes).to.deep.equal(udpAddr.bytes)
})
it('reconstruct with object', () => {
- expect(multiaddr(udpAddr).bytes === udpAddr.bytes).to.equal(false)
- expect(multiaddr(udpAddr).bytes).to.deep.equal(udpAddr.bytes)
+ expect(new Multiaddr(udpAddr).bytes === udpAddr.bytes).to.equal(false)
+ expect(new Multiaddr(udpAddr).bytes).to.deep.equal(udpAddr.bytes)
})
it('reconstruct with JSON', () => {
- expect(multiaddr(JSON.parse(JSON.stringify(udpAddr))).bytes === udpAddr.bytes).to.equal(false)
- expect(multiaddr(JSON.parse(JSON.stringify(udpAddr))).bytes).to.deep.equal(udpAddr.bytes)
+ expect(new Multiaddr(JSON.parse(JSON.stringify(udpAddr))).bytes === udpAddr.bytes).to.equal(false)
+ expect(new Multiaddr(JSON.parse(JSON.stringify(udpAddr))).bytes).to.deep.equal(udpAddr.bytes)
})
it('empty construct still works', () => {
- expect(multiaddr('').toString()).to.equal('/')
+ expect(new Multiaddr('').toString()).to.equal('/')
})
it('null/undefined construct still works', () => {
- expect(multiaddr().toString()).to.equal('/')
- expect(multiaddr(null).toString()).to.equal('/')
- expect(multiaddr(undefined).toString()).to.equal('/')
+ expect(new Multiaddr().toString()).to.equal('/')
+ expect(new Multiaddr(null).toString()).to.equal('/')
+ expect(new Multiaddr(undefined).toString()).to.equal('/')
})
it('throws on truthy non string or buffer', () => {
const errRegex = /addr must be a string/
// @ts-ignore
- expect(() => multiaddr({})).to.throw(errRegex)
+ expect(() => new Multiaddr({})).to.throw(errRegex)
// @ts-ignore
- expect(() => multiaddr([])).to.throw(errRegex)
+ expect(() => new Multiaddr([])).to.throw(errRegex)
// @ts-ignore
- expect(() => multiaddr(138)).to.throw(errRegex)
+ expect(() => new Multiaddr(138)).to.throw(errRegex)
// @ts-ignore
- expect(() => multiaddr(true)).to.throw(errRegex)
+ expect(() => new Multiaddr(true)).to.throw(errRegex)
})
it('throws on falsy non string or buffer', () => {
const errRegex = /addr must be a string/
// @ts-ignore
- expect(() => multiaddr(NaN)).to.throw(errRegex)
+ expect(() => new Multiaddr(NaN)).to.throw(errRegex)
// @ts-ignore
- expect(() => multiaddr(false)).to.throw(errRegex)
+ expect(() => new Multiaddr(false)).to.throw(errRegex)
// @ts-ignore
- expect(() => multiaddr(0)).to.throw(errRegex)
+ expect(() => new Multiaddr(0)).to.throw(errRegex)
})
})
describe('requiring varint', () => {
+ /** @type {Multiaddr} */
let uTPAddr
it('create multiaddr', () => {
- uTPAddr = multiaddr('/ip4/127.0.0.1/udp/1234/utp')
- expect(uTPAddr instanceof multiaddr).to.equal(true)
+ uTPAddr = new Multiaddr('/ip4/127.0.0.1/udp/1234/utp')
+ expect(uTPAddr instanceof Multiaddr).to.equal(true)
})
it('clone multiaddr', () => {
- const uTPAddrClone = multiaddr(uTPAddr)
+ const uTPAddrClone = new Multiaddr(uTPAddr)
expect(uTPAddrClone !== uTPAddr).to.equal(true)
})
it('reconstruct with buffer', () => {
- expect(multiaddr(uTPAddr.bytes).bytes === uTPAddr.bytes).to.equal(false)
- expect(multiaddr(uTPAddr.bytes).bytes).to.deep.equal(uTPAddr.bytes)
+ expect(new Multiaddr(uTPAddr.bytes).bytes === uTPAddr.bytes).to.equal(false)
+ expect(new Multiaddr(uTPAddr.bytes).bytes).to.deep.equal(uTPAddr.bytes)
})
it('reconstruct with string', () => {
- expect(multiaddr(uTPAddr.toString()).bytes === uTPAddr.bytes).to.equal(false)
- expect(multiaddr(uTPAddr.toString()).bytes).to.deep.equal(uTPAddr.bytes)
+ expect(new Multiaddr(uTPAddr.toString()).bytes === uTPAddr.bytes).to.equal(false)
+ expect(new Multiaddr(uTPAddr.toString()).bytes).to.deep.equal(uTPAddr.bytes)
})
it('reconstruct with object', () => {
- expect(multiaddr(uTPAddr).bytes === uTPAddr.bytes).to.equal(false)
- expect(multiaddr(uTPAddr).bytes).to.deep.equal(uTPAddr.bytes)
+ expect(new Multiaddr(uTPAddr).bytes === uTPAddr.bytes).to.equal(false)
+ expect(new Multiaddr(uTPAddr).bytes).to.deep.equal(uTPAddr.bytes)
})
it('empty construct still works', () => {
- expect(multiaddr('').toString()).to.equal('/')
+ expect(new Multiaddr('').toString()).to.equal('/')
})
})
@@ -109,33 +111,33 @@ describe('manipulation', () => {
it('basic', () => {
const udpAddrStr = '/ip4/127.0.0.1/udp/1234'
const udpAddrBuf = uint8ArrayFromString('047f000001910204d2', 'base16')
- const udpAddr = multiaddr(udpAddrStr)
+ const udpAddr = new Multiaddr(udpAddrStr)
expect(udpAddr.toString()).to.equal(udpAddrStr)
expect(udpAddr.bytes).to.deep.equal(udpAddrBuf)
expect(udpAddr.protoCodes()).to.deep.equal([4, 273])
expect(udpAddr.protoNames()).to.deep.equal(['ip4', 'udp'])
- expect(udpAddr.protos()).to.deep.equal([multiaddr.protocols.codes[4], multiaddr.protocols.codes[273]])
- expect(udpAddr.protos()[0] === multiaddr.protocols.codes[4]).to.equal(false)
+ expect(udpAddr.protos()).to.deep.equal([Multiaddr.protocols.codes[4], Multiaddr.protocols.codes[273]])
+ expect(udpAddr.protos()[0] === Multiaddr.protocols.codes[4]).to.equal(false)
const udpAddrbytes2 = udpAddr.encapsulate('/udp/5678')
expect(udpAddrbytes2.toString()).to.equal('/ip4/127.0.0.1/udp/1234/udp/5678')
expect(udpAddrbytes2.decapsulate('/udp').toString()).to.equal('/ip4/127.0.0.1/udp/1234')
expect(udpAddrbytes2.decapsulate('/ip4').toString()).to.equal('/')
expect(function () { udpAddr.decapsulate('/').toString() }).to.throw()
- expect(multiaddr('/').encapsulate(udpAddr).toString()).to.equal(udpAddr.toString())
- expect(multiaddr('/').decapsulate('/').toString()).to.equal('/')
+ expect(new Multiaddr('/').encapsulate(udpAddr).toString()).to.equal(udpAddr.toString())
+ expect(new Multiaddr('/').decapsulate('/').toString()).to.equal('/')
})
it('ipfs', () => {
- const ipfsAddr = multiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
- const ip6Addr = multiaddr('/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095')
- const tcpAddr = multiaddr('/tcp/8000')
- const webAddr = multiaddr('/ws')
+ const ipfsAddr = new Multiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
+ const ip6Addr = new Multiaddr('/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095')
+ const tcpAddr = new Multiaddr('/tcp/8000')
+ const webAddr = new Multiaddr('/ws')
expect(
- multiaddr('/')
+ new Multiaddr('/')
.encapsulate(ip6Addr)
.encapsulate(tcpAddr)
.encapsulate(webAddr)
@@ -149,7 +151,7 @@ describe('manipulation', () => {
].join(''))
expect(
- multiaddr('/')
+ new Multiaddr('/')
.encapsulate(ip6Addr)
.encapsulate(tcpAddr)
.encapsulate(webAddr)
@@ -163,7 +165,7 @@ describe('manipulation', () => {
].join(''))
expect(
- multiaddr('/')
+ new Multiaddr('/')
.encapsulate(ip6Addr)
.encapsulate(tcpAddr)
.encapsulate(ipfsAddr)
@@ -181,63 +183,63 @@ describe('manipulation', () => {
describe('variants', () => {
it('ip4', () => {
const str = '/ip4/127.0.0.1'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip4 + tcp', () => {
const str = '/ip4/127.0.0.1/tcp/5000'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + tcp', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/5000'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip4 + udp', () => {
const str = '/ip4/127.0.0.1/udp/5000'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + udp', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/udp/5000'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip4 + p2p', () => {
const str = '/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip4 + ipfs', () => {
const str = '/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str.replace('/ipfs/', '/p2p/'))
})
it('ip6 + p2p', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
@@ -250,14 +252,14 @@ describe('variants', () => {
it('ip4 + udp + utp', () => {
const str = '/ip4/127.0.0.1/udp/5000/utp'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + udp + utp', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/udp/5000/utp'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.protoNames())
expect(addr.toString()).to.equal(str)
@@ -265,212 +267,212 @@ describe('variants', () => {
it('ip4 + tcp + http', () => {
const str = '/ip4/127.0.0.1/tcp/8000/http'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip4 + tcp + unix', () => {
const str = '/ip4/127.0.0.1/tcp/80/unix/a/b/c/d/e/f'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + tcp + http', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/http'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + tcp + unix', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/unix/a/b/c/d/e/f'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip4 + tcp + https', () => {
const str = '/ip4/127.0.0.1/tcp/8000/https'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + tcp + https', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/https'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip4 + tcp + websockets', () => {
const str = '/ip4/127.0.0.1/tcp/8000/ws'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + tcp + websockets', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/ws'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + tcp + websockets + ipfs', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/ws/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str.replace('/ipfs/', '/p2p/'))
})
it('ip6 + tcp + websockets + p2p', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/ws/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('ip6 + udp + quic + ipfs', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/udp/4001/quic/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str.replace('/ipfs/', '/p2p/'))
})
it('ip6 + udp + quic + p2p', () => {
const str = '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/udp/4001/quic/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('unix', () => {
const str = '/unix/a/b/c/d/e'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('p2p', () => {
const str = '/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('p2p', () => {
const str = '/p2p/bafzbeidt255unskpefjmqb2rc27vjuyxopkxgaylxij6pw35hhys4vnyp4'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal('/p2p/QmW8rAgaaA6sRydK1k6vonShQME47aDxaFidbtMevWs73t')
})
it('ipfs', () => {
const str = '/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str.replace('/ipfs/', '/p2p/'))
})
it('onion', () => {
const str = '/onion/timaq4ygg2iegci7:1234'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('onion bad length', () => {
const str = '/onion/timaq4ygg2iegci:80'
- expect(() => multiaddr(str)).to.throw()
+ expect(() => new Multiaddr(str)).to.throw()
})
it('onion bad port', () => {
const str = '/onion/timaq4ygg2iegci7:-1'
- expect(() => multiaddr(str)).to.throw()
+ expect(() => new Multiaddr(str)).to.throw()
})
it('onion no port', () => {
const str = '/onion/timaq4ygg2iegci7'
- expect(() => multiaddr(str)).to.throw()
+ expect(() => new Multiaddr(str)).to.throw()
})
it('onion3', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:1234'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('onion3 bad length', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopyyd:1234'
- expect(() => multiaddr(str)).to.throw()
+ expect(() => new Multiaddr(str)).to.throw()
})
it('onion3 bad port', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:-1'
- expect(() => multiaddr(str)).to.throw()
+ expect(() => new Multiaddr(str)).to.throw()
})
it('onion3 no port', () => {
const str = '/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd'
- expect(() => multiaddr(str)).to.throw()
+ expect(() => new Multiaddr(str)).to.throw()
})
it('p2p-circuit', () => {
const str = '/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('p2p-circuit p2p', () => {
const str = '/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/p2p-circuit'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('p2p-circuit ipfs', () => {
const str = '/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/p2p-circuit'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str.replace('/ipfs/', '/p2p/'))
})
it('p2p-webrtc-star', () => {
const str = '/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('p2p-webrtc-star ipfs', () => {
const str = '/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str.replace('/ipfs/', '/p2p/'))
})
it('p2p-webrtc-direct', () => {
const str = '/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('p2p-websocket-star', () => {
const str = '/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
it('memory + p2p', () => {
const str = '/memory/test/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
- const addr = multiaddr(str)
+ const addr = new Multiaddr(str)
expect(addr).to.have.property('bytes')
expect(addr.toString()).to.equal(str)
})
@@ -479,9 +481,9 @@ describe('variants', () => {
describe('helpers', () => {
describe('.toOptions', () => {
it('returns a well formed options object', () => {
- expect(multiaddr('/ip4/0.0.0.0/tcp/1234').toOptions())
+ expect(new Multiaddr('/ip4/0.0.0.0/tcp/1234').toOptions())
.to.eql({
- family: 'ipv4',
+ family: 4,
host: '0.0.0.0',
transport: 'tcp',
port: 1234
@@ -491,14 +493,14 @@ describe('helpers', () => {
describe('.inspect', () => {
it('renders the buffer as hex', () => {
- expect(multiaddr('/ip4/0.0.0.0/tcp/1234').inspect())
+ expect(new Multiaddr('/ip4/0.0.0.0/tcp/1234').inspect())
.to.eql('')
})
})
describe('.protos', () => {
it('returns a list of all protocols in the address', () => {
- expect(multiaddr('/ip4/0.0.0.0/utp').protos())
+ expect(new Multiaddr('/ip4/0.0.0.0/utp').protos())
.to.eql([{
code: 4,
name: 'ip4',
@@ -516,7 +518,7 @@ describe('helpers', () => {
it('works with ipfs', () => {
expect(
- multiaddr('/ip4/0.0.0.0/utp/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').protos()
+ new Multiaddr('/ip4/0.0.0.0/utp/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').protos()
).to.be.eql([{
code: 4,
name: 'ip4',
@@ -540,7 +542,7 @@ describe('helpers', () => {
it('works with p2p', () => {
expect(
- multiaddr('/ip4/0.0.0.0/utp/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').protos()
+ new Multiaddr('/ip4/0.0.0.0/utp/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').protos()
).to.be.eql([{
code: 4,
name: 'ip4',
@@ -564,7 +566,7 @@ describe('helpers', () => {
it('works with unix', () => {
expect(
- multiaddr('/ip4/0.0.0.0/tcp/8000/unix/tmp/p2p.sock').protos()
+ new Multiaddr('/ip4/0.0.0.0/tcp/8000/unix/tmp/p2p.sock').protos()
).to.be.eql([{
code: 4,
name: 'ip4',
@@ -588,7 +590,7 @@ describe('helpers', () => {
it('works with memory', () => {
expect(
- multiaddr('/memory/test/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6').protos()
+ new Multiaddr('/memory/test/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6').protos()
).to.be.eql([{
code: 777,
name: 'memory',
@@ -607,7 +609,7 @@ describe('helpers', () => {
describe('.tuples', () => {
it('returns the tuples', () => {
- expect(multiaddr('/ip4/0.0.0.0/utp').tuples())
+ expect(new Multiaddr('/ip4/0.0.0.0/utp').tuples())
.to.eql([
[4, Uint8Array.from([0, 0, 0, 0])],
[302]
@@ -617,7 +619,7 @@ describe('helpers', () => {
describe('.stringTuples', () => {
it('returns the string partss', () => {
- expect(multiaddr('/ip4/0.0.0.0/utp').stringTuples())
+ expect(new Multiaddr('/ip4/0.0.0.0/utp').stringTuples())
.to.eql([
[4, '0.0.0.0'],
[302]
@@ -628,7 +630,7 @@ describe('helpers', () => {
describe('.decapsulate', () => {
it('throws on address with no matching subaddress', () => {
expect(
- () => multiaddr('/ip4/127.0.0.1').decapsulate('/ip4/198.168.0.0')
+ () => new Multiaddr('/ip4/127.0.0.1').decapsulate('/ip4/198.168.0.0')
).to.throw(
/does not contain subaddress/
)
@@ -637,31 +639,31 @@ describe('helpers', () => {
describe('.decapsulateCode', () => {
it('removes the last occurrence of the code from the multiaddr', () => {
- const relayTCP = multiaddr('/ip4/0.0.0.0/tcp/8080')
+ const relayTCP = new Multiaddr('/ip4/0.0.0.0/tcp/8080')
const relay = relayTCP.encapsulate('/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit')
- const target = multiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
+ const target = new Multiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
const original = relay.encapsulate(target)
expect(original.decapsulateCode(421)).to.eql(relay)
expect(relay.decapsulateCode(421)).to.eql(relayTCP)
})
it('ignores missing codes', () => {
- const tcp = multiaddr('/ip4/0.0.0.0/tcp/8080')
+ const tcp = new Multiaddr('/ip4/0.0.0.0/tcp/8080')
expect(tcp.decapsulateCode(421)).to.eql(tcp)
})
})
describe('.equals', () => {
it('returns true for equal addresses', () => {
- const addr1 = multiaddr('/ip4/192.168.0.1')
- const addr2 = multiaddr('/ip4/192.168.0.1')
+ const addr1 = new Multiaddr('/ip4/192.168.0.1')
+ const addr2 = new Multiaddr('/ip4/192.168.0.1')
expect(addr1.equals(addr2)).to.equal(true)
})
it('returns false for non equal addresses', () => {
- const addr1 = multiaddr('/ip4/192.168.1.1')
- const addr2 = multiaddr('/ip4/192.168.0.1')
+ const addr1 = new Multiaddr('/ip4/192.168.1.1')
+ const addr2 = new Multiaddr('/ip4/192.168.0.1')
expect(addr1.equals(addr2)).to.equal(false)
})
@@ -670,7 +672,7 @@ describe('helpers', () => {
describe('.nodeAddress', () => {
it('throws on an invalid node address', () => {
expect(
- () => multiaddr('/ip4/192.168.0.1/utp').nodeAddress()
+ () => new Multiaddr('/ip4/192.168.0.1/utp').nodeAddress()
).to.throw(
/multiaddr must have a valid format/
)
@@ -678,7 +680,7 @@ describe('helpers', () => {
it('returns a node friendly address', () => {
expect(
- multiaddr('/ip4/192.168.0.1/tcp/1234').nodeAddress()
+ new Multiaddr('/ip4/192.168.0.1/tcp/1234').nodeAddress()
).to.be.eql({
address: '192.168.0.1',
family: 4,
@@ -688,7 +690,7 @@ describe('helpers', () => {
it('returns a node friendly address with dns', () => {
expect(
- multiaddr('/dns4/wss0.bootstrap.libp2p.io/tcp/443').nodeAddress()
+ new Multiaddr('/dns4/wss0.bootstrap.libp2p.io/tcp/443').nodeAddress()
).to.be.eql({
address: 'wss0.bootstrap.libp2p.io',
family: 4,
@@ -698,7 +700,7 @@ describe('helpers', () => {
it('throws on an invalid format address when the addr is not prefixed with a /', () => {
expect(
- () => multiaddr('ip4/192.168.0.1/udp').nodeAddress()
+ () => new Multiaddr('ip4/192.168.0.1/udp').nodeAddress()
).to.throw(
/must start with a/
)
@@ -706,7 +708,7 @@ describe('helpers', () => {
it('throws on an invalid protocol name when the addr has an invalid one', () => {
expect(
- () => multiaddr('/ip5/127.0.0.1/udp/5000')
+ () => new Multiaddr('/ip5/127.0.0.1/udp/5000')
).to.throw(
/no protocol with name/
)
@@ -714,7 +716,7 @@ describe('helpers', () => {
it('throws on an invalid protocol name when the transport protocol is not valid', () => {
expect(
- () => multiaddr('/ip4/127.0.0.1/utp/5000')
+ () => new Multiaddr('/ip4/127.0.0.1/utp/5000')
).to.throw(
/no protocol with name/
)
@@ -725,7 +727,7 @@ describe('helpers', () => {
it('throws on missing address object', () => {
expect(
// @ts-ignore
- () => multiaddr.fromNodeAddress()
+ () => Multiaddr.fromNodeAddress()
).to.throw(
/requires node address/
)
@@ -734,7 +736,7 @@ describe('helpers', () => {
it('throws on missing transport', () => {
expect(
// @ts-ignore
- () => multiaddr.fromNodeAddress({ address: '0.0.0.0' })
+ () => Multiaddr.fromNodeAddress({ address: '0.0.0.0' })
).to.throw(
/requires transport protocol/
)
@@ -742,10 +744,10 @@ describe('helpers', () => {
it('parses a node address', () => {
expect(
- multiaddr.fromNodeAddress({
+ Multiaddr.fromNodeAddress({
address: '192.168.0.1',
- family: 'IPv4',
- port: '1234'
+ family: 4,
+ port: 1234
}, 'tcp').toString()
).to.be.eql(
'/ip4/192.168.0.1/tcp/1234'
@@ -756,6 +758,7 @@ describe('helpers', () => {
describe('.isThinWaistAddress', () => {
const families = ['ip4', 'ip6']
const transports = ['tcp', 'udp']
+ /** @type {Record} */
const addresses = {
ip4: '192.168.0.1',
ip6: '2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095'
@@ -764,9 +767,7 @@ describe('helpers', () => {
transports.forEach((transport) => {
it(`returns true for /${family}-${transport}`, () => {
expect(
- multiaddr(
- `/${family}/${addresses[family]}/${transport}/1234`
- ).isThinWaistAddress()
+ new Multiaddr(`/${family}/${addresses[family]}/${transport}/1234`).isThinWaistAddress()
).to.equal(true)
})
})
@@ -774,17 +775,17 @@ describe('helpers', () => {
it('returns false for two protocols not using {IPv4, IPv6}/{TCP, UDP}', () => {
expect(
- multiaddr('/ip4/192.168.0.1/utp').isThinWaistAddress()
+ new Multiaddr('/ip4/192.168.0.1/utp').isThinWaistAddress()
).to.equal(false)
expect(
- multiaddr('/sctp/192.168.0.1/tcp/1234').isThinWaistAddress()
+ new Multiaddr('/sctp/192.168.0.1/tcp/1234').isThinWaistAddress()
).to.eql(
false
)
expect(
- multiaddr('/http/utp').isThinWaistAddress()
+ new Multiaddr('/http/utp').isThinWaistAddress()
).to.eql(
false
)
@@ -792,7 +793,7 @@ describe('helpers', () => {
it('returns false for more than two protocols', () => {
expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/utp').isThinWaistAddress()
+ new Multiaddr('/ip4/0.0.0.0/tcp/1234/utp').isThinWaistAddress()
).to.equal(
false
)
@@ -802,27 +803,27 @@ describe('helpers', () => {
describe('.getPeerId should parse id from multiaddr', () => {
it('extracts the peer Id from a multiaddr, p2p', () => {
expect(
- multiaddr('/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
+ new Multiaddr('/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
).to.equal('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
})
it('extracts the correct peer Id from a circuit multiaddr', () => {
expect(
- multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
+ new Multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
).to.equal('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
})
it('extracts the peer Id from a multiaddr, ipfs', () => {
expect(
- multiaddr('/p2p-circuit/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
+ new Multiaddr('/p2p-circuit/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
).to.equal('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
})
it('extracts the peer Id from a multiaddr, p2p and CIDv1 Base32', () => {
expect(
- multiaddr('/p2p-circuit/p2p/bafzbeigweq4zr4x4ky2dvv7nanbkw6egutvrrvzw6g3h2rftp7gidyhtt4').getPeerId()
+ new Multiaddr('/p2p-circuit/p2p/bafzbeigweq4zr4x4ky2dvv7nanbkw6egutvrrvzw6g3h2rftp7gidyhtt4').getPeerId()
).to.equal('QmckZzdVd72h9QUFuJJpQqhsZqGLwjhh81qSvZ9BhB2FQi')
})
it('extracts the peer Id from a multiaddr, p2p and CIDv1 Base32, where Id contains non b58 chars', () => {
expect(
- multiaddr('/p2p-circuit/p2p/bafzbeidt255unskpefjmqb2rc27vjuyxopkxgaylxij6pw35hhys4vnyp4').getPeerId()
+ new Multiaddr('/p2p-circuit/p2p/bafzbeidt255unskpefjmqb2rc27vjuyxopkxgaylxij6pw35hhys4vnyp4').getPeerId()
).to.equal('QmW8rAgaaA6sRydK1k6vonShQME47aDxaFidbtMevWs73t')
})
})
@@ -830,7 +831,7 @@ describe('helpers', () => {
describe('.getPeerId should return null on missing peer id in multiaddr', () => {
it('parses extracts the peer Id from a multiaddr', () => {
expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/utp').getPeerId()
+ new Multiaddr('/ip4/0.0.0.0/tcp/1234/utp').getPeerId()
).to.be.null()
})
})
@@ -838,30 +839,30 @@ describe('helpers', () => {
describe('.getPath', () => {
it('should return a path for unix', () => {
expect(
- multiaddr('/unix/tmp/p2p.sock').getPath()
+ new Multiaddr('/unix/tmp/p2p.sock').getPath()
).to.eql('/tmp/p2p.sock')
})
it('should return a path for unix when other protos exist', () => {
expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/unix/tmp/p2p.sock').getPath()
+ new Multiaddr('/ip4/0.0.0.0/tcp/1234/unix/tmp/p2p.sock').getPath()
).to.eql('/tmp/p2p.sock')
})
it('should not return a path when no path proto exists', () => {
expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPath()
+ new Multiaddr('/ip4/0.0.0.0/tcp/1234/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPath()
).to.eql(null)
})
})
describe('multiaddr.isMultiaddr', () => {
it('handles different inputs', () => {
- expect(multiaddr.isMultiaddr(multiaddr('/'))).to.be.eql(true)
- expect(multiaddr.isMultiaddr('/')).to.be.eql(false)
- expect(multiaddr.isMultiaddr(123)).to.be.eql(false)
+ expect(Multiaddr.isMultiaddr(new Multiaddr('/'))).to.be.eql(true)
+ expect(Multiaddr.isMultiaddr('/')).to.be.eql(false)
+ expect(Multiaddr.isMultiaddr(123)).to.be.eql(false)
- expect(multiaddr.isMultiaddr(uint8ArrayFromString('/hello'))).to.be.eql(false)
+ expect(Multiaddr.isMultiaddr(uint8ArrayFromString('/hello'))).to.be.eql(false)
})
})
@@ -869,48 +870,32 @@ describe('helpers', () => {
describe('.isName', () => {
it('valid name dns', () => {
const str = '/dns/ipfs.io'
- const addr = multiaddr(str)
- expect(multiaddr.isName(addr)).to.equal(true)
+ const addr = new Multiaddr(str)
+ expect(Multiaddr.isName(addr)).to.equal(true)
})
it('valid name dnsaddr', () => {
const str = '/dnsaddr/ipfs.io'
- const addr = multiaddr(str)
- expect(multiaddr.isName(addr)).to.equal(true)
+ const addr = new Multiaddr(str)
+ expect(Multiaddr.isName(addr)).to.equal(true)
})
it('valid name dns4', () => {
const str = '/dns4/ipfs.io'
- const addr = multiaddr(str)
- expect(multiaddr.isName(addr)).to.equal(true)
+ const addr = new Multiaddr(str)
+ expect(Multiaddr.isName(addr)).to.equal(true)
})
it('valid name dns6', () => {
const str = '/dns6/ipfs.io'
- const addr = multiaddr(str)
- expect(multiaddr.isName(addr)).to.equal(true)
+ const addr = new Multiaddr(str)
+ expect(Multiaddr.isName(addr)).to.equal(true)
})
it('invalid name', () => {
const str = '/ip4/127.0.0.1'
- const addr = multiaddr(str)
- expect(multiaddr.isName(addr)).to.equal(false)
- })
- })
-
- describe('.resolve', () => {
- it.skip('valid and active DNS name', (done) => {})
- it.skip('valid but inactive DNS name', () => {})
- it('invalid DNS name', () => {
- const str = '/ip4/127.0.0.1'
- const addr = multiaddr(str)
-
- return multiaddr.resolve(addr)
- // @ts-ignore
- .then(expect.fail, (err) => {
- expect(err).to.exist()
- expect(err.message).to.eql('not a valid name')
- })
+ const addr = new Multiaddr(str)
+ expect(Multiaddr.isName(addr)).to.equal(false)
})
})
})
diff --git a/test/protocols.spec.js b/test/protocols.spec.js
index b5b53016..a6e12a01 100644
--- a/test/protocols.spec.js
+++ b/test/protocols.spec.js
@@ -24,6 +24,7 @@ describe('protocols', () => {
it('else', () => {
expect(
+ // @ts-expect-error
() => protocols({ hi: 34 })
).to.throw(
/invalid protocol id type/
diff --git a/test/resolvers.spec.js b/test/resolvers.spec.js
index 747c80de..9d5959f5 100644
--- a/test/resolvers.spec.js
+++ b/test/resolvers.spec.js
@@ -4,9 +4,9 @@
const { expect } = require('aegir/utils/chai')
const sinon = require('sinon')
-const multiaddr = require('../src')
+const { Multiaddr } = require('../src')
const resolvers = require('../src/resolvers')
-const { Resolver } = require('../src/resolvers/dns')
+const Resolver = require('../src/resolvers/dns')
const dnsaddrStub1 = [
['dnsaddr=/dnsaddr/ams-1.bootstrap.libp2p.io/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd'],
@@ -28,7 +28,7 @@ const dnsaddrStub2 = [
describe('multiaddr resolve', () => {
it('should throw if no resolver is available', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
+ const ma = new Multiaddr('/dnsaddr/bootstrap.libp2p.io')
// Resolve
await expect(ma.resolve()).to.eventually.be.rejected()
@@ -38,7 +38,7 @@ describe('multiaddr resolve', () => {
describe('dnsaddr', () => {
before(() => {
// Set resolvers
- multiaddr.resolvers.set('dnsaddr', resolvers.dnsaddrResolver)
+ Multiaddr.resolvers.set('dnsaddr', resolvers.dnsaddrResolver)
})
afterEach(() => {
@@ -46,7 +46,7 @@ describe('multiaddr resolve', () => {
})
it('can resolve dnsaddr without no peerId', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
+ const ma = new Multiaddr('/dnsaddr/bootstrap.libp2p.io')
const stub = sinon.stub(Resolver.prototype, 'resolveTxt')
stub.onCall(0).returns(Promise.resolve(dnsaddrStub1))
@@ -58,12 +58,12 @@ describe('multiaddr resolve', () => {
resolvedMas.forEach((ma, index) => {
const stubAddr = dnsaddrStub1[index][0].split('=')[1]
- expect(ma.equals(multiaddr(stubAddr))).to.equal(true)
+ expect(ma.equals(new Multiaddr(stubAddr))).to.equal(true)
})
})
it('can resolve dnsaddr with peerId', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
+ const ma = new Multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
const stub = sinon.stub(Resolver.prototype, 'resolveTxt')
stub.onCall(0).returns(Promise.resolve(dnsaddrStub1))
@@ -73,11 +73,11 @@ describe('multiaddr resolve', () => {
const resolvedMas = await ma.resolve()
expect(resolvedMas).to.have.length(1)
- expect(resolvedMas[0].equals(multiaddr('/dnsaddr/ams-2.bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb'))).to.eql(true)
+ expect(resolvedMas[0].equals(new Multiaddr('/dnsaddr/ams-2.bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb'))).to.eql(true)
})
it('can resolve dnsaddr with peerId two levels', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
+ const ma = new Multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
const stub = sinon.stub(Resolver.prototype, 'resolveTxt')
stub.onCall(0).returns(Promise.resolve(dnsaddrStub1))
@@ -93,10 +93,11 @@ describe('multiaddr resolve', () => {
const resolvedMas = resolvedSecondMas.flat()
expect(resolvedMas).to.have.length(dnsaddrStub2.length)
- resolvedMas.forEach((ma, index) => {
+
+ resolvedMas.forEach((/** @type {Multiaddr} */ma, /** @type {number} */ index) => {
const stubAddr = dnsaddrStub2[index][0].split('=')[1]
- expect(ma.equals(multiaddr(stubAddr))).to.equal(true)
+ expect(ma.equals(new Multiaddr(stubAddr))).to.equal(true)
})
})
})
diff --git a/test/types.spec.ts b/test/types.spec.ts
deleted file mode 100644
index ba9129c9..00000000
--- a/test/types.spec.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import Multiaddr from '../src'
-
-const testStr = '/ip4/127.0.0.1'
-
-export const maFromFunctionConstructor: Multiaddr = Multiaddr(testStr)
-
-export const maFromClassConstructor: Multiaddr = new Multiaddr(testStr)
-
-export const maFromMa: Multiaddr = Multiaddr(new Multiaddr(testStr))
-
-export const maFromConstructorFunction: Multiaddr = Multiaddr.fromNodeAddress(
- {
- family: 'IPv4',
- address: '127.0.0.1',
- port: '12345'
- },
- 'udp'
-)
-
-export function doSthWithMa (ma: Multiaddr): void {
- ma.toOptions()
-}
diff --git a/tsconfig.json b/tsconfig.json
index 60e2c5b1..83d980a2 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,18 +1,10 @@
{
+ "extends": "aegir/src/config/tsconfig.aegir.json",
"compilerOptions": {
- "module": "commonjs",
- "lib": ["es6"],
- "target": "ES5",
- "noImplicitAny": false,
- "noImplicitThis": true,
- "strictFunctionTypes": true,
- "strictNullChecks": true,
- "esModuleInterop": true,
- "resolveJsonModule": true,
- "allowJs": true,
- "checkJs": true,
- "noEmit": true,
- "forceConsistentCasingInFileNames": true
+ "outDir": "dist"
},
- "include": ["src/index.d.ts", "test/**/*.spec.js", "test/**/*.spec.ts"]
-}
+ "include": [
+ "test",
+ "src"
+ ]
+}
\ No newline at end of file