@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.
Files changed (331) 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 +127 -118
  5. package/client/client.ts +61 -21
  6. package/client/context.ts +71 -30
  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/deno/tcpClient.ts +1 -1
  16. package/dev_utils/dummyConn.ts +17 -2
  17. package/dist/bin/conformanceServer.js +3 -2
  18. package/dist/bin/conformanceServer.js.map +1 -1
  19. package/dist/bin/demoServer.js +3 -2
  20. package/dist/bin/demoServer.js.map +1 -1
  21. package/dist/bin/mqtt.d.ts +29 -0
  22. package/dist/bin/mqtt.d.ts.map +1 -1
  23. package/dist/bin/mqtt.js +102 -97
  24. package/dist/bin/mqtt.js.map +1 -1
  25. package/dist/client/client.d.ts +16 -5
  26. package/dist/client/client.d.ts.map +1 -1
  27. package/dist/client/client.js +36 -15
  28. package/dist/client/client.js.map +1 -1
  29. package/dist/client/context.d.ts +8 -3
  30. package/dist/client/context.d.ts.map +1 -1
  31. package/dist/client/context.js +51 -21
  32. package/dist/client/context.js.map +1 -1
  33. package/dist/client/deps.d.ts +3 -2
  34. package/dist/client/deps.d.ts.map +1 -1
  35. package/dist/client/deps.js +2 -1
  36. package/dist/client/deps.js.map +1 -1
  37. package/dist/client/handlers/handleConnack.d.ts +1 -1
  38. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  39. package/dist/client/handlers/handleConnack.js +14 -5
  40. package/dist/client/handlers/handleConnack.js.map +1 -1
  41. package/dist/client/handlers/handlePublish.d.ts +1 -1
  42. package/dist/client/handlers/handlePublish.d.ts.map +1 -1
  43. package/dist/client/handlers/handlePublish.js +2 -0
  44. package/dist/client/handlers/handlePublish.js.map +1 -1
  45. package/dist/client/handlers/handlePubrec.d.ts +1 -1
  46. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  47. package/dist/client/handlers/handlePubrec.js +1 -0
  48. package/dist/client/handlers/handlePubrec.js.map +1 -1
  49. package/dist/client/handlers/handlePubrel.d.ts +1 -1
  50. package/dist/client/handlers/handlePubrel.d.ts.map +1 -1
  51. package/dist/client/handlers/handlePubrel.js +1 -0
  52. package/dist/client/handlers/handlePubrel.js.map +1 -1
  53. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  54. package/dist/client/handlers/handleSuback.js +3 -1
  55. package/dist/client/handlers/handleSuback.js.map +1 -1
  56. package/dist/client/mod.d.ts +3 -1
  57. package/dist/client/mod.d.ts.map +1 -1
  58. package/dist/client/mod.js +2 -1
  59. package/dist/client/mod.js.map +1 -1
  60. package/dist/client/store/memoryStore.d.ts +1 -1
  61. package/dist/client/store/memoryStore.d.ts.map +1 -1
  62. package/dist/client/store/memoryStore.js.map +1 -1
  63. package/dist/mqttConn/mqttConn.d.ts +13 -8
  64. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  65. package/dist/mqttConn/mqttConn.js +27 -12
  66. package/dist/mqttConn/mqttConn.js.map +1 -1
  67. package/dist/mqttPacket/PacketType.d.ts +1 -0
  68. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  69. package/dist/mqttPacket/PacketType.js +1 -0
  70. package/dist/mqttPacket/PacketType.js.map +1 -1
  71. package/dist/mqttPacket/Properties.d.ts +157 -0
  72. package/dist/mqttPacket/Properties.d.ts.map +1 -0
  73. package/dist/mqttPacket/Properties.js +177 -0
  74. package/dist/mqttPacket/Properties.js.map +1 -0
  75. package/dist/mqttPacket/ReasonCode.d.ts +74 -0
  76. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -0
  77. package/dist/mqttPacket/ReasonCode.js +230 -0
  78. package/dist/mqttPacket/ReasonCode.js.map +1 -0
  79. package/dist/mqttPacket/RetainHandling.d.ts +12 -0
  80. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -0
  81. package/dist/mqttPacket/RetainHandling.js +12 -0
  82. package/dist/mqttPacket/RetainHandling.js.map +1 -0
  83. package/dist/mqttPacket/auth.d.ts +21 -0
  84. package/dist/mqttPacket/auth.d.ts.map +1 -0
  85. package/dist/mqttPacket/auth.js +34 -0
  86. package/dist/mqttPacket/auth.js.map +1 -0
  87. package/dist/mqttPacket/connack.d.ts +19 -11
  88. package/dist/mqttPacket/connack.d.ts.map +1 -1
  89. package/dist/mqttPacket/connack.js +43 -15
  90. package/dist/mqttPacket/connack.js.map +1 -1
  91. package/dist/mqttPacket/connect.d.ts +30 -11
  92. package/dist/mqttPacket/connect.d.ts.map +1 -1
  93. package/dist/mqttPacket/connect.js +106 -30
  94. package/dist/mqttPacket/connect.js.map +1 -1
  95. package/dist/mqttPacket/decoder.d.ts +42 -3
  96. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  97. package/dist/mqttPacket/decoder.js +135 -4
  98. package/dist/mqttPacket/decoder.js.map +1 -1
  99. package/dist/mqttPacket/disconnect.d.ts +15 -9
  100. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  101. package/dist/mqttPacket/disconnect.js +45 -6
  102. package/dist/mqttPacket/disconnect.js.map +1 -1
  103. package/dist/mqttPacket/encoder.d.ts +57 -8
  104. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  105. package/dist/mqttPacket/encoder.js +185 -13
  106. package/dist/mqttPacket/encoder.js.map +1 -1
  107. package/dist/mqttPacket/length.d.ts.map +1 -1
  108. package/dist/mqttPacket/length.js +3 -2
  109. package/dist/mqttPacket/length.js.map +1 -1
  110. package/dist/mqttPacket/mod.d.ts +57 -91
  111. package/dist/mqttPacket/mod.d.ts.map +1 -1
  112. package/dist/mqttPacket/mod.js +23 -29
  113. package/dist/mqttPacket/mod.js.map +1 -1
  114. package/dist/mqttPacket/pingreq.d.ts +4 -6
  115. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  116. package/dist/mqttPacket/pingreq.js +5 -4
  117. package/dist/mqttPacket/pingreq.js.map +1 -1
  118. package/dist/mqttPacket/pingres.d.ts +4 -6
  119. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  120. package/dist/mqttPacket/pingres.js +7 -5
  121. package/dist/mqttPacket/pingres.js.map +1 -1
  122. package/dist/mqttPacket/protocolLevels.d.ts +12 -0
  123. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -0
  124. package/dist/mqttPacket/protocolLevels.js +11 -0
  125. package/dist/mqttPacket/protocolLevels.js.map +1 -0
  126. package/dist/mqttPacket/pubblishAcks.d.ts +42 -0
  127. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -0
  128. package/dist/mqttPacket/pubblishAcks.js +56 -0
  129. package/dist/mqttPacket/pubblishAcks.js.map +1 -0
  130. package/dist/mqttPacket/publish.d.ts +19 -8
  131. package/dist/mqttPacket/publish.d.ts.map +1 -1
  132. package/dist/mqttPacket/publish.js +26 -7
  133. package/dist/mqttPacket/publish.js.map +1 -1
  134. package/dist/mqttPacket/suback.d.ts +18 -11
  135. package/dist/mqttPacket/suback.d.ts.map +1 -1
  136. package/dist/mqttPacket/suback.js +41 -20
  137. package/dist/mqttPacket/suback.js.map +1 -1
  138. package/dist/mqttPacket/subscribe.d.ts +27 -12
  139. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  140. package/dist/mqttPacket/subscribe.js +71 -15
  141. package/dist/mqttPacket/subscribe.js.map +1 -1
  142. package/dist/mqttPacket/types.d.ts +36 -0
  143. package/dist/mqttPacket/types.d.ts.map +1 -1
  144. package/dist/mqttPacket/unsuback.d.ts +17 -10
  145. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  146. package/dist/mqttPacket/unsuback.js +29 -6
  147. package/dist/mqttPacket/unsuback.js.map +1 -1
  148. package/dist/mqttPacket/unsubscribe.d.ts +17 -10
  149. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  150. package/dist/mqttPacket/unsubscribe.js +24 -8
  151. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  152. package/dist/mqttPacket/validators.d.ts +15 -0
  153. package/dist/mqttPacket/validators.d.ts.map +1 -1
  154. package/dist/mqttPacket/validators.js +15 -0
  155. package/dist/mqttPacket/validators.js.map +1 -1
  156. package/dist/node/tcpClient.js +1 -1
  157. package/dist/node/tcpClient.js.map +1 -1
  158. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  159. package/dist/node/wrapNodeSocket.js.map +1 -1
  160. package/dist/persistence/deps.d.ts +1 -1
  161. package/dist/persistence/deps.d.ts.map +1 -1
  162. package/dist/persistence/deps.js +1 -1
  163. package/dist/persistence/deps.js.map +1 -1
  164. package/dist/persistence/memory/memoryPersistence.js +1 -1
  165. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  166. package/dist/server/context.d.ts +3 -1
  167. package/dist/server/context.d.ts.map +1 -1
  168. package/dist/server/context.js +8 -2
  169. package/dist/server/context.js.map +1 -1
  170. package/dist/server/deps.d.ts +2 -2
  171. package/dist/server/deps.d.ts.map +1 -1
  172. package/dist/server/deps.js +1 -1
  173. package/dist/server/deps.js.map +1 -1
  174. package/dist/server/handlers/handleConnect.d.ts +1 -1
  175. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  176. package/dist/server/handlers/handleConnect.js +9 -1
  177. package/dist/server/handlers/handleConnect.js.map +1 -1
  178. package/dist/server/handlers/handlePacket.d.ts +1 -1
  179. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  180. package/dist/server/handlers/handlePacket.js +1 -1
  181. package/dist/server/handlers/handlePacket.js.map +1 -1
  182. package/dist/server/handlers/handlePingreq.d.ts.map +1 -1
  183. package/dist/server/handlers/handlePingreq.js +1 -0
  184. package/dist/server/handlers/handlePingreq.js.map +1 -1
  185. package/dist/server/handlers/handlePublish.d.ts +2 -2
  186. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  187. package/dist/server/handlers/handlePublish.js +2 -0
  188. package/dist/server/handlers/handlePublish.js.map +1 -1
  189. package/dist/server/handlers/handlePubrec.d.ts +1 -1
  190. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  191. package/dist/server/handlers/handlePubrec.js +1 -0
  192. package/dist/server/handlers/handlePubrec.js.map +1 -1
  193. package/dist/server/handlers/handlePubrel.d.ts +1 -1
  194. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  195. package/dist/server/handlers/handlePubrel.js +1 -0
  196. package/dist/server/handlers/handlePubrel.js.map +1 -1
  197. package/dist/server/handlers/handleSubscribe.d.ts +1 -1
  198. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  199. package/dist/server/handlers/handleSubscribe.js +2 -1
  200. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  201. package/dist/server/handlers/handleUnsubscribe.d.ts +1 -1
  202. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  203. package/dist/server/handlers/handleUnsubscribe.js +1 -0
  204. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  205. package/dist/server/server.d.ts +2 -2
  206. package/dist/server/server.d.ts.map +1 -1
  207. package/dist/server/server.js +5 -3
  208. package/dist/server/server.js.map +1 -1
  209. package/dist/socket/socket.d.ts.map +1 -1
  210. package/dist/socket/socket.js +6 -1
  211. package/dist/socket/socket.js.map +1 -1
  212. package/dist/utils/assert.d.ts +0 -3
  213. package/dist/utils/assert.d.ts.map +1 -1
  214. package/dist/utils/assert.js +0 -7
  215. package/dist/utils/assert.js.map +1 -1
  216. package/dist/utils/asyncQueue.d.ts +1 -3
  217. package/dist/utils/asyncQueue.d.ts.map +1 -1
  218. package/dist/utils/asyncQueue.js +16 -21
  219. package/dist/utils/asyncQueue.js.map +1 -1
  220. package/dist/utils/logger.d.ts +5 -15
  221. package/dist/utils/logger.d.ts.map +1 -1
  222. package/dist/utils/logger.js +7 -8
  223. package/dist/utils/logger.js.map +1 -1
  224. package/dist/utils/mod.d.ts +0 -3
  225. package/dist/utils/mod.d.ts.map +1 -1
  226. package/dist/utils/mod.js +0 -2
  227. package/dist/utils/mod.js.map +1 -1
  228. package/dist/utils/utils.d.ts +2 -0
  229. package/dist/utils/utils.d.ts.map +1 -0
  230. package/dist/utils/utils.js +6 -0
  231. package/dist/utils/utils.js.map +1 -0
  232. package/mqttConn/mqttConn.test.ts +27 -12
  233. package/mqttConn/mqttConn.ts +45 -14
  234. package/mqttPacket/PacketType.ts +1 -0
  235. package/mqttPacket/Properties.ts +276 -0
  236. package/mqttPacket/ReasonCode.test.ts +22 -0
  237. package/mqttPacket/ReasonCode.ts +256 -0
  238. package/mqttPacket/RetainHandling.ts +11 -0
  239. package/mqttPacket/auth.test.ts +112 -0
  240. package/mqttPacket/auth.ts +71 -0
  241. package/mqttPacket/connack.test.ts +84 -64
  242. package/mqttPacket/connack.ts +88 -24
  243. package/mqttPacket/connect.test.ts +497 -18
  244. package/mqttPacket/connect.ts +170 -39
  245. package/mqttPacket/decoder.test.ts +33 -16
  246. package/mqttPacket/decoder.ts +173 -5
  247. package/mqttPacket/disconnect.test.ts +97 -18
  248. package/mqttPacket/disconnect.ts +84 -12
  249. package/mqttPacket/encoder.test.ts +32 -8
  250. package/mqttPacket/encoder.ts +236 -11
  251. package/mqttPacket/length.ts +3 -2
  252. package/mqttPacket/mod.ts +76 -39
  253. package/mqttPacket/pingreq.test.ts +52 -4
  254. package/mqttPacket/pingreq.ts +20 -7
  255. package/mqttPacket/pingres.test.ts +52 -4
  256. package/mqttPacket/pingres.ts +22 -8
  257. package/mqttPacket/properties.test.ts +193 -0
  258. package/mqttPacket/protocolLevels.ts +13 -0
  259. package/mqttPacket/pubblishAcks.ts +123 -0
  260. package/mqttPacket/publish.test.ts +212 -133
  261. package/mqttPacket/publish.ts +69 -14
  262. package/mqttPacket/publishAcks.test.ts +128 -0
  263. package/mqttPacket/suback.test.ts +71 -27
  264. package/mqttPacket/suback.ts +82 -30
  265. package/mqttPacket/subscribe.test.ts +132 -43
  266. package/mqttPacket/subscribe.ts +128 -25
  267. package/mqttPacket/types.ts +43 -0
  268. package/mqttPacket/unsuback.test.ts +80 -30
  269. package/mqttPacket/unsuback.ts +68 -13
  270. package/mqttPacket/unsubscribe.test.ts +59 -34
  271. package/mqttPacket/unsubscribe.ts +64 -17
  272. package/mqttPacket/validators.ts +15 -0
  273. package/node/tcpClient.ts +1 -1
  274. package/node/wrapNodeSocket.ts +2 -1
  275. package/package.json +2 -2
  276. package/persistence/deps.ts +1 -1
  277. package/persistence/memory/memoryPersistence.test.ts +5 -1
  278. package/persistence/memory/memoryPersistence.ts +1 -1
  279. package/server/context.ts +23 -10
  280. package/server/deps.ts +2 -0
  281. package/server/handlers/handleConnect.ts +12 -9
  282. package/server/handlers/handlePacket.ts +10 -11
  283. package/server/handlers/handlePingreq.ts +1 -0
  284. package/server/handlers/handlePublish.ts +6 -2
  285. package/server/handlers/handlePubrec.ts +3 -1
  286. package/server/handlers/handlePubrel.ts +3 -1
  287. package/server/handlers/handleSubscribe.ts +3 -6
  288. package/server/handlers/handleUnsubscribe.ts +3 -1
  289. package/server/server.ts +8 -12
  290. package/server/test/handleConnect.test.ts +2 -1
  291. package/server/test/test-handlers.ts +2 -1
  292. package/socket/socket.ts +5 -1
  293. package/utils/assert.ts +0 -18
  294. package/utils/asyncQueue.ts +17 -21
  295. package/utils/logger.ts +12 -11
  296. package/utils/mod.ts +0 -3
  297. package/utils/utils.ts +6 -0
  298. package/dist/mqttPacket/puback.d.ts +0 -16
  299. package/dist/mqttPacket/puback.d.ts.map +0 -1
  300. package/dist/mqttPacket/puback.js +0 -21
  301. package/dist/mqttPacket/puback.js.map +0 -1
  302. package/dist/mqttPacket/pubcomp.d.ts +0 -17
  303. package/dist/mqttPacket/pubcomp.d.ts.map +0 -1
  304. package/dist/mqttPacket/pubcomp.js +0 -21
  305. package/dist/mqttPacket/pubcomp.js.map +0 -1
  306. package/dist/mqttPacket/pubrec.d.ts +0 -17
  307. package/dist/mqttPacket/pubrec.d.ts.map +0 -1
  308. package/dist/mqttPacket/pubrec.js +0 -21
  309. package/dist/mqttPacket/pubrec.js.map +0 -1
  310. package/dist/mqttPacket/pubrel.d.ts +0 -17
  311. package/dist/mqttPacket/pubrel.d.ts.map +0 -1
  312. package/dist/mqttPacket/pubrel.js +0 -21
  313. package/dist/mqttPacket/pubrel.js.map +0 -1
  314. package/dist/utils/args.d.ts +0 -28
  315. package/dist/utils/args.d.ts.map +0 -1
  316. package/dist/utils/args.js +0 -76
  317. package/dist/utils/args.js.map +0 -1
  318. package/dist/utils/platform.d.ts +0 -5
  319. package/dist/utils/platform.d.ts.map +0 -1
  320. package/dist/utils/platform.js +0 -8
  321. package/dist/utils/platform.js.map +0 -1
  322. package/mqttPacket/puback.test.ts +0 -55
  323. package/mqttPacket/puback.ts +0 -34
  324. package/mqttPacket/pubcomp.test.ts +0 -55
  325. package/mqttPacket/pubcomp.ts +0 -35
  326. package/mqttPacket/pubrec.test.ts +0 -55
  327. package/mqttPacket/pubrec.ts +0 -35
  328. package/mqttPacket/pubrel.test.ts +0 -55
  329. package/mqttPacket/pubrel.ts +0 -35
  330. package/utils/args.ts +0 -103
  331. package/utils/platform.ts +0 -8
@@ -0,0 +1,193 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import { Encoder } from "./encoder.ts";
5
+ import { Decoder } from "./decoder.ts";
6
+ import { PacketType } from "./PacketType.ts";
7
+
8
+ test("encoder.setProperties encodes allowed properties for connect", () => {
9
+ const encoder = new Encoder(PacketType.connect);
10
+ const props = {
11
+ sessionExpiryInterval: 60,
12
+ authenticationMethod: "basic",
13
+ authenticationData: new Uint8Array([1, 2, 3]),
14
+ requestProblemInformation: true,
15
+ requestResponseInformation: false,
16
+ receiveMaximum: 100,
17
+ topicAliasMaximum: 10,
18
+ userProperty: [["key", "value"]],
19
+ maximumPacketSize: 1024,
20
+ };
21
+ encoder.setProperties(props, PacketType.connect, 2048);
22
+ assert.equal(encoder.encodedSize(), 48);
23
+ });
24
+
25
+ test("decoder.getProperties decodes allowed properties for connect", () => {
26
+ const encoder = new Encoder(PacketType.connect);
27
+ const props = {
28
+ sessionExpiryInterval: 60,
29
+ authenticationMethod: "basic",
30
+ authenticationData: new Uint8Array([1, 2, 3]),
31
+ requestProblemInformation: true,
32
+ requestResponseInformation: false,
33
+ receiveMaximum: 100,
34
+ topicAliasMaximum: 10,
35
+ userProperty: [["key1", "value1"], ["key2", "value2"]],
36
+ maximumPacketSize: 1024,
37
+ };
38
+ encoder.setProperties(props, PacketType.connect, 2048);
39
+ const buf = encoder.done(0);
40
+ // skip the first byte which contains the packet identifier
41
+ // and the second byte that holds the packet length
42
+ const decoder = new Decoder(PacketType.connect, buf, 2);
43
+ const decoded = decoder.getProperties(PacketType.connect);
44
+ assert.equal(decoded.sessionExpiryInterval, 60);
45
+ assert.equal(decoded.authenticationMethod, "basic");
46
+ assert.deepEqual(decoded.authenticationData, new Uint8Array([1, 2, 3]));
47
+ assert.equal(decoded.requestProblemInformation, true);
48
+ assert.equal(decoded.requestResponseInformation, false);
49
+ assert.equal(decoded.receiveMaximum, 100);
50
+ assert.equal(decoded.topicAliasMaximum, 10);
51
+ assert.deepEqual(decoded.userProperty, [["key1", "value1"], [
52
+ "key2",
53
+ "value2",
54
+ ]]);
55
+ assert.equal(decoded.maximumPacketSize, 1024);
56
+ });
57
+
58
+ test("decoder.getProperties decodes allowed properties for connack", () => {
59
+ const encoder = new Encoder(PacketType.connack);
60
+ const props = {
61
+ maximumQos: 2,
62
+ reasonString: "very good reason",
63
+ };
64
+ encoder.setProperties(props, PacketType.connack, 2048);
65
+ const buf = encoder.done(0);
66
+ // skip the first byte which contains the packet identifier
67
+ // and the second byte that holds the packet length
68
+ const decoder = new Decoder(PacketType.connack, buf, 2);
69
+ const decoded = decoder.getProperties(PacketType.connack);
70
+ assert.equal(decoded.maximumQos, 2);
71
+ });
72
+
73
+ test("encoder.setProperties does not encode properties not allowed for packet type", () => {
74
+ const encoder = new Encoder(PacketType.publish);
75
+ const props = {
76
+ userProperty: [["key", "value"]],
77
+ // Not allowed for publish
78
+ sessionExpiryInterval: 60,
79
+ authenticationMethod: "basic",
80
+ authenticationData: new Uint8Array([1, 2, 3]),
81
+ requestProblemInformation: true,
82
+ requestResponseInformation: false,
83
+ receiveMaximum: 100,
84
+ topicAliasMaximum: 10,
85
+ maximumPacketSize: 1024,
86
+ };
87
+ encoder.setProperties(props, PacketType.publish, 2048);
88
+ const buf = encoder.done(0);
89
+ const decoder = new Decoder(PacketType.publish, buf, 2);
90
+ const decoded = decoder.getProperties(PacketType.publish);
91
+ assert.deepStrictEqual(Object.keys(decoded), [
92
+ "userProperty",
93
+ ]);
94
+ });
95
+
96
+ test("decoder.getProperties throws on duplicate property", () => {
97
+ const encoder = new Encoder(PacketType.publish);
98
+ // Manually encode duplicate properties
99
+ encoder.setVariableByteInteger(0x04); // propertyLength
100
+ encoder.setVariableByteInteger(0x01); // payloadFormatIndicator
101
+ encoder.setByte(1);
102
+ encoder.setVariableByteInteger(0x01); // payloadFormatIndicator again
103
+ encoder.setByte(1);
104
+ const buf = encoder.done(0);
105
+ const decoder = new Decoder(PacketType.publish, buf, 2);
106
+ assert.throws(
107
+ () => decoder.getProperties(PacketType.publish),
108
+ /Property payloadFormatIndicator only allowed once/,
109
+ );
110
+ });
111
+
112
+ test("decoder.getProperties throws on property not allowed for packet type", () => {
113
+ const encoder = new Encoder(PacketType.publish);
114
+ encoder.setVariableByteInteger(0x05); // propertyLength
115
+ encoder.setVariableByteInteger(0x13); // serverKeepAlive (not allowed for publish)
116
+ encoder.setInt32(30);
117
+ const buf = encoder.done(0);
118
+ const decoder = new Decoder(PacketType.publish, buf, 2);
119
+ assert.throws(
120
+ () => decoder.getProperties(PacketType.publish),
121
+ /Property type serverKeepAlive not allowed/,
122
+ );
123
+ });
124
+
125
+ test("encoder.setProperties rewinds marker if encodedSize exceeds maximumPacketSize", () => {
126
+ const encoder = new Encoder(PacketType.puback);
127
+ const props = {
128
+ reasonString: "small",
129
+ userProperty: [["key", "value"]],
130
+ };
131
+ encoder.setProperties(props, PacketType.puback, 10); // very small max size
132
+ assert.equal(encoder.encodedSize(), 9);
133
+ });
134
+
135
+ test("encoder.setProperties removes all properties if encodedSize exceeds maximumPacketSize", () => {
136
+ const encoder = new Encoder(PacketType.puback);
137
+ const props = {
138
+ reasonString: "a very long reason",
139
+ userProperty: [["key", "value"]],
140
+ };
141
+ encoder.setProperties(props, PacketType.puback, 10); // very small max size
142
+ assert.equal(encoder.encodedSize(), 1); // only propertyLength 0 remains
143
+ });
144
+
145
+ test("decodeProperty throws on invalid property kind", () => {
146
+ const encoder = new Encoder(PacketType.publish);
147
+ // Manually encode an invalid property kind
148
+ encoder.setVariableByteInteger(0x02); // propertyLength
149
+ encoder.setVariableByteInteger(0xF0); // Invalid property ID
150
+ encoder.setByte(1);
151
+
152
+ const buf = encoder.done(0);
153
+ const decoder = new Decoder(PacketType.publish, buf, 2);
154
+
155
+ assert.throws(
156
+ () => decoder.getProperties(PacketType.publish),
157
+ /Property type 240 not allowed/,
158
+ );
159
+ });
160
+
161
+ test("userProperty must be an array", () => {
162
+ const encoder = new Encoder(PacketType.puback);
163
+ const props = {
164
+ userProperty: "I am not an array",
165
+ };
166
+ assert.throws(
167
+ () => encoder.setProperties(props, PacketType.puback, 10),
168
+ / userProperty must be an array/,
169
+ );
170
+ });
171
+
172
+ test("userProperty item must be an array", () => {
173
+ const encoder = new Encoder(PacketType.puback);
174
+ const props = {
175
+ userProperty: ["a", "b"],
176
+ };
177
+ assert.throws(
178
+ () => encoder.setProperties(props, PacketType.puback, 10),
179
+ / userProperty item must be an array/,
180
+ );
181
+ });
182
+
183
+ test("encode/decode subscriptionIdentifiers", () => {
184
+ const props = { subscriptionIdentifiers: [3, 5, 7] };
185
+ const bytes = new Uint8Array([48, 7, 6, 0xb, 3, 0xb, 5, 0xb, 7]);
186
+ const encoder = new Encoder(PacketType.publish);
187
+ encoder.setProperties(props, PacketType.publish, 1000);
188
+ const buf = encoder.done(0);
189
+ assert.deepStrictEqual(buf, bytes);
190
+ const decoder = new Decoder(PacketType.publish, buf, 2);
191
+ const decoded = decoder.getProperties(PacketType.publish);
192
+ assert.deepStrictEqual(decoded, props);
193
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * MQTT protocol levels
3
+ */
4
+
5
+ import type { ProtocolLevel } from "./types.ts";
6
+
7
+ /** available 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
+ } as const;
@@ -0,0 +1,123 @@
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
+ export type AckPacketV4<T> = {
14
+ type: TPacketType;
15
+ protocolLevel: ProtocolLevelNoV5;
16
+ id: PacketId;
17
+ };
18
+
19
+ export type AckPacketV5<T> = {
20
+ type: TPacketType;
21
+ protocolLevel: 5;
22
+ id: PacketId;
23
+ reasonCode?: TReasonCode;
24
+ properties?: PubackProperties;
25
+ };
26
+ /**
27
+ * all 4 ack packets are identical except for packet type and flags of Pubrel
28
+ */
29
+ export type AckPacket<T> = AckPacketV4<T> | AckPacketV5<T>;
30
+ /**
31
+ * PubackPacket is sent to indicate publish complete (QoS 1)
32
+ */
33
+ export type PubackPacket = AckPacket<typeof PacketType.puback>;
34
+ /**
35
+ * Pubrec is sent to indicate publish received (QoS 2)
36
+ */
37
+ export type PubrecPacket = AckPacket<typeof PacketType.pubrec>;
38
+ /**
39
+ * Pubrel is sent to indicate publish release (QoS 2)
40
+ */
41
+ export type PubrelPacket = AckPacket<typeof PacketType.pubrel>;
42
+ /**
43
+ * Pubcomp is sent to indicate publish complete (QoS 2)
44
+ */
45
+ export type PubcompPacket = AckPacket<typeof PacketType.pubcomp>;
46
+
47
+ export type AnyAckPacket =
48
+ | PubackPacket
49
+ | PubrecPacket
50
+ | PubrelPacket
51
+ | PubcompPacket;
52
+
53
+ export const anyAck: {
54
+ encode(packet: AnyAckPacket, codecOpts: CodecOpts): Uint8Array;
55
+ decode(
56
+ buffer: Uint8Array,
57
+ flags: number,
58
+ codecOpts: CodecOpts,
59
+ packetType: TPacketType,
60
+ ): AnyAckPacket;
61
+ } = {
62
+ encode(packet: AnyAckPacket, codecOpts: CodecOpts): Uint8Array {
63
+ const flags = packet.type === PacketType.pubrel ? 2 : 0;
64
+ const encoder = new Encoder(packet.type);
65
+ encoder.setInt16(packet.id);
66
+ if (packet.protocolLevel === 5) {
67
+ const reasonCode = packet.reasonCode || ReasonCode.success;
68
+ // if remaining length is less than 1 the value of 0x00 (success) is used.
69
+ if (
70
+ reasonCode === ReasonCode.success &&
71
+ Object.keys(packet.properties || {}).length === 0
72
+ ) {
73
+ return encoder.done(flags);
74
+ }
75
+ encoder.setReasonCode(reasonCode);
76
+ encoder.setProperties(
77
+ packet.properties || {},
78
+ packet.type,
79
+ codecOpts.maxOutgoingPacketSize,
80
+ );
81
+ }
82
+ return encoder.done(flags);
83
+ },
84
+
85
+ decode(
86
+ buffer: Uint8Array,
87
+ flags: number,
88
+ codecOpts: CodecOpts,
89
+ packetType: TPacketType,
90
+ ): AnyAckPacket {
91
+ const expectedFlags = packetType === PacketType.pubrel ? 2 : 0;
92
+ if (flags !== expectedFlags) {
93
+ throw new DecoderError("Invalid flags");
94
+ }
95
+ const decoder = new Decoder(packetType, buffer);
96
+ const id = decoder.getInt16();
97
+ if (codecOpts.protocolLevel !== 5) {
98
+ decoder.done();
99
+ return {
100
+ type: packetType,
101
+ protocolLevel: codecOpts.protocolLevel,
102
+ id,
103
+ };
104
+ }
105
+ if (decoder.atEnd()) {
106
+ return {
107
+ type: packetType,
108
+ protocolLevel: 5,
109
+ id,
110
+ reasonCode: 0,
111
+ };
112
+ }
113
+ const reasonCode = decoder.getReasonCode();
114
+ const properties = decoder.getProperties(packetType);
115
+ return {
116
+ type: packetType,
117
+ protocolLevel: 5,
118
+ id,
119
+ reasonCode,
120
+ properties,
121
+ };
122
+ },
123
+ };