@seriousme/opifex 1.9.4 → 1.11.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/README.md +37 -26
- package/bin/conformanceServer.ts +3 -2
- package/bin/demoServer.ts +3 -2
- package/bin/mqtt.ts +127 -118
- package/client/client.ts +61 -21
- package/client/context.ts +71 -30
- package/client/deps.ts +5 -0
- package/client/handlers/handleConnack.ts +17 -5
- package/client/handlers/handlePublish.ts +4 -1
- package/client/handlers/handlePubrec.ts +3 -1
- package/client/handlers/handlePubrel.ts +3 -1
- package/client/handlers/handleSuback.ts +3 -1
- package/client/mod.ts +8 -1
- package/client/store/memoryStore.ts +2 -1
- package/deno/tcpClient.ts +1 -1
- package/dev_utils/dummyConn.ts +17 -2
- package/dist/bin/conformanceServer.js +3 -2
- package/dist/bin/conformanceServer.js.map +1 -1
- package/dist/bin/demoServer.js +3 -2
- package/dist/bin/demoServer.js.map +1 -1
- package/dist/bin/mqtt.d.ts +29 -0
- package/dist/bin/mqtt.d.ts.map +1 -1
- package/dist/bin/mqtt.js +102 -97
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/client.d.ts +16 -5
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +36 -15
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +8 -3
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/context.js +51 -21
- package/dist/client/context.js.map +1 -1
- package/dist/client/deps.d.ts +3 -2
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js +2 -1
- package/dist/client/deps.js.map +1 -1
- package/dist/client/handlers/handleConnack.d.ts +1 -1
- package/dist/client/handlers/handleConnack.d.ts.map +1 -1
- package/dist/client/handlers/handleConnack.js +14 -5
- package/dist/client/handlers/handleConnack.js.map +1 -1
- package/dist/client/handlers/handlePublish.d.ts +1 -1
- package/dist/client/handlers/handlePublish.d.ts.map +1 -1
- package/dist/client/handlers/handlePublish.js +2 -0
- package/dist/client/handlers/handlePublish.js.map +1 -1
- package/dist/client/handlers/handlePubrec.d.ts +1 -1
- package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/client/handlers/handlePubrec.js +1 -0
- package/dist/client/handlers/handlePubrec.js.map +1 -1
- package/dist/client/handlers/handlePubrel.d.ts +1 -1
- package/dist/client/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/client/handlers/handlePubrel.js +1 -0
- package/dist/client/handlers/handlePubrel.js.map +1 -1
- package/dist/client/handlers/handleSuback.d.ts.map +1 -1
- package/dist/client/handlers/handleSuback.js +3 -1
- package/dist/client/handlers/handleSuback.js.map +1 -1
- package/dist/client/mod.d.ts +3 -1
- package/dist/client/mod.d.ts.map +1 -1
- package/dist/client/mod.js +2 -1
- package/dist/client/mod.js.map +1 -1
- package/dist/client/store/memoryStore.d.ts +1 -1
- package/dist/client/store/memoryStore.d.ts.map +1 -1
- package/dist/client/store/memoryStore.js.map +1 -1
- package/dist/mqttConn/mqttConn.d.ts +13 -8
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +27 -12
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts +1 -0
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/PacketType.js +1 -0
- package/dist/mqttPacket/PacketType.js.map +1 -1
- package/dist/mqttPacket/Properties.d.ts +157 -0
- package/dist/mqttPacket/Properties.d.ts.map +1 -0
- package/dist/mqttPacket/Properties.js +177 -0
- package/dist/mqttPacket/Properties.js.map +1 -0
- package/dist/mqttPacket/ReasonCode.d.ts +74 -0
- package/dist/mqttPacket/ReasonCode.d.ts.map +1 -0
- package/dist/mqttPacket/ReasonCode.js +230 -0
- package/dist/mqttPacket/ReasonCode.js.map +1 -0
- package/dist/mqttPacket/RetainHandling.d.ts +12 -0
- package/dist/mqttPacket/RetainHandling.d.ts.map +1 -0
- package/dist/mqttPacket/RetainHandling.js +12 -0
- package/dist/mqttPacket/RetainHandling.js.map +1 -0
- package/dist/mqttPacket/auth.d.ts +21 -0
- package/dist/mqttPacket/auth.d.ts.map +1 -0
- package/dist/mqttPacket/auth.js +34 -0
- package/dist/mqttPacket/auth.js.map +1 -0
- package/dist/mqttPacket/connack.d.ts +19 -11
- package/dist/mqttPacket/connack.d.ts.map +1 -1
- package/dist/mqttPacket/connack.js +43 -15
- package/dist/mqttPacket/connack.js.map +1 -1
- package/dist/mqttPacket/connect.d.ts +30 -11
- package/dist/mqttPacket/connect.d.ts.map +1 -1
- package/dist/mqttPacket/connect.js +106 -30
- package/dist/mqttPacket/connect.js.map +1 -1
- package/dist/mqttPacket/decoder.d.ts +42 -3
- package/dist/mqttPacket/decoder.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +135 -4
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/disconnect.d.ts +15 -9
- package/dist/mqttPacket/disconnect.d.ts.map +1 -1
- package/dist/mqttPacket/disconnect.js +45 -6
- package/dist/mqttPacket/disconnect.js.map +1 -1
- package/dist/mqttPacket/encoder.d.ts +57 -8
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +185 -13
- package/dist/mqttPacket/encoder.js.map +1 -1
- package/dist/mqttPacket/length.d.ts.map +1 -1
- package/dist/mqttPacket/length.js +3 -2
- package/dist/mqttPacket/length.js.map +1 -1
- package/dist/mqttPacket/mod.d.ts +57 -91
- package/dist/mqttPacket/mod.d.ts.map +1 -1
- package/dist/mqttPacket/mod.js +23 -29
- package/dist/mqttPacket/mod.js.map +1 -1
- package/dist/mqttPacket/pingreq.d.ts +4 -6
- package/dist/mqttPacket/pingreq.d.ts.map +1 -1
- package/dist/mqttPacket/pingreq.js +5 -4
- package/dist/mqttPacket/pingreq.js.map +1 -1
- package/dist/mqttPacket/pingres.d.ts +4 -6
- package/dist/mqttPacket/pingres.d.ts.map +1 -1
- package/dist/mqttPacket/pingres.js +7 -5
- package/dist/mqttPacket/pingres.js.map +1 -1
- package/dist/mqttPacket/protocolLevels.d.ts +12 -0
- package/dist/mqttPacket/protocolLevels.d.ts.map +1 -0
- package/dist/mqttPacket/protocolLevels.js +11 -0
- package/dist/mqttPacket/protocolLevels.js.map +1 -0
- package/dist/mqttPacket/pubblishAcks.d.ts +42 -0
- package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -0
- package/dist/mqttPacket/pubblishAcks.js +56 -0
- package/dist/mqttPacket/pubblishAcks.js.map +1 -0
- package/dist/mqttPacket/publish.d.ts +19 -8
- package/dist/mqttPacket/publish.d.ts.map +1 -1
- package/dist/mqttPacket/publish.js +26 -7
- package/dist/mqttPacket/publish.js.map +1 -1
- package/dist/mqttPacket/suback.d.ts +18 -11
- package/dist/mqttPacket/suback.d.ts.map +1 -1
- package/dist/mqttPacket/suback.js +41 -20
- package/dist/mqttPacket/suback.js.map +1 -1
- package/dist/mqttPacket/subscribe.d.ts +27 -12
- package/dist/mqttPacket/subscribe.d.ts.map +1 -1
- package/dist/mqttPacket/subscribe.js +71 -15
- package/dist/mqttPacket/subscribe.js.map +1 -1
- package/dist/mqttPacket/types.d.ts +36 -0
- package/dist/mqttPacket/types.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.d.ts +17 -10
- package/dist/mqttPacket/unsuback.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.js +29 -6
- package/dist/mqttPacket/unsuback.js.map +1 -1
- package/dist/mqttPacket/unsubscribe.d.ts +17 -10
- package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
- package/dist/mqttPacket/unsubscribe.js +24 -8
- package/dist/mqttPacket/unsubscribe.js.map +1 -1
- package/dist/mqttPacket/validators.d.ts +15 -0
- package/dist/mqttPacket/validators.d.ts.map +1 -1
- package/dist/mqttPacket/validators.js +15 -0
- package/dist/mqttPacket/validators.js.map +1 -1
- package/dist/node/tcpClient.js +1 -1
- package/dist/node/tcpClient.js.map +1 -1
- package/dist/node/wrapNodeSocket.d.ts.map +1 -1
- package/dist/node/wrapNodeSocket.js.map +1 -1
- package/dist/persistence/deps.d.ts +1 -1
- package/dist/persistence/deps.d.ts.map +1 -1
- package/dist/persistence/deps.js +1 -1
- package/dist/persistence/deps.js.map +1 -1
- package/dist/persistence/memory/memoryPersistence.js +1 -1
- package/dist/persistence/memory/memoryPersistence.js.map +1 -1
- package/dist/server/context.d.ts +3 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +8 -2
- package/dist/server/context.js.map +1 -1
- package/dist/server/deps.d.ts +2 -2
- package/dist/server/deps.d.ts.map +1 -1
- package/dist/server/deps.js +1 -1
- package/dist/server/deps.js.map +1 -1
- package/dist/server/handlers/handleConnect.d.ts +1 -1
- package/dist/server/handlers/handleConnect.d.ts.map +1 -1
- package/dist/server/handlers/handleConnect.js +9 -1
- package/dist/server/handlers/handleConnect.js.map +1 -1
- package/dist/server/handlers/handlePacket.d.ts +1 -1
- package/dist/server/handlers/handlePacket.d.ts.map +1 -1
- package/dist/server/handlers/handlePacket.js +1 -1
- package/dist/server/handlers/handlePacket.js.map +1 -1
- package/dist/server/handlers/handlePingreq.d.ts.map +1 -1
- package/dist/server/handlers/handlePingreq.js +1 -0
- package/dist/server/handlers/handlePingreq.js.map +1 -1
- package/dist/server/handlers/handlePublish.d.ts +2 -2
- package/dist/server/handlers/handlePublish.d.ts.map +1 -1
- package/dist/server/handlers/handlePublish.js +2 -0
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/server/handlers/handlePubrec.d.ts +1 -1
- package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrec.js +1 -0
- package/dist/server/handlers/handlePubrec.js.map +1 -1
- package/dist/server/handlers/handlePubrel.d.ts +1 -1
- package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrel.js +1 -0
- package/dist/server/handlers/handlePubrel.js.map +1 -1
- package/dist/server/handlers/handleSubscribe.d.ts +1 -1
- package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleSubscribe.js +2 -1
- package/dist/server/handlers/handleSubscribe.js.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.d.ts +1 -1
- package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.js +1 -0
- package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
- package/dist/server/server.d.ts +2 -2
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +5 -3
- package/dist/server/server.js.map +1 -1
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +6 -1
- package/dist/socket/socket.js.map +1 -1
- package/dist/utils/assert.d.ts +0 -3
- package/dist/utils/assert.d.ts.map +1 -1
- package/dist/utils/assert.js +0 -7
- package/dist/utils/assert.js.map +1 -1
- package/dist/utils/asyncQueue.d.ts +1 -3
- package/dist/utils/asyncQueue.d.ts.map +1 -1
- package/dist/utils/asyncQueue.js +16 -21
- package/dist/utils/asyncQueue.js.map +1 -1
- package/dist/utils/logger.d.ts +5 -15
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +7 -8
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mod.d.ts +0 -3
- package/dist/utils/mod.d.ts.map +1 -1
- package/dist/utils/mod.js +0 -2
- package/dist/utils/mod.js.map +1 -1
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +6 -0
- package/dist/utils/utils.js.map +1 -0
- package/mqttConn/mqttConn.test.ts +27 -12
- package/mqttConn/mqttConn.ts +45 -14
- package/mqttPacket/PacketType.ts +1 -0
- package/mqttPacket/Properties.ts +276 -0
- package/mqttPacket/ReasonCode.test.ts +22 -0
- package/mqttPacket/ReasonCode.ts +256 -0
- package/mqttPacket/RetainHandling.ts +11 -0
- package/mqttPacket/auth.test.ts +112 -0
- package/mqttPacket/auth.ts +71 -0
- package/mqttPacket/connack.test.ts +84 -64
- package/mqttPacket/connack.ts +88 -24
- package/mqttPacket/connect.test.ts +497 -18
- package/mqttPacket/connect.ts +170 -39
- package/mqttPacket/decoder.test.ts +33 -16
- package/mqttPacket/decoder.ts +173 -5
- package/mqttPacket/disconnect.test.ts +97 -18
- package/mqttPacket/disconnect.ts +84 -12
- package/mqttPacket/encoder.test.ts +32 -8
- package/mqttPacket/encoder.ts +236 -11
- package/mqttPacket/length.ts +3 -2
- package/mqttPacket/mod.ts +76 -39
- package/mqttPacket/pingreq.test.ts +52 -4
- package/mqttPacket/pingreq.ts +20 -7
- package/mqttPacket/pingres.test.ts +52 -4
- package/mqttPacket/pingres.ts +22 -8
- package/mqttPacket/properties.test.ts +193 -0
- package/mqttPacket/protocolLevels.ts +13 -0
- package/mqttPacket/pubblishAcks.ts +123 -0
- package/mqttPacket/publish.test.ts +212 -133
- package/mqttPacket/publish.ts +69 -14
- package/mqttPacket/publishAcks.test.ts +128 -0
- package/mqttPacket/suback.test.ts +71 -27
- package/mqttPacket/suback.ts +82 -30
- package/mqttPacket/subscribe.test.ts +132 -43
- package/mqttPacket/subscribe.ts +128 -25
- package/mqttPacket/types.ts +43 -0
- package/mqttPacket/unsuback.test.ts +80 -30
- package/mqttPacket/unsuback.ts +68 -13
- package/mqttPacket/unsubscribe.test.ts +59 -34
- package/mqttPacket/unsubscribe.ts +64 -17
- package/mqttPacket/validators.ts +15 -0
- package/node/tcpClient.ts +1 -1
- package/node/wrapNodeSocket.ts +2 -1
- package/package.json +2 -2
- package/persistence/deps.ts +1 -1
- package/persistence/memory/memoryPersistence.test.ts +5 -1
- package/persistence/memory/memoryPersistence.ts +1 -1
- package/server/context.ts +23 -10
- package/server/deps.ts +2 -0
- package/server/handlers/handleConnect.ts +12 -9
- package/server/handlers/handlePacket.ts +10 -11
- package/server/handlers/handlePingreq.ts +1 -0
- package/server/handlers/handlePublish.ts +6 -2
- package/server/handlers/handlePubrec.ts +3 -1
- package/server/handlers/handlePubrel.ts +3 -1
- package/server/handlers/handleSubscribe.ts +3 -6
- package/server/handlers/handleUnsubscribe.ts +3 -1
- package/server/server.ts +8 -12
- package/server/test/handleConnect.test.ts +2 -1
- package/server/test/test-handlers.ts +2 -1
- package/socket/socket.ts +5 -1
- package/utils/assert.ts +0 -18
- package/utils/asyncQueue.ts +17 -21
- package/utils/logger.ts +12 -11
- package/utils/mod.ts +0 -3
- package/utils/utils.ts +6 -0
- package/dist/mqttPacket/puback.d.ts +0 -16
- package/dist/mqttPacket/puback.d.ts.map +0 -1
- package/dist/mqttPacket/puback.js +0 -21
- package/dist/mqttPacket/puback.js.map +0 -1
- package/dist/mqttPacket/pubcomp.d.ts +0 -17
- package/dist/mqttPacket/pubcomp.d.ts.map +0 -1
- package/dist/mqttPacket/pubcomp.js +0 -21
- package/dist/mqttPacket/pubcomp.js.map +0 -1
- package/dist/mqttPacket/pubrec.d.ts +0 -17
- package/dist/mqttPacket/pubrec.d.ts.map +0 -1
- package/dist/mqttPacket/pubrec.js +0 -21
- package/dist/mqttPacket/pubrec.js.map +0 -1
- package/dist/mqttPacket/pubrel.d.ts +0 -17
- package/dist/mqttPacket/pubrel.d.ts.map +0 -1
- package/dist/mqttPacket/pubrel.js +0 -21
- package/dist/mqttPacket/pubrel.js.map +0 -1
- package/dist/utils/args.d.ts +0 -28
- package/dist/utils/args.d.ts.map +0 -1
- package/dist/utils/args.js +0 -76
- package/dist/utils/args.js.map +0 -1
- package/dist/utils/platform.d.ts +0 -5
- package/dist/utils/platform.d.ts.map +0 -1
- package/dist/utils/platform.js +0 -8
- package/dist/utils/platform.js.map +0 -1
- package/mqttPacket/puback.test.ts +0 -55
- package/mqttPacket/puback.ts +0 -34
- package/mqttPacket/pubcomp.test.ts +0 -55
- package/mqttPacket/pubcomp.ts +0 -35
- package/mqttPacket/pubrec.test.ts +0 -55
- package/mqttPacket/pubrec.ts +0 -35
- package/mqttPacket/pubrel.test.ts +0 -55
- package/mqttPacket/pubrel.ts +0 -35
- package/utils/args.ts +0 -103
- package/utils/platform.ts +0 -8
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { PacketType } from "./PacketType.ts";
|
|
2
|
+
import type { InvertRecord, UTF8StringPair } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
export const PropertySetType = {
|
|
5
|
+
...PacketType,
|
|
6
|
+
will: 100,
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export type TPropertySetType =
|
|
10
|
+
typeof PropertySetType[keyof typeof PropertySetType];
|
|
11
|
+
|
|
12
|
+
export const propertyKind = {
|
|
13
|
+
boolean: 0, // its a byte in the MQTT standard, but for convenience we convert to boolean
|
|
14
|
+
byte: 1,
|
|
15
|
+
int16: 2,
|
|
16
|
+
int32: 3,
|
|
17
|
+
varInt: 4,
|
|
18
|
+
byteArray: 5,
|
|
19
|
+
utf8string: 6,
|
|
20
|
+
utf8StringPairs: 7,
|
|
21
|
+
varIntArray: 8,
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
export const propertyToId = {
|
|
25
|
+
payloadFormatIndicator: 0x01,
|
|
26
|
+
messageExpiryInterval: 0x02,
|
|
27
|
+
contentType: 0x03,
|
|
28
|
+
responseTopic: 0x08,
|
|
29
|
+
correlationData: 0x09,
|
|
30
|
+
subscriptionIdentifier: 0x0b,
|
|
31
|
+
// special case,placeholder to encode decode multiple subscription identifiers
|
|
32
|
+
subscriptionIdentifiers: 0xff,
|
|
33
|
+
sessionExpiryInterval: 0x11,
|
|
34
|
+
assignedClientIdentifier: 0x12,
|
|
35
|
+
serverKeepAlive: 0x13,
|
|
36
|
+
authenticationMethod: 0x15,
|
|
37
|
+
authenticationData: 0x16,
|
|
38
|
+
requestProblemInformation: 0x17,
|
|
39
|
+
willDelayInterval: 0x18,
|
|
40
|
+
requestResponseInformation: 0x19,
|
|
41
|
+
responseInformation: 0x1a,
|
|
42
|
+
serverReference: 0x1c,
|
|
43
|
+
reasonString: 0x1f,
|
|
44
|
+
receiveMaximum: 0x21,
|
|
45
|
+
topicAliasMaximum: 0x22,
|
|
46
|
+
topicAlias: 0x23,
|
|
47
|
+
maximumQos: 0x24,
|
|
48
|
+
retainAvailable: 0x25,
|
|
49
|
+
userProperty: 0x26,
|
|
50
|
+
maximumPacketSize: 0x27,
|
|
51
|
+
wildcardSubscriptionAvailable: 0x28,
|
|
52
|
+
subscriptionIdentifierAvailable: 0x29,
|
|
53
|
+
sharedSubscriptionAvailable: 0x2a,
|
|
54
|
+
} as const;
|
|
55
|
+
|
|
56
|
+
type PropertyNames = keyof typeof propertyToId;
|
|
57
|
+
// A helper type to convert a tuple of numbers to a union of strings
|
|
58
|
+
|
|
59
|
+
export const propertyToKind = {
|
|
60
|
+
[propertyToId.payloadFormatIndicator]: propertyKind.boolean,
|
|
61
|
+
[propertyToId.messageExpiryInterval]: propertyKind.int32,
|
|
62
|
+
[propertyToId.contentType]: propertyKind.utf8string,
|
|
63
|
+
[propertyToId.responseTopic]: propertyKind.utf8string,
|
|
64
|
+
[propertyToId.correlationData]: propertyKind.byteArray,
|
|
65
|
+
[propertyToId.subscriptionIdentifier]: propertyKind.varInt,
|
|
66
|
+
[propertyToId.subscriptionIdentifiers]: propertyKind.varIntArray,
|
|
67
|
+
[propertyToId.sessionExpiryInterval]: propertyKind.int32,
|
|
68
|
+
[propertyToId.assignedClientIdentifier]: propertyKind.utf8string,
|
|
69
|
+
[propertyToId.serverKeepAlive]: propertyKind.int16,
|
|
70
|
+
[propertyToId.authenticationMethod]: propertyKind.utf8string,
|
|
71
|
+
[propertyToId.authenticationData]: propertyKind.byteArray,
|
|
72
|
+
[propertyToId.requestProblemInformation]: propertyKind.boolean,
|
|
73
|
+
[propertyToId.willDelayInterval]: propertyKind.int32,
|
|
74
|
+
[propertyToId.requestResponseInformation]: propertyKind.boolean,
|
|
75
|
+
[propertyToId.responseInformation]: propertyKind.utf8string,
|
|
76
|
+
[propertyToId.serverReference]: propertyKind.utf8string,
|
|
77
|
+
[propertyToId.reasonString]: propertyKind.utf8string,
|
|
78
|
+
[propertyToId.receiveMaximum]: propertyKind.int16,
|
|
79
|
+
[propertyToId.topicAliasMaximum]: propertyKind.int16,
|
|
80
|
+
[propertyToId.topicAlias]: propertyKind.int16,
|
|
81
|
+
[propertyToId.maximumQos]: propertyKind.byte,
|
|
82
|
+
[propertyToId.retainAvailable]: propertyKind.boolean,
|
|
83
|
+
[propertyToId.userProperty]: propertyKind.utf8StringPairs,
|
|
84
|
+
[propertyToId.maximumPacketSize]: propertyKind.int32,
|
|
85
|
+
[propertyToId.wildcardSubscriptionAvailable]: propertyKind.boolean,
|
|
86
|
+
[propertyToId.subscriptionIdentifierAvailable]: propertyKind.boolean,
|
|
87
|
+
[propertyToId.sharedSubscriptionAvailable]: propertyKind.boolean,
|
|
88
|
+
} as const;
|
|
89
|
+
|
|
90
|
+
export type UserPropertyType = Array<UTF8StringPair>;
|
|
91
|
+
export type SubscriptionIdentifiersType = Array<number>;
|
|
92
|
+
|
|
93
|
+
type PropertyKindMap = {
|
|
94
|
+
[propertyKind.boolean]: boolean;
|
|
95
|
+
[propertyKind.byte]: number;
|
|
96
|
+
[propertyKind.int16]: number;
|
|
97
|
+
[propertyKind.int32]: number;
|
|
98
|
+
[propertyKind.varInt]: number;
|
|
99
|
+
[propertyKind.byteArray]: Uint8Array;
|
|
100
|
+
[propertyKind.utf8string]: string;
|
|
101
|
+
[propertyKind.utf8StringPairs]: UserPropertyType;
|
|
102
|
+
[propertyKind.varIntArray]: SubscriptionIdentifiersType;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
type Mqttv5PropertyType<K extends number> = K extends keyof PropertyKindMap
|
|
106
|
+
? PropertyKindMap[K]
|
|
107
|
+
: never;
|
|
108
|
+
|
|
109
|
+
export type Mqttv5PropertyTypes = PropertyKindMap[keyof PropertyKindMap];
|
|
110
|
+
export type Mqttv5PropertyTypesNoUser = Exclude<
|
|
111
|
+
Mqttv5PropertyTypes,
|
|
112
|
+
UserPropertyType
|
|
113
|
+
>;
|
|
114
|
+
|
|
115
|
+
// First, create a type for all valid property numbers
|
|
116
|
+
export type ValidPropertyNumber =
|
|
117
|
+
(typeof propertyToId)[keyof typeof propertyToId];
|
|
118
|
+
// Then, create a mapped type that iterates over the property names
|
|
119
|
+
// and uses propertyToKind to look up the correct TypeScript type.
|
|
120
|
+
|
|
121
|
+
type AllMqttv5Properties = {
|
|
122
|
+
[K in PropertyNames]?: Mqttv5PropertyType<
|
|
123
|
+
typeof propertyToKind[typeof propertyToId[K]]
|
|
124
|
+
>;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
type PropertyByNumberType = InvertRecord<typeof propertyToId>;
|
|
128
|
+
|
|
129
|
+
export const propertyByNumber = Object.fromEntries(
|
|
130
|
+
Object.entries(propertyToId).map(
|
|
131
|
+
([k, v]) => [v, k],
|
|
132
|
+
),
|
|
133
|
+
) as PropertyByNumberType;
|
|
134
|
+
|
|
135
|
+
export const PropertyByPropertySetType = {
|
|
136
|
+
[PropertySetType.reserved]: [],
|
|
137
|
+
[PropertySetType.connect]: [
|
|
138
|
+
propertyToId.sessionExpiryInterval,
|
|
139
|
+
propertyToId.authenticationMethod,
|
|
140
|
+
propertyToId.authenticationData,
|
|
141
|
+
propertyToId.requestProblemInformation,
|
|
142
|
+
propertyToId.requestResponseInformation,
|
|
143
|
+
propertyToId.receiveMaximum,
|
|
144
|
+
propertyToId.topicAliasMaximum,
|
|
145
|
+
propertyToId.userProperty,
|
|
146
|
+
propertyToId.maximumPacketSize,
|
|
147
|
+
],
|
|
148
|
+
[PropertySetType.connack]: [
|
|
149
|
+
propertyToId.sessionExpiryInterval,
|
|
150
|
+
propertyToId.assignedClientIdentifier,
|
|
151
|
+
propertyToId.serverKeepAlive,
|
|
152
|
+
propertyToId.authenticationMethod,
|
|
153
|
+
propertyToId.authenticationData,
|
|
154
|
+
propertyToId.responseInformation,
|
|
155
|
+
propertyToId.serverReference,
|
|
156
|
+
propertyToId.reasonString,
|
|
157
|
+
propertyToId.receiveMaximum,
|
|
158
|
+
propertyToId.topicAliasMaximum,
|
|
159
|
+
propertyToId.maximumQos,
|
|
160
|
+
propertyToId.retainAvailable,
|
|
161
|
+
propertyToId.userProperty,
|
|
162
|
+
propertyToId.maximumPacketSize,
|
|
163
|
+
propertyToId.wildcardSubscriptionAvailable,
|
|
164
|
+
propertyToId.subscriptionIdentifierAvailable,
|
|
165
|
+
propertyToId.sharedSubscriptionAvailable,
|
|
166
|
+
],
|
|
167
|
+
[PropertySetType.publish]: [
|
|
168
|
+
propertyToId.payloadFormatIndicator,
|
|
169
|
+
propertyToId.messageExpiryInterval,
|
|
170
|
+
propertyToId.contentType,
|
|
171
|
+
propertyToId.responseTopic,
|
|
172
|
+
propertyToId.correlationData,
|
|
173
|
+
propertyToId.subscriptionIdentifiers,
|
|
174
|
+
propertyToId.topicAlias,
|
|
175
|
+
propertyToId.userProperty,
|
|
176
|
+
],
|
|
177
|
+
[PropertySetType.subscribe]: [
|
|
178
|
+
propertyToId.subscriptionIdentifier,
|
|
179
|
+
propertyToId.userProperty,
|
|
180
|
+
],
|
|
181
|
+
[PropertySetType.unsubscribe]: [
|
|
182
|
+
propertyToId.userProperty,
|
|
183
|
+
],
|
|
184
|
+
|
|
185
|
+
[PropertySetType.disconnect]: [
|
|
186
|
+
propertyToId.sessionExpiryInterval,
|
|
187
|
+
propertyToId.serverReference,
|
|
188
|
+
propertyToId.reasonString,
|
|
189
|
+
propertyToId.userProperty,
|
|
190
|
+
],
|
|
191
|
+
[PropertySetType.auth]: [
|
|
192
|
+
propertyToId.authenticationMethod,
|
|
193
|
+
propertyToId.authenticationData,
|
|
194
|
+
propertyToId.reasonString,
|
|
195
|
+
propertyToId.userProperty,
|
|
196
|
+
],
|
|
197
|
+
[PropertySetType.puback]: [
|
|
198
|
+
propertyToId.reasonString,
|
|
199
|
+
propertyToId.userProperty,
|
|
200
|
+
],
|
|
201
|
+
[PropertySetType.pubrec]: [
|
|
202
|
+
propertyToId.reasonString,
|
|
203
|
+
propertyToId.userProperty,
|
|
204
|
+
],
|
|
205
|
+
[PropertySetType.pubrel]: [
|
|
206
|
+
propertyToId.reasonString,
|
|
207
|
+
propertyToId.userProperty,
|
|
208
|
+
],
|
|
209
|
+
[PropertySetType.pubcomp]: [
|
|
210
|
+
propertyToId.reasonString,
|
|
211
|
+
propertyToId.userProperty,
|
|
212
|
+
],
|
|
213
|
+
[PropertySetType.suback]: [
|
|
214
|
+
propertyToId.reasonString,
|
|
215
|
+
propertyToId.userProperty,
|
|
216
|
+
],
|
|
217
|
+
[PropertySetType.unsuback]: [
|
|
218
|
+
propertyToId.reasonString,
|
|
219
|
+
propertyToId.userProperty,
|
|
220
|
+
],
|
|
221
|
+
[PropertySetType.pingreq]: [],
|
|
222
|
+
[PropertySetType.pingres]: [],
|
|
223
|
+
|
|
224
|
+
[PropertySetType.will]: [
|
|
225
|
+
propertyToId.payloadFormatIndicator,
|
|
226
|
+
propertyToId.messageExpiryInterval,
|
|
227
|
+
propertyToId.contentType,
|
|
228
|
+
propertyToId.responseTopic,
|
|
229
|
+
propertyToId.correlationData,
|
|
230
|
+
propertyToId.willDelayInterval,
|
|
231
|
+
propertyToId.userProperty,
|
|
232
|
+
],
|
|
233
|
+
} as const;
|
|
234
|
+
|
|
235
|
+
// helper types
|
|
236
|
+
type PropertyIdsToKeys<T extends readonly ValidPropertyNumber[]> = {
|
|
237
|
+
[K in T[number]]: (typeof propertyByNumber)[K];
|
|
238
|
+
}[T[number]];
|
|
239
|
+
|
|
240
|
+
// from AllMqttv5Properties pick the ones returned by PropertyIdsToKeys for this type
|
|
241
|
+
type GeneratePacketTypeProperties<T extends readonly ValidPropertyNumber[]> =
|
|
242
|
+
Pick<AllMqttv5Properties, PropertyIdsToKeys<T>>;
|
|
243
|
+
|
|
244
|
+
export type PropsByPacketSetType = {
|
|
245
|
+
[K in TPropertySetType]: GeneratePacketTypeProperties<
|
|
246
|
+
typeof PropertyByPropertySetType[K]
|
|
247
|
+
>;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// props per PacketType
|
|
251
|
+
export type ConnectProperties =
|
|
252
|
+
PropsByPacketSetType[typeof PropertySetType.connect];
|
|
253
|
+
export type ConnackProperties =
|
|
254
|
+
PropsByPacketSetType[typeof PropertySetType.connack];
|
|
255
|
+
export type PublishProperties =
|
|
256
|
+
PropsByPacketSetType[typeof PropertySetType.publish];
|
|
257
|
+
export type PubackProperties =
|
|
258
|
+
PropsByPacketSetType[typeof PropertySetType.puback];
|
|
259
|
+
export type PubrecProperties =
|
|
260
|
+
PropsByPacketSetType[typeof PropertySetType.pubrec];
|
|
261
|
+
export type PubrelProperties =
|
|
262
|
+
PropsByPacketSetType[typeof PropertySetType.pubrel];
|
|
263
|
+
export type PubcompProperties =
|
|
264
|
+
PropsByPacketSetType[typeof PropertySetType.pubcomp];
|
|
265
|
+
export type SubscribeProperties =
|
|
266
|
+
PropsByPacketSetType[typeof PropertySetType.subscribe];
|
|
267
|
+
export type SubackProperties =
|
|
268
|
+
PropsByPacketSetType[typeof PropertySetType.suback];
|
|
269
|
+
export type UnsubscribeProperties =
|
|
270
|
+
PropsByPacketSetType[typeof PropertySetType.unsubscribe];
|
|
271
|
+
export type UnsubackProperties =
|
|
272
|
+
PropsByPacketSetType[typeof PropertySetType.unsuback];
|
|
273
|
+
export type DisconnectProperties =
|
|
274
|
+
PropsByPacketSetType[typeof PropertySetType.disconnect];
|
|
275
|
+
export type AuthProperties = PropsByPacketSetType[typeof PropertySetType.auth];
|
|
276
|
+
export type WillProperties = PropsByPacketSetType[typeof PropertySetType.will];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { ReasonCode, reasonCodeToString } from "./ReasonCode.ts";
|
|
4
|
+
import { PacketType } from "./mod.ts";
|
|
5
|
+
|
|
6
|
+
test("lookup of reason codes works", () => {
|
|
7
|
+
assert.equal(
|
|
8
|
+
reasonCodeToString(PacketType.connect, ReasonCode.success),
|
|
9
|
+
"Success",
|
|
10
|
+
"Succes on Connect works",
|
|
11
|
+
);
|
|
12
|
+
assert.equal(
|
|
13
|
+
reasonCodeToString(PacketType.suback, ReasonCode.success),
|
|
14
|
+
"Granted QoS 0",
|
|
15
|
+
"Granted QoS 0 on Suback works",
|
|
16
|
+
);
|
|
17
|
+
assert.equal(
|
|
18
|
+
reasonCodeToString(PacketType.disconnect, ReasonCode.success),
|
|
19
|
+
"Normal disconnection",
|
|
20
|
+
"Normal disconnection on Disconnect works",
|
|
21
|
+
);
|
|
22
|
+
});
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Possible MQTT V5 reason codes
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { PacketType } from "./PacketType.ts";
|
|
6
|
+
import type { InvertRecord } from "./types.ts";
|
|
7
|
+
|
|
8
|
+
export const ReasonCode = {
|
|
9
|
+
success: 0x00,
|
|
10
|
+
normalDisconnection: 0x00,
|
|
11
|
+
grantedQos0: 0x00,
|
|
12
|
+
grantedQos1: 0x01,
|
|
13
|
+
grantedQos2: 0x02,
|
|
14
|
+
disconnectWithWillMessage: 0x04,
|
|
15
|
+
noMatchingSubscribers: 0x10,
|
|
16
|
+
noSubscriptionExisted: 0x11,
|
|
17
|
+
continueAuthentication: 0x18,
|
|
18
|
+
reAuthenticate: 0x19,
|
|
19
|
+
unspecifiedError: 0x80,
|
|
20
|
+
malformedPacket: 0x81,
|
|
21
|
+
protocolError: 0x82,
|
|
22
|
+
implementationSpecificError: 0x83,
|
|
23
|
+
unsupportedProtocolVersion: 0x84,
|
|
24
|
+
clientIdentifierNotValid: 0x85,
|
|
25
|
+
badUserNameOrPassword: 0x86,
|
|
26
|
+
notAuthorized: 0x87,
|
|
27
|
+
serverUnavailable: 0x88,
|
|
28
|
+
serverBusy: 0x89,
|
|
29
|
+
banned: 0x8a,
|
|
30
|
+
serverShuttingDown: 0x8b,
|
|
31
|
+
badAuthenticationMethod: 0x8c,
|
|
32
|
+
keepAliveTimeout: 0x8d,
|
|
33
|
+
sessionTakenOver: 0x8e,
|
|
34
|
+
topicFilterInvalid: 0x8f,
|
|
35
|
+
topicNameInvalid: 0x90,
|
|
36
|
+
packetIdentifierInUse: 0x91,
|
|
37
|
+
packetIdentifierNotFound: 0x92,
|
|
38
|
+
receiveMaximumExceeded: 0x93,
|
|
39
|
+
topicAliasInvalid: 0x94,
|
|
40
|
+
packetTooLarge: 0x95,
|
|
41
|
+
messageRateTooHigh: 0x96,
|
|
42
|
+
quotaExceeded: 0x97,
|
|
43
|
+
administrativeAction: 0x98,
|
|
44
|
+
payloadFormatInvalid: 0x99,
|
|
45
|
+
retainNotSupported: 0x9a,
|
|
46
|
+
qosNotSupported: 0x9b,
|
|
47
|
+
useAnotherServer: 0x9c,
|
|
48
|
+
serverMoved: 0x9d,
|
|
49
|
+
sharedSubscriptionsNotSupported: 0x9e,
|
|
50
|
+
connectionRateExceeded: 0x9f,
|
|
51
|
+
maximumConnectTime: 0xa0,
|
|
52
|
+
subscriptionIdentifiersNotSupported: 0xa1,
|
|
53
|
+
wildcardSubscriptionsNotSupported: 0xa2,
|
|
54
|
+
} as const;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Reverse lookup for ReasonCode
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
export type ReasonCodeByNumberType = InvertRecord<typeof ReasonCode>;
|
|
61
|
+
export const ReasonCodeByNumber = Object
|
|
62
|
+
.fromEntries(
|
|
63
|
+
Object.entries(ReasonCode).map(([k, v]) => [v, k]),
|
|
64
|
+
) as ReasonCodeByNumberType;
|
|
65
|
+
|
|
66
|
+
export const ReasonCodebyPacket = {
|
|
67
|
+
[PacketType.connack]: [
|
|
68
|
+
ReasonCode.success,
|
|
69
|
+
ReasonCode.unspecifiedError,
|
|
70
|
+
ReasonCode.malformedPacket,
|
|
71
|
+
ReasonCode.protocolError,
|
|
72
|
+
ReasonCode.implementationSpecificError,
|
|
73
|
+
ReasonCode.unsupportedProtocolVersion,
|
|
74
|
+
ReasonCode.clientIdentifierNotValid,
|
|
75
|
+
ReasonCode.badUserNameOrPassword,
|
|
76
|
+
ReasonCode.notAuthorized,
|
|
77
|
+
ReasonCode.serverUnavailable,
|
|
78
|
+
ReasonCode.serverBusy,
|
|
79
|
+
ReasonCode.banned,
|
|
80
|
+
ReasonCode.badAuthenticationMethod,
|
|
81
|
+
ReasonCode.topicNameInvalid,
|
|
82
|
+
ReasonCode.packetTooLarge,
|
|
83
|
+
ReasonCode.quotaExceeded,
|
|
84
|
+
ReasonCode.payloadFormatInvalid,
|
|
85
|
+
ReasonCode.retainNotSupported,
|
|
86
|
+
ReasonCode.qosNotSupported,
|
|
87
|
+
ReasonCode.useAnotherServer,
|
|
88
|
+
ReasonCode.serverMoved,
|
|
89
|
+
ReasonCode.connectionRateExceeded,
|
|
90
|
+
],
|
|
91
|
+
[PacketType.puback]: [
|
|
92
|
+
ReasonCode.success,
|
|
93
|
+
ReasonCode.noMatchingSubscribers,
|
|
94
|
+
ReasonCode.unspecifiedError,
|
|
95
|
+
ReasonCode.implementationSpecificError,
|
|
96
|
+
ReasonCode.notAuthorized,
|
|
97
|
+
ReasonCode.topicNameInvalid,
|
|
98
|
+
ReasonCode.packetIdentifierInUse,
|
|
99
|
+
ReasonCode.quotaExceeded,
|
|
100
|
+
ReasonCode.payloadFormatInvalid,
|
|
101
|
+
],
|
|
102
|
+
[PacketType.pubrec]: [
|
|
103
|
+
ReasonCode.success,
|
|
104
|
+
ReasonCode.noMatchingSubscribers,
|
|
105
|
+
ReasonCode.unspecifiedError,
|
|
106
|
+
ReasonCode.implementationSpecificError,
|
|
107
|
+
ReasonCode.notAuthorized,
|
|
108
|
+
ReasonCode.topicNameInvalid,
|
|
109
|
+
ReasonCode.packetIdentifierInUse,
|
|
110
|
+
ReasonCode.quotaExceeded,
|
|
111
|
+
ReasonCode.payloadFormatInvalid,
|
|
112
|
+
],
|
|
113
|
+
[PacketType.pubrel]: [
|
|
114
|
+
ReasonCode.success,
|
|
115
|
+
ReasonCode.packetIdentifierNotFound,
|
|
116
|
+
],
|
|
117
|
+
[PacketType.pubcomp]: [
|
|
118
|
+
ReasonCode.success,
|
|
119
|
+
ReasonCode.packetIdentifierNotFound,
|
|
120
|
+
],
|
|
121
|
+
[PacketType.unsuback]: [
|
|
122
|
+
ReasonCode.success,
|
|
123
|
+
ReasonCode.noSubscriptionExisted,
|
|
124
|
+
ReasonCode.unspecifiedError,
|
|
125
|
+
ReasonCode.implementationSpecificError,
|
|
126
|
+
ReasonCode.notAuthorized,
|
|
127
|
+
ReasonCode.topicFilterInvalid,
|
|
128
|
+
ReasonCode.packetIdentifierInUse,
|
|
129
|
+
],
|
|
130
|
+
[PacketType.auth]: [
|
|
131
|
+
ReasonCode.success,
|
|
132
|
+
ReasonCode.continueAuthentication,
|
|
133
|
+
ReasonCode.reAuthenticate,
|
|
134
|
+
],
|
|
135
|
+
[PacketType.disconnect]: [
|
|
136
|
+
ReasonCode.normalDisconnection,
|
|
137
|
+
ReasonCode.disconnectWithWillMessage,
|
|
138
|
+
ReasonCode.unspecifiedError,
|
|
139
|
+
ReasonCode.malformedPacket,
|
|
140
|
+
ReasonCode.protocolError,
|
|
141
|
+
ReasonCode.implementationSpecificError,
|
|
142
|
+
ReasonCode.notAuthorized,
|
|
143
|
+
ReasonCode.serverBusy,
|
|
144
|
+
ReasonCode.serverShuttingDown,
|
|
145
|
+
ReasonCode.badAuthenticationMethod,
|
|
146
|
+
ReasonCode.keepAliveTimeout,
|
|
147
|
+
ReasonCode.sessionTakenOver,
|
|
148
|
+
ReasonCode.topicFilterInvalid,
|
|
149
|
+
ReasonCode.topicNameInvalid,
|
|
150
|
+
ReasonCode.receiveMaximumExceeded,
|
|
151
|
+
ReasonCode.topicAliasInvalid,
|
|
152
|
+
ReasonCode.packetTooLarge,
|
|
153
|
+
ReasonCode.messageRateTooHigh,
|
|
154
|
+
ReasonCode.quotaExceeded,
|
|
155
|
+
ReasonCode.administrativeAction,
|
|
156
|
+
ReasonCode.payloadFormatInvalid,
|
|
157
|
+
ReasonCode.retainNotSupported,
|
|
158
|
+
ReasonCode.qosNotSupported,
|
|
159
|
+
ReasonCode.useAnotherServer,
|
|
160
|
+
ReasonCode.serverMoved,
|
|
161
|
+
ReasonCode.sharedSubscriptionsNotSupported,
|
|
162
|
+
ReasonCode.connectionRateExceeded,
|
|
163
|
+
ReasonCode.maximumConnectTime,
|
|
164
|
+
ReasonCode.subscriptionIdentifiersNotSupported,
|
|
165
|
+
ReasonCode.wildcardSubscriptionsNotSupported,
|
|
166
|
+
],
|
|
167
|
+
[PacketType.suback]: [
|
|
168
|
+
ReasonCode.grantedQos0,
|
|
169
|
+
ReasonCode.grantedQos1,
|
|
170
|
+
ReasonCode.grantedQos2,
|
|
171
|
+
ReasonCode.unspecifiedError,
|
|
172
|
+
ReasonCode.implementationSpecificError,
|
|
173
|
+
ReasonCode.notAuthorized,
|
|
174
|
+
ReasonCode.topicFilterInvalid,
|
|
175
|
+
ReasonCode.packetIdentifierInUse,
|
|
176
|
+
ReasonCode.quotaExceeded,
|
|
177
|
+
ReasonCode.sharedSubscriptionsNotSupported,
|
|
178
|
+
ReasonCode.subscriptionIdentifiersNotSupported,
|
|
179
|
+
ReasonCode.wildcardSubscriptionsNotSupported,
|
|
180
|
+
],
|
|
181
|
+
} as const;
|
|
182
|
+
|
|
183
|
+
const reasonCodesToString = {
|
|
184
|
+
[0x00]: "Success",
|
|
185
|
+
[0x01]: "Granted QoS 1",
|
|
186
|
+
[0x02]: "Granted QoS 2",
|
|
187
|
+
[0x04]: "Disconnect with Will Message",
|
|
188
|
+
[0x10]: "No matching subscribers",
|
|
189
|
+
[0x11]: "No subscription existed",
|
|
190
|
+
[0x18]: "Continue authentication",
|
|
191
|
+
[0x19]: "Re-authenticate",
|
|
192
|
+
[0x80]: "Unspecified error",
|
|
193
|
+
[0x81]: "Malformed Packet",
|
|
194
|
+
[0x82]: "Protocol Error",
|
|
195
|
+
[0x83]: "Implementation specific error",
|
|
196
|
+
[0x84]: "Unsupported Protocol Version",
|
|
197
|
+
[0x85]: "Client Identifier not valid",
|
|
198
|
+
[0x86]: "Bad User Name or Password",
|
|
199
|
+
[0x87]: "Not authorized",
|
|
200
|
+
[0x88]: "Server unavailable",
|
|
201
|
+
[0x89]: "Server busy",
|
|
202
|
+
[0x8a]: "Banned",
|
|
203
|
+
[0x8b]: "Server shutting down",
|
|
204
|
+
[0x8c]: "Bad authentication method",
|
|
205
|
+
[0x8d]: "Keep Alive timeout",
|
|
206
|
+
[0x8e]: "Session taken over",
|
|
207
|
+
[0x8f]: "Topic Filter invalid",
|
|
208
|
+
[0x90]: "Topic Name invalid",
|
|
209
|
+
[0x91]: "Packet Identifier in use",
|
|
210
|
+
[0x92]: "Packet Identifier not found",
|
|
211
|
+
[0x93]: "Receive Maximum exceeded",
|
|
212
|
+
[0x94]: "Topic Alias invalid",
|
|
213
|
+
[0x95]: "Packet too large",
|
|
214
|
+
[0x96]: "Message rate too high",
|
|
215
|
+
[0x97]: "Quota exceeded",
|
|
216
|
+
[0x98]: "Administrative action",
|
|
217
|
+
[0x99]: "Payload format invalid",
|
|
218
|
+
[0x9a]: "Retain not supported",
|
|
219
|
+
[0x9b]: "QoS not supported",
|
|
220
|
+
[0x9c]: "Use another server",
|
|
221
|
+
[0x9d]: "Server moved",
|
|
222
|
+
[0x9e]: "Shared Subscriptions not supported",
|
|
223
|
+
[0x9f]: "Connection rate exceeded",
|
|
224
|
+
[0xa0]: "Maximum connect time",
|
|
225
|
+
[0xa1]: "Subscription Identifiers not supported",
|
|
226
|
+
[0xa2]: "Wildcard Subscriptions not supported",
|
|
227
|
+
} as const;
|
|
228
|
+
|
|
229
|
+
// Can't import this from types as this would create an import loop
|
|
230
|
+
type TPacketType = typeof PacketType[keyof typeof PacketType];
|
|
231
|
+
export type TReasonCode = typeof ReasonCode[keyof typeof ReasonCode];
|
|
232
|
+
type TReasonCodeByPacket = keyof typeof ReasonCodebyPacket;
|
|
233
|
+
|
|
234
|
+
export function reasonCodeToString(
|
|
235
|
+
packetType: TPacketType,
|
|
236
|
+
code: TReasonCode,
|
|
237
|
+
): string {
|
|
238
|
+
if (code === 0) {
|
|
239
|
+
if (packetType === PacketType.disconnect) {
|
|
240
|
+
return "Normal disconnection";
|
|
241
|
+
}
|
|
242
|
+
if (packetType === PacketType.suback) {
|
|
243
|
+
return "Granted QoS 0";
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return reasonCodesToString[code];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export function isValidReasonCode(
|
|
250
|
+
packetType: TPacketType,
|
|
251
|
+
code: number,
|
|
252
|
+
): boolean {
|
|
253
|
+
const validReasonCodes =
|
|
254
|
+
ReasonCodebyPacket[packetType as TReasonCodeByPacket] as readonly number[];
|
|
255
|
+
return validReasonCodes.includes(code);
|
|
256
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*RetainHandling
|
|
3
|
+
0 = Send retained messages at the time of the subscribe
|
|
4
|
+
1 = Send retained messages at subscribe only if the subscription does not currently exist
|
|
5
|
+
2 = Do not send retained messages at the time of the subscribe
|
|
6
|
+
*/
|
|
7
|
+
export const RetainHandling = {
|
|
8
|
+
sendRetained: 0,
|
|
9
|
+
ifSubscriptionNotExists: 1,
|
|
10
|
+
noRetain: 2,
|
|
11
|
+
} as const;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { decode, encode, MQTTLevel, PacketType, ReasonCode } from "./mod.ts";
|
|
4
|
+
import type { AuthPacket, CodecOpts } from "./mod.ts";
|
|
5
|
+
|
|
6
|
+
const codecOptsV5: CodecOpts = {
|
|
7
|
+
protocolLevel: MQTTLevel.v5,
|
|
8
|
+
maxIncomingPacketSize: 0xffff,
|
|
9
|
+
maxOutgoingPacketSize: 0xffff,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const codecOptsV4: CodecOpts = {
|
|
13
|
+
protocolLevel: MQTTLevel.v4,
|
|
14
|
+
maxIncomingPacketSize: 0xffff,
|
|
15
|
+
maxOutgoingPacketSize: 0xffff,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
test("decode Auth V5 with invalid reasonCode", () => {
|
|
19
|
+
assert.throws(
|
|
20
|
+
() =>
|
|
21
|
+
decode(
|
|
22
|
+
Uint8Array.from([
|
|
23
|
+
// fixedHeader
|
|
24
|
+
0x20, // packetType + flags
|
|
25
|
+
2, // remainingLength
|
|
26
|
+
// variableHeader
|
|
27
|
+
0, // reason code
|
|
28
|
+
64, // (reserved)
|
|
29
|
+
]),
|
|
30
|
+
codecOptsV5,
|
|
31
|
+
),
|
|
32
|
+
/Invalid reason code/,
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("decode Auth V5 as V4", () => {
|
|
37
|
+
assert.throws(
|
|
38
|
+
() =>
|
|
39
|
+
decode(
|
|
40
|
+
Uint8Array.from([
|
|
41
|
+
// fixedHeader
|
|
42
|
+
0xf0, // packetType + flags
|
|
43
|
+
2, // remainingLength
|
|
44
|
+
// variableHeader
|
|
45
|
+
0, // reason code
|
|
46
|
+
0, // properties length
|
|
47
|
+
]),
|
|
48
|
+
codecOptsV4,
|
|
49
|
+
),
|
|
50
|
+
/Invalid protocol level/,
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("encode/decode minimal auth V5", () => {
|
|
55
|
+
const packet = {
|
|
56
|
+
protocolLevel: MQTTLevel.v5,
|
|
57
|
+
type: PacketType.auth,
|
|
58
|
+
reasonCode: ReasonCode.success,
|
|
59
|
+
};
|
|
60
|
+
const encoded = encode(packet, codecOptsV5);
|
|
61
|
+
assert.deepStrictEqual(
|
|
62
|
+
encoded,
|
|
63
|
+
Uint8Array.from([
|
|
64
|
+
// fixedHeader
|
|
65
|
+
|
|
66
|
+
0xf0, // auth packet + flags
|
|
67
|
+
2, // remaining length
|
|
68
|
+
0, // reason code
|
|
69
|
+
0, // property length
|
|
70
|
+
]),
|
|
71
|
+
);
|
|
72
|
+
const decoded = decode(encoded, codecOptsV5);
|
|
73
|
+
assert.deepStrictEqual(decoded, { ...packet, properties: {} });
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("encode/decode auth V5", () => {
|
|
77
|
+
const packet: AuthPacket = {
|
|
78
|
+
protocolLevel: 5,
|
|
79
|
+
type: PacketType.auth,
|
|
80
|
+
reasonCode: ReasonCode.continueAuthentication,
|
|
81
|
+
properties: {
|
|
82
|
+
userProperty: [["key", "value"]],
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
const encoded = encode(packet, codecOptsV5);
|
|
86
|
+
assert.deepStrictEqual(
|
|
87
|
+
encoded,
|
|
88
|
+
Uint8Array.from([
|
|
89
|
+
// fixedHeader
|
|
90
|
+
|
|
91
|
+
0xf0, // auth packet + flags
|
|
92
|
+
15, // remaining length
|
|
93
|
+
24, // reason code
|
|
94
|
+
13, // property length
|
|
95
|
+
38, // user property
|
|
96
|
+
0, // string MSB
|
|
97
|
+
3, // string LSB
|
|
98
|
+
107, // k
|
|
99
|
+
101, // e
|
|
100
|
+
121, // y
|
|
101
|
+
0, // string MSB
|
|
102
|
+
5, // string LSB
|
|
103
|
+
118, // v
|
|
104
|
+
97, // a
|
|
105
|
+
108, // l
|
|
106
|
+
117, // u
|
|
107
|
+
101, // e
|
|
108
|
+
]),
|
|
109
|
+
);
|
|
110
|
+
const decoded = decode(encoded, codecOptsV5);
|
|
111
|
+
assert.deepStrictEqual(decoded, packet);
|
|
112
|
+
});
|