@seriousme/opifex 1.11.3 → 2.1.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 (542) hide show
  1. package/README.md +99 -40
  2. package/bin/conformanceServer.ts +45 -13
  3. package/bin/demoServer.ts +38 -13
  4. package/bin/mqtt.ts +2 -2
  5. package/client/ConnectionState.ts +3 -1
  6. package/client/client.ts +88 -47
  7. package/client/context.ts +79 -27
  8. package/client/deps.ts +10 -3
  9. package/client/handlers/handleAuth.test.ts +193 -0
  10. package/client/handlers/handleAuth.ts +89 -0
  11. package/client/handlers/handleConnack.test.ts +173 -0
  12. package/client/handlers/handleConnack.ts +18 -8
  13. package/client/handlers/handleDisconnect.test.ts +22 -0
  14. package/client/handlers/handleDisconnect.ts +17 -0
  15. package/client/handlers/handlePacket.test.ts +242 -0
  16. package/client/handlers/handlePacket.ts +19 -5
  17. package/client/handlers/handlePuback.test.ts +99 -0
  18. package/client/handlers/handlePuback.ts +6 -0
  19. package/client/handlers/handlePubcomp.test.ts +112 -0
  20. package/client/handlers/handlePubcomp.ts +5 -0
  21. package/client/handlers/handlePublish.test.ts +188 -0
  22. package/client/handlers/handlePubrec.test.ts +119 -0
  23. package/client/handlers/handlePubrec.ts +5 -1
  24. package/client/handlers/handlePubrel.test.ts +136 -0
  25. package/client/handlers/handleSuback.test.ts +122 -0
  26. package/client/handlers/handleSuback.ts +3 -0
  27. package/client/handlers/handleUnsuback.test.ts +101 -0
  28. package/client/mod.ts +13 -2
  29. package/client/store/memoryStore.ts +12 -11
  30. package/client/store/store.ts +4 -2
  31. package/deno/README.md +1 -2
  32. package/deno/tcpClient.test.ts +75 -0
  33. package/deno/tcpClient.ts +36 -18
  34. package/deno/tcpServer.test.ts +22 -21
  35. package/deno/tcpServer.ts +26 -4
  36. package/deno/tlsServer.test.ts +97 -0
  37. package/deno/tlsServer.ts +58 -0
  38. package/deno/wsServer.test.ts +93 -0
  39. package/deno/wsServer.ts +96 -0
  40. package/dev_utils/generateCert.ts +95 -0
  41. package/dev_utils/mockConn.ts +36 -0
  42. package/dev_utils/mockServer.ts +28 -0
  43. package/dev_utils/mod.ts +30 -3
  44. package/dev_utils/packetHelpers.ts +404 -0
  45. package/dev_utils/test-handlers.ts +98 -0
  46. package/dev_utils/timers.ts +14 -0
  47. package/dev_utils/webStreamPair.test.ts +171 -0
  48. package/dev_utils/webStreamPair.ts +143 -0
  49. package/dist/bin/conformanceServer.js +17 -12
  50. package/dist/bin/conformanceServer.js.map +1 -1
  51. package/dist/bin/demoServer.js +16 -12
  52. package/dist/bin/demoServer.js.map +1 -1
  53. package/dist/bin/mqtt.js +2 -2
  54. package/dist/bin/mqtt.js.map +1 -1
  55. package/dist/client/ConnectionState.d.ts +3 -1
  56. package/dist/client/ConnectionState.d.ts.map +1 -1
  57. package/dist/client/ConnectionState.js +2 -0
  58. package/dist/client/ConnectionState.js.map +1 -1
  59. package/dist/client/client.d.ts +47 -21
  60. package/dist/client/client.d.ts.map +1 -1
  61. package/dist/client/client.js +57 -20
  62. package/dist/client/client.js.map +1 -1
  63. package/dist/client/context.d.ts +15 -7
  64. package/dist/client/context.d.ts.map +1 -1
  65. package/dist/client/context.js +44 -12
  66. package/dist/client/context.js.map +1 -1
  67. package/dist/client/deps.d.ts +4 -3
  68. package/dist/client/deps.d.ts.map +1 -1
  69. package/dist/client/deps.js +1 -1
  70. package/dist/client/deps.js.map +1 -1
  71. package/dist/client/handlers/handleAuth.d.ts +9 -0
  72. package/dist/client/handlers/handleAuth.d.ts.map +1 -0
  73. package/dist/client/handlers/handleAuth.js +66 -0
  74. package/dist/client/handlers/handleAuth.js.map +1 -0
  75. package/dist/client/handlers/handleConnack.d.ts +2 -2
  76. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  77. package/dist/client/handlers/handleConnack.js +16 -6
  78. package/dist/client/handlers/handleConnack.js.map +1 -1
  79. package/dist/client/handlers/handleDisconnect.d.ts +11 -0
  80. package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
  81. package/dist/client/handlers/handleDisconnect.js +15 -0
  82. package/dist/client/handlers/handleDisconnect.js.map +1 -0
  83. package/dist/client/handlers/handlePacket.d.ts.map +1 -1
  84. package/dist/client/handlers/handlePacket.js +14 -3
  85. package/dist/client/handlers/handlePacket.js.map +1 -1
  86. package/dist/client/handlers/handlePuback.d.ts.map +1 -1
  87. package/dist/client/handlers/handlePuback.js +5 -0
  88. package/dist/client/handlers/handlePuback.js.map +1 -1
  89. package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
  90. package/dist/client/handlers/handlePubcomp.js +5 -0
  91. package/dist/client/handlers/handlePubcomp.js.map +1 -1
  92. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  93. package/dist/client/handlers/handlePubrec.js +5 -1
  94. package/dist/client/handlers/handlePubrec.js.map +1 -1
  95. package/dist/client/handlers/handleSuback.d.ts +1 -0
  96. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  97. package/dist/client/handlers/handleSuback.js +3 -0
  98. package/dist/client/handlers/handleSuback.js.map +1 -1
  99. package/dist/client/mod.d.ts +3 -2
  100. package/dist/client/mod.d.ts.map +1 -1
  101. package/dist/client/mod.js +1 -1
  102. package/dist/client/mod.js.map +1 -1
  103. package/dist/client/store/memoryStore.d.ts +3 -3
  104. package/dist/client/store/memoryStore.d.ts.map +1 -1
  105. package/dist/client/store/memoryStore.js +3 -3
  106. package/dist/client/store/memoryStore.js.map +1 -1
  107. package/dist/client/store/store.d.ts +3 -2
  108. package/dist/client/store/store.d.ts.map +1 -1
  109. package/dist/client/store/store.js +1 -1
  110. package/dist/client/store/store.js.map +1 -1
  111. package/dist/dev_utils/generateCert.d.ts +11 -0
  112. package/dist/dev_utils/generateCert.d.ts.map +1 -0
  113. package/dist/dev_utils/generateCert.js +76 -0
  114. package/dist/dev_utils/generateCert.js.map +1 -0
  115. package/dist/examples/authHandler.test.d.ts +2 -0
  116. package/dist/examples/authHandler.test.d.ts.map +1 -0
  117. package/dist/examples/authHandler.test.js +123 -0
  118. package/dist/examples/authHandler.test.js.map +1 -0
  119. package/dist/examples/mqtt.test.d.ts +2 -0
  120. package/dist/examples/mqtt.test.d.ts.map +1 -0
  121. package/dist/examples/mqtt.test.js +70 -0
  122. package/dist/examples/mqtt.test.js.map +1 -0
  123. package/dist/examples/mqtts.test.d.ts +2 -0
  124. package/dist/examples/mqtts.test.d.ts.map +1 -0
  125. package/dist/examples/mqtts.test.js +81 -0
  126. package/dist/examples/mqtts.test.js.map +1 -0
  127. package/dist/mqttConn/mqttConn.d.ts +24 -31
  128. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  129. package/dist/mqttConn/mqttConn.js +57 -36
  130. package/dist/mqttConn/mqttConn.js.map +1 -1
  131. package/dist/mqttPacket/AuthenticationResult.d.ts +4 -0
  132. package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
  133. package/dist/mqttPacket/AuthenticationResult.js.map +1 -1
  134. package/dist/mqttPacket/BitMask.d.ts.map +1 -1
  135. package/dist/mqttPacket/PacketType.d.ts +4 -0
  136. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  137. package/dist/mqttPacket/Properties.d.ts +4 -4
  138. package/dist/mqttPacket/Properties.d.ts.map +1 -1
  139. package/dist/mqttPacket/Properties.js.map +1 -1
  140. package/dist/mqttPacket/ReasonCode.d.ts +4 -5
  141. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
  142. package/dist/mqttPacket/ReasonCode.js +1 -0
  143. package/dist/mqttPacket/ReasonCode.js.map +1 -1
  144. package/dist/mqttPacket/RetainHandling.d.ts +4 -0
  145. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
  146. package/dist/mqttPacket/auth.d.ts +7 -8
  147. package/dist/mqttPacket/auth.d.ts.map +1 -1
  148. package/dist/mqttPacket/auth.js +31 -30
  149. package/dist/mqttPacket/auth.js.map +1 -1
  150. package/dist/mqttPacket/codec.d.ts +48 -0
  151. package/dist/mqttPacket/codec.d.ts.map +1 -0
  152. package/dist/mqttPacket/codec.js +93 -0
  153. package/dist/mqttPacket/codec.js.map +1 -0
  154. package/dist/mqttPacket/connack.d.ts +11 -10
  155. package/dist/mqttPacket/connack.d.ts.map +1 -1
  156. package/dist/mqttPacket/connack.js +43 -45
  157. package/dist/mqttPacket/connack.js.map +1 -1
  158. package/dist/mqttPacket/connect.d.ts +7 -7
  159. package/dist/mqttPacket/connect.d.ts.map +1 -1
  160. package/dist/mqttPacket/connect.js +156 -157
  161. package/dist/mqttPacket/connect.js.map +1 -1
  162. package/dist/mqttPacket/decoder.d.ts +6 -16
  163. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  164. package/dist/mqttPacket/decoder.js +7 -28
  165. package/dist/mqttPacket/decoder.js.map +1 -1
  166. package/dist/mqttPacket/disconnect.d.ts +9 -8
  167. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  168. package/dist/mqttPacket/disconnect.js +41 -43
  169. package/dist/mqttPacket/disconnect.js.map +1 -1
  170. package/dist/mqttPacket/encoder.d.ts +7 -19
  171. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  172. package/dist/mqttPacket/encoder.js +5 -28
  173. package/dist/mqttPacket/encoder.js.map +1 -1
  174. package/dist/mqttPacket/mod.d.ts +21 -103
  175. package/dist/mqttPacket/mod.d.ts.map +1 -1
  176. package/dist/mqttPacket/mod.js +5 -94
  177. package/dist/mqttPacket/mod.js.map +1 -1
  178. package/dist/mqttPacket/pingreq.d.ts +6 -6
  179. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  180. package/dist/mqttPacket/pingreq.js +11 -13
  181. package/dist/mqttPacket/pingreq.js.map +1 -1
  182. package/dist/mqttPacket/pingres.d.ts +6 -6
  183. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  184. package/dist/mqttPacket/pingres.js +11 -13
  185. package/dist/mqttPacket/pingres.js.map +1 -1
  186. package/dist/mqttPacket/protocolLevels.d.ts +11 -6
  187. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
  188. package/dist/mqttPacket/protocolLevels.js +5 -1
  189. package/dist/mqttPacket/protocolLevels.js.map +1 -1
  190. package/dist/mqttPacket/pubblishAcks.d.ts +9 -10
  191. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
  192. package/dist/mqttPacket/pubblishAcks.js +43 -45
  193. package/dist/mqttPacket/pubblishAcks.js.map +1 -1
  194. package/dist/mqttPacket/publish.d.ts +8 -7
  195. package/dist/mqttPacket/publish.d.ts.map +1 -1
  196. package/dist/mqttPacket/publish.js +53 -55
  197. package/dist/mqttPacket/publish.js.map +1 -1
  198. package/dist/mqttPacket/suback.d.ts +9 -8
  199. package/dist/mqttPacket/suback.d.ts.map +1 -1
  200. package/dist/mqttPacket/suback.js +38 -40
  201. package/dist/mqttPacket/suback.js.map +1 -1
  202. package/dist/mqttPacket/subscribe.d.ts +41 -10
  203. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  204. package/dist/mqttPacket/subscribe.js +90 -89
  205. package/dist/mqttPacket/subscribe.js.map +1 -1
  206. package/dist/mqttPacket/types.d.ts +2 -29
  207. package/dist/mqttPacket/types.d.ts.map +1 -1
  208. package/dist/mqttPacket/unsuback.d.ts +9 -8
  209. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  210. package/dist/mqttPacket/unsuback.js +32 -34
  211. package/dist/mqttPacket/unsuback.js.map +1 -1
  212. package/dist/mqttPacket/unsubscribe.d.ts +26 -8
  213. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  214. package/dist/mqttPacket/unsubscribe.js +45 -44
  215. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  216. package/dist/mqttPacket/validators.d.ts +4 -16
  217. package/dist/mqttPacket/validators.d.ts.map +1 -1
  218. package/dist/mqttPacket/validators.js +5 -26
  219. package/dist/mqttPacket/validators.js.map +1 -1
  220. package/dist/node/tcpClient.d.ts +22 -2
  221. package/dist/node/tcpClient.d.ts.map +1 -1
  222. package/dist/node/tcpClient.js +29 -10
  223. package/dist/node/tcpClient.js.map +1 -1
  224. package/dist/node/tcpServer.d.ts +18 -0
  225. package/dist/node/tcpServer.d.ts.map +1 -1
  226. package/dist/node/tcpServer.js +21 -2
  227. package/dist/node/tcpServer.js.map +1 -1
  228. package/dist/node/tlsServer.d.ts +37 -0
  229. package/dist/node/tlsServer.d.ts.map +1 -0
  230. package/dist/node/tlsServer.js +73 -0
  231. package/dist/node/tlsServer.js.map +1 -0
  232. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  233. package/dist/node/wrapNodeSocket.js +6 -28
  234. package/dist/node/wrapNodeSocket.js.map +1 -1
  235. package/dist/persistence/basicPersistence.d.ts +36 -0
  236. package/dist/persistence/basicPersistence.d.ts.map +1 -0
  237. package/dist/persistence/basicPersistence.js +306 -0
  238. package/dist/persistence/basicPersistence.js.map +1 -0
  239. package/dist/persistence/deps.d.ts +3 -2
  240. package/dist/persistence/deps.d.ts.map +1 -1
  241. package/dist/persistence/deps.js +2 -1
  242. package/dist/persistence/deps.js.map +1 -1
  243. package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
  244. package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
  245. package/dist/persistence/memory/memoryPersistence.js +12 -115
  246. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  247. package/dist/persistence/memory/memoryStorage.d.ts +45 -0
  248. package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
  249. package/dist/persistence/memory/memoryStorage.js +143 -0
  250. package/dist/persistence/memory/memoryStorage.js.map +1 -0
  251. package/dist/persistence/mod.d.ts +3 -3
  252. package/dist/persistence/mod.d.ts.map +1 -1
  253. package/dist/persistence/mod.js +6 -1
  254. package/dist/persistence/mod.js.map +1 -1
  255. package/dist/persistence/persistence.d.ts +45 -70
  256. package/dist/persistence/persistence.d.ts.map +1 -1
  257. package/dist/persistence/persistence.js +1 -2
  258. package/dist/persistence/persistence.js.map +1 -1
  259. package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
  260. package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
  261. package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
  262. package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
  263. package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
  264. package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
  265. package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
  266. package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
  267. package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
  268. package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
  269. package/dist/persistence/sqlite/sqliteStorage.js +194 -0
  270. package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
  271. package/dist/persistence/storage.d.ts +38 -0
  272. package/dist/persistence/storage.d.ts.map +1 -0
  273. package/dist/persistence/storage.js +5 -0
  274. package/dist/persistence/storage.js.map +1 -0
  275. package/dist/server/config.d.ts +47 -0
  276. package/dist/server/config.d.ts.map +1 -0
  277. package/dist/server/config.js +41 -0
  278. package/dist/server/config.js.map +1 -0
  279. package/dist/server/context.d.ts +199 -25
  280. package/dist/server/context.d.ts.map +1 -1
  281. package/dist/server/context.js +432 -53
  282. package/dist/server/context.js.map +1 -1
  283. package/dist/server/deps.d.ts +5 -6
  284. package/dist/server/deps.d.ts.map +1 -1
  285. package/dist/server/deps.js +2 -2
  286. package/dist/server/deps.js.map +1 -1
  287. package/dist/server/handlers/completeConnect.d.ts +9 -0
  288. package/dist/server/handlers/completeConnect.d.ts.map +1 -0
  289. package/dist/server/handlers/completeConnect.js +74 -0
  290. package/dist/server/handlers/completeConnect.js.map +1 -0
  291. package/dist/server/handlers/handleAuth.d.ts +9 -0
  292. package/dist/server/handlers/handleAuth.d.ts.map +1 -0
  293. package/dist/server/handlers/handleAuth.js +69 -0
  294. package/dist/server/handlers/handleAuth.js.map +1 -0
  295. package/dist/server/handlers/handleConnect.d.ts +2 -4
  296. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  297. package/dist/server/handlers/handleConnect.js +140 -67
  298. package/dist/server/handlers/handleConnect.js.map +1 -1
  299. package/dist/server/handlers/handleDisconnect.d.ts +1 -1
  300. package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
  301. package/dist/server/handlers/handleDisconnect.js +3 -3
  302. package/dist/server/handlers/handleDisconnect.js.map +1 -1
  303. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  304. package/dist/server/handlers/handlePacket.js +19 -6
  305. package/dist/server/handlers/handlePacket.js.map +1 -1
  306. package/dist/server/handlers/handlePuback.d.ts +1 -3
  307. package/dist/server/handlers/handlePuback.d.ts.map +1 -1
  308. package/dist/server/handlers/handlePuback.js +2 -8
  309. package/dist/server/handlers/handlePuback.js.map +1 -1
  310. package/dist/server/handlers/handlePubcomp.d.ts +1 -1
  311. package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
  312. package/dist/server/handlers/handlePubcomp.js +2 -4
  313. package/dist/server/handlers/handlePubcomp.js.map +1 -1
  314. package/dist/server/handlers/handlePublish.d.ts +1 -1
  315. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  316. package/dist/server/handlers/handlePublish.js +149 -45
  317. package/dist/server/handlers/handlePublish.js.map +1 -1
  318. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  319. package/dist/server/handlers/handlePubrec.js +2 -3
  320. package/dist/server/handlers/handlePubrec.js.map +1 -1
  321. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  322. package/dist/server/handlers/handlePubrel.js +6 -2
  323. package/dist/server/handlers/handlePubrel.js.map +1 -1
  324. package/dist/server/handlers/handleSubscribe.d.ts +1 -6
  325. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  326. package/dist/server/handlers/handleSubscribe.js +99 -38
  327. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  328. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  329. package/dist/server/handlers/handleUnsubscribe.js +19 -4
  330. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  331. package/dist/server/mod.d.ts +3 -3
  332. package/dist/server/mod.d.ts.map +1 -1
  333. package/dist/server/mod.js +1 -1
  334. package/dist/server/mod.js.map +1 -1
  335. package/dist/server/server.d.ts +32 -9
  336. package/dist/server/server.d.ts.map +1 -1
  337. package/dist/server/server.js +84 -15
  338. package/dist/server/server.js.map +1 -1
  339. package/dist/socket/socket.d.ts +15 -9
  340. package/dist/socket/socket.d.ts.map +1 -1
  341. package/dist/socket/socket.js +66 -18
  342. package/dist/socket/socket.js.map +1 -1
  343. package/dist/timer/timer.d.ts +32 -0
  344. package/dist/timer/timer.d.ts.map +1 -1
  345. package/dist/timer/timer.js +32 -0
  346. package/dist/timer/timer.js.map +1 -1
  347. package/dist/trie/trie.d.ts +10 -5
  348. package/dist/trie/trie.d.ts.map +1 -1
  349. package/dist/trie/trie.js +61 -41
  350. package/dist/trie/trie.js.map +1 -1
  351. package/dist/utils/assert.d.ts.map +1 -1
  352. package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
  353. package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
  354. package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
  355. package/dist/utils/bufferedAsyncIterable.js.map +1 -0
  356. package/dist/utils/deferred.d.ts.map +1 -1
  357. package/dist/utils/deferred.js.map +1 -1
  358. package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
  359. package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
  360. package/dist/utils/getOrInsertPolyFill.js +12 -0
  361. package/dist/utils/getOrInsertPolyFill.js.map +1 -0
  362. package/dist/utils/logger.d.ts +42 -5
  363. package/dist/utils/logger.d.ts.map +1 -1
  364. package/dist/utils/logger.js +53 -7
  365. package/dist/utils/logger.js.map +1 -1
  366. package/dist/utils/mod.d.ts +6 -1
  367. package/dist/utils/mod.d.ts.map +1 -1
  368. package/dist/utils/mod.js +5 -1
  369. package/dist/utils/mod.js.map +1 -1
  370. package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
  371. package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
  372. package/dist/utils/outboundTopicAliasManager.js +74 -0
  373. package/dist/utils/outboundTopicAliasManager.js.map +1 -0
  374. package/dist/utils/queue.d.ts.map +1 -1
  375. package/dist/utils/topicFilter.d.ts +32 -0
  376. package/dist/utils/topicFilter.d.ts.map +1 -0
  377. package/dist/utils/topicFilter.js +52 -0
  378. package/dist/utils/topicFilter.js.map +1 -0
  379. package/dist/utils/utils.d.ts +2 -0
  380. package/dist/utils/utils.d.ts.map +1 -1
  381. package/dist/utils/utils.js +2 -0
  382. package/dist/utils/utils.js.map +1 -1
  383. package/dist/utils/validators.d.ts +34 -0
  384. package/dist/utils/validators.d.ts.map +1 -0
  385. package/dist/utils/validators.js +61 -0
  386. package/dist/utils/validators.js.map +1 -0
  387. package/dist/web/webSocketStream.d.ts +29 -0
  388. package/dist/web/webSocketStream.d.ts.map +1 -0
  389. package/dist/web/webSocketStream.js +69 -0
  390. package/dist/web/webSocketStream.js.map +1 -0
  391. package/dist/web/wrapWebSocket.d.ts +12 -0
  392. package/dist/web/wrapWebSocket.d.ts.map +1 -0
  393. package/dist/web/wrapWebSocket.js +41 -0
  394. package/dist/web/wrapWebSocket.js.map +1 -0
  395. package/dist/web/wsClient.d.ts +14 -0
  396. package/dist/web/wsClient.d.ts.map +1 -0
  397. package/dist/web/wsClient.js +33 -0
  398. package/dist/web/wsClient.js.map +1 -0
  399. package/dist/web/wsClient.test.d.ts +2 -0
  400. package/dist/web/wsClient.test.d.ts.map +1 -0
  401. package/dist/web/wsClient.test.js +20 -0
  402. package/dist/web/wsClient.test.js.map +1 -0
  403. package/examples/authHandler.test.ts +164 -0
  404. package/examples/mqtt.test.ts +89 -0
  405. package/examples/mqtts.test.ts +100 -0
  406. package/examples/webSocket.test.ts +94 -0
  407. package/mqttConn/mqttConn.test.ts +9 -9
  408. package/mqttConn/mqttConn.ts +76 -60
  409. package/mqttPacket/AuthenticationResult.ts +6 -0
  410. package/mqttPacket/PacketType.ts +5 -0
  411. package/mqttPacket/Properties.ts +8 -5
  412. package/mqttPacket/ReasonCode.ts +8 -9
  413. package/mqttPacket/RetainHandling.ts +5 -0
  414. package/mqttPacket/auth.test.ts +1 -1
  415. package/mqttPacket/auth.ts +44 -51
  416. package/mqttPacket/codec.ts +147 -0
  417. package/mqttPacket/connack.ts +63 -73
  418. package/mqttPacket/connect.test.ts +2 -2
  419. package/mqttPacket/connect.ts +178 -192
  420. package/mqttPacket/decoder.test.ts +0 -39
  421. package/mqttPacket/decoder.ts +17 -46
  422. package/mqttPacket/disconnect.ts +60 -71
  423. package/mqttPacket/encoder.test.ts +2 -2
  424. package/mqttPacket/encoder.ts +13 -46
  425. package/mqttPacket/mod.ts +48 -204
  426. package/mqttPacket/pingreq.ts +22 -28
  427. package/mqttPacket/pingres.ts +22 -28
  428. package/mqttPacket/protocolLevels.ts +12 -7
  429. package/mqttPacket/pubblishAcks.ts +61 -75
  430. package/mqttPacket/publish.ts +70 -84
  431. package/mqttPacket/publishAcks.test.ts +3 -3
  432. package/mqttPacket/suback.ts +53 -68
  433. package/mqttPacket/subscribe.ts +146 -128
  434. package/mqttPacket/types.ts +2 -35
  435. package/mqttPacket/unsuback.ts +50 -61
  436. package/mqttPacket/unsubscribe.ts +77 -72
  437. package/mqttPacket/validators.ts +5 -31
  438. package/node/socket-node-stream.test.ts +322 -0
  439. package/node/socket-node-stream.ts +174 -0
  440. package/node/tcpClient.test.ts +70 -0
  441. package/node/tcpClient.ts +33 -17
  442. package/node/tcpServer.test.ts +24 -20
  443. package/node/tcpServer.ts +29 -6
  444. package/node/tlsServer.test.ts +94 -0
  445. package/node/tlsServer.ts +97 -0
  446. package/node/wrapNodeSocket.ts +7 -30
  447. package/package.json +72 -44
  448. package/persistence/basicPersistence.ts +495 -0
  449. package/persistence/deps.ts +11 -1
  450. package/persistence/memory/memoryPersistence.ts +12 -153
  451. package/persistence/memory/memoryStorage.ts +232 -0
  452. package/persistence/mod.ts +5 -10
  453. package/persistence/persistence.test.ts +24 -0
  454. package/persistence/persistence.testing.ts +1324 -0
  455. package/persistence/persistence.ts +112 -68
  456. package/persistence/sqlite/sqliteDatabase.ts +294 -0
  457. package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
  458. package/persistence/sqlite/sqlitePersistence.ts +36 -0
  459. package/persistence/sqlite/sqliteStorage.ts +324 -0
  460. package/persistence/storage.ts +84 -0
  461. package/server/config.ts +65 -0
  462. package/server/context.ts +660 -76
  463. package/server/deps.ts +24 -5
  464. package/server/handlers/completeConnect.ts +93 -0
  465. package/server/handlers/duplicate.test.ts +196 -0
  466. package/server/handlers/handleAuth.test.ts +225 -0
  467. package/server/handlers/handleAuth.ts +88 -0
  468. package/server/handlers/handleConnect.test.ts +589 -0
  469. package/server/handlers/handleConnect.ts +201 -86
  470. package/server/handlers/handleConnect.version.test.ts +108 -0
  471. package/server/handlers/handleDisconnect.test.ts +56 -0
  472. package/server/handlers/handleDisconnect.ts +3 -3
  473. package/server/handlers/handlePacket.test.ts +24 -0
  474. package/server/handlers/handlePacket.ts +30 -8
  475. package/server/handlers/handlePingreq.test.ts +29 -0
  476. package/server/handlers/handlePuback.test.ts +28 -0
  477. package/server/handlers/handlePuback.ts +5 -8
  478. package/server/handlers/handlePubcomp.test.ts +28 -0
  479. package/server/handlers/handlePubcomp.ts +5 -4
  480. package/server/handlers/handlePublish.test.ts +471 -0
  481. package/server/handlers/handlePublish.ts +188 -35
  482. package/server/handlers/handlePubrec.test.ts +28 -0
  483. package/server/handlers/handlePubrec.ts +2 -3
  484. package/server/handlers/handlePubrel.test.ts +74 -0
  485. package/server/handlers/handlePubrel.ts +12 -2
  486. package/server/handlers/handleSubscribe.test.ts +971 -0
  487. package/server/handlers/handleSubscribe.ts +157 -39
  488. package/server/handlers/handleUnsubscribe.test.ts +79 -0
  489. package/server/handlers/handleUnsubscribe.ts +28 -4
  490. package/server/handlers/keepalive.test.ts +132 -0
  491. package/server/handlers/session.persistence.test.ts +194 -0
  492. package/server/handlers/will.delivery.test.ts +221 -0
  493. package/server/mod.ts +5 -4
  494. package/server/preconnect.test.ts +151 -0
  495. package/server/server.ts +117 -19
  496. package/socket/socket.test.ts +91 -0
  497. package/socket/socket.ts +85 -34
  498. package/timer/timer.test.ts +4 -7
  499. package/timer/timer.ts +36 -0
  500. package/tools/benchmarks/receiver.ts +51 -0
  501. package/tools/benchmarks/sender.ts +48 -0
  502. package/tools/benchmarks/utils.ts +31 -0
  503. package/tools/mqtt-compat/README.md +130 -0
  504. package/tools/mqtt-compat/broker.ts +52 -0
  505. package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
  506. package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
  507. package/trie/trie.test.ts +9 -1
  508. package/trie/trie.ts +70 -45
  509. package/utils/bufferedAsyncIterable.test.ts +92 -0
  510. package/utils/deferred.test.ts +36 -0
  511. package/utils/deferred.ts +0 -1
  512. package/utils/getOrInsertPolyFill.ts +12 -0
  513. package/utils/logger.test.ts +189 -0
  514. package/utils/logger.ts +64 -9
  515. package/utils/mod.ts +15 -1
  516. package/utils/outboundTopicAliasManager.ts +100 -0
  517. package/utils/queue.test.ts +61 -0
  518. package/utils/topicFilter.test.ts +63 -0
  519. package/utils/topicFilter.ts +61 -0
  520. package/utils/utils.ts +3 -0
  521. package/utils/validators.ts +67 -0
  522. package/web/webSocketStream.ts +97 -0
  523. package/web/wrapWebSocket.ts +52 -0
  524. package/web/wsClient.test.ts +26 -0
  525. package/web/wsClient.ts +37 -0
  526. package/benchmarks/receiver.ts +0 -35
  527. package/benchmarks/sender.ts +0 -32
  528. package/benchmarks/utils.ts +0 -9
  529. package/dev_utils/dummyConn.ts +0 -110
  530. package/dev_utils/socketPair.ts +0 -85
  531. package/dist/persistence/store.d.ts +0 -14
  532. package/dist/persistence/store.d.ts.map +0 -1
  533. package/dist/persistence/store.js +0 -2
  534. package/dist/persistence/store.js.map +0 -1
  535. package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
  536. package/dist/utils/BufferedAsyncIterable.js.map +0 -1
  537. package/examples/tcpServer.test.ts +0 -148
  538. package/persistence/memory/memoryPersistence.test.ts +0 -156
  539. package/persistence/store.ts +0 -16
  540. package/server/test/handleConnect.test.ts +0 -122
  541. package/server/test/test-handlers.ts +0 -53
  542. /package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +0 -0
@@ -0,0 +1,28 @@
1
+ import { test } from "node:test";
2
+ import type { AnyPacket } from "../deps.ts";
3
+ import { MQTTLevel, PacketType } from "../deps.ts";
4
+ import {
5
+ connect,
6
+ disconnect,
7
+ ping,
8
+ startMockServer,
9
+ } from "../../dev_utils/mod.ts";
10
+
11
+ test("PUBCOMP is handled without error", async () => {
12
+ const { mqttConn } = startMockServer();
13
+
14
+ await connect(mqttConn);
15
+
16
+ // Send PUBCOMP (simulating final step of QoS 2 outgoing flow)
17
+ const pubcompPacket: AnyPacket = {
18
+ type: PacketType.pubcomp,
19
+ protocolLevel: MQTTLevel.v4,
20
+ id: 9999,
21
+ };
22
+ mqttConn.send(pubcompPacket);
23
+
24
+ // Verify server is still responsive
25
+ await ping(mqttConn);
26
+
27
+ await disconnect(mqttConn);
28
+ });
@@ -9,9 +9,10 @@ import type { PubcompPacket } from "../deps.ts";
9
9
  * This is the fourth and final packet of the QoS 2 protocol exchange.
10
10
  * When received, it removes the message from the pendingAckOutgoing store.
11
11
  */
12
- export function handlePubcomp(ctx: Context, packet: PubcompPacket): void {
12
+ export async function handlePubcomp(
13
+ ctx: Context,
14
+ packet: PubcompPacket,
15
+ ): Promise<void> {
13
16
  const id = packet.id;
14
- if (ctx.store?.pendingAckOutgoing.has(id)) {
15
- ctx.store.pendingAckOutgoing.delete(id);
16
- }
17
+ await ctx.persistence.deletePendingAck(ctx.clientId!, id);
17
18
  }
@@ -0,0 +1,471 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import {
5
+ connect,
6
+ connect5,
7
+ disconnect,
8
+ disconnect5,
9
+ isAuthenticatedBroker,
10
+ ping,
11
+ publish,
12
+ publish5,
13
+ startMockServer,
14
+ } from "../../dev_utils/mod.ts";
15
+
16
+ import { PacketType, ReasonCode } from "../deps.ts";
17
+
18
+ test("PUBLISH QoS 0 does not receive acknowledgment", async () => {
19
+ const { mqttConn } = startMockServer();
20
+
21
+ await connect(mqttConn);
22
+
23
+ // Publish QoS 0
24
+ await publish(mqttConn, "hello", 0);
25
+
26
+ // Send PINGREQ to verify no PUBACK was queued before it
27
+ // QoS 0 should not produce PUBACK, next response should be PINGRES
28
+ await ping(mqttConn);
29
+
30
+ await disconnect(mqttConn);
31
+ });
32
+
33
+ test("PUBLISH QoS 1 receives PUBACK", async () => {
34
+ const { mqttConn } = startMockServer();
35
+
36
+ await connect(mqttConn);
37
+
38
+ // Publish QoS 1
39
+ await publish(mqttConn, "test/topic", 1);
40
+
41
+ await disconnect(mqttConn);
42
+ });
43
+
44
+ test("PUBLISH QoS 2 receives PUBREC", async () => {
45
+ const { mqttConn } = startMockServer();
46
+
47
+ await connect(mqttConn);
48
+
49
+ // Publish QoS 2
50
+ await publish(mqttConn, "test/topic", 2, { id: 2, payload: "hello" });
51
+ await disconnect(mqttConn);
52
+ });
53
+
54
+ test("Publish with missing isAuthorizedToPublish handler authorizes publish", async () => {
55
+ const { mqttConn, mqttServer } = startMockServer();
56
+ mqttServer.handlers.isAuthorizedToPublish = undefined;
57
+
58
+ await connect(mqttConn);
59
+ // Try to publish to unauthorized topic
60
+ await publish(mqttConn, "topic/unauthorized", 1, { id: 3, payload: "test" });
61
+
62
+ await disconnect(mqttConn);
63
+ });
64
+
65
+ test("Publish with isAuthorizedToPublish handler throwing error rejects publish", async () => {
66
+ const { mqttConn, mqttServer } = startMockServer();
67
+ mqttServer.handlers.isAuthorizedToPublish = () => {
68
+ throw Error("kaboom");
69
+ };
70
+
71
+ await connect(mqttConn);
72
+ await publish(mqttConn, "topic/kaboom", 1, {
73
+ id: 3,
74
+ payload: "test",
75
+ checkAcks: false,
76
+ });
77
+ await mqttConn.next();
78
+ assert.equal(mqttConn.isClosed, true, "expect connection to be closed");
79
+ });
80
+
81
+ test("PUBLISH to unauthorized topic is rejected", async () => {
82
+ const { mqttConn } = startMockServer();
83
+
84
+ await connect(mqttConn);
85
+
86
+ // Try to publish to unauthorized topic
87
+ await publish(mqttConn, "topic/unauthorized", 1, {
88
+ id: 3,
89
+ payload: "test",
90
+ checkAcks: false,
91
+ });
92
+
93
+ await mqttConn.next();
94
+ assert.equal(mqttConn.isClosed, true, "expect connection to be closed");
95
+ });
96
+
97
+ test("PUBLISH to $SYS topic is rejected", async () => {
98
+ const { mqttConn } = startMockServer();
99
+
100
+ await connect(mqttConn);
101
+
102
+ // Try to publish to $SYS topic
103
+ await publish(mqttConn, "$SYS/broker/clients", 1, {
104
+ id: 3,
105
+ payload: "test",
106
+ checkAcks: false,
107
+ });
108
+
109
+ await mqttConn.next();
110
+ assert.equal(mqttConn.isClosed, true, "expect connection to be closed");
111
+ });
112
+
113
+ test("PUBLISH to $SYS topic is allowed for brokers", async () => {
114
+ const { mqttConn, mqttServer } = startMockServer();
115
+ // this will set the context.isBroker=true on authentication
116
+ mqttServer.handlers.isAuthenticated = isAuthenticatedBroker;
117
+
118
+ await connect(mqttConn, { clientId: "broker1" });
119
+ // Try to publish to $SYS topic
120
+ await publish(mqttConn, "$SYS/broker/clients", 0, {
121
+ id: 3,
122
+ payload: "test",
123
+ });
124
+ // connection should still be alive
125
+ await ping(mqttConn);
126
+ await disconnect(mqttConn);
127
+ });
128
+
129
+ // ============================================================================
130
+ // Retain Not Supported Tests
131
+ // ============================================================================
132
+
133
+ test("PUBLISH with retain when retainAvailable is false closes connection in v4", async () => {
134
+ const { mqttConn } = startMockServer({
135
+ configuration: { context: { retainAvailable: false } },
136
+ });
137
+
138
+ await connect(mqttConn);
139
+
140
+ // Send publish with retain flag enabled
141
+ await publish(mqttConn, "test/topic", 1, {
142
+ id: 1,
143
+ payload: "test",
144
+ retain: true,
145
+ checkAcks: false,
146
+ });
147
+
148
+ // Protocol level 4 should close the connection on retain error
149
+ await mqttConn.next();
150
+ assert.equal(mqttConn.isClosed, true, "expect connection to be closed in v4");
151
+ });
152
+
153
+ test("PUBLISH v5 with retain when retainAvailable is false receives PUBACK with retainNotSupported (QoS 1)", async () => {
154
+ const { mqttConn } = startMockServer({
155
+ configuration: { context: { retainAvailable: false } },
156
+ });
157
+
158
+ await connect5(mqttConn);
159
+
160
+ // Send publish with retain flag enabled
161
+ await publish5(mqttConn, "test/topic", 1, {
162
+ id: 1,
163
+ payload: "test",
164
+ retain: true,
165
+ checkAcks: false,
166
+ });
167
+
168
+ const { value: pubAck } = await mqttConn.next();
169
+ assert.equal(pubAck.type, PacketType.puback, "Expected PUBACK packet");
170
+ assert.equal(pubAck.id, 1);
171
+ assert.equal(
172
+ pubAck.reasonCode,
173
+ ReasonCode.unspecifiedError,
174
+ "Expected retainNotSupported (0x9A) reasonCode in v5",
175
+ );
176
+
177
+ await disconnect5(mqttConn);
178
+ });
179
+
180
+ test("PUBLISH v5 with retain when retainAvailable is false receives PUBREC with retainNotSupported (QoS 2)", async () => {
181
+ const { mqttConn } = startMockServer({
182
+ configuration: { context: { retainAvailable: false } },
183
+ });
184
+
185
+ await connect5(mqttConn);
186
+
187
+ // Send publish with retain flag enabled
188
+ await publish5(mqttConn, "test/topic", 2, {
189
+ id: 2,
190
+ payload: "test",
191
+ retain: true,
192
+ checkAcks: false,
193
+ });
194
+
195
+ const { value: pubRec } = await mqttConn.next();
196
+ assert.equal(pubRec.type, PacketType.pubrec, "Expected PUBREC packet");
197
+ assert.equal(pubRec.id, 2);
198
+ assert.equal(
199
+ pubRec.reasonCode,
200
+ ReasonCode.unspecifiedError,
201
+ "Expected retainNotSupported (0x9A) reasonCode in v5",
202
+ );
203
+
204
+ await disconnect5(mqttConn);
205
+ });
206
+
207
+ // ============================================================================
208
+ // MQTT v5 Specific Authorization Tests
209
+ // ============================================================================
210
+
211
+ test("PUBLISH v5 QoS 0 to unauthorized topic is silently dropped", async () => {
212
+ const { mqttConn } = startMockServer();
213
+
214
+ await connect5(mqttConn);
215
+
216
+ // QoS 0 gets no error response message according to v5 spec
217
+ await publish5(mqttConn, "topic/unauthorized", 0, {
218
+ payload: "test",
219
+ checkAcks: false,
220
+ });
221
+
222
+ // Verify connection is still open by executing a successful PING
223
+ await ping(mqttConn);
224
+ await disconnect5(mqttConn);
225
+ });
226
+
227
+ test("PUBLISH v5 QoS 1 to unauthorized topic receives PUBACK with notAuthorized", async () => {
228
+ const { mqttConn } = startMockServer();
229
+
230
+ await connect5(mqttConn);
231
+
232
+ await publish5(mqttConn, "topic/unauthorized", 1, {
233
+ id: 10,
234
+ payload: "test",
235
+ checkAcks: false,
236
+ });
237
+
238
+ const { value: pubAck } = await mqttConn.next();
239
+ assert.equal(pubAck.type, PacketType.puback, "Expected PUBACK");
240
+ assert.equal(pubAck.id, 10);
241
+ assert.equal(
242
+ pubAck.reasonCode,
243
+ ReasonCode.notAuthorized,
244
+ "Expected notAuthorized (0x87) reasonCode",
245
+ );
246
+
247
+ await disconnect5(mqttConn);
248
+ });
249
+
250
+ test("PUBLISH v5 QoS 2 to unauthorized topic receives PUBREC with notAuthorized", async () => {
251
+ const { mqttConn } = startMockServer();
252
+
253
+ await connect5(mqttConn);
254
+
255
+ await publish5(mqttConn, "topic/unauthorized", 2, {
256
+ id: 11,
257
+ payload: "test",
258
+ checkAcks: false,
259
+ });
260
+
261
+ const { value: pubRec } = await mqttConn.next();
262
+ assert.equal(pubRec.type, PacketType.pubrec, "Expected PUBREC");
263
+ assert.equal(pubRec.id, 11);
264
+ assert.equal(
265
+ pubRec.reasonCode,
266
+ ReasonCode.notAuthorized,
267
+ "Expected notAuthorized (0x87) reasonCode",
268
+ );
269
+
270
+ await disconnect5(mqttConn);
271
+ });
272
+
273
+ test("PUBLISH v5 includes reasonString when provideReasonStrings is enabled", async () => {
274
+ const { mqttConn } = startMockServer({
275
+ configuration: { context: { provideReasonStrings: true } },
276
+ });
277
+
278
+ await connect5(mqttConn);
279
+
280
+ await publish5(mqttConn, "topic/unauthorized", 1, {
281
+ id: 12,
282
+ payload: "test",
283
+ checkAcks: false,
284
+ });
285
+
286
+ const { value: pubAck } = await mqttConn.next();
287
+ assert.equal(pubAck.type, PacketType.puback);
288
+ assert.equal(pubAck.reasonCode, ReasonCode.notAuthorized);
289
+ assert.equal(
290
+ pubAck.properties?.reasonString,
291
+ "Client not authorized to publish to topic/unauthorized",
292
+ );
293
+
294
+ await disconnect5(mqttConn);
295
+ });
296
+
297
+ // ============================================================================
298
+ // Invalid Topic & Topic Alias Tests
299
+ // ============================================================================
300
+
301
+ test("PUBLISH v4 with invalid topic containing wildcards closes connection", async () => {
302
+ const { mqttConn } = startMockServer();
303
+
304
+ await connect(mqttConn);
305
+
306
+ await publish(mqttConn, "invalid/+/topic", 1, {
307
+ id: 1,
308
+ payload: "test",
309
+ checkAcks: false,
310
+ });
311
+
312
+ await mqttConn.next();
313
+ assert.equal(mqttConn.isClosed, true, "expect connection to be closed in v4");
314
+ });
315
+
316
+ test("PUBLISH v5 QoS 1 with invalid topic containing wildcards receives PUBACK with topicNameInvalid", async () => {
317
+ const { mqttConn } = startMockServer();
318
+
319
+ await connect5(mqttConn);
320
+
321
+ await publish5(mqttConn, "invalid/+/topic", 1, {
322
+ id: 1,
323
+ payload: "test",
324
+ checkAcks: false,
325
+ });
326
+
327
+ const { value: pubAck } = await mqttConn.next();
328
+ assert.equal(pubAck.type, PacketType.puback);
329
+ assert.equal(pubAck.id, 1);
330
+ assert.equal(
331
+ pubAck.reasonCode,
332
+ ReasonCode.topicNameInvalid,
333
+ "Expected topicNameInvalid (0x90) reasonCode",
334
+ );
335
+
336
+ await disconnect5(mqttConn);
337
+ });
338
+
339
+ test("PUBLISH v5 QoS 2 with invalid topic containing wildcards receives PUBREC with topicNameInvalid", async () => {
340
+ const { mqttConn } = startMockServer();
341
+
342
+ await connect5(mqttConn);
343
+
344
+ await publish5(mqttConn, "invalid/#", 2, {
345
+ id: 2,
346
+ payload: "test",
347
+ checkAcks: false,
348
+ });
349
+
350
+ const { value: pubRec } = await mqttConn.next();
351
+ assert.equal(pubRec.type, PacketType.pubrec);
352
+ assert.equal(pubRec.id, 2);
353
+ assert.equal(
354
+ pubRec.reasonCode,
355
+ ReasonCode.topicNameInvalid,
356
+ "Expected topicNameInvalid (0x90) reasonCode",
357
+ );
358
+
359
+ await disconnect5(mqttConn);
360
+ });
361
+
362
+ test("PUBLISH v5 with topic level count exceeding maxTopicLevels receives topicNameInvalid", async () => {
363
+ const { mqttConn } = startMockServer({
364
+ configuration: { context: { maxTopicLevels: 1 } },
365
+ });
366
+
367
+ await connect5(mqttConn);
368
+
369
+ await publish5(mqttConn, "level1/level2", 1, {
370
+ id: 3,
371
+ payload: "test",
372
+ checkAcks: false,
373
+ });
374
+
375
+ const { value: pubAck } = await mqttConn.next();
376
+ assert.equal(pubAck.type, PacketType.puback);
377
+ assert.equal(
378
+ pubAck.reasonCode,
379
+ ReasonCode.topicNameInvalid,
380
+ "Expected topicNameInvalid (0x90) reasonCode",
381
+ );
382
+
383
+ await disconnect5(mqttConn);
384
+ });
385
+
386
+ test("PUBLISH v5 with empty topic and no topic alias receives topicNameInvalid", async () => {
387
+ const { mqttConn } = startMockServer();
388
+
389
+ await connect5(mqttConn);
390
+
391
+ await publish5(mqttConn, "", 1, {
392
+ id: 4,
393
+ payload: "test",
394
+ checkAcks: false,
395
+ });
396
+
397
+ const { value: pubAck } = await mqttConn.next();
398
+ assert.equal(pubAck.type, PacketType.puback);
399
+ assert.equal(
400
+ pubAck.reasonCode,
401
+ ReasonCode.topicNameInvalid,
402
+ "Expected topicNameInvalid (0x90) reasonCode",
403
+ );
404
+
405
+ await disconnect5(mqttConn);
406
+ });
407
+
408
+ test("PUBLISH v5 with topic alias works", async () => {
409
+ const { mqttConn } = startMockServer();
410
+
411
+ await connect5(mqttConn);
412
+ // Topic with topicAlias
413
+ await publish5(mqttConn, "topic/alias", 1, {
414
+ id: 4,
415
+ payload: "test",
416
+ properties: { topicAlias: 1 },
417
+ });
418
+ // Empty topic with topicAlias
419
+ await publish5(mqttConn, "", 1, {
420
+ id: 5,
421
+ payload: "test",
422
+ properties: { topicAlias: 1 },
423
+ });
424
+
425
+ await disconnect5(mqttConn);
426
+ });
427
+
428
+ test("PUBLISH v5 with invalid topic alias results in disconnect", async () => {
429
+ const { mqttConn } = startMockServer();
430
+
431
+ await connect5(mqttConn);
432
+ // Empty topic with unknown topicAlias
433
+ await publish5(mqttConn, "", 1, {
434
+ id: 5,
435
+ payload: "test",
436
+ properties: { topicAlias: 1 },
437
+ checkAcks: false,
438
+ });
439
+ const { value: disc } = await mqttConn.next();
440
+ assert.equal(disc.type, PacketType.disconnect);
441
+ assert.equal(
442
+ disc.reasonCode,
443
+ ReasonCode.topicAliasInvalid,
444
+ "Expected topicAliasInvalid (0x94) reasonCode",
445
+ );
446
+ });
447
+
448
+ test("PUBLISH v5 omits reasonString when provideReasonStrings is false", async () => {
449
+ const { mqttConn } = startMockServer({
450
+ configuration: { context: { provideReasonStrings: false } },
451
+ });
452
+
453
+ await connect5(mqttConn);
454
+
455
+ await publish5(mqttConn, "topic/unauthorized", 1, {
456
+ id: 6,
457
+ payload: "test",
458
+ checkAcks: false,
459
+ });
460
+
461
+ const { value: pubAck } = await mqttConn.next();
462
+ assert.equal(pubAck.type, PacketType.puback);
463
+ assert.equal(pubAck.reasonCode, ReasonCode.notAuthorized);
464
+ assert.equal(
465
+ pubAck.properties?.reasonString,
466
+ undefined,
467
+ "Expected reasonString to be omitted when provideReasonStrings is false",
468
+ );
469
+
470
+ await disconnect5(mqttConn);
471
+ });