@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
@@ -2,19 +2,39 @@ import { PacketType } from "./PacketType.ts";
2
2
  import assert from "node:assert/strict";
3
3
  import { test } from "node:test";
4
4
 
5
- import { decode, encode } from "./mod.ts";
5
+ import { decode, encode, MQTTLevel } from "./mod.ts";
6
+ import type { CodecOpts } from "./mod.ts";
7
+
8
+ const codecOptsV4: CodecOpts = {
9
+ protocolLevel: MQTTLevel.v4,
10
+ maxIncomingPacketSize: 0xffff,
11
+ maxOutgoingPacketSize: 0xffff,
12
+ };
13
+
14
+ const codecOptsV5: CodecOpts = {
15
+ protocolLevel: MQTTLevel.v5,
16
+ maxIncomingPacketSize: 0xffff,
17
+ maxOutgoingPacketSize: 0xffff,
18
+ };
6
19
 
7
20
  // const utf8Decoder = new TextDecoder();
8
21
  const utf8Encoder = new TextEncoder();
9
22
  const payload = utf8Encoder.encode("payload");
10
23
 
11
- test("encode Publish", () => {
24
+ test("encode/decode short Publish v4", () => {
25
+ const packet = {
26
+ type: PacketType.publish,
27
+ protocolLevel: MQTTLevel.v4,
28
+ qos: 0,
29
+ dup: false,
30
+ id: undefined,
31
+ retain: false,
32
+ topic: "a/b",
33
+ payload,
34
+ };
35
+ const encoded = encode(packet, codecOptsV4);
12
36
  assert.deepStrictEqual(
13
- encode({
14
- type: PacketType.publish,
15
- topic: "a/b",
16
- payload,
17
- }),
37
+ encoded,
18
38
  Uint8Array.from([
19
39
  // fixedHeader
20
40
  48, // packetType + flags
@@ -35,123 +55,85 @@ test("encode Publish", () => {
35
55
  100, // 'd'
36
56
  ]),
37
57
  );
58
+ const decoded = decode(encoded, codecOptsV4);
59
+ assert.deepStrictEqual(decoded, packet);
38
60
  });
39
61
 
40
- test("decode Publish", () => {
41
- assert.deepStrictEqual(
42
- decode(
43
- Uint8Array.from([
44
- // fixedHeader
45
- 48, // packetType + flags
46
- 12, // remainingLength
47
- // variableHeader
48
- 0, // topicLength MSB
49
- 3, // topicLength LSB
50
- 97, // 'a'
51
- 47, // '/'
52
- 98, // 'b'
53
- // payload
54
- 112, // 'p'
55
- 97, // 'a'
56
- 121, // 'y'
57
- 108, // 'l'
58
- 111, // 'o'
59
- 97, // 'a'
60
- 100, // 'd'
61
- ]),
62
- ),
63
- {
64
- type: PacketType.publish,
65
- dup: false,
66
- qos: 0,
67
- retain: false,
68
- id: 0,
69
- topic: "a/b",
70
- payload: Uint8Array.from([
71
- 112, // 'p'
72
- 97, // 'a'
73
- 121, // 'y'
74
- 108, // 'l'
75
- 111, // 'o'
76
- 97, // 'a'
77
- 100, // 'd'
78
- ]),
79
- },
80
- );
81
- });
82
-
83
- test("decode Publish with extra bytes", () => {
62
+ test("encode/decode extended Publish v4", () => {
63
+ const packet = {
64
+ type: PacketType.publish,
65
+ protocolLevel: MQTTLevel.v4,
66
+ dup: false,
67
+ qos: 0,
68
+ retain: false,
69
+ id: undefined,
70
+ topic: "a/b",
71
+ payload: Uint8Array.from([
72
+ 112, // 'p'
73
+ 97, // 'a'
74
+ 121, // 'y'
75
+ 108, // 'l'
76
+ 111, // 'o'
77
+ 97, // 'a'
78
+ 100, // 'd'
79
+ ]),
80
+ };
81
+ const encoded = encode(packet, codecOptsV4);
84
82
  assert.deepStrictEqual(
85
- decode(
86
- Uint8Array.from([
87
- // fixedHeader
88
- 48, // packetType + flags
89
- 12, // remainingLength
90
- // variableHeader
91
- 0, // topicLength MSB
92
- 3, // topicLength LSB
93
- 97, // 'a'
94
- 47, // '/'
95
- 98, // 'b'
96
- // payload
97
- 112, // 'p'
98
- 97, // 'a'
99
- 121, // 'y'
100
- 108, // 'l'
101
- 111, // 'o'
102
- 97, // 'a'
103
- 100, // 'd'
104
- 101, // 'e'
105
- 116, // 't'
106
- 99, // 'c'
107
- ]),
108
- ),
109
- {
110
- type: PacketType.publish,
111
- dup: false,
112
- qos: 0,
113
- retain: false,
114
- id: 0,
115
- topic: "a/b",
116
- payload: Uint8Array.from([
117
- 112, // 'p'
118
- 97, // 'a'
119
- 121, // 'y'
120
- 108, // 'l'
121
- 111, // 'o'
122
- 97, // 'a'
123
- 100, // 'd'
124
- ]),
125
- },
83
+ encoded,
84
+ Uint8Array.from([
85
+ // fixedHeader
86
+ 48, // packetType + flags
87
+ 12, // remainingLength
88
+ // variableHeader
89
+ 0, // topicLength MSB
90
+ 3, // topicLength LSB
91
+ 97, // 'a'
92
+ 47, // '/'
93
+ 98, // 'b'
94
+ // payload
95
+ 112, // 'p'
96
+ 97, // 'a'
97
+ 121, // 'y'
98
+ 108, // 'l'
99
+ 111, // 'o'
100
+ 97, // 'a'
101
+ 100, // 'd'
102
+ ]),
126
103
  );
104
+ const decoded = decode(encoded, codecOptsV4);
105
+ assert.deepStrictEqual(decoded, packet);
127
106
  });
128
107
 
129
- test("decode Publish no payload", () => {
108
+ test("encode/decode Publish v4 no payload", () => {
109
+ const packet = {
110
+ type: PacketType.publish,
111
+ protocolLevel: MQTTLevel.v4,
112
+ dup: false,
113
+ qos: 0,
114
+ retain: false,
115
+ id: undefined,
116
+ topic: "a/b",
117
+ payload: Uint8Array.from([]),
118
+ };
119
+ const encoded = encode(packet, codecOptsV4);
130
120
  assert.deepStrictEqual(
131
- decode(
132
- Uint8Array.from([
133
- // fixedHeader
134
- 48, // packetType + flags
135
- 5, // remainingLength
136
- // variableHeader
137
- 0, // topicLength MSB
138
- 3, // topicLength LSB
139
- 97, // 'a'
140
- 47, // '/'
141
- 98, // 'b'
142
- // payload
143
- ]),
144
- ),
145
- {
146
- type: PacketType.publish,
147
- dup: false,
148
- qos: 0,
149
- retain: false,
150
- id: 0,
151
- topic: "a/b",
152
- payload: Uint8Array.from([]),
153
- },
121
+ encoded,
122
+ Uint8Array.from([
123
+ // fixedHeader
124
+ 48, // packetType + flags
125
+ 5, // remainingLength
126
+ // variableHeader
127
+ 0, // topicLength MSB
128
+ 3, // topicLength LSB
129
+ 97, // 'a'
130
+ 47, // '/'
131
+ 98, // 'b'
132
+ // payload
133
+ ]),
154
134
  );
135
+ const decoded = decode(encoded, codecOptsV4);
136
+ assert.deepStrictEqual(decoded, packet);
155
137
  });
156
138
 
157
139
  test("Invalid qos", () => {
@@ -170,29 +152,126 @@ test("Invalid qos", () => {
170
152
  98, // 'b'
171
153
  // payload
172
154
  ]),
155
+ codecOptsV4,
173
156
  ),
174
157
  Error,
175
158
  "Invalid qos",
176
159
  );
177
160
  });
178
- test("Invalid qos for duplicate", () => {
161
+
162
+ test("QoS 2, but no packetId", () => {
179
163
  assert.throws(
180
164
  () =>
181
- decode(
182
- Uint8Array.from([
183
- // fixedHeader
184
- 0x38, // packetType + flags
185
- 5, // remainingLength
186
- // variableHeader
187
- 0, // topicLength MSB
188
- 3, // topicLength LSB
189
- 97, // 'a'
190
- 47, // '/'
191
- 98, // 'b'
192
- // payload
193
- ]),
194
- ),
195
- Error,
196
- "Invalid qos for possible duplicate",
165
+ encode({
166
+ type: PacketType.publish,
167
+ protocolLevel: MQTTLevel.v4,
168
+ topic: "a/b",
169
+ payload,
170
+ qos: 2,
171
+ }, codecOptsV4),
172
+ /when qos is 1 or 2, packet must have id/,
173
+ );
174
+ });
175
+
176
+ test("encode/decode Publish v5", () => {
177
+ const packet = {
178
+ type: PacketType.publish,
179
+ protocolLevel: MQTTLevel.v5,
180
+ dup: false,
181
+ qos: 0,
182
+ retain: false,
183
+ id: undefined,
184
+ topic: "a/b",
185
+ payload,
186
+ properties: {
187
+ payloadFormatIndicator: true,
188
+ messageExpiryInterval: 1234,
189
+ contentType: "content",
190
+ responseTopic: "response",
191
+ correlationData: Uint8Array.from([1, 2, 3]),
192
+ subscriptionIdentifiers: [123],
193
+ topicAlias: 123,
194
+ userProperty: [["user", "property"]],
195
+ },
196
+ };
197
+ const encoded = encode(packet, codecOptsV5);
198
+ assert.deepStrictEqual(
199
+ encoded,
200
+ Uint8Array.from([
201
+ // fixedHeader
202
+ 48, // packetType + flags
203
+ 69, // remainingLength
204
+ 0, // topic length MSB
205
+ 3, // topic length LSB
206
+ 97, // a
207
+ 47, // /
208
+ 98, // b
209
+ 56, // propertyLength
210
+ 1, // payload format indicator
211
+ 1, // true
212
+ 2, // message expiry interval (4 bytes)
213
+ 0,
214
+ 0,
215
+ 4,
216
+ 210,
217
+ 3, // content type
218
+ 0, // string length MSB
219
+ 7, // string length LSB
220
+ 99, // c
221
+ 111, // o
222
+ 110, // n
223
+ 116, // t
224
+ 101, // e
225
+ 110, // n
226
+ 116, // t
227
+ 8, // response topic
228
+ 0, // string length MSB
229
+ 8, // string length LSB
230
+ 114, // r
231
+ 101, // e
232
+ 115, // s
233
+ 112, // p
234
+ 111, // o
235
+ 110, // n
236
+ 115, // s
237
+ 101, // e
238
+ 9, // correlation data 3 bytes
239
+ 0, // byte length MSB
240
+ 3, // byte length LSB
241
+ 1,
242
+ 2,
243
+ 3,
244
+ 11, // subscriptionIdentifier
245
+ 123, // 123
246
+ 35, // topicAlias
247
+ 0,
248
+ 123,
249
+ 38, // userproperties
250
+ 0, // string length MSB
251
+ 4, // string length LSB
252
+ 117, // u
253
+ 115, // s
254
+ 101, // e
255
+ 114, // r
256
+ 0, // string length MSB
257
+ 8, // string length LSB
258
+ 112, // p
259
+ 114, // r
260
+ 111, // o
261
+ 112, // p
262
+ 101, // e
263
+ 114, // r
264
+ 116, // t
265
+ 121, // y
266
+ 112, // p
267
+ 97, // a
268
+ 121, // y
269
+ 108, // l
270
+ 111, // o
271
+ 97, // a
272
+ 100, // d
273
+ ]),
197
274
  );
275
+ const decoded = decode(encoded, codecOptsV5);
276
+ assert.deepStrictEqual(decoded, packet);
198
277
  });
@@ -1,4 +1,13 @@
1
- import type { Payload, QoS, Topic, TPacketType } from "./types.ts";
1
+ import type {
2
+ CodecOpts,
3
+ Dup,
4
+ Payload,
5
+ ProtocolLevelNoV5,
6
+ QoS,
7
+ Topic,
8
+ TPacketType,
9
+ } from "./types.ts";
10
+ import type { PublishProperties } from "./Properties.ts";
2
11
  import { PacketType } from "./PacketType.ts";
3
12
  import { BitMask } from "./BitMask.ts";
4
13
  import { Encoder, EncoderError } from "./encoder.ts";
@@ -8,21 +17,40 @@ import { booleanFlag, Decoder, DecoderError } from "./decoder.ts";
8
17
  * PublishPacket is used to send data from client to server and
9
18
  * from server to subscribers
10
19
  */
11
- export type PublishPacket = {
20
+ export type PublishPacketV4 = {
12
21
  type: TPacketType;
22
+ protocolLevel: ProtocolLevelNoV5;
13
23
  topic: Topic;
14
24
  payload: Payload;
15
- dup?: boolean;
25
+ dup?: Dup;
16
26
  retain?: boolean;
17
27
  qos?: QoS;
18
28
  id?: number;
19
29
  };
30
+ export type PublishPacketV5 = {
31
+ type: TPacketType;
32
+ protocolLevel: 5;
33
+ topic: Topic;
34
+ payload: Payload;
35
+ dup?: Dup;
36
+ retain?: boolean;
37
+ qos?: QoS;
38
+ id?: number;
39
+ properties?: PublishProperties;
40
+ };
41
+
42
+ export type PublishPacket = PublishPacketV4 | PublishPacketV5;
20
43
 
21
44
  export const publish: {
22
- encode(packet: PublishPacket): { flags: number; bytes: number[] };
23
- decode(buffer: Uint8Array, flags: number): PublishPacket;
45
+ encode(packet: PublishPacket, _codecOpts: CodecOpts): Uint8Array;
46
+ decode(
47
+ buffer: Uint8Array,
48
+ flags: number,
49
+ codecOpts: CodecOpts,
50
+ packetType: TPacketType,
51
+ ): PublishPacket;
24
52
  } = {
25
- encode(packet: PublishPacket): { flags: number; bytes: number[] } {
53
+ encode(packet: PublishPacket, codecOpts: CodecOpts): Uint8Array {
26
54
  const qos = packet.qos || 0;
27
55
 
28
56
  const flags = (packet.dup ? BitMask.bit3 : 0) +
@@ -30,7 +58,7 @@ export const publish: {
30
58
  (qos & 1 ? BitMask.bit1 : 0) +
31
59
  (packet.retain ? BitMask.bit0 : 0);
32
60
 
33
- const encoder = new Encoder();
61
+ const encoder = new Encoder(packet.type);
34
62
  encoder.setTopic(packet.topic);
35
63
 
36
64
  if (qos === 1 || qos === 2) {
@@ -39,11 +67,24 @@ export const publish: {
39
67
  }
40
68
  encoder.setInt16(packet.id);
41
69
  }
70
+
71
+ if (packet.protocolLevel === 5) {
72
+ encoder.setProperties(
73
+ packet.properties || {},
74
+ PacketType.publish,
75
+ codecOpts.maxOutgoingPacketSize,
76
+ );
77
+ }
42
78
  encoder.setRemainder(packet.payload);
43
- return { flags, bytes: encoder.done() };
79
+ return encoder.done(flags);
44
80
  },
45
81
 
46
- decode(buffer: Uint8Array, flags: number): PublishPacket {
82
+ decode(
83
+ buffer: Uint8Array,
84
+ flags: number,
85
+ codecOpts: CodecOpts,
86
+ packetType: TPacketType,
87
+ ): PublishPacket {
47
88
  const dup = booleanFlag(flags, BitMask.bit3);
48
89
  const qos = (flags & 6) >> 1;
49
90
  const retain = booleanFlag(flags, BitMask.bit0);
@@ -56,19 +97,33 @@ export const publish: {
56
97
  throw new DecoderError("Invalid qos for possible duplicate");
57
98
  }
58
99
 
59
- const decoder = new Decoder(buffer);
100
+ const decoder = new Decoder(packetType, buffer);
60
101
  const topic = decoder.getTopic();
61
102
 
62
- let id = 0;
103
+ let id = undefined;
63
104
  if (qos > 0) {
64
105
  id = decoder.getInt16();
65
106
  }
66
- const payload = decoder.getRemainder();
67
-
107
+ if (codecOpts.protocolLevel === 5) {
108
+ const properties = decoder.getProperties(PacketType.publish);
109
+ const payload = decoder.getRemainder();
110
+ return {
111
+ type: PacketType.publish,
112
+ protocolLevel: 5,
113
+ properties,
114
+ topic,
115
+ payload,
116
+ dup,
117
+ retain,
118
+ qos,
119
+ id,
120
+ };
121
+ }
68
122
  // no decoder.done() required because of getRemainder
69
-
123
+ const payload = decoder.getRemainder();
70
124
  return {
71
125
  type: PacketType.publish,
126
+ protocolLevel: codecOpts.protocolLevel,
72
127
  topic,
73
128
  payload,
74
129
  dup,
@@ -0,0 +1,128 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import { decode, encode, MQTTLevel, PacketType, ReasonCode } from "./mod.ts";
5
+ import type { CodecOpts, TPacketType, TReasonCode } from "./mod.ts";
6
+
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
+ const packetTypesToTest = [
20
+ [PacketType.puback, "Puback", ReasonCode.packetIdentifierInUse],
21
+ [PacketType.pubrec, "Pubrec", ReasonCode.packetIdentifierInUse],
22
+ [PacketType.pubrel, "Pubrel", ReasonCode.packetIdentifierNotFound],
23
+ [PacketType.pubcomp, "Pubcomp", ReasonCode.packetIdentifierNotFound],
24
+ ];
25
+ for (const item of packetTypesToTest) {
26
+ const [ackType, label, reasonCode] = item as [
27
+ TPacketType,
28
+ string,
29
+ TReasonCode,
30
+ ];
31
+ const ackTypeByte = (ackType << 4) + (ackType === PacketType.pubrel ? 2 : 0);
32
+ test(`encode/decode ${label} v4`, () => {
33
+ const packet = {
34
+ type: ackType,
35
+ protocolLevel: MQTTLevel.v4,
36
+ id: 1337,
37
+ };
38
+ const encoded = encode(packet, codecOptsV4);
39
+ assert.deepStrictEqual(
40
+ encoded,
41
+ Uint8Array.from([
42
+ // fixedHeader
43
+ ackTypeByte, // packetType + flags
44
+ 2, // remainingLength
45
+ // variableHeader
46
+ 5, // id MSB
47
+ 57, // id LSB
48
+ ]),
49
+ );
50
+ const decoded = decode(encoded, codecOptsV4);
51
+ assert.deepStrictEqual(decoded, packet);
52
+ });
53
+
54
+ test(`encode/decode ${label} v5`, () => {
55
+ const packet = {
56
+ type: ackType,
57
+ protocolLevel: MQTTLevel.v5,
58
+ id: 1337,
59
+ reasonCode,
60
+ properties: { reasonString: "test" },
61
+ };
62
+ const encoded = encode(packet, codecOptsV5);
63
+ assert.deepStrictEqual(
64
+ encoded,
65
+ Uint8Array.from([
66
+ // fixedHeader
67
+ ackTypeByte, // packetType + flags
68
+ 11, // remainingLength
69
+ // variableHeader
70
+ 5, // id MSB
71
+ 57, // id LSB
72
+ reasonCode, // reasonCode
73
+ // properties
74
+ 7, // propertyLength
75
+ 31, // reasonString
76
+ 0, // string length MSB
77
+ 4, // string length LSB
78
+ 116, //'t'
79
+ 101, //'e'
80
+ 115, //'s'
81
+ 116, //'t'
82
+ ]),
83
+ );
84
+ const decoded = decode(encoded, codecOptsV5);
85
+ assert.deepStrictEqual(decoded, packet);
86
+ });
87
+
88
+ test(`encode/decode short ${label} v5`, () => {
89
+ const packet = {
90
+ type: ackType,
91
+ protocolLevel: MQTTLevel.v5,
92
+ id: 1337,
93
+ reasonCode: 0,
94
+ };
95
+ const encoded = encode(packet, codecOptsV5);
96
+ assert.deepStrictEqual(
97
+ encoded,
98
+ Uint8Array.from([
99
+ // fixedHeader
100
+ ackTypeByte, // packetType + flags
101
+ 2, // remainingLength
102
+ // variableHeader
103
+ 5, // id MSB
104
+ 57, // id LSB
105
+ ]),
106
+ );
107
+ const decoded = decode(encoded, codecOptsV5);
108
+ assert.deepStrictEqual(decoded, packet);
109
+ });
110
+
111
+ test("decode short puback packets", () => {
112
+ assert.throws(
113
+ () => decode(Uint8Array.from([ackTypeByte]), codecOptsV4),
114
+ Error,
115
+ "decoding failed",
116
+ );
117
+ assert.throws(
118
+ () => decode(Uint8Array.from([ackTypeByte, 3, 0, 0, 0]), codecOptsV4),
119
+ Error,
120
+ "too long",
121
+ );
122
+ assert.throws(
123
+ () => decode(Uint8Array.from([ackTypeByte, 2, 5]), codecOptsV5),
124
+ Error,
125
+ "decoding failed",
126
+ );
127
+ });
128
+ }