aedes 0.47.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +23 -3
- package/.github/workflows/sast.yml +29 -0
- package/README.md +1 -1
- package/aedes.d.ts +3 -9
- package/aedes.js +36 -16
- package/docs/Aedes.md +5 -3
- package/lib/handlers/connect.js +3 -3
- package/lib/handlers/subscribe.js +1 -1
- package/package.json +15 -15
- package/test/connect.js +4 -4
- package/test/events.js +42 -1
- package/test/helper.js +11 -11
- package/test/meta.js +1 -1
- package/test/not-blocking.js +5 -5
- package/test/retain.js +2 -2
- package/test/topics.js +4 -4
- package/test/types/aedes.test-d.ts +17 -14
- package/test/will.js +66 -15
- package/types/.eslintrc.json +7 -5
- package/types/client.d.ts +28 -23
- package/types/instance.d.ts +98 -97
- package/types/packet.d.ts +18 -13
- package/types/tsconfig.json +6 -4
package/.github/workflows/ci.yml
CHANGED
|
@@ -11,21 +11,39 @@ on:
|
|
|
11
11
|
- '*.md'
|
|
12
12
|
|
|
13
13
|
jobs:
|
|
14
|
+
dependency-review:
|
|
15
|
+
name: Dependency Review
|
|
16
|
+
if: github.event_name == 'pull_request'
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
steps:
|
|
21
|
+
- name: Check out repo
|
|
22
|
+
uses: actions/checkout@v3
|
|
23
|
+
with:
|
|
24
|
+
persist-credentials: false
|
|
25
|
+
|
|
26
|
+
- name: Dependency review
|
|
27
|
+
uses: actions/dependency-review-action@v2
|
|
28
|
+
|
|
14
29
|
test:
|
|
15
30
|
runs-on: ${{ matrix.os }}
|
|
16
|
-
|
|
31
|
+
permissions:
|
|
32
|
+
contents: read
|
|
17
33
|
strategy:
|
|
18
34
|
matrix:
|
|
19
|
-
node-version: [14
|
|
35
|
+
node-version: [14, 16, '*']
|
|
20
36
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
|
21
|
-
|
|
22
37
|
steps:
|
|
23
38
|
- uses: actions/checkout@v3
|
|
39
|
+
with:
|
|
40
|
+
persist-credentials: false
|
|
24
41
|
|
|
25
42
|
- name: Use Node.js
|
|
26
43
|
uses: actions/setup-node@v3
|
|
27
44
|
with:
|
|
28
45
|
node-version: ${{ matrix.node-version }}
|
|
46
|
+
check-latest: true
|
|
29
47
|
|
|
30
48
|
- name: Install
|
|
31
49
|
run: |
|
|
@@ -49,6 +67,8 @@ jobs:
|
|
|
49
67
|
coverage:
|
|
50
68
|
needs: test
|
|
51
69
|
runs-on: ubuntu-latest
|
|
70
|
+
permissions:
|
|
71
|
+
contents: read
|
|
52
72
|
steps:
|
|
53
73
|
- name: Coveralls Finished
|
|
54
74
|
uses: coverallsapp/github-action@master
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: sast
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches-ignore:
|
|
6
|
+
- 'dependabot/**'
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
analyze:
|
|
11
|
+
name: Analyze
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
security-events: write
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: true
|
|
18
|
+
matrix:
|
|
19
|
+
language: [ 'javascript' ]
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v3
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
|
|
25
|
+
- uses: github/codeql-action/init@v2
|
|
26
|
+
with:
|
|
27
|
+
languages: ${{ matrix.language }}
|
|
28
|
+
|
|
29
|
+
- uses: github/codeql-action/analyze@v2
|
package/README.md
CHANGED
|
@@ -107,7 +107,7 @@ Brokers that support the [Bridge Protocol][bridge_protocol] can connect to
|
|
|
107
107
|
Aedes. When connecting with this special protocol, subscriptions work as usual
|
|
108
108
|
except that the `retain` flag in the packet is propagated as-is.
|
|
109
109
|
|
|
110
|
-
##
|
|
110
|
+
## Extensions
|
|
111
111
|
|
|
112
112
|
- [aedes-logging]: Logging module for Aedes, based on Pino
|
|
113
113
|
- [aedes-stats]: Stats for Aedes
|
package/aedes.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare function Server (options?: AedesOptions): Aedes
|
|
5
|
-
|
|
6
|
-
export * from './types/instance'
|
|
7
|
-
export * from './types/packet'
|
|
8
|
-
export * from './types/client'
|
|
9
|
-
export default aedes
|
|
1
|
+
/// <reference path="./types/instance.d.ts" />
|
|
2
|
+
/// <reference path="./types/client.d.ts" />
|
|
3
|
+
/// <reference path="./types/packet.d.ts" />
|
package/aedes.js
CHANGED
|
@@ -79,10 +79,19 @@ function Aedes (opts) {
|
|
|
79
79
|
this.brokers = {}
|
|
80
80
|
|
|
81
81
|
const heartbeatTopic = $SYS_PREFIX + that.id + '/heartbeat'
|
|
82
|
+
const birthTopic = $SYS_PREFIX + that.id + '/birth'
|
|
83
|
+
|
|
82
84
|
this._heartbeatInterval = setInterval(heartbeat, opts.heartbeatInterval)
|
|
83
85
|
|
|
84
86
|
const bufId = Buffer.from(that.id, 'utf8')
|
|
85
87
|
|
|
88
|
+
// in a cluster env this is used to warn other broker instances
|
|
89
|
+
// that this broker is alive
|
|
90
|
+
that.publish({
|
|
91
|
+
topic: birthTopic,
|
|
92
|
+
payload: bufId
|
|
93
|
+
}, noop)
|
|
94
|
+
|
|
86
95
|
function heartbeat () {
|
|
87
96
|
that.publish({
|
|
88
97
|
topic: heartbeatTopic,
|
|
@@ -115,27 +124,25 @@ function Aedes (opts) {
|
|
|
115
124
|
}
|
|
116
125
|
|
|
117
126
|
function checkAndPublish (will, done) {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
that.brokers[will.brokerId] + (3 * opts.heartbeatInterval) <
|
|
121
|
-
Date.now()
|
|
122
|
-
|
|
123
|
-
if (needsPublishing) {
|
|
124
|
-
// randomize this, so that multiple brokers
|
|
125
|
-
// do not publish the same wills at the same time
|
|
126
|
-
that.publish(will, function publishWill (err) {
|
|
127
|
-
if (err) {
|
|
128
|
-
return done(err)
|
|
129
|
-
}
|
|
127
|
+
const notPublish =
|
|
128
|
+
that.brokers[will.brokerId] !== undefined && that.brokers[will.brokerId] + (3 * opts.heartbeatInterval) >= Date.now()
|
|
130
129
|
|
|
130
|
+
if (notPublish) return done()
|
|
131
|
+
|
|
132
|
+
// randomize this, so that multiple brokers
|
|
133
|
+
// do not publish the same wills at the same time
|
|
134
|
+
this.authorizePublish(that.clients[will.clientId] || null, will, function (err) {
|
|
135
|
+
if (err) { return doneWill() }
|
|
136
|
+
that.publish(will, doneWill)
|
|
137
|
+
|
|
138
|
+
function doneWill (err) {
|
|
139
|
+
if (err) { return done(err) }
|
|
131
140
|
that.persistence.delWill({
|
|
132
141
|
id: will.clientId,
|
|
133
142
|
brokerId: will.brokerId
|
|
134
143
|
}, done)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
done()
|
|
138
|
-
}
|
|
144
|
+
}
|
|
145
|
+
})
|
|
139
146
|
}
|
|
140
147
|
|
|
141
148
|
this.mq.on($SYS_PREFIX + '+/heartbeat', function storeBroker (packet, done) {
|
|
@@ -143,6 +150,19 @@ function Aedes (opts) {
|
|
|
143
150
|
done()
|
|
144
151
|
})
|
|
145
152
|
|
|
153
|
+
this.mq.on($SYS_PREFIX + '+/birth', function brokerBorn (packet, done) {
|
|
154
|
+
const brokerId = packet.payload.toString()
|
|
155
|
+
|
|
156
|
+
// reset duplicates counter
|
|
157
|
+
if (brokerId !== that.id) {
|
|
158
|
+
for (const clientId in that.clients) {
|
|
159
|
+
delete that.clients[clientId].duplicates[brokerId]
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
done()
|
|
164
|
+
})
|
|
165
|
+
|
|
146
166
|
this.mq.on($SYS_PREFIX + '+/new/clients', function closeSameClients (packet, done) {
|
|
147
167
|
const serverId = packet.topic.split('/')[1]
|
|
148
168
|
const clientId = packet.payload.toString()
|
package/docs/Aedes.md
CHANGED
|
@@ -186,7 +186,7 @@ const server = require('net').createServer(aedes.handle)
|
|
|
186
186
|
|
|
187
187
|
Directly subscribe a `topic` in server side. Bypass [`authorizeSubscribe`](#handler-authorizesubscribe-client-subscription-callback)
|
|
188
188
|
|
|
189
|
-
The `topic` and `deliverfunc` is a compound key to differentiate the uniqueness of its subscription pool. `topic` could be the one that is existed, in this case `deliverfunc` will be invoked as well as `SUBSCRIBE` does.
|
|
189
|
+
The `topic` and `deliverfunc` is a compound key to differentiate the uniqueness of its subscription pool. `topic` could be the one that is existed, in this case `deliverfunc` will be invoked as well as [`SUBSCRIBE`][SUBSCRIBE] does.
|
|
190
190
|
|
|
191
191
|
`deliverfunc` supports backpressue.
|
|
192
192
|
|
|
@@ -291,7 +291,7 @@ Please refer to [Connect Return Code](http://docs.oasis-open.org/mqtt/mqtt/v3.1.
|
|
|
291
291
|
|
|
292
292
|
## Handler: authorizePublish (client, packet, callback)
|
|
293
293
|
|
|
294
|
-
- client: [`<Client>`](./Client.md)
|
|
294
|
+
- client: [`<Client>`](./Client.md) | `null`
|
|
295
295
|
- packet: `<object>` [`PUBLISH`][PUBLISH]
|
|
296
296
|
- callback: `<Function>` `(error) => void`
|
|
297
297
|
- error `<Error>` | `null`
|
|
@@ -301,6 +301,8 @@ Invoked when
|
|
|
301
301
|
1. publish LWT to all online clients
|
|
302
302
|
2. incoming client publish
|
|
303
303
|
|
|
304
|
+
`client` is `null` when aedes publishes obsolete LWT without connected clients
|
|
305
|
+
|
|
304
306
|
If invoked `callback` with no errors, server authorizes the packet otherwise emits `clientError` with `error`. If an `error` occurs the client connection will be closed, but no error is returned to the client (MQTT-3.3.5-2)
|
|
305
307
|
|
|
306
308
|
```js
|
|
@@ -337,7 +339,7 @@ function defaultAuthorizePublish (client, packet, callback) {
|
|
|
337
339
|
Invoked when
|
|
338
340
|
|
|
339
341
|
1. restore subscriptions in non-clean session.
|
|
340
|
-
2. incoming client `SUBSCRIBE`
|
|
342
|
+
2. incoming client [`SUBSCRIBE`][SUBSCRIBE]
|
|
341
343
|
|
|
342
344
|
`subscription` is a dictionary object like `{ topic: hello, qos: 0 }`.
|
|
343
345
|
|
package/lib/handlers/connect.js
CHANGED
|
@@ -70,7 +70,7 @@ function init (client, packet, done) {
|
|
|
70
70
|
const error = new Error(errorMessages[returnCode])
|
|
71
71
|
error.errorCode = returnCode
|
|
72
72
|
doConnack(
|
|
73
|
-
{ client
|
|
73
|
+
{ client, returnCode, sessionPresent: false },
|
|
74
74
|
done.bind(this, error))
|
|
75
75
|
return
|
|
76
76
|
}
|
|
@@ -156,8 +156,8 @@ function fetchSubs (arg, done) {
|
|
|
156
156
|
if (!this.packet.clean) {
|
|
157
157
|
client.broker.persistence.subscriptionsByClient({
|
|
158
158
|
id: client.id,
|
|
159
|
-
done
|
|
160
|
-
arg
|
|
159
|
+
done,
|
|
160
|
+
arg
|
|
161
161
|
}, gotSubs)
|
|
162
162
|
return
|
|
163
163
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aedes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"description": "Stream-based MQTT broker",
|
|
5
5
|
"main": "aedes.js",
|
|
6
6
|
"types": "aedes.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"lint": "npm run lint:standard && npm run lint:typescript && npm run lint:markdown",
|
|
9
|
-
"lint:fix": "standard --fix",
|
|
9
|
+
"lint:fix": "standard --fix && eslint -c types/.eslintrc.json --fix aedes.d.ts types/**/*.ts test/types/**/*.test-d.ts",
|
|
10
10
|
"lint:standard": "standard --verbose | snazzy",
|
|
11
11
|
"lint:typescript": "eslint -c types/.eslintrc.json aedes.d.ts types/**/*.ts test/types/**/*.test-d.ts",
|
|
12
12
|
"lint:markdown": "markdownlint docs/*.md README.md",
|
|
@@ -98,37 +98,37 @@
|
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@sinonjs/fake-timers": "^9.1.2",
|
|
101
|
-
"@types/node": "^
|
|
102
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
103
|
-
"@typescript-eslint/parser": "^5.
|
|
101
|
+
"@types/node": "^18.6.1",
|
|
102
|
+
"@typescript-eslint/eslint-plugin": "^5.31.0",
|
|
103
|
+
"@typescript-eslint/parser": "^5.31.0",
|
|
104
104
|
"concat-stream": "^2.0.0",
|
|
105
105
|
"duplexify": "^4.1.2",
|
|
106
106
|
"license-checker": "^25.0.1",
|
|
107
|
-
"markdownlint-cli": "^0.
|
|
107
|
+
"markdownlint-cli": "^0.32.1",
|
|
108
108
|
"mqtt": "^4.3.7",
|
|
109
109
|
"mqtt-connection": "^4.1.0",
|
|
110
110
|
"pre-commit": "^1.2.2",
|
|
111
111
|
"proxyquire": "^2.1.3",
|
|
112
|
-
"release-it": "^
|
|
112
|
+
"release-it": "^15.2.0",
|
|
113
113
|
"snazzy": "^9.0.0",
|
|
114
|
-
"standard": "^
|
|
115
|
-
"tap": "^16.0
|
|
116
|
-
"tsd": "^0.
|
|
117
|
-
"typescript": "^4.
|
|
114
|
+
"standard": "^17.0.0",
|
|
115
|
+
"tap": "^16.3.0",
|
|
116
|
+
"tsd": "^0.23.0",
|
|
117
|
+
"typescript": "^4.7.4",
|
|
118
118
|
"websocket-stream": "^5.5.2"
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
121
121
|
"aedes-packet": "^3.0.0",
|
|
122
|
-
"aedes-persistence": "^9.1.
|
|
122
|
+
"aedes-persistence": "^9.1.2",
|
|
123
123
|
"end-of-stream": "^1.4.4",
|
|
124
124
|
"fastfall": "^1.5.1",
|
|
125
125
|
"fastparallel": "^2.4.1",
|
|
126
126
|
"fastseries": "^2.0.0",
|
|
127
127
|
"hyperid": "^3.0.1",
|
|
128
|
-
"mqemitter": "^
|
|
129
|
-
"mqtt-packet": "^
|
|
128
|
+
"mqemitter": "^5.0.0",
|
|
129
|
+
"mqtt-packet": "^8.1.1",
|
|
130
130
|
"retimer": "^3.0.0",
|
|
131
131
|
"reusify": "^1.0.4",
|
|
132
|
-
"uuid": "^
|
|
132
|
+
"uuid": "^9.0.0"
|
|
133
133
|
}
|
|
134
134
|
}
|
package/test/connect.js
CHANGED
|
@@ -214,13 +214,13 @@ test('client connect clear outgoing', function (t) {
|
|
|
214
214
|
const broker = aedes({ id: brokerId })
|
|
215
215
|
t.teardown(broker.close.bind(broker))
|
|
216
216
|
|
|
217
|
-
const subs = [{ clientId
|
|
217
|
+
const subs = [{ clientId }]
|
|
218
218
|
const packet = {
|
|
219
219
|
cmd: 'publish',
|
|
220
220
|
topic: 'hello',
|
|
221
221
|
payload: Buffer.from('world'),
|
|
222
222
|
qos: 1,
|
|
223
|
-
brokerId
|
|
223
|
+
brokerId,
|
|
224
224
|
brokerCounter: 2,
|
|
225
225
|
retain: true,
|
|
226
226
|
messageId: 42,
|
|
@@ -235,7 +235,7 @@ test('client connect clear outgoing', function (t) {
|
|
|
235
235
|
protocolId: 'MQTT',
|
|
236
236
|
protocolVersion: 4,
|
|
237
237
|
clean: true,
|
|
238
|
-
clientId
|
|
238
|
+
clientId,
|
|
239
239
|
keepalive: 0
|
|
240
240
|
})
|
|
241
241
|
|
|
@@ -705,7 +705,7 @@ test('websocket clients have access to the request object', function (t) {
|
|
|
705
705
|
|
|
706
706
|
const server = http.createServer()
|
|
707
707
|
ws.createServer({
|
|
708
|
-
server
|
|
708
|
+
server
|
|
709
709
|
}, broker.handle)
|
|
710
710
|
|
|
711
711
|
server.listen(port, function (err) {
|
package/test/events.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { test } = require('tap')
|
|
4
|
+
const mqemitter = require('mqemitter')
|
|
4
5
|
const { setup, connect, subscribe } = require('./helper')
|
|
5
6
|
const aedes = require('../')
|
|
6
7
|
|
|
@@ -16,9 +17,49 @@ test('publishes an hearbeat', function (t) {
|
|
|
16
17
|
const id = message.topic.match(/\$SYS\/([^/]+)\/heartbeat/)[1]
|
|
17
18
|
t.equal(id, broker.id, 'broker id matches')
|
|
18
19
|
t.same(message.payload.toString(), id, 'message has id as the payload')
|
|
20
|
+
cb()
|
|
19
21
|
})
|
|
20
22
|
})
|
|
21
23
|
|
|
24
|
+
test('publishes birth', function (t) {
|
|
25
|
+
t.plan(4)
|
|
26
|
+
|
|
27
|
+
const mq = mqemitter()
|
|
28
|
+
const brokerId = 'test-broker'
|
|
29
|
+
const fakeBroker = 'fake-broker'
|
|
30
|
+
const clientId = 'test-client'
|
|
31
|
+
|
|
32
|
+
mq.on(`$SYS/${brokerId}/birth`, (message, cb) => {
|
|
33
|
+
t.pass('broker birth received')
|
|
34
|
+
t.same(message.payload.toString(), brokerId, 'message has id as the payload')
|
|
35
|
+
cb()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const broker = aedes({
|
|
39
|
+
id: brokerId,
|
|
40
|
+
mq
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
broker.on('client', (client) => {
|
|
44
|
+
t.equal(client.id, clientId, 'client connected')
|
|
45
|
+
// set a fake counter on a fake broker
|
|
46
|
+
process.nextTick(() => {
|
|
47
|
+
broker.clients[clientId].duplicates[fakeBroker] = 42
|
|
48
|
+
mq.emit({ topic: `$SYS/${fakeBroker}/birth`, payload: Buffer.from(fakeBroker) })
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
mq.on(`$SYS/${fakeBroker}/birth`, (message, cb) => {
|
|
53
|
+
process.nextTick(() => {
|
|
54
|
+
t.equal(!!broker.clients[clientId].duplicates[fakeBroker], false, 'client duplicates has been resetted')
|
|
55
|
+
cb()
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const s = connect(setup(broker), { clientId })
|
|
60
|
+
t.teardown(s.broker.close.bind(s.broker))
|
|
61
|
+
})
|
|
62
|
+
|
|
22
63
|
;['$mcollina', '$SYS'].forEach(function (topic) {
|
|
23
64
|
test('does not forward $ prefixed topics to # subscription - ' + topic, function (t) {
|
|
24
65
|
t.plan(4)
|
|
@@ -161,7 +202,7 @@ test('Test backpressure aedes published function', function (t) {
|
|
|
161
202
|
|
|
162
203
|
server.listen(0, function () {
|
|
163
204
|
const port = server.address().port
|
|
164
|
-
publisher = mqtt.connect({ port
|
|
205
|
+
publisher = mqtt.connect({ port, host: 'localhost', clean: true, keepalive: 30 })
|
|
165
206
|
|
|
166
207
|
function next () {
|
|
167
208
|
if (--publishCount > 0) { process.nextTick(publish) }
|
package/test/helper.js
CHANGED
|
@@ -19,10 +19,10 @@ function setup (broker) {
|
|
|
19
19
|
|
|
20
20
|
return {
|
|
21
21
|
client: broker.handle(conn),
|
|
22
|
-
conn
|
|
23
|
-
inStream
|
|
24
|
-
outStream
|
|
25
|
-
broker
|
|
22
|
+
conn,
|
|
23
|
+
inStream,
|
|
24
|
+
outStream,
|
|
25
|
+
broker
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -74,8 +74,8 @@ function subscribe (t, subscriber, topic, qos, done) {
|
|
|
74
74
|
cmd: 'subscribe',
|
|
75
75
|
messageId: 24,
|
|
76
76
|
subscriptions: [{
|
|
77
|
-
topic
|
|
78
|
-
qos
|
|
77
|
+
topic,
|
|
78
|
+
qos
|
|
79
79
|
}]
|
|
80
80
|
})
|
|
81
81
|
|
|
@@ -110,10 +110,10 @@ function subscribeMultiple (t, subscriber, subs, expectedGranted, done) {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
module.exports = {
|
|
113
|
-
setup
|
|
114
|
-
connect
|
|
115
|
-
noError
|
|
116
|
-
subscribe
|
|
117
|
-
subscribeMultiple
|
|
113
|
+
setup,
|
|
114
|
+
connect,
|
|
115
|
+
noError,
|
|
116
|
+
subscribe,
|
|
117
|
+
subscribeMultiple,
|
|
118
118
|
delay: util.promisify(setTimeout)
|
|
119
119
|
}
|
package/test/meta.js
CHANGED
package/test/not-blocking.js
CHANGED
|
@@ -42,7 +42,7 @@ test('connect 500 concurrent clients', function (t) {
|
|
|
42
42
|
|
|
43
43
|
for (let i = 0; i < total; i++) {
|
|
44
44
|
clients[i] = mqtt.connect({
|
|
45
|
-
port
|
|
45
|
+
port,
|
|
46
46
|
keepalive: 0,
|
|
47
47
|
reconnectPeriod: 100
|
|
48
48
|
}).on('connect', function () {
|
|
@@ -79,7 +79,7 @@ test('do not block after a subscription', function (t) {
|
|
|
79
79
|
const port = server.address().port
|
|
80
80
|
|
|
81
81
|
const publisher = mqtt.connect({
|
|
82
|
-
port
|
|
82
|
+
port,
|
|
83
83
|
keepalive: 0
|
|
84
84
|
}).on('error', function (err) {
|
|
85
85
|
clock.clearTimeout(clockId)
|
|
@@ -103,7 +103,7 @@ test('do not block after a subscription', function (t) {
|
|
|
103
103
|
|
|
104
104
|
function startSubscriber () {
|
|
105
105
|
subscriber = mqtt.connect({
|
|
106
|
-
port
|
|
106
|
+
port,
|
|
107
107
|
keepalive: 0
|
|
108
108
|
}).on('error', function (err) {
|
|
109
109
|
clock.clearTimeout(clockId)
|
|
@@ -163,7 +163,7 @@ test('do not block with overlapping subscription', function (t) {
|
|
|
163
163
|
const port = server.address().port
|
|
164
164
|
|
|
165
165
|
const publisher = mqtt.connect({
|
|
166
|
-
port
|
|
166
|
+
port,
|
|
167
167
|
keepalive: 0
|
|
168
168
|
}).on('error', function (err) {
|
|
169
169
|
clock.clearTimeout(clockId)
|
|
@@ -187,7 +187,7 @@ test('do not block with overlapping subscription', function (t) {
|
|
|
187
187
|
|
|
188
188
|
function startSubscriber () {
|
|
189
189
|
subscriber = mqtt.connect({
|
|
190
|
-
port
|
|
190
|
+
port,
|
|
191
191
|
keepalive: 0
|
|
192
192
|
}).on('error', function (err) {
|
|
193
193
|
clock.clearTimeout(clockId)
|
package/test/retain.js
CHANGED
|
@@ -275,7 +275,7 @@ test('new QoS 0 subscribers receive QoS 0 retained messages when clean', functio
|
|
|
275
275
|
})
|
|
276
276
|
|
|
277
277
|
clock.setTimeout(() => {
|
|
278
|
-
t.equal(broker.counter,
|
|
278
|
+
t.equal(broker.counter, 9)
|
|
279
279
|
}, 200)
|
|
280
280
|
})
|
|
281
281
|
|
|
@@ -315,7 +315,7 @@ test('new QoS 0 subscribers receive downgraded QoS 1 retained messages when clea
|
|
|
315
315
|
})
|
|
316
316
|
})
|
|
317
317
|
broker.on('closed', function () {
|
|
318
|
-
t.equal(broker.counter,
|
|
318
|
+
t.equal(broker.counter, 8)
|
|
319
319
|
})
|
|
320
320
|
})
|
|
321
321
|
|
package/test/topics.js
CHANGED
|
@@ -108,7 +108,7 @@ test('publish invalid topic with +', function (t) {
|
|
|
108
108
|
cmd: 'subscribe',
|
|
109
109
|
messageId: 24,
|
|
110
110
|
subscriptions: [{
|
|
111
|
-
topic
|
|
111
|
+
topic,
|
|
112
112
|
qos: 0
|
|
113
113
|
}]
|
|
114
114
|
})
|
|
@@ -157,7 +157,7 @@ test('topics are case-sensitive', function (t) {
|
|
|
157
157
|
;['hello', 'HELLO', 'heLLo', 'HELLO/#', 'hello/+'].forEach(function (topic) {
|
|
158
158
|
publisher.inStream.write({
|
|
159
159
|
cmd: 'publish',
|
|
160
|
-
topic
|
|
160
|
+
topic,
|
|
161
161
|
payload: 'world',
|
|
162
162
|
qos: 0,
|
|
163
163
|
retain: false
|
|
@@ -171,7 +171,7 @@ function subscribeMultipleTopics (t, broker, qos, subscriber, subscriptions, don
|
|
|
171
171
|
subscriber.inStream.write({
|
|
172
172
|
cmd: 'subscribe',
|
|
173
173
|
messageId: 24,
|
|
174
|
-
subscriptions
|
|
174
|
+
subscriptions
|
|
175
175
|
})
|
|
176
176
|
|
|
177
177
|
subscriber.outStream.once('data', function (packet) {
|
|
@@ -183,7 +183,7 @@ function subscribeMultipleTopics (t, broker, qos, subscriber, subscriptions, don
|
|
|
183
183
|
cmd: 'publish',
|
|
184
184
|
topic: 'hello/world',
|
|
185
185
|
payload: 'world',
|
|
186
|
-
qos
|
|
186
|
+
qos,
|
|
187
187
|
messageId: 42
|
|
188
188
|
})
|
|
189
189
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
/// <reference path="../../aedes.d.ts" />
|
|
2
|
+
|
|
3
|
+
import type { AedesPublishPacket, ConnackPacket, ConnectPacket, PingreqPacket, PublishPacket, PubrelPacket, SubscribePacket, Subscription, UnsubscribePacket } from 'aedes:packet'
|
|
4
|
+
import type { AuthenticateError, Brokers, Connection } from 'aedes:server'
|
|
5
|
+
import Server, { Aedes } from 'aedes:server'
|
|
6
|
+
|
|
7
|
+
import { IncomingMessage } from 'node:http'
|
|
8
|
+
import type { Client } from 'aedes:client'
|
|
9
|
+
import { Socket } from 'node:net'
|
|
1
10
|
import { expectType } from 'tsd'
|
|
2
|
-
import { Socket } from 'net'
|
|
3
|
-
import type {
|
|
4
|
-
Aedes,
|
|
5
|
-
Brokers,
|
|
6
|
-
AuthenticateError,
|
|
7
|
-
Client,
|
|
8
|
-
Connection
|
|
9
|
-
} from '../../aedes'
|
|
10
|
-
import { Server } from '../../aedes'
|
|
11
|
-
import type { AedesPublishPacket, ConnackPacket, ConnectPacket, PingreqPacket, PublishPacket, PubrelPacket, Subscription, SubscribePacket, UnsubscribePacket } from '../../types/packet'
|
|
12
11
|
|
|
13
12
|
// Aedes server
|
|
14
|
-
|
|
13
|
+
let broker = new Server()
|
|
14
|
+
expectType<Aedes>(broker)
|
|
15
|
+
|
|
16
|
+
broker = new Aedes({
|
|
15
17
|
id: 'aedes',
|
|
16
18
|
concurrency: 100,
|
|
17
19
|
heartbeatInterval: 60000,
|
|
@@ -37,7 +39,7 @@ const broker = Server({
|
|
|
37
39
|
callback(error, false)
|
|
38
40
|
}
|
|
39
41
|
},
|
|
40
|
-
authorizePublish: (client: Client, packet: PublishPacket, callback) => {
|
|
42
|
+
authorizePublish: (client: Client | null, packet: PublishPacket, callback) => {
|
|
41
43
|
if (packet.topic === 'aaaa') {
|
|
42
44
|
return callback(new Error('wrong topic'))
|
|
43
45
|
}
|
|
@@ -93,7 +95,7 @@ expectType<Aedes>(broker.on('clientError', (client: Client, error: Error) => {})
|
|
|
93
95
|
expectType<Aedes>(broker.on('connectionError', (client: Client, error: Error) => {}))
|
|
94
96
|
expectType<Aedes>(broker.on('connackSent', (packet: ConnackPacket, client: Client) => {}))
|
|
95
97
|
expectType<Aedes>(broker.on('ping', (packet: PingreqPacket, client: Client) => {}))
|
|
96
|
-
expectType<Aedes>(broker.on('publish', (packet: AedesPublishPacket, client: Client) => {}))
|
|
98
|
+
expectType<Aedes>(broker.on('publish', (packet: AedesPublishPacket, client: Client | null) => {}))
|
|
97
99
|
expectType<Aedes>(broker.on('ack', (packet: PublishPacket | PubrelPacket, client: Client) => {}))
|
|
98
100
|
expectType<Aedes>(broker.on('subscribe', (subscriptions: Subscription[], client: Client) => {}))
|
|
99
101
|
expectType<Aedes>(broker.on('unsubscribe', (unsubscriptions: string[], client: Client) => {}))
|
|
@@ -123,11 +125,12 @@ expectType<void>(broker.close())
|
|
|
123
125
|
expectType<void>(broker.close(() => {}))
|
|
124
126
|
|
|
125
127
|
// Aedes client
|
|
126
|
-
const client = broker.handle({} as Connection)
|
|
128
|
+
const client = broker.handle({} as Connection, {} as IncomingMessage)
|
|
127
129
|
|
|
128
130
|
expectType<Client>(client)
|
|
129
131
|
|
|
130
132
|
expectType<Connection>(client.conn)
|
|
133
|
+
expectType<IncomingMessage>(client.req!)
|
|
131
134
|
|
|
132
135
|
expectType<Client>(client.on('connected', () => {}))
|
|
133
136
|
expectType<Client>(client.on('error', (error: Error) => {
|
package/test/will.js
CHANGED
|
@@ -58,8 +58,11 @@ test('calling close two times should not deliver two wills', function (t) {
|
|
|
58
58
|
willConnect(setup(broker), opts)
|
|
59
59
|
|
|
60
60
|
function onWill (packet, cb) {
|
|
61
|
-
broker.mq.removeListener('mywill', onWill)
|
|
62
|
-
|
|
61
|
+
broker.mq.removeListener('mywill', onWill, function () {
|
|
62
|
+
broker.mq.on('mywill', function (packet) {
|
|
63
|
+
t.fail('the will must be delivered only once')
|
|
64
|
+
})
|
|
65
|
+
})
|
|
63
66
|
t.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
64
67
|
t.same(packet.payload, opts.will.payload, 'payload matches')
|
|
65
68
|
t.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
@@ -69,7 +72,7 @@ test('calling close two times should not deliver two wills', function (t) {
|
|
|
69
72
|
})
|
|
70
73
|
|
|
71
74
|
test('delivers old will in case of a crash', function (t) {
|
|
72
|
-
t.plan(
|
|
75
|
+
t.plan(8)
|
|
73
76
|
|
|
74
77
|
const persistence = memory()
|
|
75
78
|
const will = {
|
|
@@ -88,10 +91,16 @@ test('delivers old will in case of a crash', function (t) {
|
|
|
88
91
|
}, will, function (err) {
|
|
89
92
|
t.error(err, 'no error')
|
|
90
93
|
|
|
94
|
+
let authorized = false
|
|
91
95
|
const interval = 10 // ms, so that the will check happens fast!
|
|
92
96
|
const broker = aedes({
|
|
93
|
-
persistence
|
|
94
|
-
heartbeatInterval: interval
|
|
97
|
+
persistence,
|
|
98
|
+
heartbeatInterval: interval,
|
|
99
|
+
authorizePublish: function (client, packet, callback) {
|
|
100
|
+
t.strictSame(client, null, 'client must be null')
|
|
101
|
+
authorized = true
|
|
102
|
+
callback(null)
|
|
103
|
+
}
|
|
95
104
|
})
|
|
96
105
|
t.teardown(broker.close.bind(broker))
|
|
97
106
|
|
|
@@ -100,15 +109,58 @@ test('delivers old will in case of a crash', function (t) {
|
|
|
100
109
|
broker.mq.on('mywill', check)
|
|
101
110
|
|
|
102
111
|
function check (packet, cb) {
|
|
103
|
-
broker.mq.removeListener('mywill', check)
|
|
112
|
+
broker.mq.removeListener('mywill', check, function () {
|
|
113
|
+
broker.mq.on('mywill', function (packet) {
|
|
114
|
+
t.fail('the will must be delivered only once')
|
|
115
|
+
})
|
|
116
|
+
})
|
|
104
117
|
t.ok(Date.now() - start >= 3 * interval, 'the will needs to be emitted after 3 heartbeats')
|
|
105
118
|
t.equal(packet.topic, will.topic, 'topic matches')
|
|
106
119
|
t.same(packet.payload, will.payload, 'payload matches')
|
|
107
120
|
t.equal(packet.qos, will.qos, 'qos matches')
|
|
108
121
|
t.equal(packet.retain, will.retain, 'retain matches')
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
t.equal(authorized, true, 'authorization called')
|
|
123
|
+
cb()
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
test('deliver old will without authorization in case of a crash', function (t) {
|
|
129
|
+
t.plan(2)
|
|
130
|
+
|
|
131
|
+
const persistence = memory()
|
|
132
|
+
const will = {
|
|
133
|
+
topic: 'mywill',
|
|
134
|
+
payload: Buffer.from('last will'),
|
|
135
|
+
qos: 0,
|
|
136
|
+
retain: false
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
persistence.broker = {
|
|
140
|
+
id: 'anotherBroker'
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
persistence.putWill({
|
|
144
|
+
id: 'myClientId42'
|
|
145
|
+
}, will, function (err) {
|
|
146
|
+
t.error(err, 'no error')
|
|
147
|
+
|
|
148
|
+
const interval = 10 // ms, so that the will check happens fast!
|
|
149
|
+
const broker = aedes({
|
|
150
|
+
persistence,
|
|
151
|
+
heartbeatInterval: interval,
|
|
152
|
+
authorizePublish: function (client, packet, callback) {
|
|
153
|
+
t.strictSame(client, null, 'client must be null')
|
|
154
|
+
callback(new Error())
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
t.teardown(broker.close.bind(broker))
|
|
159
|
+
|
|
160
|
+
broker.mq.on('mywill', check)
|
|
161
|
+
|
|
162
|
+
function check (packet, cb) {
|
|
163
|
+
t.fail('received will without authorization')
|
|
112
164
|
cb()
|
|
113
165
|
}
|
|
114
166
|
})
|
|
@@ -121,7 +173,7 @@ test('delete old broker', function (t) {
|
|
|
121
173
|
|
|
122
174
|
const heartbeatInterval = 100
|
|
123
175
|
const broker = aedes({
|
|
124
|
-
heartbeatInterval
|
|
176
|
+
heartbeatInterval
|
|
125
177
|
})
|
|
126
178
|
t.teardown(broker.close.bind(broker))
|
|
127
179
|
|
|
@@ -185,8 +237,7 @@ test('delete the will in the persistence after publish', function (t) {
|
|
|
185
237
|
willConnect(setup(broker), opts)
|
|
186
238
|
|
|
187
239
|
function check (packet, cb) {
|
|
188
|
-
broker.mq.removeListener('mywill', check)
|
|
189
|
-
setImmediate(function () {
|
|
240
|
+
broker.mq.removeListener('mywill', check, function () {
|
|
190
241
|
broker.persistence.getWill({
|
|
191
242
|
id: opts.clientId
|
|
192
243
|
}, function (err, p) {
|
|
@@ -421,7 +472,7 @@ test('don\'t delivers a will if broker alive', function (t) {
|
|
|
421
472
|
t.error(err, 'no error')
|
|
422
473
|
|
|
423
474
|
const opts = {
|
|
424
|
-
persistence
|
|
475
|
+
persistence,
|
|
425
476
|
heartbeatInterval: 10
|
|
426
477
|
}
|
|
427
478
|
|
|
@@ -472,7 +523,7 @@ test('handle will publish error', function (t) {
|
|
|
472
523
|
t.error(err, 'no error')
|
|
473
524
|
|
|
474
525
|
const opts = {
|
|
475
|
-
persistence
|
|
526
|
+
persistence,
|
|
476
527
|
heartbeatInterval: 10
|
|
477
528
|
}
|
|
478
529
|
|
|
@@ -509,7 +560,7 @@ test('handle will publish error 2', function (t) {
|
|
|
509
560
|
t.error(err, 'no error')
|
|
510
561
|
|
|
511
562
|
const opts = {
|
|
512
|
-
persistence
|
|
563
|
+
persistence,
|
|
513
564
|
heartbeatInterval: 10
|
|
514
565
|
}
|
|
515
566
|
|
package/types/.eslintrc.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": [
|
|
3
3
|
"eslint:recommended",
|
|
4
|
-
"plugin:@typescript-eslint/eslint-recommended",
|
|
5
4
|
"plugin:@typescript-eslint/recommended",
|
|
6
5
|
"standard"
|
|
7
6
|
],
|
|
@@ -15,16 +14,19 @@
|
|
|
15
14
|
"createDefaultProgram": true
|
|
16
15
|
},
|
|
17
16
|
"rules": {
|
|
17
|
+
"linebreak-style": ["warn", "unix"],
|
|
18
18
|
"no-console": "off",
|
|
19
|
-
"@typescript-eslint/indent": ["error", 2],
|
|
20
19
|
"semi": ["error", "never"],
|
|
21
|
-
"import/export": "off" // this errors on multiple exports (overload interfaces)
|
|
20
|
+
"import/export": "off", // this errors on multiple exports (overload interfaces)
|
|
21
|
+
"@typescript-eslint/indent": ["error", 2]
|
|
22
22
|
},
|
|
23
23
|
"overrides": [
|
|
24
24
|
{
|
|
25
|
-
"files": ["*.d.ts","*.test-d.ts"],
|
|
25
|
+
"files": ["*.d.ts", "*.test-d.ts"],
|
|
26
26
|
"rules": {
|
|
27
|
-
"
|
|
27
|
+
"no-dupe-class-members": "off",
|
|
28
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
29
|
+
"@typescript-eslint/triple-slash-reference": "off"
|
|
28
30
|
}
|
|
29
31
|
},
|
|
30
32
|
{
|
package/types/client.d.ts
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
declare module 'client' {
|
|
2
|
+
import { IncomingMessage } from 'node:http'
|
|
3
|
+
import { PublishPacket, SubscribePacket, Subscription, Subscriptions, UnsubscribePacket } from 'aedes:packet'
|
|
4
|
+
import { Connection } from 'aedes:server'
|
|
5
|
+
import { EventEmitter } from 'node:events'
|
|
5
6
|
|
|
6
|
-
export interface Client extends EventEmitter {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
export interface Client extends EventEmitter {
|
|
8
|
+
id: Readonly<string>
|
|
9
|
+
clean: Readonly<boolean>
|
|
10
|
+
version: Readonly<number>
|
|
11
|
+
conn: Connection
|
|
12
|
+
req?: IncomingMessage
|
|
13
|
+
connecting: Readonly<boolean>
|
|
14
|
+
connected: Readonly<boolean>
|
|
15
|
+
closed: Readonly<boolean>
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
on (event: 'connected', listener: () => void): this
|
|
18
|
+
on (event: 'error', listener: (error: Error) => void): this
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
publish (message: PublishPacket, callback?: (error?: Error) => void): void
|
|
21
|
+
subscribe (
|
|
22
|
+
subscriptions: Subscriptions | Subscription | Subscription[] | SubscribePacket,
|
|
23
|
+
callback?: (error?: Error) => void
|
|
24
|
+
): void
|
|
25
|
+
unsubscribe (topicObjects: Subscriptions | Subscription | Subscription[] | UnsubscribePacket, callback?: (error?: Error) => void): void
|
|
26
|
+
close (callback?: () => void): void
|
|
27
|
+
emptyOutgoingQueue (callback?: () => void): void
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
declare module 'aedes:client' {
|
|
31
|
+
export * from 'client'
|
|
27
32
|
}
|
package/types/instance.d.ts
CHANGED
|
@@ -1,100 +1,101 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
type
|
|
27
|
-
|
|
28
|
-
type
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
type
|
|
38
|
-
|
|
39
|
-
type
|
|
40
|
-
|
|
41
|
-
type
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
declare module 'aedes' {
|
|
2
|
+
import { Duplex } from 'node:stream'
|
|
3
|
+
import { Socket } from 'node:net'
|
|
4
|
+
import { IncomingMessage } from 'http'
|
|
5
|
+
import { Client } from 'aedes:client'
|
|
6
|
+
import type { AedesPublishPacket, ConnectPacket, ConnackPacket, Subscription, PingreqPacket, PublishPacket, PubrelPacket } from 'aedes:packet'
|
|
7
|
+
import { EventEmitter } from 'node:events'
|
|
8
|
+
|
|
9
|
+
type LastHearthbeatTimestamp = Date;
|
|
10
|
+
|
|
11
|
+
export interface Brokers {
|
|
12
|
+
[brokerId: string]: LastHearthbeatTimestamp;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type Connection = Duplex | Socket
|
|
16
|
+
|
|
17
|
+
/* eslint no-unused-vars: 0 */
|
|
18
|
+
export const enum AuthErrorCode {
|
|
19
|
+
UNNACCEPTABLE_PROTOCOL = 1,
|
|
20
|
+
IDENTIFIER_REJECTED = 2,
|
|
21
|
+
SERVER_UNAVAILABLE = 3,
|
|
22
|
+
BAD_USERNAME_OR_PASSWORD = 4,
|
|
23
|
+
NOT_AUTHORIZED = 5
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type AuthenticateError = Error & { returnCode: AuthErrorCode }
|
|
27
|
+
|
|
28
|
+
type PreConnectHandler = (client: Client, packet: ConnectPacket, callback: (error: Error | null, success: boolean) => void) => void
|
|
29
|
+
|
|
30
|
+
type AuthenticateHandler = (
|
|
31
|
+
client: Client,
|
|
32
|
+
username: Readonly<string>,
|
|
33
|
+
password: Readonly<Buffer>,
|
|
34
|
+
done: (error: AuthenticateError | null, success: boolean | null) => void
|
|
35
|
+
) => void
|
|
36
|
+
|
|
37
|
+
type AuthorizePublishHandler = (client: Client | null, packet: PublishPacket, callback: (error?: Error | null) => void) => void
|
|
38
|
+
|
|
39
|
+
type AuthorizeSubscribeHandler = (client: Client, subscription: Subscription, callback: (error: Error | null, subscription?: Subscription | null) => void) => void
|
|
40
|
+
|
|
41
|
+
type AuthorizeForwardHandler = (client: Client, packet: AedesPublishPacket) => AedesPublishPacket | null | void
|
|
42
|
+
|
|
43
|
+
type PublishedHandler = (packet: AedesPublishPacket, client: Client, callback: (error?: Error | null) => void) => void
|
|
44
|
+
|
|
45
|
+
export interface AedesOptions {
|
|
46
|
+
mq?: any
|
|
47
|
+
id?: string
|
|
48
|
+
persistence?: any
|
|
49
|
+
concurrency?: number
|
|
50
|
+
heartbeatInterval?: number
|
|
51
|
+
connectTimeout?: number
|
|
52
|
+
queueLimit?: number
|
|
53
|
+
maxClientsIdLength?: number
|
|
54
|
+
preConnect?: PreConnectHandler
|
|
55
|
+
authenticate?: AuthenticateHandler
|
|
56
|
+
authorizePublish?: AuthorizePublishHandler
|
|
57
|
+
authorizeSubscribe?: AuthorizeSubscribeHandler
|
|
58
|
+
authorizeForward?: AuthorizeForwardHandler
|
|
59
|
+
published?: PublishedHandler
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default class Aedes extends EventEmitter {
|
|
63
|
+
id: Readonly<string>
|
|
64
|
+
connectedClients: Readonly<number>
|
|
65
|
+
closed: Readonly<boolean>
|
|
66
|
+
brokers: Readonly<Brokers>
|
|
67
|
+
|
|
68
|
+
constructor(option?: AedesOptions)
|
|
69
|
+
handle: (stream: Connection, request: IncomingMessage) => Client
|
|
70
|
+
|
|
71
|
+
on (event: 'closed', listener: () => void): this
|
|
72
|
+
on (event: 'client' | 'clientReady' | 'clientDisconnect' | 'keepaliveTimeout', listener: (client: Client) => void): this
|
|
73
|
+
on (event: 'clientError' | 'connectionError', listener: (client: Client, error: Error) => void): this
|
|
74
|
+
on (event: 'connackSent', listener: (packet: ConnackPacket, client: Client) => void): this
|
|
75
|
+
on (event: 'ping', listener: (packet: PingreqPacket, client: Client) => void): this
|
|
76
|
+
on (event: 'publish', listener: (packet: AedesPublishPacket, client: Client | null) => void): this
|
|
77
|
+
on (event: 'ack', listener: (packet: PublishPacket | PubrelPacket, client: Client) => void): this
|
|
78
|
+
on (event: 'subscribe', listener: (subscriptions: Subscription[], client: Client) => void): this
|
|
79
|
+
on (event: 'unsubscribe', listener: (unsubscriptions: string[], client: Client) => void): this
|
|
80
|
+
|
|
81
|
+
publish (packet: PublishPacket, callback: (error?: Error) => void): void
|
|
82
|
+
subscribe (topic: string, deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void, callback: () => void): void
|
|
83
|
+
unsubscribe (topic: string, deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void, callback: () => void): void
|
|
84
|
+
close (callback?: () => void): void
|
|
85
|
+
|
|
86
|
+
preConnect: PreConnectHandler
|
|
87
|
+
authenticate: AuthenticateHandler
|
|
88
|
+
authorizePublish: AuthorizePublishHandler
|
|
89
|
+
authorizeSubscribe: AuthorizeSubscribeHandler
|
|
90
|
+
authorizeForward: AuthorizeForwardHandler
|
|
91
|
+
published: PublishedHandler
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { Aedes }
|
|
95
|
+
// export function createServer(options?: AedesOptions): Aedes
|
|
58
96
|
}
|
|
59
97
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
closed: Readonly<boolean>
|
|
64
|
-
brokers: Readonly<Brokers>
|
|
65
|
-
|
|
66
|
-
handle: (stream: Connection) => Client
|
|
67
|
-
|
|
68
|
-
on (event: 'closed', listener: () => void): this
|
|
69
|
-
on (event: 'client' | 'clientReady' | 'clientDisconnect' | 'keepaliveTimeout', listener: (client: Client) => void): this
|
|
70
|
-
on (event: 'clientError' | 'connectionError', listener: (client: Client, error: Error) => void): this
|
|
71
|
-
on (event: 'connackSent', listener: (packet: ConnackPacket, client: Client) => void): this
|
|
72
|
-
on (event: 'ping', listener: (packet: PingreqPacket, client: Client) => void): this
|
|
73
|
-
on (event: 'publish', listener: (packet: AedesPublishPacket, client: Client) => void): this
|
|
74
|
-
on (event: 'ack', listener: (packet: PublishPacket | PubrelPacket, client: Client) => void): this
|
|
75
|
-
on (event: 'subscribe', listener: (subscriptions: Subscription[], client: Client) => void): this
|
|
76
|
-
on (event: 'unsubscribe', listener: (unsubscriptions: string[], client: Client) => void): this
|
|
77
|
-
|
|
78
|
-
publish (
|
|
79
|
-
packet: PublishPacket,
|
|
80
|
-
callback: (error?: Error) => void
|
|
81
|
-
): void
|
|
82
|
-
subscribe (
|
|
83
|
-
topic: string,
|
|
84
|
-
deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void,
|
|
85
|
-
callback: () => void
|
|
86
|
-
): void
|
|
87
|
-
unsubscribe (
|
|
88
|
-
topic: string,
|
|
89
|
-
deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void,
|
|
90
|
-
callback: () => void
|
|
91
|
-
): void
|
|
92
|
-
close (callback?: () => void): void
|
|
93
|
-
|
|
94
|
-
preConnect: PreConnectHandler
|
|
95
|
-
authenticate: AuthenticateHandler
|
|
96
|
-
authorizePublish: AuthorizePublishHandler
|
|
97
|
-
authorizeSubscribe: AuthorizeSubscribeHandler
|
|
98
|
-
authorizeForward: AuthorizeForwardHandler
|
|
99
|
-
published: PublishedHandler
|
|
98
|
+
declare module 'aedes:server' {
|
|
99
|
+
export * from 'aedes'
|
|
100
|
+
export { default } from 'aedes'
|
|
100
101
|
}
|
package/types/packet.d.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
declare module 'packet' {
|
|
2
|
+
import { AedesPacket } from 'aedes-packet'
|
|
3
|
+
import { IConnackPacket, IConnectPacket, IPingreqPacket, IPublishPacket, IPubrelPacket, ISubscribePacket, ISubscription, IUnsubscribePacket } from 'mqtt-packet'
|
|
4
|
+
import { Client } from 'aedes:client'
|
|
4
5
|
|
|
5
|
-
export type SubscribePacket = ISubscribePacket & { cmd: 'subscribe' }
|
|
6
|
-
export type UnsubscribePacket = IUnsubscribePacket & { cmd: 'unsubscribe' }
|
|
7
|
-
export type Subscription = ISubscription & { clientId?: Client['id'] }
|
|
8
|
-
export type Subscriptions = { subscriptions: Subscription[] }
|
|
6
|
+
export type SubscribePacket = ISubscribePacket & { cmd: 'subscribe' }
|
|
7
|
+
export type UnsubscribePacket = IUnsubscribePacket & { cmd: 'unsubscribe' }
|
|
8
|
+
export type Subscription = ISubscription & { clientId?: Client['id'] }
|
|
9
|
+
export type Subscriptions = { subscriptions: Subscription[] }
|
|
9
10
|
|
|
10
|
-
export type PublishPacket = IPublishPacket & { cmd: 'publish' }
|
|
11
|
+
export type PublishPacket = IPublishPacket & { cmd: 'publish' }
|
|
11
12
|
|
|
12
|
-
export type ConnectPacket = IConnectPacket & { cmd: 'connect' }
|
|
13
|
-
export type ConnackPacket = IConnackPacket & { cmd: 'connack' }
|
|
13
|
+
export type ConnectPacket = IConnectPacket & { cmd: 'connect' }
|
|
14
|
+
export type ConnackPacket = IConnackPacket & { cmd: 'connack' }
|
|
14
15
|
|
|
15
|
-
export type PubrelPacket = IPubrelPacket & { cmd: 'pubrel' }
|
|
16
|
-
export type PingreqPacket = IPingreqPacket & { cmd: 'pingreq' }
|
|
16
|
+
export type PubrelPacket = IPubrelPacket & { cmd: 'pubrel' }
|
|
17
|
+
export type PingreqPacket = IPingreqPacket & { cmd: 'pingreq' }
|
|
17
18
|
|
|
18
|
-
export type AedesPublishPacket = PublishPacket & AedesPacket
|
|
19
|
+
export type AedesPublishPacket = PublishPacket & AedesPacket
|
|
20
|
+
}
|
|
21
|
+
declare module 'aedes:packet' {
|
|
22
|
+
export * from 'packet'
|
|
23
|
+
}
|
package/types/tsconfig.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"module": "commonjs",
|
|
4
3
|
"target": "es6",
|
|
4
|
+
"module": "commonjs",
|
|
5
5
|
"noEmit": true,
|
|
6
|
-
"strict": true
|
|
6
|
+
"strict": true,
|
|
7
|
+
"removeComments": true,
|
|
8
|
+
"typeRoots" : ["../types", "../node_modules/@types/"]
|
|
7
9
|
},
|
|
8
10
|
"include": [
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
+
"./test/types/*.test-d.ts",
|
|
12
|
+
"./types/*.d.ts",
|
|
11
13
|
"aedes.d.ts"
|
|
12
14
|
]
|
|
13
15
|
}
|