diff --git a/README.md b/README.md index d18af69..17c5778 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/tableflip/uri-to-multiaddr.svg?branch=master)](https://travis-ci.org/tableflip/uri-to-multiaddr) [![dependencies Status](https://david-dm.org/tableflip/uri-to-multiaddr/status.svg)](https://david-dm.org/tableflip/uri-to-multiaddr) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) -> Convert a URI to a [Multiaddr](https://multiformats.io/multiaddr/): https://protocol.ai -> /dnsaddr/protocol.ai/https +> Convert a URI to a [Multiaddr](https://multiformats.io/multiaddr/): https://protocol.ai -> /dns4/protocol.ai/https ## Install @@ -16,14 +16,31 @@ npm install uri-to-multiaddr const toMultiaddr = require('uri-to-multiaddr') console.log(toMultiaddr('https://protocol.ai')) +// -> /dns4/protocol.ai/https +``` + +Domain names can represent one of + +- `/dns4` - domain resolves to an ipv4 address (**default**) +- `/dns6` - domain resolves to an ipv6 address +- `/dnsaddr` - domain has a [DNSLink](https://docs.ipfs.io/guides/concepts/dnslink/) TXT record pointing to an IPFS CID + +This library assumes `/dns4` when it finds a domain name in the input string. +It makes no attempt query DNS. To override the default assumption, you can pass +in an options object as the second parameter to override it: + +```js +const toMultiaddr = require('uri-to-multiaddr') + +console.log(toMultiaddr('https://protocol.ai'), {defaultDnsType: 'dnsaddr'}) // -> /dnsaddr/protocol.ai/https ``` -* See [test.js](./test.js) for the currently supported conversions. -* Might be lossy - e.g. a DNSv6 multiaddr -* Can throw if the passed URI: - * is not a valid - * is not supported yet e.g. quic +See [test.js](./test.js) for the currently supported conversions. + +**Note**: `uri-to-multiaddr` will throw if the passed URI: + - is not a valid, according the WHATWG URL spec implementation used. + - is not supported yet e.g. quic ## Related @@ -35,4 +52,4 @@ Feel free to dive in! [Open an issue](https://github.com/tableflip/uri-to-multia ## License -[MIT](LICENSE) © TABLEFLIP \ No newline at end of file +[MIT](LICENSE) © TABLEFLIP diff --git a/index.js b/index.js index d2c315e..06edb26 100644 --- a/index.js +++ b/index.js @@ -2,19 +2,24 @@ const url = require('url') const isIp = require('is-ip') const Multiaddr = require('multiaddr') -// Convert a URI to a multiaddr -// -// [https, foobar.com] => /dnsaddr/foobar.com/https -// [https, foobar.com, 8080] => /dnsaddr/foobar.com/tcp/8080/https -// [ws, foobar.com] => /dnsaddr/foobar.com/ws -// [https, 127.0.0.1, 8080] => /ip4/127.0.0.1/tcp/8080/https -// [tcp, foobar.com, 8080] => /dnsaddr/foobar.com/tcp/8080 -// [udp, foobar.com, 8080] => /dnsaddr/foobar.com/udp/8080 +/** + * Convert a URI to a multiaddr + * + * http://foobar.com => /dns4/foobar.com/https + * https://foobar.com:8080 => /dns4/foobar.com/tcp/8080/https + * ws://foobar.com => /dns4/foobar.com/ws + * https://127.0.0.1:8080 => /ip4/127.0.0.1/tcp/8080/https + * http://[::1]:8080 => /ip6/::1/tcp/8080/http + * tcp://foobar.com:8080 => /dns4/foobar.com/tcp/8080 + * udp://foobar.com:8080 => /dns4/foobar.com/udp/8080 + */ -function multiaddrFromUri (uriStr) { +function multiaddrFromUri (uriStr, opts) { + opts = opts || {} + const defaultDnsType = opts.defaultDnsType || 'dns4' const { scheme, hostname, port } = parseUri(uriStr) const parts = [ - tupleForHostname(hostname), + tupleForHostname(hostname, defaultDnsType), tupleForPort(port, scheme), tupleForScheme(scheme) ] @@ -35,7 +40,7 @@ function parseUri (uriStr) { return { scheme, hostname, port } } -function tupleForHostname (hostname) { +function tupleForHostname (hostname, defaultDnsType) { if (!hostname) throw new Error('hostname is requried') if (isIp.v4(hostname)) { return ['ip4', hostname] @@ -51,8 +56,8 @@ function tupleForHostname (hostname) { return ['ip6', trimmed] } } - // assumes that any non-ip hostname is a dns address. - return ['dnsaddr', hostname] + // assumes that any non-ip hostname is a dns4 address. + return [defaultDnsType, hostname] } function tupleForPort (port, scheme) { diff --git a/test.js b/test.js index 975255f..a5e0241 100644 --- a/test.js +++ b/test.js @@ -11,15 +11,15 @@ test('should convert URIs to multiaddrs', (t) => { ['/ip6/::/tcp/0', 'tcp://[::]:0'], ['/ip4/0.0.7.6/udp/1234', 'udp://0.0.7.6:1234'], ['/ip6/::/udp/0', 'udp://[::]:0'], - ['/dnsaddr/protocol.ai/tcp/80', 'tcp://protocol.ai:80'], - ['/dnsaddr/protocol.ai/tcp/80/http', 'http://protocol.ai:80'], - ['/dnsaddr/protocol.ai/tcp/80/https', 'https://protocol.ai:80'], - ['/dnsaddr/ipfs.io/ws', 'ws://ipfs.io'], - ['/dnsaddr/ipfs.io/http', 'http://ipfs.io'], - ['/dnsaddr/ipfs.io/https', 'https://ipfs.io'], + ['/dns4/protocol.ai/tcp/80', 'tcp://protocol.ai:80'], + ['/dns4/protocol.ai/tcp/80/http', 'http://protocol.ai:80'], + ['/dns4/protocol.ai/tcp/80/https', 'https://protocol.ai:80'], + ['/dns4/ipfs.io/ws', 'ws://ipfs.io'], + ['/dns4/ipfs.io/http', 'http://ipfs.io'], + ['/dns4/ipfs.io/https', 'https://ipfs.io'], ['/ip4/1.2.3.4/tcp/3456/ws', 'ws://1.2.3.4:3456'], ['/ip6/::/tcp/0/ws', 'ws://[::]:0'], - ['/dnsaddr/ipfs.io/wss', 'wss://ipfs.io'], + ['/dns4/ipfs.io/wss', 'wss://ipfs.io'], ['/ip4/1.2.3.4/tcp/3456/wss', 'wss://1.2.3.4:3456'], ['/ip6/::/tcp/0/wss', 'wss://[::]:0'] ] @@ -27,6 +27,16 @@ test('should convert URIs to multiaddrs', (t) => { data.forEach(d => t.is(toMultiaddr(d[1]).toString(), d[0], `Converts ${d[1]} to ${d[0]}`)) }) +test('should use the defaultDnsType where provided', (t) => { + const data = [ + ['/dns4/protocol.ai/tcp/80', 'tcp://protocol.ai:80', { defaultDnsType: 'dns4' }], + ['/dns6/protocol.ai/tcp/80/http', 'http://protocol.ai:80', { defaultDnsType: 'dns6' }], + ['/dnsaddr/protocol.ai/tcp/80/https', 'https://protocol.ai:80', { defaultDnsType: 'dnsaddr' }] + ] + + data.forEach(d => t.is(toMultiaddr(d[1], d[2]).toString(), d[0], `Converts ${d[1]} to ${d[0]} with opts ${d[2]}`)) +}) + test('should throw for unsupported protocol', (t) => { t.throws(() => toMultiaddr('quic://')) })