diff --git a/README.md b/README.md index e4c0c84..bec33b2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # dns2 -![NPM version](https://img.shields.io/npm/v/dns2.svg?style=flat) -[![Node.js CI](https://github.com/song940/node-dns/actions/workflows/node.js.yml/badge.svg)](https://github.com/song940/node-dns/actions/workflows/node.js.yml) +![NPM version][npm-img] [![Build Status][ci-img]][ci-url] > A DNS Server and Client Implementation in Pure JavaScript with no dependencies. @@ -27,10 +26,9 @@ DNS client will use UDP by default. const dns2 = require('dns2'); const options = { - // available options - // dns: dns server ip address or hostname (string), - // port: dns server port (number), - // recursive: Recursion Desired flag (boolean, default true, since > v1.4.2) + // nameServers: ['8.8.8.8'] — array of DNS server IPs (default: Google + 114dns) + // port: 53 — DNS server port (number) + // recursive: true — Recursion Desired flag (boolean, default true) }; const dns = new dns2(options); @@ -311,3 +309,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +[npm-img]: https://img.shields.io/npm/v/dns2.svg?style=flat +[ci-img]: https://github.com/song940/node-dns/actions/workflows/node.js.yml/badge.svg +[ci-url]: https://github.com/song940/node-dns/actions/workflows/node.js.yml diff --git a/index.js b/index.js index 9535d47..735e062 100644 --- a/index.js +++ b/index.js @@ -15,8 +15,13 @@ const EventEmitter = require('node:events'); * @docs https://tools.ietf.org/html/rfc1035 */ class DNS extends EventEmitter { - constructor(options) { + constructor(options = {}) { super(); + // Accept `dns` as a shorthand alias for `nameServers` so that + // `new DNS({ dns: '8.8.8.8' })` works as documented and intuited. + if (options.dns != null && options.nameServers == null) { + options = Object.assign({}, options, { nameServers: [].concat(options.dns) }); + } Object.assign(this, { port : 53, retries : 3, diff --git a/test/client.js b/test/client.js index 185616e..fc89029 100644 --- a/test/client.js +++ b/test/client.js @@ -291,3 +291,43 @@ test('dns#resolveSOA returns SOA record via high-level DNS class', async() => { await new Promise(resolve => server.close(resolve)); }); + +test('dns#constructor accepts dns shorthand alias for nameServers', async() => { + const server = createUDPServer(); + server.on('request', (request, send) => { + const response = Packet.createResponseFromRequest(request); + response.answers.push({ + name : request.questions[0].name, + type : Packet.TYPE.A, + class : Packet.CLASS.IN, + ttl : 60, + address : '1.2.3.4', + }); + send(response); + }); + await server.listen(0, '127.0.0.1'); + const { port } = server.address(); + + // Use `dns` string shorthand — this is what the docs showed and what broke. + const dns = new DNS({ dns: '127.0.0.1', port }); + assert.deepEqual(dns.nameServers, [ '127.0.0.1' ], + '`dns` string is normalised to nameServers array'); + + const result = await dns.resolveA('alias.test'); + assert.equal(result.answers[0].address, '1.2.3.4', + 'query reaches the intended server, promise settles'); + + await new Promise(resolve => server.close(resolve)); +}); + +test('dns#constructor accepts dns array shorthand for nameServers', () => { + const dns = new DNS({ dns: [ '1.1.1.1', '8.8.8.8' ] }); + assert.deepEqual(dns.nameServers, [ '1.1.1.1', '8.8.8.8' ], + '`dns` array is normalised to nameServers'); +}); + +test('dns#constructor dns alias does not override explicit nameServers', () => { + const dns = new DNS({ dns: '1.1.1.1', nameServers: [ '9.9.9.9' ] }); + assert.deepEqual(dns.nameServers, [ '9.9.9.9' ], + 'explicit nameServers takes precedence over dns alias'); +}); diff --git a/ts/index.d.ts b/ts/index.d.ts index 9a928b6..d797b86 100644 --- a/ts/index.d.ts +++ b/ts/index.d.ts @@ -301,6 +301,8 @@ declare namespace DNS { timeout: number; recursive: boolean; resolverProtocol: 'UDP' | 'TCP' | 'DOH' | 'Google'; + /** Shorthand alias for `nameServers`. A single IP string or an array. */ + dns?: string | string[]; nameServers: string[]; rootServers: string[]; }