@seriousme/opifex 1.11.2 → 2.0.3

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 (538) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +102 -43
  3. package/bin/conformanceServer.ts +45 -13
  4. package/bin/demoServer.ts +38 -13
  5. package/bin/mqtt.ts +52 -30
  6. package/client/ConnectionState.ts +2 -0
  7. package/client/client.ts +57 -47
  8. package/client/context.ts +75 -21
  9. package/client/deps.ts +5 -0
  10. package/client/handlers/handleAuth.test.ts +193 -0
  11. package/client/handlers/handleAuth.ts +89 -0
  12. package/client/handlers/handleConnack.test.ts +173 -0
  13. package/client/handlers/handleConnack.ts +16 -6
  14. package/client/handlers/handleDisconnect.test.ts +22 -0
  15. package/client/handlers/handleDisconnect.ts +17 -0
  16. package/client/handlers/handlePacket.test.ts +242 -0
  17. package/client/handlers/handlePacket.ts +19 -5
  18. package/client/handlers/handlePuback.test.ts +99 -0
  19. package/client/handlers/handlePuback.ts +6 -0
  20. package/client/handlers/handlePubcomp.test.ts +112 -0
  21. package/client/handlers/handlePubcomp.ts +5 -0
  22. package/client/handlers/handlePublish.test.ts +188 -0
  23. package/client/handlers/handlePubrec.test.ts +119 -0
  24. package/client/handlers/handlePubrec.ts +5 -1
  25. package/client/handlers/handlePubrel.test.ts +136 -0
  26. package/client/handlers/handleSuback.test.ts +122 -0
  27. package/client/handlers/handleSuback.ts +3 -0
  28. package/client/handlers/handleUnsuback.test.ts +101 -0
  29. package/client/mod.ts +2 -2
  30. package/client/store/memoryStore.ts +2 -2
  31. package/client/store/store.ts +3 -1
  32. package/deno/README.md +1 -2
  33. package/deno/tcpClient.test.ts +75 -0
  34. package/deno/tcpClient.ts +16 -11
  35. package/deno/tcpServer.test.ts +22 -21
  36. package/deno/tcpServer.ts +5 -0
  37. package/deno/tlsServer.test.ts +97 -0
  38. package/deno/tlsServer.ts +42 -0
  39. package/deno/wsServer.test.ts +93 -0
  40. package/deno/wsServer.ts +73 -0
  41. package/dev_utils/generateCert.ts +95 -0
  42. package/dev_utils/mockConn.ts +36 -0
  43. package/dev_utils/mockServer.ts +28 -0
  44. package/dev_utils/mod.ts +30 -2
  45. package/dev_utils/packetHelpers.ts +404 -0
  46. package/dev_utils/test-handlers.ts +98 -0
  47. package/dev_utils/timers.ts +14 -0
  48. package/dev_utils/webStreamPair.test.ts +171 -0
  49. package/dev_utils/webStreamPair.ts +143 -0
  50. package/dist/bin/conformanceServer.js +17 -12
  51. package/dist/bin/conformanceServer.js.map +1 -1
  52. package/dist/bin/demoServer.js +16 -12
  53. package/dist/bin/demoServer.js.map +1 -1
  54. package/dist/bin/mqtt.js +19 -16
  55. package/dist/bin/mqtt.js.map +1 -1
  56. package/dist/client/ConnectionState.d.ts +2 -0
  57. package/dist/client/ConnectionState.d.ts.map +1 -1
  58. package/dist/client/ConnectionState.js +2 -0
  59. package/dist/client/ConnectionState.js.map +1 -1
  60. package/dist/client/client.d.ts +19 -22
  61. package/dist/client/client.d.ts.map +1 -1
  62. package/dist/client/client.js +34 -20
  63. package/dist/client/client.js.map +1 -1
  64. package/dist/client/context.d.ts +11 -3
  65. package/dist/client/context.d.ts.map +1 -1
  66. package/dist/client/context.js +44 -12
  67. package/dist/client/context.js.map +1 -1
  68. package/dist/client/deps.d.ts +3 -2
  69. package/dist/client/deps.d.ts.map +1 -1
  70. package/dist/client/deps.js +1 -1
  71. package/dist/client/deps.js.map +1 -1
  72. package/dist/client/handlers/handleAuth.d.ts +9 -0
  73. package/dist/client/handlers/handleAuth.d.ts.map +1 -0
  74. package/dist/client/handlers/handleAuth.js +66 -0
  75. package/dist/client/handlers/handleAuth.js.map +1 -0
  76. package/dist/client/handlers/handleConnack.d.ts +2 -2
  77. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  78. package/dist/client/handlers/handleConnack.js +16 -6
  79. package/dist/client/handlers/handleConnack.js.map +1 -1
  80. package/dist/client/handlers/handleDisconnect.d.ts +11 -0
  81. package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
  82. package/dist/client/handlers/handleDisconnect.js +15 -0
  83. package/dist/client/handlers/handleDisconnect.js.map +1 -0
  84. package/dist/client/handlers/handlePacket.d.ts.map +1 -1
  85. package/dist/client/handlers/handlePacket.js +14 -3
  86. package/dist/client/handlers/handlePacket.js.map +1 -1
  87. package/dist/client/handlers/handlePuback.d.ts.map +1 -1
  88. package/dist/client/handlers/handlePuback.js +5 -0
  89. package/dist/client/handlers/handlePuback.js.map +1 -1
  90. package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
  91. package/dist/client/handlers/handlePubcomp.js +5 -0
  92. package/dist/client/handlers/handlePubcomp.js.map +1 -1
  93. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  94. package/dist/client/handlers/handlePubrec.js +5 -1
  95. package/dist/client/handlers/handlePubrec.js.map +1 -1
  96. package/dist/client/handlers/handleSuback.d.ts +1 -0
  97. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  98. package/dist/client/handlers/handleSuback.js +3 -0
  99. package/dist/client/handlers/handleSuback.js.map +1 -1
  100. package/dist/client/mod.d.ts +2 -2
  101. package/dist/client/mod.d.ts.map +1 -1
  102. package/dist/client/mod.js +1 -1
  103. package/dist/client/mod.js.map +1 -1
  104. package/dist/client/store/memoryStore.d.ts.map +1 -1
  105. package/dist/client/store/memoryStore.js +2 -2
  106. package/dist/client/store/memoryStore.js.map +1 -1
  107. package/dist/client/store/store.d.ts +2 -1
  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 +25 -16
  128. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  129. package/dist/mqttConn/mqttConn.js +69 -40
  130. package/dist/mqttConn/mqttConn.js.map +1 -1
  131. package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
  132. package/dist/mqttPacket/BitMask.d.ts +12 -11
  133. package/dist/mqttPacket/BitMask.d.ts.map +1 -1
  134. package/dist/mqttPacket/BitMask.js +10 -18
  135. package/dist/mqttPacket/BitMask.js.map +1 -1
  136. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  137. package/dist/mqttPacket/Properties.d.ts +2 -2
  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 +1 -0
  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.map +1 -1
  145. package/dist/mqttPacket/auth.d.ts +3 -5
  146. package/dist/mqttPacket/auth.d.ts.map +1 -1
  147. package/dist/mqttPacket/auth.js +31 -30
  148. package/dist/mqttPacket/auth.js.map +1 -1
  149. package/dist/mqttPacket/codec.d.ts +48 -0
  150. package/dist/mqttPacket/codec.d.ts.map +1 -0
  151. package/dist/mqttPacket/codec.js +93 -0
  152. package/dist/mqttPacket/codec.js.map +1 -0
  153. package/dist/mqttPacket/connack.d.ts +4 -5
  154. package/dist/mqttPacket/connack.d.ts.map +1 -1
  155. package/dist/mqttPacket/connack.js +43 -45
  156. package/dist/mqttPacket/connack.js.map +1 -1
  157. package/dist/mqttPacket/connect.d.ts +26 -27
  158. package/dist/mqttPacket/connect.d.ts.map +1 -1
  159. package/dist/mqttPacket/connect.js +156 -157
  160. package/dist/mqttPacket/connect.js.map +1 -1
  161. package/dist/mqttPacket/decoder.d.ts +1 -13
  162. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  163. package/dist/mqttPacket/decoder.js +7 -28
  164. package/dist/mqttPacket/decoder.js.map +1 -1
  165. package/dist/mqttPacket/disconnect.d.ts +4 -5
  166. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  167. package/dist/mqttPacket/disconnect.js +41 -43
  168. package/dist/mqttPacket/disconnect.js.map +1 -1
  169. package/dist/mqttPacket/encoder.d.ts +1 -15
  170. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  171. package/dist/mqttPacket/encoder.js +4 -27
  172. package/dist/mqttPacket/encoder.js.map +1 -1
  173. package/dist/mqttPacket/length.js +1 -1
  174. package/dist/mqttPacket/length.js.map +1 -1
  175. package/dist/mqttPacket/mod.d.ts +21 -103
  176. package/dist/mqttPacket/mod.d.ts.map +1 -1
  177. package/dist/mqttPacket/mod.js +5 -94
  178. package/dist/mqttPacket/mod.js.map +1 -1
  179. package/dist/mqttPacket/pingreq.d.ts +4 -5
  180. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  181. package/dist/mqttPacket/pingreq.js +11 -13
  182. package/dist/mqttPacket/pingreq.js.map +1 -1
  183. package/dist/mqttPacket/pingres.d.ts +4 -5
  184. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  185. package/dist/mqttPacket/pingres.js +11 -13
  186. package/dist/mqttPacket/pingres.js.map +1 -1
  187. package/dist/mqttPacket/protocolLevels.d.ts +11 -6
  188. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
  189. package/dist/mqttPacket/protocolLevels.js +5 -1
  190. package/dist/mqttPacket/protocolLevels.js.map +1 -1
  191. package/dist/mqttPacket/pubblishAcks.d.ts +9 -10
  192. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
  193. package/dist/mqttPacket/pubblishAcks.js +43 -45
  194. package/dist/mqttPacket/pubblishAcks.js.map +1 -1
  195. package/dist/mqttPacket/publish.d.ts +14 -14
  196. package/dist/mqttPacket/publish.d.ts.map +1 -1
  197. package/dist/mqttPacket/publish.js +53 -55
  198. package/dist/mqttPacket/publish.js.map +1 -1
  199. package/dist/mqttPacket/suback.d.ts +4 -5
  200. package/dist/mqttPacket/suback.d.ts.map +1 -1
  201. package/dist/mqttPacket/suback.js +38 -40
  202. package/dist/mqttPacket/suback.js.map +1 -1
  203. package/dist/mqttPacket/subscribe.d.ts +36 -7
  204. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  205. package/dist/mqttPacket/subscribe.js +90 -89
  206. package/dist/mqttPacket/subscribe.js.map +1 -1
  207. package/dist/mqttPacket/types.d.ts +1 -8
  208. package/dist/mqttPacket/types.d.ts.map +1 -1
  209. package/dist/mqttPacket/unsuback.d.ts +4 -5
  210. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  211. package/dist/mqttPacket/unsuback.js +32 -34
  212. package/dist/mqttPacket/unsuback.js.map +1 -1
  213. package/dist/mqttPacket/unsubscribe.d.ts +23 -6
  214. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  215. package/dist/mqttPacket/unsubscribe.js +45 -44
  216. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  217. package/dist/mqttPacket/validators.d.ts +4 -16
  218. package/dist/mqttPacket/validators.d.ts.map +1 -1
  219. package/dist/mqttPacket/validators.js +5 -26
  220. package/dist/mqttPacket/validators.js.map +1 -1
  221. package/dist/node/tcpClient.d.ts +1 -1
  222. package/dist/node/tcpClient.d.ts.map +1 -1
  223. package/dist/node/tcpClient.js +12 -7
  224. package/dist/node/tcpClient.js.map +1 -1
  225. package/dist/node/tcpServer.d.ts.map +1 -1
  226. package/dist/node/tcpServer.js +4 -0
  227. package/dist/node/tcpServer.js.map +1 -1
  228. package/dist/node/tlsServer.d.ts +19 -0
  229. package/dist/node/tlsServer.d.ts.map +1 -0
  230. package/dist/node/tlsServer.js +58 -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 +44 -69
  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 +198 -24
  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 +8 -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 +29 -6
  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 +11 -9
  340. package/dist/socket/socket.d.ts.map +1 -1
  341. package/dist/socket/socket.js +67 -15
  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 +47 -17
  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 +40 -3
  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 +7 -0
  396. package/dist/web/wsClient.d.ts.map +1 -0
  397. package/dist/web/wsClient.js +22 -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 +91 -49
  409. package/mqttPacket/BitMask.ts +11 -19
  410. package/mqttPacket/Properties.ts +6 -3
  411. package/mqttPacket/ReasonCode.ts +2 -1
  412. package/mqttPacket/auth.test.ts +1 -1
  413. package/mqttPacket/auth.ts +41 -48
  414. package/mqttPacket/codec.ts +146 -0
  415. package/mqttPacket/connack.ts +57 -68
  416. package/mqttPacket/connect.test.ts +2 -2
  417. package/mqttPacket/connect.ts +197 -204
  418. package/mqttPacket/decoder.test.ts +0 -39
  419. package/mqttPacket/decoder.ts +9 -36
  420. package/mqttPacket/disconnect.ts +57 -68
  421. package/mqttPacket/encoder.ts +5 -40
  422. package/mqttPacket/length.ts +1 -1
  423. package/mqttPacket/mod.ts +48 -200
  424. package/mqttPacket/pingreq.ts +21 -27
  425. package/mqttPacket/pingres.ts +21 -27
  426. package/mqttPacket/protocolLevels.ts +12 -7
  427. package/mqttPacket/pubblishAcks.ts +68 -77
  428. package/mqttPacket/publish.ts +76 -83
  429. package/mqttPacket/suback.ts +48 -58
  430. package/mqttPacket/subscribe.ts +141 -117
  431. package/mqttPacket/types.ts +1 -9
  432. package/mqttPacket/unsuback.ts +46 -58
  433. package/mqttPacket/unsubscribe.ts +74 -63
  434. package/mqttPacket/validators.ts +5 -31
  435. package/node/socket-node-stream.test.ts +322 -0
  436. package/node/socket-node-stream.ts +174 -0
  437. package/node/tcpClient.test.ts +70 -0
  438. package/node/tcpClient.ts +13 -12
  439. package/node/tcpServer.test.ts +24 -20
  440. package/node/tcpServer.ts +6 -0
  441. package/node/tlsServer.test.ts +94 -0
  442. package/node/tlsServer.ts +81 -0
  443. package/node/wrapNodeSocket.ts +7 -30
  444. package/package.json +73 -45
  445. package/persistence/basicPersistence.ts +495 -0
  446. package/persistence/deps.ts +11 -1
  447. package/persistence/memory/memoryPersistence.ts +12 -152
  448. package/persistence/memory/memoryStorage.ts +232 -0
  449. package/persistence/mod.ts +4 -4
  450. package/persistence/persistence.test.ts +24 -0
  451. package/persistence/persistence.testing.ts +1324 -0
  452. package/persistence/persistence.ts +111 -67
  453. package/persistence/sqlite/sqliteDatabase.ts +294 -0
  454. package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
  455. package/persistence/sqlite/sqlitePersistence.ts +36 -0
  456. package/persistence/sqlite/sqliteStorage.ts +324 -0
  457. package/persistence/storage.ts +84 -0
  458. package/server/config.ts +65 -0
  459. package/server/context.ts +658 -74
  460. package/server/deps.ts +25 -5
  461. package/server/handlers/completeConnect.ts +93 -0
  462. package/server/handlers/duplicate.test.ts +196 -0
  463. package/server/handlers/handleAuth.test.ts +225 -0
  464. package/server/handlers/handleAuth.ts +88 -0
  465. package/server/handlers/handleConnect.test.ts +589 -0
  466. package/server/handlers/handleConnect.ts +201 -86
  467. package/server/handlers/handleConnect.version.test.ts +108 -0
  468. package/server/handlers/handleDisconnect.test.ts +56 -0
  469. package/server/handlers/handleDisconnect.ts +3 -3
  470. package/server/handlers/handlePacket.test.ts +24 -0
  471. package/server/handlers/handlePacket.ts +30 -8
  472. package/server/handlers/handlePingreq.test.ts +29 -0
  473. package/server/handlers/handlePuback.test.ts +28 -0
  474. package/server/handlers/handlePuback.ts +5 -8
  475. package/server/handlers/handlePubcomp.test.ts +28 -0
  476. package/server/handlers/handlePubcomp.ts +5 -4
  477. package/server/handlers/handlePublish.test.ts +471 -0
  478. package/server/handlers/handlePublish.ts +189 -35
  479. package/server/handlers/handlePubrec.test.ts +28 -0
  480. package/server/handlers/handlePubrec.ts +2 -3
  481. package/server/handlers/handlePubrel.test.ts +74 -0
  482. package/server/handlers/handlePubrel.ts +12 -2
  483. package/server/handlers/handleSubscribe.test.ts +971 -0
  484. package/server/handlers/handleSubscribe.ts +158 -39
  485. package/server/handlers/handleUnsubscribe.test.ts +79 -0
  486. package/server/handlers/handleUnsubscribe.ts +29 -5
  487. package/server/handlers/keepalive.test.ts +132 -0
  488. package/server/handlers/session.persistence.test.ts +194 -0
  489. package/server/handlers/will.delivery.test.ts +221 -0
  490. package/server/mod.ts +4 -3
  491. package/server/preconnect.test.ts +151 -0
  492. package/server/server.ts +115 -17
  493. package/socket/socket.test.ts +91 -0
  494. package/socket/socket.ts +81 -31
  495. package/timer/timer.test.ts +4 -7
  496. package/timer/timer.ts +36 -0
  497. package/tools/benchmarks/receiver.ts +51 -0
  498. package/tools/benchmarks/sender.ts +48 -0
  499. package/tools/benchmarks/utils.ts +31 -0
  500. package/tools/mqtt-compat/README.md +130 -0
  501. package/tools/mqtt-compat/broker.ts +52 -0
  502. package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
  503. package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
  504. package/trie/trie.test.ts +9 -1
  505. package/trie/trie.ts +57 -22
  506. package/utils/bufferedAsyncIterable.test.ts +92 -0
  507. package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +1 -1
  508. package/utils/deferred.test.ts +36 -0
  509. package/utils/deferred.ts +0 -1
  510. package/utils/getOrInsertPolyFill.ts +12 -0
  511. package/utils/logger.test.ts +189 -0
  512. package/utils/logger.ts +62 -7
  513. package/utils/mod.ts +15 -1
  514. package/utils/outboundTopicAliasManager.ts +100 -0
  515. package/utils/queue.test.ts +61 -0
  516. package/utils/topicFilter.test.ts +63 -0
  517. package/utils/topicFilter.ts +61 -0
  518. package/utils/utils.ts +3 -0
  519. package/utils/validators.ts +67 -0
  520. package/web/webSocketStream.ts +97 -0
  521. package/web/wrapWebSocket.ts +52 -0
  522. package/web/wsClient.test.ts +26 -0
  523. package/web/wsClient.ts +25 -0
  524. package/benchmarks/receiver.ts +0 -35
  525. package/benchmarks/sender.ts +0 -32
  526. package/benchmarks/utils.ts +0 -9
  527. package/dev_utils/dummyConn.ts +0 -110
  528. package/dist/persistence/store.d.ts +0 -13
  529. package/dist/persistence/store.d.ts.map +0 -1
  530. package/dist/persistence/store.js +0 -2
  531. package/dist/persistence/store.js.map +0 -1
  532. package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
  533. package/dist/utils/BufferedAsyncIterable.js.map +0 -1
  534. package/examples/tcpServer.test.ts +0 -148
  535. package/persistence/memory/memoryPersistence.test.ts +0 -156
  536. package/persistence/store.ts +0 -15
  537. package/server/test/handleConnect.test.ts +0 -130
  538. package/server/test/test-handlers.ts +0 -53
package/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023-2025 Hans Klunder
3
+ Copyright (c) 2023-2026 Hans Klunder
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -6,21 +6,58 @@
6
6
 
7
7
  Opifex aims to provide a MQTT server and MQTT client in Typescript to be used
8
8
  with [NodeJS](https://nodejs.org), [Deno](https://deno.land) or
9
- [Bun](https://bun.sh) It has _no_ third party dependencies, it only relies on
10
- built in modules.
9
+ [Bun](https://bun.sh). It has _no_ third-party dependencies, it only relies on
10
+ built-in modules.
11
11
 
12
12
  # Compatibility
13
13
 
14
14
  The following MQTT versions are supported:
15
15
 
16
- | | MQTT 3.1 (v3) | MQTT 3.11 (v4) | MQTT 5.0 (v5) |
17
- | -------------- | ------------- | -------------- | ------------- |
18
- | Packet/encoder | ✅ | ✅ | ✅ |
19
- | Client | ✅ | ✅ | ✅ partially |
20
- | Server | ❌ | ✅ | ❌ |
16
+ | | MQTT 3.1 (v3) | MQTT 3.1.1 (v4) | MQTT 5.0 (v5) |
17
+ | -------------- | ------------- | --------------- | --------------- |
18
+ | Packet/encoder | ✅ | ✅ | ✅ |
19
+ | Client | ✅ | ✅ | ✅ <sup>1</sup> |
20
+ | Server | ❌ | ✅ | ✅ |
21
21
 
22
- Client and server currently only have memory based persistence, but one can
23
- provide its own persistence. (see [Architecture](#architecture))
22
+ <sup>1</sup> The client API fully supports MQTTv5, the CLI only supports a
23
+ subset
24
+
25
+ Version 5 support includes:
26
+
27
+ - Client Topic Alias ✅
28
+ - Server Topic Alias ✅
29
+ - Subscription Identifiers ✅
30
+ - Subscription options (NoLocal, RetainAsPublished, RetainHandling) ✅
31
+ - Message expiry interval ✅
32
+ - Will delay ✅
33
+ - Assigned Client Identifier ✅
34
+ - Client receive maximum ✅
35
+ - Server receive maximum ✅
36
+ - Shared Subscriptions ✅
37
+
38
+ # Transports
39
+
40
+ The following transports are currently supported:
41
+
42
+ - plain TCP ✅
43
+ - TLS ✅
44
+ - WebSockets ✅ <sup>2</sup>
45
+
46
+ <sup>2</sup> Deno + Browser only, NodeJS has no native websocket support.
47
+
48
+ You can add your own transports.
49
+
50
+ # Persistence
51
+
52
+ Opifex offers pluggable persistence, but one can provide its own persistence.
53
+ (see [Architecture](#architecture))
54
+
55
+ The following types are currently provided:
56
+
57
+ | | Plugable | Memory | Sqlite |
58
+ | ------ | -------- | ------ | ------ |
59
+ | Client | ✅ | ✅ | ❌ |
60
+ | Server | ✅ | ✅ | ✅ |
24
61
 
25
62
  ## Usage
26
63
 
@@ -35,8 +72,8 @@ can be done with CLI options then the next step is to clone the demo server
35
72
  and/or the client scripts and modify them to your liking.
36
73
 
37
74
  If you want to port the platform independent client and server libs to other
38
- types of transports (e.g. Unix sockets or websocketstream) then it's recommended
39
- to clone and modify the platform specific code in `/node` or `/deno` as well.
75
+ types of transports (e.g. Unix sockets) then it's recommended to clone and
76
+ modify the platform specific code in `/node` , `/deno` or `/web` as well.
40
77
 
41
78
  If you want to port the platform independent client and server libs to another
42
79
  platform then the platform specific code in `/node` or `/deno` might serve as
@@ -47,20 +84,25 @@ but for historic reasons `/deno` still exists.
47
84
 
48
85
  ## Example
49
86
 
50
- A simple server example using Deno.
87
+ A simple server example:
51
88
 
52
89
  ```typescript
53
- import { MqttServer } from "./server/mod.ts";
54
-
55
- const listener = Deno.listen();
56
- const mqttServer = new MqttServer(mqttOptions);
57
- for await (const conn of this.listener) {
58
- mqttServer.serve(conn);
59
- }
90
+ import { TcpServer } from "@seriousme/opifex/tcpServer";
91
+
92
+ const server = new TcpServer({ port: 1883 }, {
93
+ // just an example of how to configure the server
94
+ configuration: {
95
+ context: { maximumConnectPacketSize: 3000 },
96
+ },
97
+ });
98
+ server.start();
99
+ console.log(
100
+ `MQTT server running on port: ${server.port}, address: ${server.address}`,
101
+ );
60
102
  ```
61
103
 
62
- A more elaborate example including client and server can be found in the
63
- [examples](/examples/) folder.
104
+ More elaborate examples including client and server, TLS, Websockets and sqlite
105
+ can be found in the [examples](/examples/) folder.
64
106
 
65
107
  ## Architecture
66
108
 
@@ -69,18 +111,18 @@ A more elaborate example including client and server can be found in the
69
111
  encode and decode packets.
70
112
 
71
113
  2. On top of mqttPacket sits the MQTT connection module
72
- ([mqttConn/mod.ts](mqttConn/mod.ts)) module that reads packets from a
73
- Readable stream and writes them to Writable stream. It will take care of
74
- incomplete and/or malformed packets. mqttConn provides an async iterable that
75
- can be awaited for new packets.
114
+ ([mqttConn/mod.ts](mqttConn/mod.ts)) that reads packets from a Readable
115
+ stream and writes them to Writable stream. It will take care of incomplete
116
+ and/or malformed packets. mqttConn provides an async iterable that can be
117
+ awaited for new packets.
76
118
 
77
119
  3. On top of mqttConn live the MQTT server ([server/mod.ts](server/mod.ts)) and
78
120
  MQTT client ([client/mod.ts](client/mod.ts)) that take care of the MQTT
79
- protocol handling like requiring an authentication to be successfull before
121
+ protocol handling like requiring an authentication to be successful before
80
122
  another type of packet will be accepted. Both follow a similar model of
81
123
  implementation where for each packet that is received a handler is invoked
82
- which then triggers the next step. Server and client are totally independ of
83
- the technical implementation of the connection and only need a socketConn
124
+ which then triggers the next step. Server and client are totally independent
125
+ of the technical implementation of the connection and only need a socketConn
84
126
  ([socket](socket)) to be able to work.
85
127
 
86
128
  4. As the server needs to be able to serve multiple clients at the same time, it
@@ -88,29 +130,46 @@ A more elaborate example including client and server can be found in the
88
130
  keep track of its state and associated timers.
89
131
 
90
132
  5. Persistence of data is handled by a pluggable persistence module
91
- ([persistence](persistence)) which currently only offers memory persistence
92
- ([persistence/memory](persistence/memory)) but can be extended with database
93
- backed persistence supported by third party modules.
133
+ ([persistence](persistence)) which currently offers single process
134
+ persistence which you can replace by something more scalable (e.g. redis
135
+ based clusters etc) This is backed by two storage providers:
136
+ - [memory](persistence/memory)
137
+ - [sqlite](persistence/sqlite), based on node:sqlite
138
+
139
+ but can be extended with other database backend persistence supported by
140
+ third-party modules.
141
+
142
+ 6. Server behavior can be customized by passing a
143
+ [ConfigurationInput object](server/config.ts) via
144
+ `MqttServerOptions.configuration`, see the example above.
94
145
 
95
- 6. The demo server listens to a platform specific socket and runs the `serve()`
146
+ 7. The demo server listens to a platform specific socket and runs the `serve()`
96
147
  method from the server module on the platform independent streams of every
97
148
  connection.
98
149
 
99
- 7. The demo client opens a platform specific socket and passes the resulting
150
+ 8. The demo client opens a platform specific socket and passes the resulting
100
151
  platform independent streams to the client module.
101
152
 
102
153
  ## Exports
103
154
 
104
- | Export | Description |
105
- | ----------------------------- | ------------------------------------------------------- |
106
- | @seriousme/opifex/tcpClient | Exports a MQTT over TCP client |
107
- | @seriousme/opifex/tcpServer | Exports a MQTT over TCP server |
108
- | @seriousme/opifex/server | Exports a transport agnostic MQTT server |
109
- | @seriousme/opifex/client | Exports a transport agnostic MQTT client |
110
- | @seriousme/opifex/persistence | Exports an Typescript interface for storage persistence |
111
- | @seriousme/opifex/mqttConn | Exports MQTT connection handling |
112
- | @seriousme/opifex/mqttPacket | Exports MQTT packet handling |
113
- | @seriousme/opifex/utils | Exports various utilities |
155
+ | Export | Description |
156
+ | ----------------------------- | ------------------------------------------------------------ |
157
+ | @seriousme/opifex/tcpClient | Exports a MQTT over TCP/TLS client |
158
+ | @seriousme/opifex/tcpServer | Exports a MQTT over TCP server |
159
+ | @seriousme/opifex/tlsServer | Exports a MQTT over TLS server |
160
+ | @seriousme/opifex/wsClient | Exports a MQTT over Websocket client (deno and browser only) |
161
+ | @seriousme/opifex/wsServer | Exports a MQTT over Websocket server (deno only) |
162
+ | @seriousme/opifex/server | Exports a transport agnostic MQTT server |
163
+ | @seriousme/opifex/client | Exports a transport agnostic MQTT client |
164
+ | @seriousme/opifex/persistence | Exports a Typescript interface for storage persistence |
165
+ | @seriousme/opifex/mqttConn | Exports MQTT connection handling |
166
+ | @seriousme/opifex/mqttPacket | Exports MQTT packet handling |
167
+ | @seriousme/opifex/utils | Exports various utilities |
168
+
169
+ ## API docs
170
+
171
+ The latest API documentation can be found at:
172
+ https://jsr.io/@seriousme/opifex@latest/doc
114
173
 
115
174
  ## Naming
116
175
 
@@ -7,8 +7,14 @@
7
7
  */
8
8
  import { parseArgs } from "node:util";
9
9
  import { TcpServer } from "../node/tcpServer.ts";
10
- import type { Context, TAuthenticationResult, Topic } from "../server/mod.ts";
11
- import { AuthenticationResult } from "../server/mod.ts";
10
+ import type {
11
+ AuthenticatedResult,
12
+ ConnectPacket,
13
+ Context,
14
+ ShareName,
15
+ Topic,
16
+ } from "../server/mod.ts";
17
+ import { ReasonCode } from "../server/mod.ts";
12
18
  import { logger, LogLevel } from "../utils/mod.ts";
13
19
 
14
20
  /**
@@ -42,35 +48,49 @@ const checkUsername = true;
42
48
  * @param {string} clientId - Client identifier
43
49
  * @param {string} username - Username to authenticate
44
50
  * @param {Uint8Array} password - Password as byte array
45
- * @returns {TAuthenticationResult} Authentication result
51
+ * @param {ConnectPacket} connectPacket - The raw connect packet
52
+ * @returns {IsAuthenticationResult} Authentication result
46
53
  */
47
54
  function isAuthenticated(
48
55
  _ctx: Context,
49
56
  clientId: string,
50
57
  username: string,
51
58
  password: Uint8Array,
52
- ): TAuthenticationResult {
59
+ connectPacket: ConnectPacket,
60
+ ): AuthenticatedResult {
53
61
  const pwd = utf8Decoder.decode(password);
54
62
  logger.info(
55
- `Verifying authentication of client '${clientId}' with username '${username}' and password '${pwd}'`,
63
+ "Verifying authentication of client",
64
+ clientId,
65
+ "with username",
66
+ username,
67
+ );
68
+ logger.debug(
69
+ "Client",
70
+ clientId,
71
+ "connecting with protocol level",
72
+ connectPacket.protocolLevel,
56
73
  );
57
74
 
58
75
  if (!checkUsername) {
59
76
  // allow all users access
60
- return AuthenticationResult.ok;
77
+ return { reasonCode: ReasonCode.success };
61
78
  }
62
79
  // is the username valid according to MQTT specification
63
80
  if (!strictUsername.test(username)) {
64
- return AuthenticationResult.badUsernameOrPassword;
81
+ return { reasonCode: ReasonCode.badUserNameOrPassword };
65
82
  }
66
83
  // Does user and password match an entry in userTable
67
84
  if (userTable.has(username)) {
68
85
  const pass = userTable.get(username);
69
86
  if (pwd === pass) {
70
- return AuthenticationResult.ok;
87
+ return { reasonCode: ReasonCode.success };
71
88
  }
72
89
  }
73
- return AuthenticationResult.notAuthorized;
90
+ return {
91
+ reasonCode: ReasonCode.notAuthorized,
92
+ reasonString: "Authentication failed",
93
+ };
74
94
  }
75
95
 
76
96
  /**
@@ -81,7 +101,10 @@ function isAuthenticated(
81
101
  */
82
102
  function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
83
103
  logger.debug(
84
- `Checking authorization of client '${ctx.store?.clientId}' to publish on topic '${topic}'`,
104
+ "Checking authorization of client",
105
+ ctx.clientId,
106
+ "to publish on topic",
107
+ topic,
85
108
  );
86
109
  return true;
87
110
  }
@@ -92,9 +115,18 @@ function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
92
115
  * @param {Topic} topic - Topic to subscribe to
93
116
  * @returns {boolean} True if authorized
94
117
  */
95
- function isAuthorizedToSubscribe(ctx: Context, topic: Topic): boolean {
118
+ function isAuthorizedToSubscribe(
119
+ ctx: Context,
120
+ topic: Topic,
121
+ shareName: ShareName,
122
+ ): boolean {
96
123
  logger.debug(
97
- `Checking authorization of client '${ctx.store?.clientId}' to subscribe to topic '${topic}'`,
124
+ "Checking authorization of client",
125
+ ctx.clientId,
126
+ "to subscribe to topic",
127
+ topic,
128
+ "using shareName",
129
+ shareName,
98
130
  );
99
131
  return true;
100
132
  }
@@ -118,4 +150,4 @@ const tcpServer = new TcpServer({ port, hostname }, {
118
150
  },
119
151
  });
120
152
  tcpServer.start();
121
- logger.info(`Server started on port ${tcpServer.port}`);
153
+ logger.info("Server started on port", tcpServer.port);
package/bin/demoServer.ts CHANGED
@@ -6,8 +6,14 @@
6
6
  */
7
7
  import { parseArgs } from "node:util";
8
8
  import { TcpServer } from "../node/tcpServer.ts";
9
- import type { Context, TAuthenticationResult, Topic } from "../server/mod.ts";
10
- import { AuthenticationResult } from "../server/mod.ts";
9
+ import type {
10
+ AuthenticatedResult,
11
+ ConnectPacket,
12
+ Context,
13
+ ShareName,
14
+ Topic,
15
+ } from "../server/mod.ts";
16
+ import { ReasonCode } from "../server/mod.ts";
11
17
  import { logger, LogLevel } from "../utils/mod.ts";
12
18
 
13
19
  /**
@@ -41,35 +47,42 @@ const checkUsername = false;
41
47
  * @param {string} clientId - Client identifier
42
48
  * @param {string} username - Username to authenticate
43
49
  * @param {Uint8Array} password - Password as byte array
44
- * @returns {TAuthenticationResult} Authentication result
50
+ * @returns {IsAuthenticationResult} Authentication result
45
51
  */
46
52
  function isAuthenticated(
47
53
  _ctx: Context,
48
54
  clientId: string,
49
55
  username: string,
50
56
  password: Uint8Array,
51
- ): TAuthenticationResult {
57
+ connectPacket: ConnectPacket,
58
+ ): AuthenticatedResult {
52
59
  const pwd = utf8Decoder.decode(password);
53
60
  logger.info(
54
- `Verifying authentication of client '${clientId}' with username '${username}' and password '${pwd}'`,
61
+ `Verifying authentication of client '${clientId}' with username '${username}'`,
62
+ );
63
+ logger.debug(
64
+ `Client '${clientId}' connecting with protocol level ${connectPacket.protocolLevel}`,
55
65
  );
56
66
 
57
67
  if (!checkUsername) {
58
68
  // allow all users access
59
- return AuthenticationResult.ok;
69
+ return { reasonCode: ReasonCode.success };
60
70
  }
61
71
  // is the username valid according to MQTT specification
62
72
  if (!strictUsername.test(username)) {
63
- return AuthenticationResult.badUsernameOrPassword;
73
+ return { reasonCode: ReasonCode.badUserNameOrPassword };
64
74
  }
65
75
  // Does user and password match an entry in userTable
66
76
  if (userTable.has(username)) {
67
77
  const pass = userTable.get(username);
68
78
  if (pwd === pass) {
69
- return AuthenticationResult.ok;
79
+ return { reasonCode: ReasonCode.success };
70
80
  }
71
81
  }
72
- return AuthenticationResult.notAuthorized;
82
+ return {
83
+ reasonCode: ReasonCode.notAuthorized,
84
+ reasonString: "Authentication failed",
85
+ };
73
86
  }
74
87
 
75
88
  /**
@@ -80,7 +93,10 @@ function isAuthenticated(
80
93
  */
81
94
  function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
82
95
  logger.debug(
83
- `Checking authorization of client '${ctx.store?.clientId}' to publish on topic '${topic}'`,
96
+ "Checking authorization of client",
97
+ ctx.clientId,
98
+ "to publish on topic",
99
+ topic,
84
100
  );
85
101
  return true;
86
102
  }
@@ -91,9 +107,18 @@ function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
91
107
  * @param {Topic} topic - Topic to subscribe to
92
108
  * @returns {boolean} True if authorized
93
109
  */
94
- function isAuthorizedToSubscribe(ctx: Context, topic: Topic): boolean {
110
+ function isAuthorizedToSubscribe(
111
+ ctx: Context,
112
+ topic: Topic,
113
+ shareName: ShareName,
114
+ ): boolean {
95
115
  logger.debug(
96
- `Checking authorization of client '${ctx.store?.clientId}' to subscribe to topic '${topic}'`,
116
+ "Checking authorization of client",
117
+ ctx.clientId,
118
+ "to subscribe to topic",
119
+ topic,
120
+ "using shareName",
121
+ shareName,
97
122
  );
98
123
  return true;
99
124
  }
@@ -117,4 +142,4 @@ const tcpServer = new TcpServer({ port, hostname }, {
117
142
  },
118
143
  });
119
144
  tcpServer.start();
120
- logger.info(`Server started on port ${tcpServer.port}`);
145
+ logger.info("Server started on port", tcpServer.port);
package/bin/mqtt.ts CHANGED
@@ -37,16 +37,26 @@ import {
37
37
  DEFAULT_PROTOCOLLEVEL,
38
38
  DEFAULT_URL,
39
39
  } from "../client/mod.ts";
40
- import type { ProtocolLevel } from "../client/mod.ts";
40
+ import type { ProtocolLevel, QoS } from "../client/mod.ts";
41
41
  import { getFileData, TcpClient } from "../node/tcpClient.ts";
42
42
  import { logger, LogLevel } from "../utils/mod.ts";
43
43
 
44
- type Args = Record<string, string | boolean>;
45
44
  const client = new TcpClient();
46
45
  const encoder = new TextEncoder();
47
46
  const decoder = new TextDecoder();
48
47
  logger.level(LogLevel.info);
49
48
 
49
+ // --- TypeScript Utility Types to Derive Args Natively ---
50
+ type MapOptType<T> = T extends { type: "string" } ? string | undefined
51
+ : T extends { type: "boolean" } ? boolean
52
+ : never;
53
+
54
+ type ParsedArgsFromOpts<
55
+ T extends Record<string, { type: "string" | "boolean" }>,
56
+ > = {
57
+ [K in keyof T]: MapOptType<T[K]>;
58
+ };
59
+
50
60
  const MQTTHelp = `MQTT command line interface, available commands are:
51
61
 
52
62
  * publish publish a message to the broker
@@ -94,7 +104,9 @@ const connectOpts = {
94
104
  help: { type: "boolean", short: "h", default: false },
95
105
  } as const;
96
106
 
97
- async function connect(connectArgs: Args) {
107
+ type ConnectArgs = ParsedArgsFromOpts<typeof connectOpts>;
108
+
109
+ async function connect(connectArgs: ConnectArgs) {
98
110
  const {
99
111
  caCerts,
100
112
  cert,
@@ -111,25 +123,24 @@ async function connect(connectArgs: Args) {
111
123
  clientId: connectArgs.clientId as string,
112
124
  clean: !connectArgs.noClean,
113
125
  keepAlive: Number(connectArgs.keepAlive),
114
- protocolLevel: parseInt(
115
- connectArgs.mqttVersion as string,
116
- ) as ProtocolLevel,
126
+ protocolLevel: parseProtocolLevel(connectArgs.mqttVersion),
117
127
  },
118
128
  });
119
129
  logger.debug("Connected !");
120
130
  }
121
131
 
122
- function parseQos(qosArg: string | number) {
132
+ function parseProtocolLevel(mqttVersion: string | undefined): ProtocolLevel {
133
+ const result = parseInt(mqttVersion ?? "");
134
+ if (result >= 3 && result <= 5) {
135
+ return result as ProtocolLevel;
136
+ }
137
+ return DEFAULT_PROTOCOLLEVEL;
138
+ }
139
+
140
+ function parseQos(qosArg: string | number | undefined): QoS {
123
141
  const qos = Number(qosArg);
124
- switch (qos) {
125
- case 0:
126
- return 0;
127
- case 1:
128
- return 1;
129
- case 2:
130
- return 2;
131
- default:
132
- break;
142
+ if (qos === 0 || qos === 1 || qos === 2) {
143
+ return qos;
133
144
  }
134
145
  console.log("QoS must be between 0 and 2");
135
146
  return 0;
@@ -142,14 +153,17 @@ function safeParseArgs(config: ParseArgsConfig) {
142
153
  if (err instanceof Error) {
143
154
  console.error(err.message);
144
155
  }
156
+ return undefined;
145
157
  }
146
158
  }
147
159
 
148
- async function getTLSdata(connectArgs: Args) {
149
- const caFileData = await getFileData(connectArgs.caFile as string);
160
+ async function getTLSdata(connectArgs: Partial<ConnectArgs>) {
161
+ const caFileData = connectArgs.caFile
162
+ ? await getFileData(connectArgs.caFile)
163
+ : undefined;
150
164
  const caCerts = caFileData ? [caFileData] : undefined;
151
- const cert = await getFileData(connectArgs.certFile as string);
152
- const key = await getFileData(connectArgs.keyFile as string);
165
+ const cert = await getFileData(connectArgs.certFile);
166
+ const key = await getFileData(connectArgs.keyFile);
153
167
  return {
154
168
  caCerts,
155
169
  cert,
@@ -177,13 +191,18 @@ const subscribeOpts = {
177
191
  qos: { type: "string", short: "q", default: "0" },
178
192
  } as const;
179
193
 
194
+ type SubscribeArgs = ParsedArgsFromOpts<
195
+ typeof connectOpts & typeof subscribeOpts
196
+ >;
197
+
180
198
  async function subscribe() {
181
199
  const res = safeParseArgs({
182
200
  options: { ...connectOpts, ...subscribeOpts },
183
201
  allowPositionals: true,
184
202
  });
185
203
  if (!res) return;
186
- const subscribeArgs = res.values as Record<string, string | boolean>;
204
+
205
+ const subscribeArgs = res.values as unknown as SubscribeArgs;
187
206
  if (subscribeArgs.help) {
188
207
  console.log(SubscribeHelp);
189
208
  return;
@@ -198,7 +217,7 @@ async function subscribe() {
198
217
  subscriptions: [
199
218
  {
200
219
  topicFilter: subscribeArgs.topic,
201
- qos: parseQos(subscribeArgs.qos as string),
220
+ qos: parseQos(subscribeArgs.qos),
202
221
  },
203
222
  ],
204
223
  });
@@ -209,8 +228,8 @@ async function subscribe() {
209
228
  }
210
229
  } catch (err) {
211
230
  if (err instanceof Error) {
212
- // @ts-ignore the type spec of err is missing err.code
213
- logger.info(`Error: ${err.message || err.code}`);
231
+ const errorWithCode = err as Error & { code?: string };
232
+ logger.info("Error:", errorWithCode.message || errorWithCode.code);
214
233
  }
215
234
  }
216
235
  }
@@ -232,13 +251,16 @@ const publishOpts = {
232
251
  retain: { type: "boolean", short: "r", default: false },
233
252
  } as const;
234
253
 
254
+ type PublishArgs = ParsedArgsFromOpts<typeof connectOpts & typeof publishOpts>;
255
+
235
256
  async function publish() {
236
257
  const res = safeParseArgs({
237
258
  options: { ...connectOpts, ...publishOpts },
238
259
  allowPositionals: true,
239
260
  });
240
261
  if (!res) return;
241
- const publishArgs = res.values as Record<string, string | boolean>;
262
+
263
+ const publishArgs = res.values as unknown as PublishArgs;
242
264
  if (publishArgs.help) {
243
265
  console.log(PublishHelp);
244
266
  return;
@@ -251,17 +273,17 @@ async function publish() {
251
273
  await connect(publishArgs);
252
274
  await client.publish({
253
275
  topic: publishArgs.topic,
254
- payload: encoder.encode(publishArgs.message as string),
255
- retain: publishArgs.retain as boolean,
256
- qos: parseQos(publishArgs.qos as string),
276
+ payload: encoder.encode(publishArgs.message ?? ""),
277
+ retain: publishArgs.retain,
278
+ qos: parseQos(publishArgs.qos),
257
279
  });
258
280
  logger.debug("Published!");
259
281
  client.disconnect();
260
282
  logger.debug("Disconnected !");
261
283
  } catch (err) {
262
284
  if (err instanceof Error) {
263
- // @ts-ignore the type spec of err is missing err.code
264
- logger.info(`Error: ${err.message || err.code}`);
285
+ const errorWithCode = err as Error & { code?: string };
286
+ logger.info("Error:", errorWithCode.message || errorWithCode.code);
265
287
  }
266
288
  }
267
289
  }
@@ -13,6 +13,8 @@ export const ConnectionState = {
13
13
  disconnecting: "disconnecting",
14
14
  /** System has been disconnected */
15
15
  disconnected: "disconnected",
16
+ /** System is authenticating mid session */
17
+ authenticating: "authenticating",
16
18
  } as const;
17
19
 
18
20
  /**