@seriousme/opifex 1.9.4 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. package/README.md +37 -26
  2. package/bin/conformanceServer.ts +3 -2
  3. package/bin/demoServer.ts +3 -2
  4. package/bin/mqtt.ts +127 -118
  5. package/client/client.ts +61 -21
  6. package/client/context.ts +71 -30
  7. package/client/deps.ts +5 -0
  8. package/client/handlers/handleConnack.ts +17 -5
  9. package/client/handlers/handlePublish.ts +4 -1
  10. package/client/handlers/handlePubrec.ts +3 -1
  11. package/client/handlers/handlePubrel.ts +3 -1
  12. package/client/handlers/handleSuback.ts +3 -1
  13. package/client/mod.ts +8 -1
  14. package/client/store/memoryStore.ts +2 -1
  15. package/deno/tcpClient.ts +1 -1
  16. package/dev_utils/dummyConn.ts +17 -2
  17. package/dist/bin/conformanceServer.js +3 -2
  18. package/dist/bin/conformanceServer.js.map +1 -1
  19. package/dist/bin/demoServer.js +3 -2
  20. package/dist/bin/demoServer.js.map +1 -1
  21. package/dist/bin/mqtt.d.ts +29 -0
  22. package/dist/bin/mqtt.d.ts.map +1 -1
  23. package/dist/bin/mqtt.js +102 -97
  24. package/dist/bin/mqtt.js.map +1 -1
  25. package/dist/client/client.d.ts +16 -5
  26. package/dist/client/client.d.ts.map +1 -1
  27. package/dist/client/client.js +36 -15
  28. package/dist/client/client.js.map +1 -1
  29. package/dist/client/context.d.ts +8 -3
  30. package/dist/client/context.d.ts.map +1 -1
  31. package/dist/client/context.js +51 -21
  32. package/dist/client/context.js.map +1 -1
  33. package/dist/client/deps.d.ts +3 -2
  34. package/dist/client/deps.d.ts.map +1 -1
  35. package/dist/client/deps.js +2 -1
  36. package/dist/client/deps.js.map +1 -1
  37. package/dist/client/handlers/handleConnack.d.ts +1 -1
  38. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  39. package/dist/client/handlers/handleConnack.js +14 -5
  40. package/dist/client/handlers/handleConnack.js.map +1 -1
  41. package/dist/client/handlers/handlePublish.d.ts +1 -1
  42. package/dist/client/handlers/handlePublish.d.ts.map +1 -1
  43. package/dist/client/handlers/handlePublish.js +2 -0
  44. package/dist/client/handlers/handlePublish.js.map +1 -1
  45. package/dist/client/handlers/handlePubrec.d.ts +1 -1
  46. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  47. package/dist/client/handlers/handlePubrec.js +1 -0
  48. package/dist/client/handlers/handlePubrec.js.map +1 -1
  49. package/dist/client/handlers/handlePubrel.d.ts +1 -1
  50. package/dist/client/handlers/handlePubrel.d.ts.map +1 -1
  51. package/dist/client/handlers/handlePubrel.js +1 -0
  52. package/dist/client/handlers/handlePubrel.js.map +1 -1
  53. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  54. package/dist/client/handlers/handleSuback.js +3 -1
  55. package/dist/client/handlers/handleSuback.js.map +1 -1
  56. package/dist/client/mod.d.ts +3 -1
  57. package/dist/client/mod.d.ts.map +1 -1
  58. package/dist/client/mod.js +2 -1
  59. package/dist/client/mod.js.map +1 -1
  60. package/dist/client/store/memoryStore.d.ts +1 -1
  61. package/dist/client/store/memoryStore.d.ts.map +1 -1
  62. package/dist/client/store/memoryStore.js.map +1 -1
  63. package/dist/mqttConn/mqttConn.d.ts +13 -8
  64. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  65. package/dist/mqttConn/mqttConn.js +27 -12
  66. package/dist/mqttConn/mqttConn.js.map +1 -1
  67. package/dist/mqttPacket/PacketType.d.ts +1 -0
  68. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  69. package/dist/mqttPacket/PacketType.js +1 -0
  70. package/dist/mqttPacket/PacketType.js.map +1 -1
  71. package/dist/mqttPacket/Properties.d.ts +157 -0
  72. package/dist/mqttPacket/Properties.d.ts.map +1 -0
  73. package/dist/mqttPacket/Properties.js +177 -0
  74. package/dist/mqttPacket/Properties.js.map +1 -0
  75. package/dist/mqttPacket/ReasonCode.d.ts +74 -0
  76. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -0
  77. package/dist/mqttPacket/ReasonCode.js +230 -0
  78. package/dist/mqttPacket/ReasonCode.js.map +1 -0
  79. package/dist/mqttPacket/RetainHandling.d.ts +12 -0
  80. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -0
  81. package/dist/mqttPacket/RetainHandling.js +12 -0
  82. package/dist/mqttPacket/RetainHandling.js.map +1 -0
  83. package/dist/mqttPacket/auth.d.ts +21 -0
  84. package/dist/mqttPacket/auth.d.ts.map +1 -0
  85. package/dist/mqttPacket/auth.js +34 -0
  86. package/dist/mqttPacket/auth.js.map +1 -0
  87. package/dist/mqttPacket/connack.d.ts +19 -11
  88. package/dist/mqttPacket/connack.d.ts.map +1 -1
  89. package/dist/mqttPacket/connack.js +43 -15
  90. package/dist/mqttPacket/connack.js.map +1 -1
  91. package/dist/mqttPacket/connect.d.ts +30 -11
  92. package/dist/mqttPacket/connect.d.ts.map +1 -1
  93. package/dist/mqttPacket/connect.js +106 -30
  94. package/dist/mqttPacket/connect.js.map +1 -1
  95. package/dist/mqttPacket/decoder.d.ts +42 -3
  96. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  97. package/dist/mqttPacket/decoder.js +135 -4
  98. package/dist/mqttPacket/decoder.js.map +1 -1
  99. package/dist/mqttPacket/disconnect.d.ts +15 -9
  100. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  101. package/dist/mqttPacket/disconnect.js +45 -6
  102. package/dist/mqttPacket/disconnect.js.map +1 -1
  103. package/dist/mqttPacket/encoder.d.ts +57 -8
  104. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  105. package/dist/mqttPacket/encoder.js +185 -13
  106. package/dist/mqttPacket/encoder.js.map +1 -1
  107. package/dist/mqttPacket/length.d.ts.map +1 -1
  108. package/dist/mqttPacket/length.js +3 -2
  109. package/dist/mqttPacket/length.js.map +1 -1
  110. package/dist/mqttPacket/mod.d.ts +57 -91
  111. package/dist/mqttPacket/mod.d.ts.map +1 -1
  112. package/dist/mqttPacket/mod.js +23 -29
  113. package/dist/mqttPacket/mod.js.map +1 -1
  114. package/dist/mqttPacket/pingreq.d.ts +4 -6
  115. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  116. package/dist/mqttPacket/pingreq.js +5 -4
  117. package/dist/mqttPacket/pingreq.js.map +1 -1
  118. package/dist/mqttPacket/pingres.d.ts +4 -6
  119. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  120. package/dist/mqttPacket/pingres.js +7 -5
  121. package/dist/mqttPacket/pingres.js.map +1 -1
  122. package/dist/mqttPacket/protocolLevels.d.ts +12 -0
  123. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -0
  124. package/dist/mqttPacket/protocolLevels.js +11 -0
  125. package/dist/mqttPacket/protocolLevels.js.map +1 -0
  126. package/dist/mqttPacket/pubblishAcks.d.ts +42 -0
  127. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -0
  128. package/dist/mqttPacket/pubblishAcks.js +56 -0
  129. package/dist/mqttPacket/pubblishAcks.js.map +1 -0
  130. package/dist/mqttPacket/publish.d.ts +19 -8
  131. package/dist/mqttPacket/publish.d.ts.map +1 -1
  132. package/dist/mqttPacket/publish.js +26 -7
  133. package/dist/mqttPacket/publish.js.map +1 -1
  134. package/dist/mqttPacket/suback.d.ts +18 -11
  135. package/dist/mqttPacket/suback.d.ts.map +1 -1
  136. package/dist/mqttPacket/suback.js +41 -20
  137. package/dist/mqttPacket/suback.js.map +1 -1
  138. package/dist/mqttPacket/subscribe.d.ts +27 -12
  139. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  140. package/dist/mqttPacket/subscribe.js +71 -15
  141. package/dist/mqttPacket/subscribe.js.map +1 -1
  142. package/dist/mqttPacket/types.d.ts +36 -0
  143. package/dist/mqttPacket/types.d.ts.map +1 -1
  144. package/dist/mqttPacket/unsuback.d.ts +17 -10
  145. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  146. package/dist/mqttPacket/unsuback.js +29 -6
  147. package/dist/mqttPacket/unsuback.js.map +1 -1
  148. package/dist/mqttPacket/unsubscribe.d.ts +17 -10
  149. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  150. package/dist/mqttPacket/unsubscribe.js +24 -8
  151. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  152. package/dist/mqttPacket/validators.d.ts +15 -0
  153. package/dist/mqttPacket/validators.d.ts.map +1 -1
  154. package/dist/mqttPacket/validators.js +15 -0
  155. package/dist/mqttPacket/validators.js.map +1 -1
  156. package/dist/node/tcpClient.js +1 -1
  157. package/dist/node/tcpClient.js.map +1 -1
  158. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  159. package/dist/node/wrapNodeSocket.js.map +1 -1
  160. package/dist/persistence/deps.d.ts +1 -1
  161. package/dist/persistence/deps.d.ts.map +1 -1
  162. package/dist/persistence/deps.js +1 -1
  163. package/dist/persistence/deps.js.map +1 -1
  164. package/dist/persistence/memory/memoryPersistence.js +1 -1
  165. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  166. package/dist/server/context.d.ts +3 -1
  167. package/dist/server/context.d.ts.map +1 -1
  168. package/dist/server/context.js +8 -2
  169. package/dist/server/context.js.map +1 -1
  170. package/dist/server/deps.d.ts +2 -2
  171. package/dist/server/deps.d.ts.map +1 -1
  172. package/dist/server/deps.js +1 -1
  173. package/dist/server/deps.js.map +1 -1
  174. package/dist/server/handlers/handleConnect.d.ts +1 -1
  175. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  176. package/dist/server/handlers/handleConnect.js +9 -1
  177. package/dist/server/handlers/handleConnect.js.map +1 -1
  178. package/dist/server/handlers/handlePacket.d.ts +1 -1
  179. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  180. package/dist/server/handlers/handlePacket.js +1 -1
  181. package/dist/server/handlers/handlePacket.js.map +1 -1
  182. package/dist/server/handlers/handlePingreq.d.ts.map +1 -1
  183. package/dist/server/handlers/handlePingreq.js +1 -0
  184. package/dist/server/handlers/handlePingreq.js.map +1 -1
  185. package/dist/server/handlers/handlePublish.d.ts +2 -2
  186. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  187. package/dist/server/handlers/handlePublish.js +2 -0
  188. package/dist/server/handlers/handlePublish.js.map +1 -1
  189. package/dist/server/handlers/handlePubrec.d.ts +1 -1
  190. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  191. package/dist/server/handlers/handlePubrec.js +1 -0
  192. package/dist/server/handlers/handlePubrec.js.map +1 -1
  193. package/dist/server/handlers/handlePubrel.d.ts +1 -1
  194. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  195. package/dist/server/handlers/handlePubrel.js +1 -0
  196. package/dist/server/handlers/handlePubrel.js.map +1 -1
  197. package/dist/server/handlers/handleSubscribe.d.ts +1 -1
  198. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  199. package/dist/server/handlers/handleSubscribe.js +2 -1
  200. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  201. package/dist/server/handlers/handleUnsubscribe.d.ts +1 -1
  202. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  203. package/dist/server/handlers/handleUnsubscribe.js +1 -0
  204. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  205. package/dist/server/server.d.ts +2 -2
  206. package/dist/server/server.d.ts.map +1 -1
  207. package/dist/server/server.js +5 -3
  208. package/dist/server/server.js.map +1 -1
  209. package/dist/socket/socket.d.ts.map +1 -1
  210. package/dist/socket/socket.js +6 -1
  211. package/dist/socket/socket.js.map +1 -1
  212. package/dist/utils/assert.d.ts +0 -3
  213. package/dist/utils/assert.d.ts.map +1 -1
  214. package/dist/utils/assert.js +0 -7
  215. package/dist/utils/assert.js.map +1 -1
  216. package/dist/utils/asyncQueue.d.ts +1 -3
  217. package/dist/utils/asyncQueue.d.ts.map +1 -1
  218. package/dist/utils/asyncQueue.js +16 -21
  219. package/dist/utils/asyncQueue.js.map +1 -1
  220. package/dist/utils/logger.d.ts +5 -15
  221. package/dist/utils/logger.d.ts.map +1 -1
  222. package/dist/utils/logger.js +7 -8
  223. package/dist/utils/logger.js.map +1 -1
  224. package/dist/utils/mod.d.ts +0 -3
  225. package/dist/utils/mod.d.ts.map +1 -1
  226. package/dist/utils/mod.js +0 -2
  227. package/dist/utils/mod.js.map +1 -1
  228. package/dist/utils/utils.d.ts +2 -0
  229. package/dist/utils/utils.d.ts.map +1 -0
  230. package/dist/utils/utils.js +6 -0
  231. package/dist/utils/utils.js.map +1 -0
  232. package/mqttConn/mqttConn.test.ts +27 -12
  233. package/mqttConn/mqttConn.ts +45 -14
  234. package/mqttPacket/PacketType.ts +1 -0
  235. package/mqttPacket/Properties.ts +276 -0
  236. package/mqttPacket/ReasonCode.test.ts +22 -0
  237. package/mqttPacket/ReasonCode.ts +256 -0
  238. package/mqttPacket/RetainHandling.ts +11 -0
  239. package/mqttPacket/auth.test.ts +112 -0
  240. package/mqttPacket/auth.ts +71 -0
  241. package/mqttPacket/connack.test.ts +84 -64
  242. package/mqttPacket/connack.ts +88 -24
  243. package/mqttPacket/connect.test.ts +497 -18
  244. package/mqttPacket/connect.ts +170 -39
  245. package/mqttPacket/decoder.test.ts +33 -16
  246. package/mqttPacket/decoder.ts +173 -5
  247. package/mqttPacket/disconnect.test.ts +97 -18
  248. package/mqttPacket/disconnect.ts +84 -12
  249. package/mqttPacket/encoder.test.ts +32 -8
  250. package/mqttPacket/encoder.ts +236 -11
  251. package/mqttPacket/length.ts +3 -2
  252. package/mqttPacket/mod.ts +76 -39
  253. package/mqttPacket/pingreq.test.ts +52 -4
  254. package/mqttPacket/pingreq.ts +20 -7
  255. package/mqttPacket/pingres.test.ts +52 -4
  256. package/mqttPacket/pingres.ts +22 -8
  257. package/mqttPacket/properties.test.ts +193 -0
  258. package/mqttPacket/protocolLevels.ts +13 -0
  259. package/mqttPacket/pubblishAcks.ts +123 -0
  260. package/mqttPacket/publish.test.ts +212 -133
  261. package/mqttPacket/publish.ts +69 -14
  262. package/mqttPacket/publishAcks.test.ts +128 -0
  263. package/mqttPacket/suback.test.ts +71 -27
  264. package/mqttPacket/suback.ts +82 -30
  265. package/mqttPacket/subscribe.test.ts +132 -43
  266. package/mqttPacket/subscribe.ts +128 -25
  267. package/mqttPacket/types.ts +43 -0
  268. package/mqttPacket/unsuback.test.ts +80 -30
  269. package/mqttPacket/unsuback.ts +68 -13
  270. package/mqttPacket/unsubscribe.test.ts +59 -34
  271. package/mqttPacket/unsubscribe.ts +64 -17
  272. package/mqttPacket/validators.ts +15 -0
  273. package/node/tcpClient.ts +1 -1
  274. package/node/wrapNodeSocket.ts +2 -1
  275. package/package.json +2 -2
  276. package/persistence/deps.ts +1 -1
  277. package/persistence/memory/memoryPersistence.test.ts +5 -1
  278. package/persistence/memory/memoryPersistence.ts +1 -1
  279. package/server/context.ts +23 -10
  280. package/server/deps.ts +2 -0
  281. package/server/handlers/handleConnect.ts +12 -9
  282. package/server/handlers/handlePacket.ts +10 -11
  283. package/server/handlers/handlePingreq.ts +1 -0
  284. package/server/handlers/handlePublish.ts +6 -2
  285. package/server/handlers/handlePubrec.ts +3 -1
  286. package/server/handlers/handlePubrel.ts +3 -1
  287. package/server/handlers/handleSubscribe.ts +3 -6
  288. package/server/handlers/handleUnsubscribe.ts +3 -1
  289. package/server/server.ts +8 -12
  290. package/server/test/handleConnect.test.ts +2 -1
  291. package/server/test/test-handlers.ts +2 -1
  292. package/socket/socket.ts +5 -1
  293. package/utils/assert.ts +0 -18
  294. package/utils/asyncQueue.ts +17 -21
  295. package/utils/logger.ts +12 -11
  296. package/utils/mod.ts +0 -3
  297. package/utils/utils.ts +6 -0
  298. package/dist/mqttPacket/puback.d.ts +0 -16
  299. package/dist/mqttPacket/puback.d.ts.map +0 -1
  300. package/dist/mqttPacket/puback.js +0 -21
  301. package/dist/mqttPacket/puback.js.map +0 -1
  302. package/dist/mqttPacket/pubcomp.d.ts +0 -17
  303. package/dist/mqttPacket/pubcomp.d.ts.map +0 -1
  304. package/dist/mqttPacket/pubcomp.js +0 -21
  305. package/dist/mqttPacket/pubcomp.js.map +0 -1
  306. package/dist/mqttPacket/pubrec.d.ts +0 -17
  307. package/dist/mqttPacket/pubrec.d.ts.map +0 -1
  308. package/dist/mqttPacket/pubrec.js +0 -21
  309. package/dist/mqttPacket/pubrec.js.map +0 -1
  310. package/dist/mqttPacket/pubrel.d.ts +0 -17
  311. package/dist/mqttPacket/pubrel.d.ts.map +0 -1
  312. package/dist/mqttPacket/pubrel.js +0 -21
  313. package/dist/mqttPacket/pubrel.js.map +0 -1
  314. package/dist/utils/args.d.ts +0 -28
  315. package/dist/utils/args.d.ts.map +0 -1
  316. package/dist/utils/args.js +0 -76
  317. package/dist/utils/args.js.map +0 -1
  318. package/dist/utils/platform.d.ts +0 -5
  319. package/dist/utils/platform.d.ts.map +0 -1
  320. package/dist/utils/platform.js +0 -8
  321. package/dist/utils/platform.js.map +0 -1
  322. package/mqttPacket/puback.test.ts +0 -55
  323. package/mqttPacket/puback.ts +0 -34
  324. package/mqttPacket/pubcomp.test.ts +0 -55
  325. package/mqttPacket/pubcomp.ts +0 -35
  326. package/mqttPacket/pubrec.test.ts +0 -55
  327. package/mqttPacket/pubrec.ts +0 -35
  328. package/mqttPacket/pubrel.test.ts +0 -55
  329. package/mqttPacket/pubrel.ts +0 -35
  330. package/utils/args.ts +0 -103
  331. package/utils/platform.ts +0 -8
@@ -1,6 +1,8 @@
1
1
  import type { BitMask } from "./BitMask.ts";
2
2
  import type { PacketType } from "./PacketType.ts";
3
+ import type { RetainHandling } from "./RetainHandling.ts";
3
4
  import type { AuthenticationResult } from "./AuthenticationResult.ts";
5
+ import type { ReasonCode } from "./ReasonCode.ts";
4
6
 
5
7
  /**
6
8
  * Type to limit bit mask to valid values
@@ -17,6 +19,20 @@ export type TPacketType = typeof PacketType[keyof typeof PacketType];
17
19
  export type TAuthenticationResult =
18
20
  typeof AuthenticationResult[keyof typeof AuthenticationResult];
19
21
 
22
+ /**
23
+ * Type to limit reason code to valid values
24
+ */
25
+ export type TReasonCode = typeof ReasonCode[keyof typeof ReasonCode];
26
+
27
+ /**
28
+ * Protocol version
29
+ * 3.1 = 3
30
+ * 3.1.1 = 4
31
+ * 5.0 = 5
32
+ */
33
+ export type ProtocolLevel = 3 | 4 | 5 | undefined;
34
+ export type ProtocolLevelNoV5 = Exclude<ProtocolLevel, 5>;
35
+
20
36
  /**
21
37
  * Quality of Service level
22
38
  */
@@ -56,3 +72,30 @@ export type ReturnCodes = number[];
56
72
  * Client identifier that uniquely identifies a client
57
73
  */
58
74
  export type ClientId = string;
75
+
76
+ /**
77
+ * helper type to limit retain handling values
78
+ */
79
+ export type TRetainHandling =
80
+ typeof RetainHandling[keyof typeof RetainHandling];
81
+
82
+ /**
83
+ * UTF8 string pair (for v5)
84
+ */
85
+ export type UTF8StringPair = [string, string];
86
+
87
+ /**
88
+ * Options for the codec
89
+ */
90
+ export type CodecOpts = {
91
+ protocolLevel: ProtocolLevel;
92
+ maxIncomingPacketSize: number;
93
+ maxOutgoingPacketSize: number;
94
+ };
95
+
96
+ /**
97
+ * Typescript helper to create an inverted record type
98
+ */
99
+ export type InvertRecord<R extends Record<string, number>> = {
100
+ [K in keyof R as R[K]]: K;
101
+ };
@@ -1,15 +1,30 @@
1
- import { PacketType } from "./PacketType.ts";
2
1
  import assert from "node:assert/strict";
3
2
  import { test } from "node:test";
4
3
 
5
- import { decode, encode } from "./mod.ts";
4
+ import { decode, encode, MQTTLevel, PacketType, ReasonCode } from "./mod.ts";
5
+ import type { CodecOpts } from "./mod.ts";
6
6
 
7
- test("encode Puback", () => {
7
+ const codecOptsV4: CodecOpts = {
8
+ protocolLevel: MQTTLevel.v4,
9
+ maxIncomingPacketSize: 0xffff,
10
+ maxOutgoingPacketSize: 0xffff,
11
+ };
12
+
13
+ const codecOptsV5: CodecOpts = {
14
+ protocolLevel: MQTTLevel.v5,
15
+ maxIncomingPacketSize: 0xffff,
16
+ maxOutgoingPacketSize: 0xffff,
17
+ };
18
+
19
+ test("encode/decode Unsuback V4", () => {
20
+ const packet = {
21
+ type: PacketType.unsuback,
22
+ protocolLevel: MQTTLevel.v4,
23
+ id: 1337,
24
+ };
25
+ const encoded = encode(packet, codecOptsV4);
8
26
  assert.deepStrictEqual(
9
- encode({
10
- type: PacketType.unsuback,
11
- id: 1337,
12
- }),
27
+ encoded,
13
28
  Uint8Array.from([
14
29
  // fixedHeader
15
30
  0xb0, // packetType + flags
@@ -19,37 +34,72 @@ test("encode Puback", () => {
19
34
  57, // id LSB
20
35
  ]),
21
36
  );
37
+ const decoded = decode(encoded, codecOptsV4);
38
+ assert.deepStrictEqual(decoded, packet);
22
39
  });
23
40
 
24
- test("decode Puback ", () => {
25
- assert.deepStrictEqual(
26
- decode(
27
- Uint8Array.from([
28
- // fixedHeader
29
- 0xb0, // packetType + flags
30
- 2, // remainingLength
31
- // variableHeader
32
- 5, // id MSB
33
- 57, // id LSB
34
- ]),
35
- ),
36
- {
37
- type: PacketType.unsuback,
38
- id: 1337,
41
+ test("encode/decode Unsuback V5", () => {
42
+ const packet = {
43
+ type: PacketType.unsuback,
44
+ protocolLevel: MQTTLevel.v5,
45
+ id: 1337,
46
+ properties: {
47
+ reasonString: "reason",
39
48
  },
49
+ reasonCodes: [ReasonCode.success, ReasonCode.unspecifiedError],
50
+ };
51
+ const encoded = encode(packet, codecOptsV5);
52
+ assert.deepStrictEqual(
53
+ encoded,
54
+ Uint8Array.from([
55
+ // fixedHeader
56
+ 176, // packet type + flags
57
+ 14, // remaining length
58
+ 5, // id MSB
59
+ 57, // id LSB
60
+ 9, // property length
61
+ 31, // reasonString reason
62
+ 0, // string lenght MSB
63
+ 6, // string lengtg LSB
64
+ 114, // r
65
+ 101, // e
66
+ 97, // a
67
+ 115, // s
68
+ 111, // o
69
+ 110, // n
70
+ 0, // ReasonCode.success
71
+ 128, // ReasonCode.unspecifiedError
72
+ ]),
40
73
  );
74
+ const decoded = decode(encoded, codecOptsV5);
75
+ assert.deepStrictEqual(decoded, packet);
41
76
  });
42
77
 
43
- test("decodeShortPubackPackets", () => {
78
+ test("decode short unsuback packets", () => {
79
+ assert.throws(
80
+ () => decode(Uint8Array.from([0xb0]), codecOptsV4),
81
+ /Packet decoding failed/,
82
+ "single byte",
83
+ );
44
84
  assert.throws(
45
- () => decode(Uint8Array.from([0xb0])),
46
- Error,
47
- "decoding failed",
85
+ () => decode(Uint8Array.from([0xb0, 2]), codecOptsV4),
86
+ /too short/,
87
+ "incorrect length",
48
88
  );
49
- assert.throws(() => decode(Uint8Array.from([0xb0, 2])), Error, "too short");
50
89
  assert.throws(
51
- () => decode(Uint8Array.from([0xb0, 3, 0, 0, 0])),
52
- Error,
53
- "too long",
90
+ () => decode(Uint8Array.from([0xb0, 3, 0, 0, 0]), codecOptsV4),
91
+ /too long/,
92
+ "additional bytes",
93
+ );
94
+ });
95
+
96
+ test("decode invalid Unsuback V5, invalid reasonCode", () => {
97
+ assert.throws(
98
+ () =>
99
+ decode(
100
+ Uint8Array.from([224, 4, 1, 0, 0, ReasonCode.quotaExceeded]),
101
+ codecOptsV5,
102
+ ),
103
+ /Invalid reason code/,
54
104
  );
55
105
  });
@@ -1,34 +1,89 @@
1
- import type { PacketId, TPacketType } from "./types.ts";
1
+ import type {
2
+ CodecOpts,
3
+ PacketId,
4
+ ProtocolLevelNoV5,
5
+ TPacketType,
6
+ TReasonCode,
7
+ } from "./types.ts";
8
+ import type { UnsubackProperties } from "./Properties.ts";
2
9
  import { PacketType } from "./PacketType.ts";
3
- import { Decoder } from "./decoder.ts";
10
+ import { Decoder, hasEmptyFlags } from "./decoder.ts";
4
11
  import { Encoder } from "./encoder.ts";
5
12
 
13
+ export type UnsubackPacketV4 = {
14
+ type: TPacketType;
15
+ protocolLevel: ProtocolLevelNoV5;
16
+ id: PacketId;
17
+ };
18
+
19
+ export type UnsubackPacketV5 = {
20
+ type: TPacketType;
21
+ protocolLevel: 5;
22
+ id: PacketId;
23
+ properties: UnsubackProperties;
24
+ reasonCodes: Array<TReasonCode>;
25
+ };
26
+
6
27
  /**
7
28
  * UnsubackPacket is sent by the server to the client to confirm receipt
8
29
  * of an UnsubscribePacket.
9
30
  */
10
- export type UnsubackPacket = {
11
- type: TPacketType;
12
- id: PacketId;
13
- };
31
+ export type UnsubackPacket = UnsubackPacketV4 | UnsubackPacketV5;
14
32
 
15
33
  export const unsuback: {
16
- encode(packet: UnsubackPacket): { flags: number; bytes: number[] };
17
- decode(buffer: Uint8Array): UnsubackPacket;
34
+ encode(packet: UnsubackPacket, codecOpts: CodecOpts): Uint8Array;
35
+ decode(
36
+ buffer: Uint8Array,
37
+ flags: number,
38
+ codecOpts: CodecOpts,
39
+ packetType: TPacketType,
40
+ ): UnsubackPacket;
18
41
  } = {
19
- encode(packet: UnsubackPacket): { flags: number; bytes: number[] } {
42
+ encode(packet: UnsubackPacket, codecOpts: CodecOpts): Uint8Array {
20
43
  const flags = 0;
21
- const encoder = new Encoder();
44
+ const encoder = new Encoder(packet.type);
22
45
  encoder.setInt16(packet.id);
23
- return { flags, bytes: encoder.done() };
46
+ if (packet.protocolLevel === 5) {
47
+ encoder.setProperties(
48
+ packet.properties || {},
49
+ PacketType.unsuback,
50
+ codecOpts.maxOutgoingPacketSize,
51
+ );
52
+ for (const reasonCode of packet.reasonCodes) {
53
+ encoder.setByte(reasonCode);
54
+ }
55
+ }
56
+ return encoder.done(flags);
24
57
  },
25
58
 
26
- decode(buffer: Uint8Array): UnsubackPacket {
27
- const decoder = new Decoder(buffer);
59
+ decode(
60
+ buffer: Uint8Array,
61
+ flags: number,
62
+ codecOpts: CodecOpts,
63
+ packetType: TPacketType,
64
+ ): UnsubackPacket {
65
+ hasEmptyFlags(flags);
66
+ const decoder = new Decoder(packetType, buffer);
28
67
  const id = decoder.getInt16();
68
+ if (codecOpts.protocolLevel === 5) {
69
+ const properties = decoder.getProperties(PacketType.unsuback);
70
+ const reasonCodes = [];
71
+ while (!decoder.atEnd()) {
72
+ const reasonCode = decoder.getReasonCode();
73
+ reasonCodes.push(reasonCode);
74
+ }
75
+ return {
76
+ type: PacketType.unsuback,
77
+ protocolLevel: 5,
78
+ id,
79
+ properties,
80
+ reasonCodes: reasonCodes as Array<TReasonCode>,
81
+ };
82
+ }
29
83
  decoder.done();
30
84
  return {
31
85
  type: PacketType.unsuback,
86
+ protocolLevel: codecOpts.protocolLevel,
32
87
  id,
33
88
  };
34
89
  },
@@ -1,16 +1,31 @@
1
1
  import { PacketType } from "./PacketType.ts";
2
2
  import assert from "node:assert/strict";
3
3
  import { test } from "node:test";
4
+ import { decode, encode, MQTTLevel } from "./mod.ts";
5
+ import type { CodecOpts } from "./mod.ts";
4
6
 
5
- import { decode, encode } from "./mod.ts";
7
+ const codecOptsV4: CodecOpts = {
8
+ protocolLevel: MQTTLevel.v4,
9
+ maxIncomingPacketSize: 0xffff,
10
+ maxOutgoingPacketSize: 0xffff,
11
+ };
6
12
 
7
- test("encode Unsubscribe", () => {
13
+ const codecOptsV5: CodecOpts = {
14
+ protocolLevel: MQTTLevel.v5,
15
+ maxIncomingPacketSize: 0xffff,
16
+ maxOutgoingPacketSize: 0xffff,
17
+ };
18
+
19
+ test("encode/decode Unsubscribe V4", () => {
20
+ const packet = {
21
+ type: PacketType.unsubscribe,
22
+ protocolLevel: MQTTLevel.v4,
23
+ id: 1,
24
+ topicFilters: ["a/b", "c/d"],
25
+ };
26
+ const encoded = encode(packet, codecOptsV4);
8
27
  assert.deepStrictEqual(
9
- encode({
10
- type: PacketType.unsubscribe,
11
- id: 1,
12
- topicFilters: ["a/b", "c/d"],
13
- }),
28
+ encoded,
14
29
  Uint8Array.from([
15
30
  // fixedHeader
16
31
  0xa2, // packetType + flags
@@ -31,37 +46,44 @@ test("encode Unsubscribe", () => {
31
46
  100, // 'd'
32
47
  ]),
33
48
  );
49
+ const decoded = decode(encoded, codecOptsV4);
50
+ assert.deepStrictEqual(decoded, packet);
34
51
  });
35
52
 
36
- test("decode Unsubscribe", () => {
53
+ test("encode/decode Unsubscribe V5", () => {
54
+ const packet = {
55
+ type: PacketType.unsubscribe,
56
+ protocolLevel: MQTTLevel.v5,
57
+ id: 1,
58
+ properties: {},
59
+ topicFilters: ["a/b", "c/d"],
60
+ };
61
+ const encoded = encode(packet, codecOptsV4);
37
62
  assert.deepStrictEqual(
38
- decode(
39
- Uint8Array.from([
40
- // fixedHeader
41
- 0xa2, // packetType + flags
42
- 12, // remainingLength
43
- // variableHeader
44
- 0, // id MSB
45
- 1, // id LSB
46
- // payload
47
- 0, // topic filter length MSB
48
- 3, // topic filter length LSB
49
- 97, // 'a'
50
- 47, // '/'
51
- 98, // 'b'
52
- 0, // topic filter length MSB
53
- 3, // topic filter length LSB
54
- 99, // 'c'
55
- 47, // '/'
56
- 100, // 'd'
57
- ]),
58
- ),
59
- {
60
- type: PacketType.unsubscribe,
61
- id: 1,
62
- topicFilters: ["a/b", "c/d"],
63
- },
63
+ encoded,
64
+ Uint8Array.from([
65
+ // fixedHeader
66
+ 0xa2, // packetType + flags
67
+ 13, // remainingLength
68
+ // variableHeader
69
+ 0, // id MSB
70
+ 1, // id LSB
71
+ 0, // property length
72
+ // payload
73
+ 0, // topic filter length MSB
74
+ 3, // topic filter length LSB
75
+ 97, // 'a'
76
+ 47, // '/'
77
+ 98, // 'b'
78
+ 0, // topic filter length MSB
79
+ 3, // topic filter length LSB
80
+ 99, // 'c'
81
+ 47, // '/'
82
+ 100, // 'd'
83
+ ]),
64
84
  );
85
+ const decoded = decode(encoded, codecOptsV5);
86
+ assert.deepStrictEqual(decoded, packet);
65
87
  });
66
88
 
67
89
  test("decode Unsubscribe missing bit 1 flag", () => {
@@ -87,6 +109,7 @@ test("decode Unsubscribe missing bit 1 flag", () => {
87
109
  47, // '/'
88
110
  100, // 'd'
89
111
  ]),
112
+ codecOptsV4,
90
113
  ),
91
114
  Error,
92
115
  "Invalid header",
@@ -114,6 +137,7 @@ test("decode unsubscribe packet too short", () => {
114
137
  3, // topic filter length LSB
115
138
  99, // 'c'
116
139
  ]),
140
+ codecOptsV4,
117
141
  ),
118
142
  Error,
119
143
  "too short",
@@ -129,6 +153,7 @@ test("decode unsubscribe packet too short", () => {
129
153
  0, // id MSB
130
154
  1, // id LSB
131
155
  ]),
156
+ codecOptsV4,
132
157
  ),
133
158
  Error,
134
159
  "too short",
@@ -1,53 +1,100 @@
1
- import type { PacketId, Topic, TopicFilter, TPacketType } from "./types.ts";
1
+ import type {
2
+ CodecOpts,
3
+ PacketId,
4
+ ProtocolLevelNoV5,
5
+ Topic,
6
+ TopicFilter,
7
+ TPacketType,
8
+ } from "./types.ts";
9
+ import type { UnsubscribeProperties } from "./Properties.ts";
2
10
  import { PacketType } from "./PacketType.ts";
3
- import { BitMask } from "./BitMask.ts";
4
11
  import { Encoder } from "./encoder.ts";
5
- import { booleanFlag, Decoder, DecoderError } from "./decoder.ts";
12
+ import { Decoder, DecoderError } from "./decoder.ts";
6
13
 
7
- /**
8
- * UnsubscribePacket is sent from client to server to unsubscribe from topics
9
- */
10
- export type UnsubscribePacket = {
14
+ export type UnsubscribePacketV4 = {
11
15
  type: TPacketType;
16
+ protocolLevel: ProtocolLevelNoV5;
12
17
  id: PacketId;
13
18
  topicFilters: TopicFilter[];
14
19
  };
15
20
 
21
+ export type UnsubscribePacketV5 = {
22
+ type: TPacketType;
23
+ protocolLevel: 5;
24
+ id: PacketId;
25
+ properties?: UnsubscribeProperties;
26
+ topicFilters: TopicFilter[];
27
+ };
28
+
29
+ /**
30
+ * UnsubscribePacket is sent from client to server to unsubscribe from topics
31
+ */
32
+ export type UnsubscribePacket = UnsubscribePacketV4 | UnsubscribePacketV5;
33
+
16
34
  export const unsubscribe: {
17
- encode(packet: UnsubscribePacket): { flags: number; bytes: number[] };
18
- decode(buffer: Uint8Array, flags: number): UnsubscribePacket;
35
+ encode(packet: UnsubscribePacket, codecOpts: CodecOpts): Uint8Array;
36
+ decode(
37
+ buffer: Uint8Array,
38
+ flags: number,
39
+ codecOpts: CodecOpts,
40
+ packetType: TPacketType,
41
+ ): UnsubscribePacket;
19
42
  } = {
20
- encode(packet: UnsubscribePacket): { flags: number; bytes: number[] } {
43
+ encode(packet: UnsubscribePacket, codecOpts: CodecOpts): Uint8Array {
21
44
  // Bits 3,2,1 and 0 of the fixed header of the UNSUBSCRIBE Control Packet are reserved and
22
45
  // MUST be set to 0,0,1 and 0 respectively. The Server MUST treat any other value as
23
46
  // malformed and close the Network Connection [MQTT-3.10.1-1].
24
47
  const flags = 0b0010;
25
48
 
26
- const encoder = new Encoder();
49
+ const encoder = new Encoder(packet.type);
27
50
  encoder.setInt16(packet.id);
51
+ if (packet.protocolLevel === 5) {
52
+ encoder.setProperties(
53
+ packet.properties || {},
54
+ PacketType.unsubscribe,
55
+ codecOpts.maxOutgoingPacketSize,
56
+ );
57
+ }
28
58
  for (const topicFilter of packet.topicFilters) {
29
59
  encoder.setTopicFilter(topicFilter);
30
60
  }
31
- return { flags, bytes: encoder.done() };
61
+ return encoder.done(flags);
32
62
  },
33
63
 
34
- decode(buffer: Uint8Array, flags: number): UnsubscribePacket {
35
- if (!booleanFlag(flags, BitMask.bit1)) {
64
+ decode(
65
+ buffer: Uint8Array,
66
+ flags: number,
67
+ codecOpts: CodecOpts,
68
+ packetType: TPacketType,
69
+ ): UnsubscribePacket {
70
+ if (flags !== 0b0010) {
36
71
  throw new DecoderError("Invalid header");
37
72
  }
38
- const decoder = new Decoder(buffer);
73
+ const decoder = new Decoder(packetType, buffer);
39
74
  const id = decoder.getInt16();
40
-
75
+ let properties = {};
76
+ if (codecOpts.protocolLevel === 5) {
77
+ properties = decoder.getProperties(PacketType.unsubscribe);
78
+ }
41
79
  const topicFilters: Topic[] = [];
42
80
  do {
43
81
  const topicFilter = decoder.getTopicFilter();
44
82
  topicFilters.push(topicFilter);
45
83
  } while (!decoder.atEnd());
46
84
  decoder.done();
47
-
85
+ if (codecOpts.protocolLevel !== 5) {
86
+ return {
87
+ type: PacketType.unsubscribe,
88
+ protocolLevel: codecOpts.protocolLevel,
89
+ id,
90
+ topicFilters,
91
+ };
92
+ }
48
93
  return {
49
94
  type: PacketType.unsubscribe,
95
+ protocolLevel: 5,
50
96
  id,
97
+ properties,
51
98
  topicFilters,
52
99
  };
53
100
  },
@@ -7,14 +7,29 @@ const invalidTopicRegEx = new RegExp(/^$|\+|#|\x00|\uFFFD/);
7
7
  // deno-lint-ignore no-control-regex
8
8
  const invalidTopicFilterRegEx = new RegExp(/^$|#.|[^\/]\+|\+[^\/]|\x00|\uFFFD/);
9
9
 
10
+ /**
11
+ * check for invalid UTF-8 characters
12
+ * @param value string to test
13
+ * @returns true if the string contains invalid UTF-8 characters
14
+ */
10
15
  export function invalidUTF8(value: string): boolean {
11
16
  return invalidUTF8regEx.test(value);
12
17
  }
13
18
 
19
+ /**
20
+ * check for invalid topic characters
21
+ * @param value
22
+ * @returns true if the topic is invalid
23
+ */
14
24
  export function invalidTopic(value: Topic): boolean {
15
25
  return invalidTopicRegEx.test(value);
16
26
  }
17
27
 
28
+ /**
29
+ * check for invalid topic filter characters
30
+ * @param value topic filter to test
31
+ * @returns true if the topic filter is invalid
32
+ */
18
33
  export function invalidTopicFilter(value: TopicFilter): boolean {
19
34
  return invalidTopicFilterRegEx.test(value);
20
35
  }
package/node/tcpClient.ts CHANGED
@@ -96,6 +96,6 @@ export class TcpClient extends Client {
96
96
  if (protocol === "mqtt:") {
97
97
  return this.connectMQTT(hostname, port);
98
98
  }
99
- throw `Unsupported protocol: ${protocol}`;
99
+ throw new Error(`Unsupported protocol: ${protocol}`);
100
100
  }
101
101
  }
@@ -4,6 +4,7 @@
4
4
  import type { Socket } from "node:net";
5
5
  import { Writable } from "node:stream";
6
6
  import type { NetAddr, SockConn } from "../socket/socket.ts";
7
+
7
8
  /**
8
9
  * Closes a Node.js socket if it is not already closed
9
10
  * @param sock - The Node.js socket to close
@@ -24,7 +25,7 @@ export function wrapNodeSocket(socket: Socket): SockConn {
24
25
  {
25
26
  type: "bytes",
26
27
  start(controller) {
27
- socket.on("data", (data: ArrayBufferView) => {
28
+ socket.on("data", (data: Uint8Array<ArrayBuffer>) => {
28
29
  controller.enqueue(data);
29
30
  const desiredSize = controller.desiredSize ?? 0;
30
31
  if (desiredSize <= 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seriousme/opifex",
3
- "version": "1.9.4",
3
+ "version": "1.11.0",
4
4
  "description": "MQTT client & server for Deno & NodeJS",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -68,6 +68,6 @@
68
68
  },
69
69
  "homepage": "https://github.com/seriousme/opifex#readme",
70
70
  "devDependencies": {
71
- "@types/node": "^22.13.1"
71
+ "@types/node": "^24.6.2"
72
72
  }
73
73
  }
@@ -7,6 +7,6 @@ export type {
7
7
  Topic,
8
8
  TopicFilter,
9
9
  } from "../mqttPacket/mod.ts";
10
- export { PacketType } from "../mqttPacket/mod.ts";
10
+ export { MQTTLevel, PacketType } from "../mqttPacket/mod.ts";
11
11
  export { Trie } from "../trie/trie.ts";
12
12
  export { logger } from "../utils/mod.ts";
@@ -5,7 +5,8 @@ import {
5
5
 
6
6
  import assert from "node:assert/strict";
7
7
  import { test } from "node:test";
8
- import { PacketType, type PublishPacket } from "../deps.ts";
8
+ import { MQTTLevel, PacketType } from "../deps.ts";
9
+ import type { PublishPacket } from "../deps.ts";
9
10
 
10
11
  const payloadAny = new TextEncoder().encode("any");
11
12
  const qos = 1;
@@ -39,6 +40,7 @@ test("pub/sub should work", async () => {
39
40
  const topic = "/myTopic";
40
41
  const publishPacket: PublishPacket = {
41
42
  type: PacketType.publish,
43
+ protocolLevel: MQTTLevel.v4,
42
44
  id: 1,
43
45
  topic,
44
46
  payload: payloadAny,
@@ -77,6 +79,7 @@ test("many packets should work", async () => {
77
79
  const numMessages = 1000;
78
80
  const publishPacket: PublishPacket = {
79
81
  type: PacketType.publish,
82
+ protocolLevel: MQTTLevel.v4,
80
83
  id: 1,
81
84
  topic,
82
85
  payload: payloadAny,
@@ -123,6 +126,7 @@ test("unsubscribe should work", () => {
123
126
  const topic = "/myTopic";
124
127
  const publishPacket: PublishPacket = {
125
128
  type: PacketType.publish,
129
+ protocolLevel: MQTTLevel.v4,
126
130
  id: 1,
127
131
  topic,
128
132
  payload: payloadAny,
@@ -134,7 +134,7 @@ export class MemoryPersistence implements IPersistence {
134
134
  newPacket.qos = qos;
135
135
  // logger.debug(`publish ${topic} to client ${clientId}`);
136
136
  const client = this.clientList.get(clientId);
137
- client?.handler(packet);
137
+ client?.handler(newPacket);
138
138
  }
139
139
  }
140
140