aedes 0.48.0 → 0.49.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/.coveralls.yml +0 -0
- package/.gitattributes +0 -0
- package/.github/dependabot.yml +0 -0
- package/.github/labeler.yml +0 -0
- package/.github/workflows/ci.yml +0 -0
- package/.github/workflows/labeler.yml +0 -0
- package/.github/workflows/sast.yml +0 -0
- package/.taprc +0 -0
- package/CODE_OF_CONDUCT.md +0 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/SECURITY.md +0 -0
- package/aedes.d.ts +8 -3
- package/aedes.js +1 -1
- package/benchmarks/server.js +0 -0
- package/docs/Aedes.md +0 -0
- package/docs/Client.md +0 -0
- package/docs/Examples.md +16 -0
- package/example.js +0 -0
- package/examples/clusters/index.js +30 -18
- package/examples/clusters/package.json +5 -3
- package/lib/client.js +0 -0
- package/lib/handlers/connect.js +0 -0
- package/lib/handlers/index.js +0 -0
- package/lib/handlers/ping.js +0 -0
- package/lib/handlers/puback.js +0 -0
- package/lib/handlers/publish.js +0 -0
- package/lib/handlers/pubrec.js +0 -0
- package/lib/handlers/pubrel.js +0 -0
- package/lib/handlers/subscribe.js +0 -0
- package/lib/handlers/unsubscribe.js +0 -0
- package/lib/qos-packet.js +0 -0
- package/lib/utils.js +5 -3
- package/lib/write.js +0 -0
- package/package.json +12 -12
- package/test/auth.js +0 -0
- package/test/basic.js +2 -2
- package/test/bridge.js +0 -0
- package/test/client-pub-sub.js +0 -0
- package/test/close_socket_by_other_party.js +0 -0
- package/test/connect.js +0 -0
- package/test/events.js +0 -0
- package/test/helper.js +0 -0
- package/test/keep-alive.js +0 -0
- package/test/meta.js +0 -0
- package/test/not-blocking.js +0 -0
- package/test/qos1.js +0 -0
- package/test/qos2.js +0 -0
- package/test/regr-21.js +0 -0
- package/test/retain.js +0 -0
- package/test/topics.js +8 -0
- package/test/types/aedes.test-d.ts +107 -57
- package/test/will.js +0 -0
- package/types/.eslintrc.json +0 -0
- package/types/client.d.ts +40 -28
- package/types/instance.d.ts +156 -98
- package/types/packet.d.ts +22 -18
- package/types/tsconfig.json +4 -4
package/.coveralls.yml
CHANGED
|
File without changes
|
package/.gitattributes
CHANGED
|
File without changes
|
package/.github/dependabot.yml
CHANGED
|
File without changes
|
package/.github/labeler.yml
CHANGED
|
File without changes
|
package/.github/workflows/ci.yml
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/.taprc
CHANGED
|
File without changes
|
package/CODE_OF_CONDUCT.md
CHANGED
|
File without changes
|
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
File without changes
|
package/SECURITY.md
CHANGED
|
File without changes
|
package/aedes.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import Aedes, { AedesOptions } from './types/instance'
|
|
2
|
+
|
|
3
|
+
export declare function createBroker (options?: AedesOptions): Aedes
|
|
4
|
+
|
|
5
|
+
export * from './types/instance'
|
|
6
|
+
export * from './types/packet'
|
|
7
|
+
export * from './types/client'
|
|
8
|
+
export default Aedes
|
package/aedes.js
CHANGED
|
@@ -13,7 +13,7 @@ const mqemitter = require('mqemitter')
|
|
|
13
13
|
const Client = require('./lib/client')
|
|
14
14
|
const { $SYS_PREFIX, bulk } = require('./lib/utils')
|
|
15
15
|
|
|
16
|
-
module.exports = Aedes.
|
|
16
|
+
module.exports = Aedes.createBroker = Aedes
|
|
17
17
|
|
|
18
18
|
const defaultOptions = {
|
|
19
19
|
concurrency: 100,
|
package/benchmarks/server.js
CHANGED
|
File without changes
|
package/docs/Aedes.md
CHANGED
|
File without changes
|
package/docs/Client.md
CHANGED
|
File without changes
|
package/docs/Examples.md
CHANGED
|
@@ -13,6 +13,22 @@ server.listen(port, function () {
|
|
|
13
13
|
})
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
## Typescript
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import Aedes from 'aedes'
|
|
20
|
+
import { createServer } from 'net'
|
|
21
|
+
|
|
22
|
+
const port = 1883
|
|
23
|
+
|
|
24
|
+
const aedes = new Aedes()
|
|
25
|
+
const server = createServer(aedes.handle)
|
|
26
|
+
|
|
27
|
+
server.listen(port, function () {
|
|
28
|
+
console.log('server started and listening on port ', port)
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
16
32
|
## Simple plain MQTT server using server-factory
|
|
17
33
|
|
|
18
34
|
```js
|
package/example.js
CHANGED
|
File without changes
|
|
@@ -1,34 +1,46 @@
|
|
|
1
1
|
const cluster = require('cluster')
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
|
|
2
|
+
const Aedes = require('aedes')
|
|
3
|
+
const { createServer } = require('net')
|
|
4
|
+
const { cpus } = require('os')
|
|
5
5
|
const MONGO_URL = 'mongodb://127.0.0.1/aedes-clusters'
|
|
6
6
|
|
|
7
|
+
const mq = process.env.MQ === 'redis'
|
|
8
|
+
? require('mqemitter-redis')({
|
|
9
|
+
port: process.env.REDIS_PORT || 6379
|
|
10
|
+
})
|
|
11
|
+
: require('mqemitter-mongodb')({
|
|
12
|
+
url: MONGO_URL
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const persistence = process.env.PERSISTENCE === 'redis'
|
|
16
|
+
? require('aedes-persistence-redis')({
|
|
17
|
+
port: process.env.REDIS_PORT || 6379
|
|
18
|
+
})
|
|
19
|
+
: require('aedes-persistence-mongodb')({
|
|
20
|
+
url: MONGO_URL
|
|
21
|
+
})
|
|
22
|
+
|
|
7
23
|
function startAedes () {
|
|
8
24
|
const port = 1883
|
|
9
25
|
|
|
10
|
-
const aedes =
|
|
26
|
+
const aedes = Aedes({
|
|
11
27
|
id: 'BROKER_' + cluster.worker.id,
|
|
12
|
-
mq
|
|
13
|
-
|
|
14
|
-
}),
|
|
15
|
-
persistence: mongoPersistence({
|
|
16
|
-
url: MONGO_URL,
|
|
17
|
-
// Optional ttl settings
|
|
18
|
-
ttl: {
|
|
19
|
-
packets: 300, // Number of seconds
|
|
20
|
-
subscriptions: 300
|
|
21
|
-
}
|
|
22
|
-
})
|
|
28
|
+
mq,
|
|
29
|
+
persistence
|
|
23
30
|
})
|
|
24
31
|
|
|
25
|
-
const server =
|
|
32
|
+
const server = createServer(aedes.handle)
|
|
26
33
|
|
|
27
|
-
server.listen(port, function () {
|
|
34
|
+
server.listen(port, '0.0.0.0', function () {
|
|
28
35
|
console.log('Aedes listening on port:', port)
|
|
29
36
|
aedes.publish({ topic: 'aedes/hello', payload: "I'm broker " + aedes.id })
|
|
30
37
|
})
|
|
31
38
|
|
|
39
|
+
server.on('error', function (err) {
|
|
40
|
+
console.log('Server error', err)
|
|
41
|
+
process.exit(1)
|
|
42
|
+
})
|
|
43
|
+
|
|
32
44
|
aedes.on('subscribe', function (subscriptions, client) {
|
|
33
45
|
console.log('MQTT client \x1b[32m' + (client ? client.id : client) +
|
|
34
46
|
'\x1b[0m subscribed to topics: ' + subscriptions.map(s => s.topic).join('\n'), 'from broker', aedes.id)
|
|
@@ -56,7 +68,7 @@ function startAedes () {
|
|
|
56
68
|
}
|
|
57
69
|
|
|
58
70
|
if (cluster.isMaster) {
|
|
59
|
-
const numWorkers =
|
|
71
|
+
const numWorkers = cpus().length
|
|
60
72
|
for (let i = 0; i < numWorkers; i++) {
|
|
61
73
|
cluster.fork()
|
|
62
74
|
}
|
|
@@ -9,8 +9,10 @@
|
|
|
9
9
|
"author": "robertsLando",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"aedes": "^0.
|
|
13
|
-
"aedes-persistence-mongodb": "^
|
|
14
|
-
"
|
|
12
|
+
"aedes": "^0.48.1",
|
|
13
|
+
"aedes-persistence-mongodb": "^9.1.0",
|
|
14
|
+
"aedes-persistence-redis": "^9.0.1",
|
|
15
|
+
"mqemitter-mongodb": "^8.1.0",
|
|
16
|
+
"mqemitter-redis": "^5.0.0"
|
|
15
17
|
}
|
|
16
18
|
}
|
package/lib/client.js
CHANGED
|
File without changes
|
package/lib/handlers/connect.js
CHANGED
|
File without changes
|
package/lib/handlers/index.js
CHANGED
|
File without changes
|
package/lib/handlers/ping.js
CHANGED
|
File without changes
|
package/lib/handlers/puback.js
CHANGED
|
File without changes
|
package/lib/handlers/publish.js
CHANGED
|
File without changes
|
package/lib/handlers/pubrec.js
CHANGED
|
File without changes
|
package/lib/handlers/pubrel.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/qos-packet.js
CHANGED
|
File without changes
|
package/lib/utils.js
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
const { Transform, Writable } = require('stream')
|
|
4
4
|
|
|
5
5
|
function validateTopic (topic, message) {
|
|
6
|
+
if (!topic || topic.length === 0) { // [MQTT-3.8.3-3]
|
|
7
|
+
return new Error('impossible to ' + message + ' to an empty topic')
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
const end = topic.length - 1
|
|
7
11
|
const endMinus = end - 1
|
|
8
12
|
const slashInPreEnd = endMinus > 0 && topic.charCodeAt(endMinus) !== 47
|
|
9
|
-
|
|
10
|
-
return new Error('impossible to ' + message + ' to an empty topic')
|
|
11
|
-
}
|
|
13
|
+
|
|
12
14
|
for (let i = 0; i < topic.length; i++) {
|
|
13
15
|
switch (topic.charCodeAt(i)) {
|
|
14
16
|
case 35: { // #
|
package/lib/write.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aedes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "Stream-based MQTT broker",
|
|
5
5
|
"main": "aedes.js",
|
|
6
6
|
"types": "aedes.d.ts",
|
|
@@ -97,24 +97,24 @@
|
|
|
97
97
|
"node": ">=14"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
|
-
"@sinonjs/fake-timers": "^
|
|
101
|
-
"@types/node": "^18.
|
|
102
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
103
|
-
"@typescript-eslint/parser": "^5.
|
|
100
|
+
"@sinonjs/fake-timers": "^10.0.2",
|
|
101
|
+
"@types/node": "^18.14.2",
|
|
102
|
+
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
|
103
|
+
"@typescript-eslint/parser": "^5.54.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.33.0",
|
|
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": "^15.
|
|
112
|
+
"release-it": "^15.6.1",
|
|
113
113
|
"snazzy": "^9.0.0",
|
|
114
114
|
"standard": "^17.0.0",
|
|
115
|
-
"tap": "^16.3.
|
|
116
|
-
"tsd": "^0.
|
|
117
|
-
"typescript": "^4.
|
|
115
|
+
"tap": "^16.3.4",
|
|
116
|
+
"tsd": "^0.25.0",
|
|
117
|
+
"typescript": "^4.9.5",
|
|
118
118
|
"websocket-stream": "^5.5.2"
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
@@ -124,9 +124,9 @@
|
|
|
124
124
|
"fastfall": "^1.5.1",
|
|
125
125
|
"fastparallel": "^2.4.1",
|
|
126
126
|
"fastseries": "^2.0.0",
|
|
127
|
-
"hyperid": "^3.
|
|
127
|
+
"hyperid": "^3.1.1",
|
|
128
128
|
"mqemitter": "^5.0.0",
|
|
129
|
-
"mqtt-packet": "^8.1.
|
|
129
|
+
"mqtt-packet": "^8.1.2",
|
|
130
130
|
"retimer": "^3.0.0",
|
|
131
131
|
"reusify": "^1.0.4",
|
|
132
132
|
"uuid": "^9.0.0"
|
package/test/auth.js
CHANGED
|
File without changes
|
package/test/basic.js
CHANGED
|
@@ -6,10 +6,10 @@ const { setup, connect, subscribe, subscribeMultiple, noError } = require('./hel
|
|
|
6
6
|
const aedes = require('../')
|
|
7
7
|
const proxyquire = require('proxyquire')
|
|
8
8
|
|
|
9
|
-
test('test aedes.
|
|
9
|
+
test('test aedes.createBroker', function (t) {
|
|
10
10
|
t.plan(1)
|
|
11
11
|
|
|
12
|
-
const broker =
|
|
12
|
+
const broker = aedes.createBroker()
|
|
13
13
|
t.teardown(broker.close.bind(broker))
|
|
14
14
|
|
|
15
15
|
connect(setup(broker), {}, function () {
|
package/test/bridge.js
CHANGED
|
File without changes
|
package/test/client-pub-sub.js
CHANGED
|
File without changes
|
|
File without changes
|
package/test/connect.js
CHANGED
|
File without changes
|
package/test/events.js
CHANGED
|
File without changes
|
package/test/helper.js
CHANGED
|
File without changes
|
package/test/keep-alive.js
CHANGED
|
File without changes
|
package/test/meta.js
CHANGED
|
File without changes
|
package/test/not-blocking.js
CHANGED
|
File without changes
|
package/test/qos1.js
CHANGED
|
File without changes
|
package/test/qos2.js
CHANGED
|
File without changes
|
package/test/regr-21.js
CHANGED
|
File without changes
|
package/test/retain.js
CHANGED
|
File without changes
|
package/test/topics.js
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
const { test } = require('tap')
|
|
4
4
|
const { setup, connect, subscribe } = require('./helper')
|
|
5
5
|
const aedes = require('../')
|
|
6
|
+
const { validateTopic } = require('../lib/utils')
|
|
7
|
+
|
|
8
|
+
test('validation of `null` topic', function (t) {
|
|
9
|
+
// issue #780
|
|
10
|
+
t.plan(1)
|
|
11
|
+
const err = validateTopic(null, 'SUBSCRIBE')
|
|
12
|
+
t.equal(err.message, 'impossible to SUBSCRIBE to an empty topic')
|
|
13
|
+
})
|
|
6
14
|
|
|
7
15
|
// [MQTT-4.7.1-3]
|
|
8
16
|
test('Single-level wildcard should match empty level', function (t) {
|
|
@@ -1,16 +1,18 @@
|
|
|
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
1
|
|
|
7
2
|
import { IncomingMessage } from 'node:http'
|
|
8
|
-
import type { Client } from 'aedes:client'
|
|
9
3
|
import { Socket } from 'node:net'
|
|
4
|
+
import type {
|
|
5
|
+
Brokers,
|
|
6
|
+
AuthenticateError,
|
|
7
|
+
Client,
|
|
8
|
+
Connection
|
|
9
|
+
} from '../../aedes'
|
|
10
|
+
import Aedes, { createBroker } from '../../aedes'
|
|
11
|
+
import type { AedesPublishPacket, ConnackPacket, ConnectPacket, PingreqPacket, PublishPacket, PubrelPacket, Subscription, SubscribePacket, UnsubscribePacket } from '../../types/packet'
|
|
10
12
|
import { expectType } from 'tsd'
|
|
11
13
|
|
|
12
14
|
// Aedes server
|
|
13
|
-
let broker =
|
|
15
|
+
let broker = createBroker()
|
|
14
16
|
expectType<Aedes>(broker)
|
|
15
17
|
|
|
16
18
|
broker = new Aedes({
|
|
@@ -29,8 +31,17 @@ broker = new Aedes({
|
|
|
29
31
|
callback(new Error('connection error'), false)
|
|
30
32
|
}
|
|
31
33
|
},
|
|
32
|
-
authenticate: (
|
|
33
|
-
|
|
34
|
+
authenticate: (
|
|
35
|
+
client: Client,
|
|
36
|
+
username: Readonly<string | undefined>,
|
|
37
|
+
password: Readonly<Buffer | undefined>,
|
|
38
|
+
callback
|
|
39
|
+
) => {
|
|
40
|
+
if (
|
|
41
|
+
username === 'test' &&
|
|
42
|
+
password === Buffer.from('test') &&
|
|
43
|
+
client.version === 4
|
|
44
|
+
) {
|
|
34
45
|
callback(null, true)
|
|
35
46
|
} else {
|
|
36
47
|
const error = new Error() as AuthenticateError
|
|
@@ -39,7 +50,11 @@ broker = new Aedes({
|
|
|
39
50
|
callback(error, false)
|
|
40
51
|
}
|
|
41
52
|
},
|
|
42
|
-
authorizePublish: (
|
|
53
|
+
authorizePublish: (
|
|
54
|
+
client: Client | null,
|
|
55
|
+
packet: PublishPacket,
|
|
56
|
+
callback
|
|
57
|
+
) => {
|
|
43
58
|
if (packet.topic === 'aaaa') {
|
|
44
59
|
return callback(new Error('wrong topic'))
|
|
45
60
|
}
|
|
@@ -66,7 +81,10 @@ broker = new Aedes({
|
|
|
66
81
|
if (packet.topic === 'aaaa' && client.id === 'I should not see this') {
|
|
67
82
|
return null
|
|
68
83
|
// also works with return undefined
|
|
69
|
-
} else if (
|
|
84
|
+
} else if (
|
|
85
|
+
packet.topic === 'aaaa' &&
|
|
86
|
+
client.id === 'I should not see this either'
|
|
87
|
+
) {
|
|
70
88
|
return
|
|
71
89
|
}
|
|
72
90
|
|
|
@@ -91,75 +109,107 @@ expectType<Aedes>(broker.on('client', (client: Client) => {}))
|
|
|
91
109
|
expectType<Aedes>(broker.on('clientReady', (client: Client) => {}))
|
|
92
110
|
expectType<Aedes>(broker.on('clientDisconnect', (client: Client) => {}))
|
|
93
111
|
expectType<Aedes>(broker.on('keepaliveTimeout', (client: Client) => {}))
|
|
94
|
-
expectType<Aedes>(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
expectType<Aedes>(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
expectType<Aedes>(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
expectType<
|
|
104
|
-
|
|
105
|
-
|
|
112
|
+
expectType<Aedes>(
|
|
113
|
+
broker.on('clientError', (client: Client, error: Error) => {})
|
|
114
|
+
)
|
|
115
|
+
expectType<Aedes>(
|
|
116
|
+
broker.on('connectionError', (client: Client, error: Error) => {})
|
|
117
|
+
)
|
|
118
|
+
expectType<Aedes>(
|
|
119
|
+
broker.on('connackSent', (packet: ConnackPacket, client: Client) => {})
|
|
120
|
+
)
|
|
121
|
+
expectType<Aedes>(
|
|
122
|
+
broker.on('ping', (packet: PingreqPacket, client: Client) => {})
|
|
123
|
+
)
|
|
124
|
+
expectType<Aedes>(
|
|
125
|
+
broker.on(
|
|
126
|
+
'publish',
|
|
127
|
+
(packet: AedesPublishPacket, client: Client | null) => {}
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
expectType<Aedes>(
|
|
131
|
+
broker.on('ack', (packet: PublishPacket | PubrelPacket, client: Client) => {})
|
|
132
|
+
)
|
|
133
|
+
expectType<Aedes>(
|
|
134
|
+
broker.on('subscribe', (subscriptions: Subscription[], client: Client) => {})
|
|
135
|
+
)
|
|
136
|
+
expectType<Aedes>(
|
|
137
|
+
broker.on('unsubscribe', (unsubscriptions: string[], client: Client) => {})
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
expectType<void>(
|
|
141
|
+
broker.publish({} as PublishPacket, (error?: Error) => {
|
|
106
142
|
if (error) {
|
|
107
143
|
console.error(error)
|
|
108
144
|
}
|
|
109
|
-
}
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
expectType<void>(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
(
|
|
122
|
-
|
|
145
|
+
})
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
expectType<void>(
|
|
149
|
+
broker.subscribe(
|
|
150
|
+
'topic',
|
|
151
|
+
(packet: AedesPublishPacket, callback: () => void) => {},
|
|
152
|
+
() => {}
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
expectType<void>(
|
|
157
|
+
broker.unsubscribe(
|
|
158
|
+
'topic',
|
|
159
|
+
(packet: AedesPublishPacket, callback: () => void) => {},
|
|
160
|
+
() => {}
|
|
161
|
+
)
|
|
162
|
+
)
|
|
123
163
|
|
|
124
164
|
expectType<void>(broker.close())
|
|
125
165
|
expectType<void>(broker.close(() => {}))
|
|
126
166
|
|
|
127
167
|
// Aedes client
|
|
128
168
|
const client = broker.handle({} as Connection, {} as IncomingMessage)
|
|
169
|
+
const client2 = broker.handle({} as Connection)
|
|
129
170
|
|
|
130
171
|
expectType<Client>(client)
|
|
172
|
+
expectType<Client>(client2)
|
|
131
173
|
|
|
132
174
|
expectType<Connection>(client.conn)
|
|
133
175
|
expectType<IncomingMessage>(client.req!)
|
|
134
176
|
|
|
135
177
|
expectType<Client>(client.on('connected', () => {}))
|
|
136
|
-
expectType<Client>(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
178
|
+
expectType<Client>(
|
|
179
|
+
client.on('error', (error: Error) => {
|
|
180
|
+
if (error) {
|
|
181
|
+
console.error(error)
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
)
|
|
141
185
|
|
|
142
|
-
expectType<void>(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
186
|
+
expectType<void>(
|
|
187
|
+
client.publish({} as PublishPacket, (error?: Error) => {
|
|
188
|
+
if (error) {
|
|
189
|
+
console.error(error)
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
)
|
|
147
193
|
expectType<void>(client.publish({} as PublishPacket))
|
|
148
194
|
|
|
149
|
-
expectType<void>(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
195
|
+
expectType<void>(
|
|
196
|
+
client.subscribe({} as Subscription, (error?: Error) => {
|
|
197
|
+
if (error) {
|
|
198
|
+
console.error(error)
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
)
|
|
154
202
|
expectType<void>(client.subscribe({} as Subscription))
|
|
155
203
|
expectType<void>(client.subscribe([] as Subscription[]))
|
|
156
204
|
expectType<void>(client.subscribe({} as SubscribePacket))
|
|
157
205
|
|
|
158
|
-
expectType<void>(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
206
|
+
expectType<void>(
|
|
207
|
+
client.unsubscribe({} as Subscription, (error?: Error) => {
|
|
208
|
+
if (error) {
|
|
209
|
+
console.error(error)
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
)
|
|
163
213
|
expectType<void>(client.unsubscribe({} as Subscription))
|
|
164
214
|
expectType<void>(client.unsubscribe([] as Subscription[]))
|
|
165
215
|
expectType<void>(client.unsubscribe({} as UnsubscribePacket))
|
package/test/will.js
CHANGED
|
File without changes
|
package/types/.eslintrc.json
CHANGED
|
File without changes
|
package/types/client.d.ts
CHANGED
|
@@ -1,32 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { IncomingMessage } from 'node:http'
|
|
2
|
+
import {
|
|
3
|
+
PublishPacket,
|
|
4
|
+
SubscribePacket,
|
|
5
|
+
Subscription,
|
|
6
|
+
Subscriptions,
|
|
7
|
+
UnsubscribePacket
|
|
8
|
+
} from './packet'
|
|
9
|
+
import { Connection } from './instance'
|
|
10
|
+
import { EventEmitter } from 'node:events'
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
export interface Client extends EventEmitter {
|
|
13
|
+
id: Readonly<string>;
|
|
14
|
+
clean: Readonly<boolean>;
|
|
15
|
+
version: Readonly<number>;
|
|
16
|
+
conn: Connection;
|
|
17
|
+
req?: IncomingMessage;
|
|
18
|
+
connecting: Readonly<boolean>;
|
|
19
|
+
connected: Readonly<boolean>;
|
|
20
|
+
closed: Readonly<boolean>;
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
on(event: 'connected', listener: () => void): this;
|
|
23
|
+
on(event: 'error', listener: (error: Error) => void): this;
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
publish(message: PublishPacket, callback?: (error?: Error) => void): void;
|
|
26
|
+
subscribe(
|
|
27
|
+
subscriptions:
|
|
28
|
+
| Subscriptions
|
|
29
|
+
| Subscription
|
|
30
|
+
| Subscription[]
|
|
31
|
+
| SubscribePacket,
|
|
32
|
+
callback?: (error?: Error) => void
|
|
33
|
+
): void;
|
|
34
|
+
unsubscribe(
|
|
35
|
+
topicObjects:
|
|
36
|
+
| Subscriptions
|
|
37
|
+
| Subscription
|
|
38
|
+
| Subscription[]
|
|
39
|
+
| UnsubscribePacket,
|
|
40
|
+
callback?: (error?: Error) => void
|
|
41
|
+
): void;
|
|
42
|
+
close(callback?: () => void): void;
|
|
43
|
+
emptyOutgoingQueue(callback?: () => void): void;
|
|
32
44
|
}
|
package/types/instance.d.ts
CHANGED
|
@@ -1,101 +1,159 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
1
|
+
import { Duplex } from 'node:stream'
|
|
2
|
+
import { Socket } from 'node:net'
|
|
3
|
+
import { IncomingMessage } from 'http'
|
|
4
|
+
import { Client } from './client'
|
|
5
|
+
import type {
|
|
6
|
+
AedesPublishPacket,
|
|
7
|
+
ConnectPacket,
|
|
8
|
+
ConnackPacket,
|
|
9
|
+
Subscription,
|
|
10
|
+
PingreqPacket,
|
|
11
|
+
PublishPacket,
|
|
12
|
+
PubrelPacket
|
|
13
|
+
} from './packet'
|
|
14
|
+
import { EventEmitter } from 'node:events'
|
|
15
|
+
|
|
16
|
+
type LastHearthbeatTimestamp = Date;
|
|
17
|
+
|
|
18
|
+
export interface Brokers {
|
|
19
|
+
[brokerId: string]: LastHearthbeatTimestamp;
|
|
96
20
|
}
|
|
97
21
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
22
|
+
export type Connection = Duplex | Socket;
|
|
23
|
+
|
|
24
|
+
/* eslint no-unused-vars: 0 */
|
|
25
|
+
export const enum AuthErrorCode {
|
|
26
|
+
UNNACCEPTABLE_PROTOCOL = 1,
|
|
27
|
+
IDENTIFIER_REJECTED = 2,
|
|
28
|
+
SERVER_UNAVAILABLE = 3,
|
|
29
|
+
BAD_USERNAME_OR_PASSWORD = 4,
|
|
30
|
+
NOT_AUTHORIZED = 5,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type AuthenticateError = Error & { returnCode: AuthErrorCode };
|
|
34
|
+
|
|
35
|
+
type PreConnectHandler = (
|
|
36
|
+
client: Client,
|
|
37
|
+
packet: ConnectPacket,
|
|
38
|
+
callback: (error: Error | null, success: boolean) => void
|
|
39
|
+
) => void;
|
|
40
|
+
|
|
41
|
+
type AuthenticateHandler = (
|
|
42
|
+
client: Client,
|
|
43
|
+
username: Readonly<string | undefined>,
|
|
44
|
+
password: Readonly<Buffer | undefined>,
|
|
45
|
+
done: (error: AuthenticateError | null, success: boolean | null) => void
|
|
46
|
+
) => void;
|
|
47
|
+
|
|
48
|
+
type AuthorizePublishHandler = (
|
|
49
|
+
client: Client | null,
|
|
50
|
+
packet: PublishPacket,
|
|
51
|
+
callback: (error?: Error | null) => void
|
|
52
|
+
) => void;
|
|
53
|
+
|
|
54
|
+
type AuthorizeSubscribeHandler = (
|
|
55
|
+
client: Client,
|
|
56
|
+
subscription: Subscription,
|
|
57
|
+
callback: (error: Error | null, subscription?: Subscription | null) => void
|
|
58
|
+
) => void;
|
|
59
|
+
|
|
60
|
+
type AuthorizeForwardHandler = (
|
|
61
|
+
client: Client,
|
|
62
|
+
packet: AedesPublishPacket
|
|
63
|
+
) => AedesPublishPacket | null | void;
|
|
64
|
+
|
|
65
|
+
type PublishedHandler = (
|
|
66
|
+
packet: AedesPublishPacket,
|
|
67
|
+
client: Client,
|
|
68
|
+
callback: (error?: Error | null) => void
|
|
69
|
+
) => void;
|
|
70
|
+
|
|
71
|
+
export interface AedesOptions {
|
|
72
|
+
mq?: any;
|
|
73
|
+
id?: string;
|
|
74
|
+
persistence?: any;
|
|
75
|
+
concurrency?: number;
|
|
76
|
+
heartbeatInterval?: number;
|
|
77
|
+
connectTimeout?: number;
|
|
78
|
+
queueLimit?: number;
|
|
79
|
+
maxClientsIdLength?: number;
|
|
80
|
+
preConnect?: PreConnectHandler;
|
|
81
|
+
authenticate?: AuthenticateHandler;
|
|
82
|
+
authorizePublish?: AuthorizePublishHandler;
|
|
83
|
+
authorizeSubscribe?: AuthorizeSubscribeHandler;
|
|
84
|
+
authorizeForward?: AuthorizeForwardHandler;
|
|
85
|
+
published?: PublishedHandler;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export default class Aedes extends EventEmitter {
|
|
89
|
+
id: Readonly<string>
|
|
90
|
+
connectedClients: Readonly<number>
|
|
91
|
+
closed: Readonly<boolean>
|
|
92
|
+
brokers: Readonly<Brokers>
|
|
93
|
+
|
|
94
|
+
constructor(option?: AedesOptions);
|
|
95
|
+
handle: (stream: Connection, request?: IncomingMessage) => Client
|
|
96
|
+
|
|
97
|
+
on(event: 'closed', listener: () => void): this;
|
|
98
|
+
on(
|
|
99
|
+
event: 'client' | 'clientReady' | 'clientDisconnect' | 'keepaliveTimeout',
|
|
100
|
+
listener: (client: Client) => void
|
|
101
|
+
): this;
|
|
102
|
+
|
|
103
|
+
on(
|
|
104
|
+
event: 'clientError' | 'connectionError',
|
|
105
|
+
listener: (client: Client, error: Error) => void
|
|
106
|
+
): this;
|
|
107
|
+
|
|
108
|
+
on(
|
|
109
|
+
event: 'connackSent',
|
|
110
|
+
listener: (packet: ConnackPacket, client: Client) => void
|
|
111
|
+
): this;
|
|
112
|
+
|
|
113
|
+
on(
|
|
114
|
+
event: 'ping',
|
|
115
|
+
listener: (packet: PingreqPacket, client: Client) => void
|
|
116
|
+
): this;
|
|
117
|
+
|
|
118
|
+
on(
|
|
119
|
+
event: 'publish',
|
|
120
|
+
listener: (packet: AedesPublishPacket, client: Client | null) => void
|
|
121
|
+
): this;
|
|
122
|
+
|
|
123
|
+
on(
|
|
124
|
+
event: 'ack',
|
|
125
|
+
listener: (packet: PublishPacket | PubrelPacket, client: Client) => void
|
|
126
|
+
): this;
|
|
127
|
+
|
|
128
|
+
on(
|
|
129
|
+
event: 'subscribe',
|
|
130
|
+
listener: (subscriptions: Subscription[], client: Client) => void
|
|
131
|
+
): this;
|
|
132
|
+
|
|
133
|
+
on(
|
|
134
|
+
event: 'unsubscribe',
|
|
135
|
+
listener: (unsubscriptions: string[], client: Client) => void
|
|
136
|
+
): this;
|
|
137
|
+
|
|
138
|
+
publish(packet: PublishPacket, callback: (error?: Error) => void): void;
|
|
139
|
+
subscribe(
|
|
140
|
+
topic: string,
|
|
141
|
+
deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void,
|
|
142
|
+
callback: () => void
|
|
143
|
+
): void;
|
|
144
|
+
|
|
145
|
+
unsubscribe(
|
|
146
|
+
topic: string,
|
|
147
|
+
deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void,
|
|
148
|
+
callback: () => void
|
|
149
|
+
): void;
|
|
150
|
+
|
|
151
|
+
close(callback?: () => void): void;
|
|
152
|
+
|
|
153
|
+
preConnect: PreConnectHandler
|
|
154
|
+
authenticate: AuthenticateHandler
|
|
155
|
+
authorizePublish: AuthorizePublishHandler
|
|
156
|
+
authorizeSubscribe: AuthorizeSubscribeHandler
|
|
157
|
+
authorizeForward: AuthorizeForwardHandler
|
|
158
|
+
published: PublishedHandler
|
|
101
159
|
}
|
package/types/packet.d.ts
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { AedesPacket } from 'aedes-packet'
|
|
2
|
+
import {
|
|
3
|
+
IConnackPacket,
|
|
4
|
+
IConnectPacket,
|
|
5
|
+
IPingreqPacket,
|
|
6
|
+
IPublishPacket,
|
|
7
|
+
IPubrelPacket,
|
|
8
|
+
ISubscribePacket,
|
|
9
|
+
ISubscription,
|
|
10
|
+
IUnsubscribePacket
|
|
11
|
+
} from 'mqtt-packet'
|
|
12
|
+
import { Client } from './client'
|
|
5
13
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
export type SubscribePacket = ISubscribePacket & { cmd: 'subscribe' };
|
|
15
|
+
export type UnsubscribePacket = IUnsubscribePacket & { cmd: 'unsubscribe' };
|
|
16
|
+
export type Subscription = ISubscription & { clientId?: Client['id'] };
|
|
17
|
+
export type Subscriptions = { subscriptions: Subscription[] };
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
export type PublishPacket = IPublishPacket & { cmd: 'publish' };
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
export type ConnectPacket = IConnectPacket & { cmd: 'connect' };
|
|
22
|
+
export type ConnackPacket = IConnackPacket & { cmd: 'connack' };
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
export type PubrelPacket = IPubrelPacket & { cmd: 'pubrel' };
|
|
25
|
+
export type PingreqPacket = IPingreqPacket & { cmd: 'pingreq' };
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
declare module 'aedes:packet' {
|
|
22
|
-
export * from 'packet'
|
|
23
|
-
}
|
|
27
|
+
export type AedesPublishPacket = PublishPacket & AedesPacket;
|
package/types/tsconfig.json
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"noEmit": true,
|
|
6
6
|
"strict": true,
|
|
7
7
|
"removeComments": true,
|
|
8
|
-
"typeRoots" : ["
|
|
8
|
+
"typeRoots" : ["./", "../node_modules/@types/"]
|
|
9
9
|
},
|
|
10
10
|
"include": [
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"aedes.d.ts"
|
|
11
|
+
"../test/types/*.test-d.ts",
|
|
12
|
+
"./*.d.ts",
|
|
13
|
+
"../aedes.d.ts"
|
|
14
14
|
]
|
|
15
15
|
}
|