Skip to content

[WIP] Add TypeScript 2.1 typings #547

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ npm-debug.log
dist/
yarn.lock
coverage
.idea/
107 changes: 87 additions & 20 deletions lib/connect/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,88 @@ protocols.wss = require('./ws')
*
* @param {Object} [opts] option object
*/
function parseAuthOptions (opts) {
function parseAuthOptions (auth, opts) {
var matches
if (opts.auth) {
matches = opts.auth.match(/^(.+):(.+)$/)
if (auth) {
matches = auth.match(/^(.+):(.+)$/)
if (matches) {
opts.username = matches[1]
opts.password = matches[2]
} else {
opts.username = opts.auth
opts.username = auth
}
}
}

function parseBrokerUrl (brokerUrl) {
var opts = {}
var parsed = url.parse(brokerUrl, /* parseQueryString = */ true)
if (parsed.port != null) {
opts.port = Number(parsed.port)
}
if (parsed.protocol) {
opts.protocol = parsed.protocol.replace(/:$/, '')
}

// Parse username/password
parseAuthOptions(parsed.auth, opts)

// Support clientId passed in the query string of the url
if (parsed.query && typeof parsed.query.clientId === 'string') {
opts.clientId = parsed.query.clientId
}

return xtend(
opts,
// username
// password
// port
// protocol
// clientId
{
// NOTE: we use JUST the host, not parsed.host which includes the port
host: parsed.hostname,
path: parsed.path || '/',
// TODO: remove
hostname: parsed.hostname
})
}

function warnHostNameDeprecation () {
// The test uses hostname twice, once in `connect` when checking passed in
// opts and once in the acutall test to check the value is correct.
console.warn('Use of mqtt.Client ' +
'`opts.hostname` is deprecated. Use `opts.host`.\n' +
// Note we clone options in connect/ssl and delete 'hostname'
// so hostname isn't used.
patchHostName.usages +
' usages detected.')
}

patchHostName.usages = 0
function patchHostName (opts) {
if (!patchHostName.setHandler) {
process.once('exit', warnHostNameDeprecation)
patchHostName.setHandler = true
}

if (opts.hostname) {
var _hostname = opts.hostname
delete opts['hostname']
Object.defineProperty(opts, 'hostname', {
get: function () {
patchHostName.usages++
return _hostname
},
set: function (value) {
_hostname = value
},
configurable: true,
enumerable: true
})
}
}

/**
* connect - connect to an MQTT broker.
*
Expand All @@ -48,27 +117,26 @@ function connect (brokerUrl, opts) {

opts = opts || {}

if (brokerUrl) {
var parsed = url.parse(brokerUrl, true)
if (parsed.port != null) {
parsed.port = Number(parsed.port)
}

opts = xtend(parsed, opts)
if (opts.hostname) {
opts.host = opts.hostname
patchHostName.usages++
// For testing
warnHostNameDeprecation()
}

if (opts.protocol === null) {
if (brokerUrl) {
// Options object always override brokerUrl specified options
opts = xtend(parseBrokerUrl(brokerUrl), opts)
if (!opts.protocol) {
throw new Error('Missing protocol')
}
opts.protocol = opts.protocol.replace(/:$/, '')
}

// merge in the auth options if supplied
parseAuthOptions(opts)
patchHostName(opts)

// support clientId passed in the query string of the url
if (opts.query && typeof opts.query.clientId === 'string') {
opts.clientId = opts.query.clientId
}
// Someone out in the wild might be using {auth: 'user:pass'} out in the wild
// Keep old behaviour? Tests actually pass without this.
Copy link
Member Author

Choose a reason for hiding this comment

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

Personally I'd just remove this ...

parseAuthOptions(opts.auth, opts)

if (opts.cert && opts.key) {
if (opts.protocol) {
Expand Down Expand Up @@ -130,7 +198,6 @@ function connect (brokerUrl, opts) {

opts.host = opts.servers[client._reconnectCount].host
opts.port = opts.servers[client._reconnectCount].port
opts.hostname = opts.host

client._reconnectCount++
}
Expand Down
4 changes: 2 additions & 2 deletions lib/connect/tcp.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ var net = require('net')
function buildBuilder (client, opts) {
var port, host
opts.port = opts.port || 1883
opts.hostname = opts.hostname || opts.host || 'localhost'
opts.host = opts.host || 'localhost'

port = opts.port
host = opts.hostname
host = opts.host

return net.createConnection(port, host)
}
Expand Down
11 changes: 9 additions & 2 deletions lib/connect/tls.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
'use strict'
var tls = require('tls')

function buildBuilder (mqttClient, opts) {
function buildBuilder (mqttClient, opts_) {
var opts = Object.keys(opts_).reduce(function (acc, k) {
if (k !== 'hostname') {
acc[k] = opts_[k]
}
return acc
}, {})

var connection
opts.port = opts.port || 8883
opts.host = opts.hostname || opts.host || 'localhost'
opts.host = opts.host || 'localhost'

opts.rejectUnauthorized = opts.rejectUnauthorized !== false

Expand Down
27 changes: 12 additions & 15 deletions lib/connect/ws.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ var WSS_OPTIONS = [
var IS_BROWSER = process.title === 'browser'

function buildUrl (opts, client) {
var url = opts.protocol + '://' + opts.hostname + ':' + opts.port + opts.path
var url = opts.protocol + '://' + opts.host + ':' + opts.port + opts.path
if (typeof (opts.transformWsUrl) === 'function') {
url = opts.transformWsUrl(url, opts, client)
}
return url
}

function setDefaultOpts (opts) {
if (!opts.hostname) {
opts.hostname = 'localhost'
if (!opts.host) {
opts.host = 'localhost'
}
if (!opts.port) {
if (opts.protocol === 'wss') {
Expand Down Expand Up @@ -64,22 +64,19 @@ function buildBuilder (client, opts) {
}

function buildBuilderBrowser (client, opts) {
if (!opts.hostname) {
opts.hostname = opts.host
}

if (!opts.hostname) {
// Throwing an error in a Web Worker if no `hostname` is given, because we
// can not determine the `hostname` automatically. If connecting to
// localhost, please supply the `hostname` as an argument.
if (!opts.host) {
// Throwing an error in a Web Worker if no `host` is given, because we
// can not determine the `host` automatically. If connecting to
// localhost, please supply the `host` as an argument.
if (typeof (document) === 'undefined') {
throw new Error('Could not determine host. Specify host manually.')
throw new Error('Could not determine host. Specify `host` manually.')
}
var parsed = urlModule.parse(document.URL)
opts.hostname = parsed.hostname
var parsed = urlModule.parse(document.URL, true)

opts.host = parsed.hostname

if (!opts.port) {
opts.port = parsed.port
opts.port = Number(parsed.port)
}
}
return createWebSocket(client, opts)
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
"url": "git://github.com/mqttjs/MQTT.js.git"
},
"main": "mqtt.js",
"types": "types/index.d.ts",
"scripts": {
"test": "node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --bail",
"pretest": "standard | snazzy",
"tslint": "tslint types/**/*.d.ts",
"prepublish": "nsp check && npm run browser-build",
"browser-build": "rimraf dist/ && mkdirp dist/ && browserify mqtt.js -s mqtt > dist/mqtt.js && uglifyjs --screw-ie8 < dist/mqtt.js > dist/mqtt.min.js",
"browser-test": "zuul --server test/browser/server.js --local --open test/browser/test.js",
"sauce-test": "zuul --server test/browser/server.js --tunnel ngrok -- test/browser/test.js",
"ci": "npm run test && codecov"
"ci": "npm run tslint && npm run test && codecov"
},
"pre-commit": [
"test"
Expand Down Expand Up @@ -84,6 +86,9 @@
"snazzy": "^6.0.0",
"standard": "^8.6.0",
"through2": "^2.0.3",
"tslint": "^4.5.1",
"tslint-config-standard": "^4.0.0",
"typescript": "^2.2.1",
Copy link
Member Author

Choose a reason for hiding this comment

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

typescript is a peer dependency of tslint

"uglify": "^0.1.5",
"uglify-js": "^2.7.5",
"ws": "^1.0.0",
Expand Down
21 changes: 20 additions & 1 deletion test/mqtt.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ describe('mqtt', function () {
c.should.be.instanceOf(mqtt.MqttClient)
})

it('should warn that `hostname` is deprecated, while still honouring it', function () {
var oldWarn = console.warn
try {
var asserted = false
console.warn = function (s) {
asserted = true
s.split('\n')[0].should.be.equal(
'Use of mqtt.Client `opts.hostname` is deprecated. Use `opts.host`.')
}
var c = mqtt.connect('mqtt://localhost:1883', {hostname: 'test'})
asserted.should.be.equal(true)
c.should.be.instanceOf(mqtt.MqttClient)
c.options.hostname.should.be.equal('test')
c.options.host.should.be.equal('test')
} finally {
console.warn = oldWarn
}
})

it('should throw an error when called with no protocol specified', function () {
(function () {
mqtt.connect('foo.bar.com')
Expand Down Expand Up @@ -56,7 +75,7 @@ describe('mqtt', function () {
it('should return an MqttClient with correct host when called with a host and port', function () {
var c = mqtt.connect('tcp://user:pass@localhost:1883')

c.options.should.have.property('hostname', 'localhost')
c.options.should.have.property('host', 'localhost')
c.options.should.have.property('port', 1883)
})

Expand Down
3 changes: 3 additions & 0 deletions tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "tslint-config-standard"
}
7 changes: 7 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './lib/client'
export * from './lib/connect'
export * from './lib/store'
export * from './lib/types'
export * from './lib/client-options'
import { MqttClient } from './lib/client'
export { MqttClient as Client }
Loading