@seriousme/opifex 1.9.4 → 1.10.1

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.
Files changed (304) hide show
  1. package/README.md +37 -26
  2. package/bin/conformanceServer.ts +3 -2
  3. package/bin/demoServer.ts +3 -2
  4. package/bin/mqtt.ts +126 -117
  5. package/client/client.ts +35 -15
  6. package/client/context.ts +42 -22
  7. package/client/deps.ts +5 -0
  8. package/client/handlers/handleConnack.ts +17 -5
  9. package/client/handlers/handlePublish.ts +4 -1
  10. package/client/handlers/handlePubrec.ts +3 -1
  11. package/client/handlers/handlePubrel.ts +3 -1
  12. package/client/handlers/handleSuback.ts +3 -1
  13. package/client/mod.ts +8 -1
  14. package/client/store/memoryStore.ts +2 -1
  15. package/dev_utils/dummyConn.ts +17 -2
  16. package/dist/bin/conformanceServer.js +3 -2
  17. package/dist/bin/conformanceServer.js.map +1 -1
  18. package/dist/bin/demoServer.js +3 -2
  19. package/dist/bin/demoServer.js.map +1 -1
  20. package/dist/bin/mqtt.d.ts +29 -0
  21. package/dist/bin/mqtt.d.ts.map +1 -1
  22. package/dist/bin/mqtt.js +101 -96
  23. package/dist/bin/mqtt.js.map +1 -1
  24. package/dist/client/client.d.ts +7 -4
  25. package/dist/client/client.d.ts.map +1 -1
  26. package/dist/client/client.js +17 -9
  27. package/dist/client/client.js.map +1 -1
  28. package/dist/client/context.d.ts +3 -1
  29. package/dist/client/context.d.ts.map +1 -1
  30. package/dist/client/context.js +27 -13
  31. package/dist/client/context.js.map +1 -1
  32. package/dist/client/deps.d.ts +3 -2
  33. package/dist/client/deps.d.ts.map +1 -1
  34. package/dist/client/deps.js +2 -1
  35. package/dist/client/deps.js.map +1 -1
  36. package/dist/client/handlers/handleConnack.d.ts +1 -1
  37. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  38. package/dist/client/handlers/handleConnack.js +14 -5
  39. package/dist/client/handlers/handleConnack.js.map +1 -1
  40. package/dist/client/handlers/handlePublish.d.ts +1 -1
  41. package/dist/client/handlers/handlePublish.d.ts.map +1 -1
  42. package/dist/client/handlers/handlePublish.js +2 -0
  43. package/dist/client/handlers/handlePublish.js.map +1 -1
  44. package/dist/client/handlers/handlePubrec.d.ts +1 -1
  45. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  46. package/dist/client/handlers/handlePubrec.js +1 -0
  47. package/dist/client/handlers/handlePubrec.js.map +1 -1
  48. package/dist/client/handlers/handlePubrel.d.ts +1 -1
  49. package/dist/client/handlers/handlePubrel.d.ts.map +1 -1
  50. package/dist/client/handlers/handlePubrel.js +1 -0
  51. package/dist/client/handlers/handlePubrel.js.map +1 -1
  52. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  53. package/dist/client/handlers/handleSuback.js +3 -1
  54. package/dist/client/handlers/handleSuback.js.map +1 -1
  55. package/dist/client/mod.d.ts +3 -1
  56. package/dist/client/mod.d.ts.map +1 -1
  57. package/dist/client/mod.js +2 -1
  58. package/dist/client/mod.js.map +1 -1
  59. package/dist/client/store/memoryStore.d.ts +1 -1
  60. package/dist/client/store/memoryStore.d.ts.map +1 -1
  61. package/dist/client/store/memoryStore.js.map +1 -1
  62. package/dist/mqttConn/mqttConn.d.ts +13 -8
  63. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  64. package/dist/mqttConn/mqttConn.js +27 -12
  65. package/dist/mqttConn/mqttConn.js.map +1 -1
  66. package/dist/mqttPacket/PacketType.d.ts +1 -0
  67. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  68. package/dist/mqttPacket/PacketType.js +1 -0
  69. package/dist/mqttPacket/PacketType.js.map +1 -1
  70. package/dist/mqttPacket/Properties.d.ts +157 -0
  71. package/dist/mqttPacket/Properties.d.ts.map +1 -0
  72. package/dist/mqttPacket/Properties.js +177 -0
  73. package/dist/mqttPacket/Properties.js.map +1 -0
  74. package/dist/mqttPacket/ReasonCode.d.ts +74 -0
  75. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -0
  76. package/dist/mqttPacket/ReasonCode.js +230 -0
  77. package/dist/mqttPacket/ReasonCode.js.map +1 -0
  78. package/dist/mqttPacket/RetainHandling.d.ts +12 -0
  79. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -0
  80. package/dist/mqttPacket/RetainHandling.js +12 -0
  81. package/dist/mqttPacket/RetainHandling.js.map +1 -0
  82. package/dist/mqttPacket/auth.d.ts +21 -0
  83. package/dist/mqttPacket/auth.d.ts.map +1 -0
  84. package/dist/mqttPacket/auth.js +34 -0
  85. package/dist/mqttPacket/auth.js.map +1 -0
  86. package/dist/mqttPacket/connack.d.ts +15 -7
  87. package/dist/mqttPacket/connack.d.ts.map +1 -1
  88. package/dist/mqttPacket/connack.js +43 -15
  89. package/dist/mqttPacket/connack.js.map +1 -1
  90. package/dist/mqttPacket/connect.d.ts +27 -8
  91. package/dist/mqttPacket/connect.d.ts.map +1 -1
  92. package/dist/mqttPacket/connect.js +106 -30
  93. package/dist/mqttPacket/connect.js.map +1 -1
  94. package/dist/mqttPacket/decoder.d.ts +42 -3
  95. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  96. package/dist/mqttPacket/decoder.js +135 -4
  97. package/dist/mqttPacket/decoder.js.map +1 -1
  98. package/dist/mqttPacket/disconnect.d.ts +13 -7
  99. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  100. package/dist/mqttPacket/disconnect.js +45 -6
  101. package/dist/mqttPacket/disconnect.js.map +1 -1
  102. package/dist/mqttPacket/encoder.d.ts +57 -8
  103. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  104. package/dist/mqttPacket/encoder.js +185 -13
  105. package/dist/mqttPacket/encoder.js.map +1 -1
  106. package/dist/mqttPacket/length.d.ts.map +1 -1
  107. package/dist/mqttPacket/length.js +3 -2
  108. package/dist/mqttPacket/length.js.map +1 -1
  109. package/dist/mqttPacket/mod.d.ts +56 -91
  110. package/dist/mqttPacket/mod.d.ts.map +1 -1
  111. package/dist/mqttPacket/mod.js +22 -29
  112. package/dist/mqttPacket/mod.js.map +1 -1
  113. package/dist/mqttPacket/pingreq.d.ts +4 -6
  114. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  115. package/dist/mqttPacket/pingreq.js +5 -4
  116. package/dist/mqttPacket/pingreq.js.map +1 -1
  117. package/dist/mqttPacket/pingres.d.ts +4 -6
  118. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  119. package/dist/mqttPacket/pingres.js +7 -5
  120. package/dist/mqttPacket/pingres.js.map +1 -1
  121. package/dist/mqttPacket/protocolLevels.d.ts +11 -0
  122. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -0
  123. package/dist/mqttPacket/protocolLevels.js +11 -0
  124. package/dist/mqttPacket/protocolLevels.js.map +1 -0
  125. package/dist/mqttPacket/pubblishAcks.d.ts +35 -0
  126. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -0
  127. package/dist/mqttPacket/pubblishAcks.js +56 -0
  128. package/dist/mqttPacket/pubblishAcks.js.map +1 -0
  129. package/dist/mqttPacket/publish.d.ts +19 -8
  130. package/dist/mqttPacket/publish.d.ts.map +1 -1
  131. package/dist/mqttPacket/publish.js +26 -7
  132. package/dist/mqttPacket/publish.js.map +1 -1
  133. package/dist/mqttPacket/suback.d.ts +14 -7
  134. package/dist/mqttPacket/suback.d.ts.map +1 -1
  135. package/dist/mqttPacket/suback.js +41 -20
  136. package/dist/mqttPacket/suback.js.map +1 -1
  137. package/dist/mqttPacket/subscribe.d.ts +24 -9
  138. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  139. package/dist/mqttPacket/subscribe.js +71 -15
  140. package/dist/mqttPacket/subscribe.js.map +1 -1
  141. package/dist/mqttPacket/types.d.ts +33 -0
  142. package/dist/mqttPacket/types.d.ts.map +1 -1
  143. package/dist/mqttPacket/unsuback.d.ts +14 -7
  144. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  145. package/dist/mqttPacket/unsuback.js +29 -6
  146. package/dist/mqttPacket/unsuback.js.map +1 -1
  147. package/dist/mqttPacket/unsubscribe.d.ts +14 -7
  148. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  149. package/dist/mqttPacket/unsubscribe.js +24 -8
  150. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  151. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  152. package/dist/node/wrapNodeSocket.js.map +1 -1
  153. package/dist/persistence/deps.d.ts +1 -1
  154. package/dist/persistence/deps.d.ts.map +1 -1
  155. package/dist/persistence/deps.js +1 -1
  156. package/dist/persistence/deps.js.map +1 -1
  157. package/dist/server/context.d.ts +3 -1
  158. package/dist/server/context.d.ts.map +1 -1
  159. package/dist/server/context.js +8 -2
  160. package/dist/server/context.js.map +1 -1
  161. package/dist/server/deps.d.ts +2 -2
  162. package/dist/server/deps.d.ts.map +1 -1
  163. package/dist/server/deps.js +1 -1
  164. package/dist/server/deps.js.map +1 -1
  165. package/dist/server/handlers/handleConnect.d.ts +1 -1
  166. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  167. package/dist/server/handlers/handleConnect.js +9 -1
  168. package/dist/server/handlers/handleConnect.js.map +1 -1
  169. package/dist/server/handlers/handlePacket.d.ts +1 -1
  170. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  171. package/dist/server/handlers/handlePacket.js +1 -1
  172. package/dist/server/handlers/handlePacket.js.map +1 -1
  173. package/dist/server/handlers/handlePingreq.d.ts.map +1 -1
  174. package/dist/server/handlers/handlePingreq.js +1 -0
  175. package/dist/server/handlers/handlePingreq.js.map +1 -1
  176. package/dist/server/handlers/handlePublish.d.ts +2 -2
  177. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  178. package/dist/server/handlers/handlePublish.js +2 -0
  179. package/dist/server/handlers/handlePublish.js.map +1 -1
  180. package/dist/server/handlers/handlePubrec.d.ts +1 -1
  181. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  182. package/dist/server/handlers/handlePubrec.js +1 -0
  183. package/dist/server/handlers/handlePubrec.js.map +1 -1
  184. package/dist/server/handlers/handlePubrel.d.ts +1 -1
  185. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  186. package/dist/server/handlers/handlePubrel.js +1 -0
  187. package/dist/server/handlers/handlePubrel.js.map +1 -1
  188. package/dist/server/handlers/handleSubscribe.d.ts +1 -1
  189. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  190. package/dist/server/handlers/handleSubscribe.js +2 -1
  191. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  192. package/dist/server/handlers/handleUnsubscribe.d.ts +1 -1
  193. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  194. package/dist/server/handlers/handleUnsubscribe.js +1 -0
  195. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  196. package/dist/server/server.d.ts +2 -2
  197. package/dist/server/server.d.ts.map +1 -1
  198. package/dist/server/server.js +5 -3
  199. package/dist/server/server.js.map +1 -1
  200. package/dist/socket/socket.d.ts.map +1 -1
  201. package/dist/socket/socket.js +6 -1
  202. package/dist/socket/socket.js.map +1 -1
  203. package/dist/utils/assert.d.ts +0 -3
  204. package/dist/utils/assert.d.ts.map +1 -1
  205. package/dist/utils/assert.js +0 -7
  206. package/dist/utils/assert.js.map +1 -1
  207. package/dist/utils/mod.d.ts +0 -3
  208. package/dist/utils/mod.d.ts.map +1 -1
  209. package/dist/utils/mod.js +0 -2
  210. package/dist/utils/mod.js.map +1 -1
  211. package/mqttConn/mqttConn.test.ts +27 -12
  212. package/mqttConn/mqttConn.ts +45 -14
  213. package/mqttPacket/PacketType.ts +1 -0
  214. package/mqttPacket/Properties.ts +276 -0
  215. package/mqttPacket/ReasonCode.test.ts +22 -0
  216. package/mqttPacket/ReasonCode.ts +256 -0
  217. package/mqttPacket/RetainHandling.ts +11 -0
  218. package/mqttPacket/auth.test.ts +112 -0
  219. package/mqttPacket/auth.ts +72 -0
  220. package/mqttPacket/connack.test.ts +84 -64
  221. package/mqttPacket/connack.ts +84 -20
  222. package/mqttPacket/connect.test.ts +497 -18
  223. package/mqttPacket/connect.ts +167 -36
  224. package/mqttPacket/decoder.test.ts +33 -16
  225. package/mqttPacket/decoder.ts +173 -5
  226. package/mqttPacket/disconnect.test.ts +97 -18
  227. package/mqttPacket/disconnect.ts +82 -10
  228. package/mqttPacket/encoder.test.ts +32 -8
  229. package/mqttPacket/encoder.ts +236 -11
  230. package/mqttPacket/length.ts +3 -2
  231. package/mqttPacket/mod.ts +75 -39
  232. package/mqttPacket/pingreq.test.ts +52 -4
  233. package/mqttPacket/pingreq.ts +20 -7
  234. package/mqttPacket/pingres.test.ts +52 -4
  235. package/mqttPacket/pingres.ts +22 -8
  236. package/mqttPacket/properties.test.ts +193 -0
  237. package/mqttPacket/protocolLevels.ts +13 -0
  238. package/mqttPacket/pubblishAcks.ts +117 -0
  239. package/mqttPacket/publish.test.ts +212 -133
  240. package/mqttPacket/publish.ts +69 -14
  241. package/mqttPacket/publishAcks.test.ts +128 -0
  242. package/mqttPacket/suback.test.ts +71 -27
  243. package/mqttPacket/suback.ts +78 -26
  244. package/mqttPacket/subscribe.test.ts +132 -43
  245. package/mqttPacket/subscribe.ts +125 -22
  246. package/mqttPacket/types.ts +40 -0
  247. package/mqttPacket/unsuback.test.ts +80 -30
  248. package/mqttPacket/unsuback.ts +65 -10
  249. package/mqttPacket/unsubscribe.test.ts +59 -34
  250. package/mqttPacket/unsubscribe.ts +61 -14
  251. package/node/wrapNodeSocket.ts +2 -1
  252. package/package.json +2 -2
  253. package/persistence/deps.ts +1 -1
  254. package/persistence/memory/memoryPersistence.test.ts +5 -1
  255. package/server/context.ts +23 -10
  256. package/server/deps.ts +2 -0
  257. package/server/handlers/handleConnect.ts +12 -9
  258. package/server/handlers/handlePacket.ts +10 -11
  259. package/server/handlers/handlePingreq.ts +1 -0
  260. package/server/handlers/handlePublish.ts +6 -2
  261. package/server/handlers/handlePubrec.ts +3 -1
  262. package/server/handlers/handlePubrel.ts +3 -1
  263. package/server/handlers/handleSubscribe.ts +3 -6
  264. package/server/handlers/handleUnsubscribe.ts +3 -1
  265. package/server/server.ts +8 -12
  266. package/server/test/handleConnect.test.ts +2 -1
  267. package/server/test/test-handlers.ts +2 -1
  268. package/socket/socket.ts +5 -1
  269. package/utils/assert.ts +0 -18
  270. package/utils/mod.ts +0 -3
  271. package/dist/mqttPacket/puback.d.ts +0 -16
  272. package/dist/mqttPacket/puback.d.ts.map +0 -1
  273. package/dist/mqttPacket/puback.js +0 -21
  274. package/dist/mqttPacket/puback.js.map +0 -1
  275. package/dist/mqttPacket/pubcomp.d.ts +0 -17
  276. package/dist/mqttPacket/pubcomp.d.ts.map +0 -1
  277. package/dist/mqttPacket/pubcomp.js +0 -21
  278. package/dist/mqttPacket/pubcomp.js.map +0 -1
  279. package/dist/mqttPacket/pubrec.d.ts +0 -17
  280. package/dist/mqttPacket/pubrec.d.ts.map +0 -1
  281. package/dist/mqttPacket/pubrec.js +0 -21
  282. package/dist/mqttPacket/pubrec.js.map +0 -1
  283. package/dist/mqttPacket/pubrel.d.ts +0 -17
  284. package/dist/mqttPacket/pubrel.d.ts.map +0 -1
  285. package/dist/mqttPacket/pubrel.js +0 -21
  286. package/dist/mqttPacket/pubrel.js.map +0 -1
  287. package/dist/utils/args.d.ts +0 -28
  288. package/dist/utils/args.d.ts.map +0 -1
  289. package/dist/utils/args.js +0 -76
  290. package/dist/utils/args.js.map +0 -1
  291. package/dist/utils/platform.d.ts +0 -5
  292. package/dist/utils/platform.d.ts.map +0 -1
  293. package/dist/utils/platform.js +0 -8
  294. package/dist/utils/platform.js.map +0 -1
  295. package/mqttPacket/puback.test.ts +0 -55
  296. package/mqttPacket/puback.ts +0 -34
  297. package/mqttPacket/pubcomp.test.ts +0 -55
  298. package/mqttPacket/pubcomp.ts +0 -35
  299. package/mqttPacket/pubrec.test.ts +0 -55
  300. package/mqttPacket/pubrec.ts +0 -35
  301. package/mqttPacket/pubrel.test.ts +0 -55
  302. package/mqttPacket/pubrel.ts +0 -35
  303. package/utils/args.ts +0 -103
  304. package/utils/platform.ts +0 -8
@@ -0,0 +1,13 @@
1
+ /**
2
+ * MQTT protocol levels
3
+ */
4
+
5
+ import type { ProtocolLevel } from "./types.ts";
6
+
7
+ // MQTT Protocol levels
8
+ export const MQTTLevel = {
9
+ unknown: undefined as ProtocolLevel,
10
+ v3: 3 as ProtocolLevel,
11
+ v4: 4 as ProtocolLevel,
12
+ v5: 5 as ProtocolLevel,
13
+ };
@@ -0,0 +1,117 @@
1
+ import type {
2
+ CodecOpts,
3
+ PacketId,
4
+ ProtocolLevelNoV5,
5
+ TPacketType,
6
+ } from "./types.ts";
7
+ import { ReasonCode, type TReasonCode } from "./ReasonCode.ts";
8
+ import type { PubackProperties } from "./Properties.ts";
9
+ import { PacketType } from "./PacketType.ts";
10
+ import { Decoder, DecoderError } from "./decoder.ts";
11
+ import { Encoder } from "./encoder.ts";
12
+
13
+ /**
14
+ * PubackPacket is sent to indicate publish complete (QoS 1)
15
+ * Pubrec is sent to indicate publish received (QoS 2)
16
+ * Pubrel is sent to indicate publish release (QoS 2)
17
+ * Pubcomp is sent to indicate publish complete (QoS 2)
18
+ *
19
+ * all 4 packets are identical except for packet type
20
+ */
21
+ export type AckPacketV4<T> = {
22
+ type: TPacketType;
23
+ protocolLevel: ProtocolLevelNoV5;
24
+ id: PacketId;
25
+ };
26
+
27
+ export type AckPacketV5<T> = {
28
+ type: TPacketType;
29
+ protocolLevel: 5;
30
+ id: PacketId;
31
+ reasonCode?: TReasonCode;
32
+ properties?: PubackProperties;
33
+ };
34
+
35
+ export type AckPacket<T> = AckPacketV4<T> | AckPacketV5<T>;
36
+ export type PubackPacket = AckPacket<typeof PacketType.puback>;
37
+ export type PubrecPacket = AckPacket<typeof PacketType.pubrec>;
38
+ export type PubrelPacket = AckPacket<typeof PacketType.pubrel>;
39
+ export type PubcompPacket = AckPacket<typeof PacketType.pubcomp>;
40
+
41
+ export type AnyAckPacket =
42
+ | PubackPacket
43
+ | PubrecPacket
44
+ | PubrelPacket
45
+ | PubcompPacket;
46
+
47
+ export const anyAck: {
48
+ encode(packet: AnyAckPacket, codecOpts: CodecOpts): Uint8Array;
49
+ decode(
50
+ buffer: Uint8Array,
51
+ flags: number,
52
+ codecOpts: CodecOpts,
53
+ packetType: TPacketType,
54
+ ): AnyAckPacket;
55
+ } = {
56
+ encode(packet: AnyAckPacket, codecOpts: CodecOpts): Uint8Array {
57
+ const flags = packet.type === PacketType.pubrel ? 2 : 0;
58
+ const encoder = new Encoder(packet.type);
59
+ encoder.setInt16(packet.id);
60
+ if (packet.protocolLevel === 5) {
61
+ const reasonCode = packet.reasonCode || ReasonCode.success;
62
+ // if remaining length is less than 1 the value of 0x00 (success) is used.
63
+ if (
64
+ reasonCode === ReasonCode.success &&
65
+ Object.keys(packet.properties || {}).length === 0
66
+ ) {
67
+ return encoder.done(flags);
68
+ }
69
+ encoder.setReasonCode(reasonCode);
70
+ encoder.setProperties(
71
+ packet.properties || {},
72
+ packet.type,
73
+ codecOpts.maxOutgoingPacketSize,
74
+ );
75
+ }
76
+ return encoder.done(flags);
77
+ },
78
+
79
+ decode(
80
+ buffer: Uint8Array,
81
+ flags: number,
82
+ codecOpts: CodecOpts,
83
+ packetType: TPacketType,
84
+ ): AnyAckPacket {
85
+ const expectedFlags = packetType === PacketType.pubrel ? 2 : 0;
86
+ if (flags !== expectedFlags) {
87
+ throw new DecoderError("Invalid flags");
88
+ }
89
+ const decoder = new Decoder(packetType, buffer);
90
+ const id = decoder.getInt16();
91
+ if (codecOpts.protocolLevel !== 5) {
92
+ decoder.done();
93
+ return {
94
+ type: packetType,
95
+ protocolLevel: codecOpts.protocolLevel,
96
+ id,
97
+ };
98
+ }
99
+ if (decoder.atEnd()) {
100
+ return {
101
+ type: packetType,
102
+ protocolLevel: 5,
103
+ id,
104
+ reasonCode: 0,
105
+ };
106
+ }
107
+ const reasonCode = decoder.getReasonCode();
108
+ const properties = decoder.getProperties(packetType);
109
+ return {
110
+ type: packetType,
111
+ protocolLevel: 5,
112
+ id,
113
+ reasonCode,
114
+ properties,
115
+ };
116
+ },
117
+ };
@@ -2,19 +2,39 @@ import { PacketType } from "./PacketType.ts";
2
2
  import assert from "node:assert/strict";
3
3
  import { test } from "node:test";
4
4
 
5
- import { decode, encode } from "./mod.ts";
5
+ import { decode, encode, MQTTLevel } from "./mod.ts";
6
+ import type { CodecOpts } from "./mod.ts";
7
+
8
+ const codecOptsV4: CodecOpts = {
9
+ protocolLevel: MQTTLevel.v4,
10
+ maxIncomingPacketSize: 0xffff,
11
+ maxOutgoingPacketSize: 0xffff,
12
+ };
13
+
14
+ const codecOptsV5: CodecOpts = {
15
+ protocolLevel: MQTTLevel.v5,
16
+ maxIncomingPacketSize: 0xffff,
17
+ maxOutgoingPacketSize: 0xffff,
18
+ };
6
19
 
7
20
  // const utf8Decoder = new TextDecoder();
8
21
  const utf8Encoder = new TextEncoder();
9
22
  const payload = utf8Encoder.encode("payload");
10
23
 
11
- test("encode Publish", () => {
24
+ test("encode/decode short Publish v4", () => {
25
+ const packet = {
26
+ type: PacketType.publish,
27
+ protocolLevel: MQTTLevel.v4,
28
+ qos: 0,
29
+ dup: false,
30
+ id: undefined,
31
+ retain: false,
32
+ topic: "a/b",
33
+ payload,
34
+ };
35
+ const encoded = encode(packet, codecOptsV4);
12
36
  assert.deepStrictEqual(
13
- encode({
14
- type: PacketType.publish,
15
- topic: "a/b",
16
- payload,
17
- }),
37
+ encoded,
18
38
  Uint8Array.from([
19
39
  // fixedHeader
20
40
  48, // packetType + flags
@@ -35,123 +55,85 @@ test("encode Publish", () => {
35
55
  100, // 'd'
36
56
  ]),
37
57
  );
58
+ const decoded = decode(encoded, codecOptsV4);
59
+ assert.deepStrictEqual(decoded, packet);
38
60
  });
39
61
 
40
- test("decode Publish", () => {
41
- assert.deepStrictEqual(
42
- decode(
43
- Uint8Array.from([
44
- // fixedHeader
45
- 48, // packetType + flags
46
- 12, // remainingLength
47
- // variableHeader
48
- 0, // topicLength MSB
49
- 3, // topicLength LSB
50
- 97, // 'a'
51
- 47, // '/'
52
- 98, // 'b'
53
- // payload
54
- 112, // 'p'
55
- 97, // 'a'
56
- 121, // 'y'
57
- 108, // 'l'
58
- 111, // 'o'
59
- 97, // 'a'
60
- 100, // 'd'
61
- ]),
62
- ),
63
- {
64
- type: PacketType.publish,
65
- dup: false,
66
- qos: 0,
67
- retain: false,
68
- id: 0,
69
- topic: "a/b",
70
- payload: Uint8Array.from([
71
- 112, // 'p'
72
- 97, // 'a'
73
- 121, // 'y'
74
- 108, // 'l'
75
- 111, // 'o'
76
- 97, // 'a'
77
- 100, // 'd'
78
- ]),
79
- },
80
- );
81
- });
82
-
83
- test("decode Publish with extra bytes", () => {
62
+ test("encode/decode extended Publish v4", () => {
63
+ const packet = {
64
+ type: PacketType.publish,
65
+ protocolLevel: MQTTLevel.v4,
66
+ dup: false,
67
+ qos: 0,
68
+ retain: false,
69
+ id: undefined,
70
+ topic: "a/b",
71
+ payload: Uint8Array.from([
72
+ 112, // 'p'
73
+ 97, // 'a'
74
+ 121, // 'y'
75
+ 108, // 'l'
76
+ 111, // 'o'
77
+ 97, // 'a'
78
+ 100, // 'd'
79
+ ]),
80
+ };
81
+ const encoded = encode(packet, codecOptsV4);
84
82
  assert.deepStrictEqual(
85
- decode(
86
- Uint8Array.from([
87
- // fixedHeader
88
- 48, // packetType + flags
89
- 12, // remainingLength
90
- // variableHeader
91
- 0, // topicLength MSB
92
- 3, // topicLength LSB
93
- 97, // 'a'
94
- 47, // '/'
95
- 98, // 'b'
96
- // payload
97
- 112, // 'p'
98
- 97, // 'a'
99
- 121, // 'y'
100
- 108, // 'l'
101
- 111, // 'o'
102
- 97, // 'a'
103
- 100, // 'd'
104
- 101, // 'e'
105
- 116, // 't'
106
- 99, // 'c'
107
- ]),
108
- ),
109
- {
110
- type: PacketType.publish,
111
- dup: false,
112
- qos: 0,
113
- retain: false,
114
- id: 0,
115
- topic: "a/b",
116
- payload: Uint8Array.from([
117
- 112, // 'p'
118
- 97, // 'a'
119
- 121, // 'y'
120
- 108, // 'l'
121
- 111, // 'o'
122
- 97, // 'a'
123
- 100, // 'd'
124
- ]),
125
- },
83
+ encoded,
84
+ Uint8Array.from([
85
+ // fixedHeader
86
+ 48, // packetType + flags
87
+ 12, // remainingLength
88
+ // variableHeader
89
+ 0, // topicLength MSB
90
+ 3, // topicLength LSB
91
+ 97, // 'a'
92
+ 47, // '/'
93
+ 98, // 'b'
94
+ // payload
95
+ 112, // 'p'
96
+ 97, // 'a'
97
+ 121, // 'y'
98
+ 108, // 'l'
99
+ 111, // 'o'
100
+ 97, // 'a'
101
+ 100, // 'd'
102
+ ]),
126
103
  );
104
+ const decoded = decode(encoded, codecOptsV4);
105
+ assert.deepStrictEqual(decoded, packet);
127
106
  });
128
107
 
129
- test("decode Publish no payload", () => {
108
+ test("encode/decode Publish v4 no payload", () => {
109
+ const packet = {
110
+ type: PacketType.publish,
111
+ protocolLevel: MQTTLevel.v4,
112
+ dup: false,
113
+ qos: 0,
114
+ retain: false,
115
+ id: undefined,
116
+ topic: "a/b",
117
+ payload: Uint8Array.from([]),
118
+ };
119
+ const encoded = encode(packet, codecOptsV4);
130
120
  assert.deepStrictEqual(
131
- decode(
132
- Uint8Array.from([
133
- // fixedHeader
134
- 48, // packetType + flags
135
- 5, // remainingLength
136
- // variableHeader
137
- 0, // topicLength MSB
138
- 3, // topicLength LSB
139
- 97, // 'a'
140
- 47, // '/'
141
- 98, // 'b'
142
- // payload
143
- ]),
144
- ),
145
- {
146
- type: PacketType.publish,
147
- dup: false,
148
- qos: 0,
149
- retain: false,
150
- id: 0,
151
- topic: "a/b",
152
- payload: Uint8Array.from([]),
153
- },
121
+ encoded,
122
+ Uint8Array.from([
123
+ // fixedHeader
124
+ 48, // packetType + flags
125
+ 5, // remainingLength
126
+ // variableHeader
127
+ 0, // topicLength MSB
128
+ 3, // topicLength LSB
129
+ 97, // 'a'
130
+ 47, // '/'
131
+ 98, // 'b'
132
+ // payload
133
+ ]),
154
134
  );
135
+ const decoded = decode(encoded, codecOptsV4);
136
+ assert.deepStrictEqual(decoded, packet);
155
137
  });
156
138
 
157
139
  test("Invalid qos", () => {
@@ -170,29 +152,126 @@ test("Invalid qos", () => {
170
152
  98, // 'b'
171
153
  // payload
172
154
  ]),
155
+ codecOptsV4,
173
156
  ),
174
157
  Error,
175
158
  "Invalid qos",
176
159
  );
177
160
  });
178
- test("Invalid qos for duplicate", () => {
161
+
162
+ test("QoS 2, but no packetId", () => {
179
163
  assert.throws(
180
164
  () =>
181
- decode(
182
- Uint8Array.from([
183
- // fixedHeader
184
- 0x38, // packetType + flags
185
- 5, // remainingLength
186
- // variableHeader
187
- 0, // topicLength MSB
188
- 3, // topicLength LSB
189
- 97, // 'a'
190
- 47, // '/'
191
- 98, // 'b'
192
- // payload
193
- ]),
194
- ),
195
- Error,
196
- "Invalid qos for possible duplicate",
165
+ encode({
166
+ type: PacketType.publish,
167
+ protocolLevel: MQTTLevel.v4,
168
+ topic: "a/b",
169
+ payload,
170
+ qos: 2,
171
+ }, codecOptsV4),
172
+ /when qos is 1 or 2, packet must have id/,
173
+ );
174
+ });
175
+
176
+ test("encode/decode Publish v5", () => {
177
+ const packet = {
178
+ type: PacketType.publish,
179
+ protocolLevel: MQTTLevel.v5,
180
+ dup: false,
181
+ qos: 0,
182
+ retain: false,
183
+ id: undefined,
184
+ topic: "a/b",
185
+ payload,
186
+ properties: {
187
+ payloadFormatIndicator: true,
188
+ messageExpiryInterval: 1234,
189
+ contentType: "content",
190
+ responseTopic: "response",
191
+ correlationData: Uint8Array.from([1, 2, 3]),
192
+ subscriptionIdentifiers: [123],
193
+ topicAlias: 123,
194
+ userProperty: [["user", "property"]],
195
+ },
196
+ };
197
+ const encoded = encode(packet, codecOptsV5);
198
+ assert.deepStrictEqual(
199
+ encoded,
200
+ Uint8Array.from([
201
+ // fixedHeader
202
+ 48, // packetType + flags
203
+ 69, // remainingLength
204
+ 0, // topic length MSB
205
+ 3, // topic length LSB
206
+ 97, // a
207
+ 47, // /
208
+ 98, // b
209
+ 56, // propertyLength
210
+ 1, // payload format indicator
211
+ 1, // true
212
+ 2, // message expiry interval (4 bytes)
213
+ 0,
214
+ 0,
215
+ 4,
216
+ 210,
217
+ 3, // content type
218
+ 0, // string length MSB
219
+ 7, // string length LSB
220
+ 99, // c
221
+ 111, // o
222
+ 110, // n
223
+ 116, // t
224
+ 101, // e
225
+ 110, // n
226
+ 116, // t
227
+ 8, // response topic
228
+ 0, // string length MSB
229
+ 8, // string length LSB
230
+ 114, // r
231
+ 101, // e
232
+ 115, // s
233
+ 112, // p
234
+ 111, // o
235
+ 110, // n
236
+ 115, // s
237
+ 101, // e
238
+ 9, // correlation data 3 bytes
239
+ 0, // byte length MSB
240
+ 3, // byte length LSB
241
+ 1,
242
+ 2,
243
+ 3,
244
+ 11, // subscriptionIdentifier
245
+ 123, // 123
246
+ 35, // topicAlias
247
+ 0,
248
+ 123,
249
+ 38, // userproperties
250
+ 0, // string length MSB
251
+ 4, // string length LSB
252
+ 117, // u
253
+ 115, // s
254
+ 101, // e
255
+ 114, // r
256
+ 0, // string length MSB
257
+ 8, // string length LSB
258
+ 112, // p
259
+ 114, // r
260
+ 111, // o
261
+ 112, // p
262
+ 101, // e
263
+ 114, // r
264
+ 116, // t
265
+ 121, // y
266
+ 112, // p
267
+ 97, // a
268
+ 121, // y
269
+ 108, // l
270
+ 111, // o
271
+ 97, // a
272
+ 100, // d
273
+ ]),
197
274
  );
275
+ const decoded = decode(encoded, codecOptsV5);
276
+ assert.deepStrictEqual(decoded, packet);
198
277
  });
@@ -1,4 +1,13 @@
1
- import type { Payload, QoS, Topic, TPacketType } from "./types.ts";
1
+ import type {
2
+ CodecOpts,
3
+ Dup,
4
+ Payload,
5
+ ProtocolLevelNoV5,
6
+ QoS,
7
+ Topic,
8
+ TPacketType,
9
+ } from "./types.ts";
10
+ import type { PublishProperties } from "./Properties.ts";
2
11
  import { PacketType } from "./PacketType.ts";
3
12
  import { BitMask } from "./BitMask.ts";
4
13
  import { Encoder, EncoderError } from "./encoder.ts";
@@ -8,21 +17,40 @@ import { booleanFlag, Decoder, DecoderError } from "./decoder.ts";
8
17
  * PublishPacket is used to send data from client to server and
9
18
  * from server to subscribers
10
19
  */
11
- export type PublishPacket = {
20
+ export type PublishPacketV4 = {
12
21
  type: TPacketType;
22
+ protocolLevel: ProtocolLevelNoV5;
13
23
  topic: Topic;
14
24
  payload: Payload;
15
- dup?: boolean;
25
+ dup?: Dup;
16
26
  retain?: boolean;
17
27
  qos?: QoS;
18
28
  id?: number;
19
29
  };
30
+ export type PublishPacketV5 = {
31
+ type: TPacketType;
32
+ protocolLevel: 5;
33
+ topic: Topic;
34
+ payload: Payload;
35
+ dup?: Dup;
36
+ retain?: boolean;
37
+ qos?: QoS;
38
+ id?: number;
39
+ properties?: PublishProperties;
40
+ };
41
+
42
+ export type PublishPacket = PublishPacketV4 | PublishPacketV5;
20
43
 
21
44
  export const publish: {
22
- encode(packet: PublishPacket): { flags: number; bytes: number[] };
23
- decode(buffer: Uint8Array, flags: number): PublishPacket;
45
+ encode(packet: PublishPacket, _codecOpts: CodecOpts): Uint8Array;
46
+ decode(
47
+ buffer: Uint8Array,
48
+ flags: number,
49
+ codecOpts: CodecOpts,
50
+ packetType: TPacketType,
51
+ ): PublishPacket;
24
52
  } = {
25
- encode(packet: PublishPacket): { flags: number; bytes: number[] } {
53
+ encode(packet: PublishPacket, codecOpts: CodecOpts): Uint8Array {
26
54
  const qos = packet.qos || 0;
27
55
 
28
56
  const flags = (packet.dup ? BitMask.bit3 : 0) +
@@ -30,7 +58,7 @@ export const publish: {
30
58
  (qos & 1 ? BitMask.bit1 : 0) +
31
59
  (packet.retain ? BitMask.bit0 : 0);
32
60
 
33
- const encoder = new Encoder();
61
+ const encoder = new Encoder(packet.type);
34
62
  encoder.setTopic(packet.topic);
35
63
 
36
64
  if (qos === 1 || qos === 2) {
@@ -39,11 +67,24 @@ export const publish: {
39
67
  }
40
68
  encoder.setInt16(packet.id);
41
69
  }
70
+
71
+ if (packet.protocolLevel === 5) {
72
+ encoder.setProperties(
73
+ packet.properties || {},
74
+ PacketType.publish,
75
+ codecOpts.maxOutgoingPacketSize,
76
+ );
77
+ }
42
78
  encoder.setRemainder(packet.payload);
43
- return { flags, bytes: encoder.done() };
79
+ return encoder.done(flags);
44
80
  },
45
81
 
46
- decode(buffer: Uint8Array, flags: number): PublishPacket {
82
+ decode(
83
+ buffer: Uint8Array,
84
+ flags: number,
85
+ codecOpts: CodecOpts,
86
+ packetType: TPacketType,
87
+ ): PublishPacket {
47
88
  const dup = booleanFlag(flags, BitMask.bit3);
48
89
  const qos = (flags & 6) >> 1;
49
90
  const retain = booleanFlag(flags, BitMask.bit0);
@@ -56,19 +97,33 @@ export const publish: {
56
97
  throw new DecoderError("Invalid qos for possible duplicate");
57
98
  }
58
99
 
59
- const decoder = new Decoder(buffer);
100
+ const decoder = new Decoder(packetType, buffer);
60
101
  const topic = decoder.getTopic();
61
102
 
62
- let id = 0;
103
+ let id = undefined;
63
104
  if (qos > 0) {
64
105
  id = decoder.getInt16();
65
106
  }
66
- const payload = decoder.getRemainder();
67
-
107
+ if (codecOpts.protocolLevel === 5) {
108
+ const properties = decoder.getProperties(PacketType.publish);
109
+ const payload = decoder.getRemainder();
110
+ return {
111
+ type: PacketType.publish,
112
+ protocolLevel: 5,
113
+ properties,
114
+ topic,
115
+ payload,
116
+ dup,
117
+ retain,
118
+ qos,
119
+ id,
120
+ };
121
+ }
68
122
  // no decoder.done() required because of getRemainder
69
-
123
+ const payload = decoder.getRemainder();
70
124
  return {
71
125
  type: PacketType.publish,
126
+ protocolLevel: codecOpts.protocolLevel,
72
127
  topic,
73
128
  payload,
74
129
  dup,