@seriousme/opifex 1.6.3 → 1.7.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 (91) hide show
  1. package/package.json +12 -2
  2. package/.github/dependabot.yml +0 -7
  3. package/.github/workflows/closeStale.yml +0 -15
  4. package/.github/workflows/codeql-analysis.yml +0 -71
  5. package/.github/workflows/deno-ci.yml +0 -16
  6. package/.github/workflows/nodejs-ci.yml +0 -23
  7. package/.github/workflows/publish.yml +0 -16
  8. package/.github/workflows/update-license-year.sh +0 -14
  9. package/.github/workflows/update-license-year.yml +0 -13
  10. package/CHANGELOG.md +0 -80
  11. package/deno.json +0 -16
  12. package/deno.lock +0 -34
  13. package/dist/bin/conformanceServer.js +0 -97
  14. package/dist/bin/demoServer.js +0 -96
  15. package/dist/bin/mqtt.js +0 -256
  16. package/dist/client/ConnectionState.js +0 -16
  17. package/dist/client/client.js +0 -187
  18. package/dist/client/context.js +0 -152
  19. package/dist/client/deps.js +0 -5
  20. package/dist/client/handlers/handleConnack.js +0 -24
  21. package/dist/client/handlers/handlePacket.js +0 -57
  22. package/dist/client/handlers/handlePuback.js +0 -13
  23. package/dist/client/handlers/handlePubcomp.js +0 -16
  24. package/dist/client/handlers/handlePublish.js +0 -33
  25. package/dist/client/handlers/handlePubrec.js +0 -26
  26. package/dist/client/handlers/handlePubrel.js +0 -31
  27. package/dist/client/handlers/handleSuback.js +0 -14
  28. package/dist/client/handlers/handleUnsuback.js +0 -15
  29. package/dist/client/mod.js +0 -5
  30. package/dist/client/store/deps.js +0 -1
  31. package/dist/client/store/memoryStore.js +0 -58
  32. package/dist/client/store/store.js +0 -4
  33. package/dist/mqttConn/mqttConn.js +0 -104
  34. package/dist/mqttPacket/AuthenticationResult.js +0 -16
  35. package/dist/mqttPacket/BitMask.js +0 -10
  36. package/dist/mqttPacket/PacketType.js +0 -18
  37. package/dist/mqttPacket/connack.js +0 -27
  38. package/dist/mqttPacket/connect.js +0 -115
  39. package/dist/mqttPacket/decoder.js +0 -89
  40. package/dist/mqttPacket/disconnect.js +0 -14
  41. package/dist/mqttPacket/encoder.js +0 -56
  42. package/dist/mqttPacket/length.js +0 -43
  43. package/dist/mqttPacket/mod.js +0 -76
  44. package/dist/mqttPacket/pingreq.js +0 -15
  45. package/dist/mqttPacket/pingres.js +0 -14
  46. package/dist/mqttPacket/puback.js +0 -20
  47. package/dist/mqttPacket/pubcomp.js +0 -20
  48. package/dist/mqttPacket/publish.js +0 -51
  49. package/dist/mqttPacket/pubrec.js +0 -20
  50. package/dist/mqttPacket/pubrel.js +0 -20
  51. package/dist/mqttPacket/suback.js +0 -29
  52. package/dist/mqttPacket/subscribe.js +0 -52
  53. package/dist/mqttPacket/types.js +0 -1
  54. package/dist/mqttPacket/unsuback.js +0 -20
  55. package/dist/mqttPacket/unsubscribe.js +0 -36
  56. package/dist/mqttPacket/validators.js +0 -15
  57. package/dist/node/tcpClient.js +0 -81
  58. package/dist/node/tcpServer.js +0 -50
  59. package/dist/node/wrapNodeSocket.js +0 -56
  60. package/dist/persistence/deps.js +0 -3
  61. package/dist/persistence/memory/memoryPersistence.js +0 -118
  62. package/dist/persistence/persistence.js +0 -1
  63. package/dist/persistence/store.js +0 -1
  64. package/dist/server/context.js +0 -100
  65. package/dist/server/deps.js +0 -5
  66. package/dist/server/handlers/handleConnect.js +0 -80
  67. package/dist/server/handlers/handleDisconnect.js +0 -9
  68. package/dist/server/handlers/handlePacket.js +0 -65
  69. package/dist/server/handlers/handlePingreq.js +0 -11
  70. package/dist/server/handlers/handlePuback.js +0 -16
  71. package/dist/server/handlers/handlePubcomp.js +0 -14
  72. package/dist/server/handlers/handlePublish.js +0 -54
  73. package/dist/server/handlers/handlePubrec.js +0 -23
  74. package/dist/server/handlers/handlePubrel.js +0 -27
  75. package/dist/server/handlers/handleSubscribe.js +0 -56
  76. package/dist/server/handlers/handleUnsubscribe.js +0 -18
  77. package/dist/server/mod.js +0 -7
  78. package/dist/server/server.js +0 -47
  79. package/dist/socket/socket.js +0 -36
  80. package/dist/timer/timer.js +0 -40
  81. package/dist/trie/trie.js +0 -95
  82. package/dist/tsconfig.tsbuildinfo +0 -1
  83. package/dist/utils/args.js +0 -75
  84. package/dist/utils/assert.js +0 -20
  85. package/dist/utils/asyncQueue.js +0 -69
  86. package/dist/utils/deferred.js +0 -14
  87. package/dist/utils/logger.js +0 -58
  88. package/dist/utils/mod.js +0 -11
  89. package/dist/utils/nextTick.js +0 -18
  90. package/dist/utils/platform.js +0 -7
  91. package/tsconfig.json +0 -22
@@ -1,13 +0,0 @@
1
- /**
2
- * Handles PUBACK packet processing for QoS level 1 PUBLISH responses
3
- * @param ctx - The MQTT client context
4
- * @param packet - The PUBACK packet received from the broker
5
- * @description
6
- * - Removes the packet ID from the list of pending outgoing messages
7
- * - Completes the corresponding publish operation
8
- */
9
- export function handlePuback(ctx, packet) {
10
- const id = packet.id;
11
- ctx.store.pendingOutgoing.delete(id);
12
- ctx.receivePuback(id);
13
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Handles PUBCOMP packets which are the response to PUBREL packets in QoS 2 flow
3
- * @param ctx - The connection context containing the client state and store
4
- * @param packet - The PUBCOMP packet received from the broker
5
- * @description
6
- * This function processes PUBCOMP packets which are the fourth and final packet
7
- * in the QoS 2 protocol exchange. It removes the message from pendingAckOutgoing queue
8
- * Completes the corresponding publish operation
9
- */
10
- export function handlePubcomp(ctx, packet) {
11
- const id = packet.id;
12
- if (ctx.store.pendingAckOutgoing.has(id)) {
13
- ctx.store.pendingAckOutgoing.delete(id);
14
- ctx.receivePubcomp(id);
15
- }
16
- }
@@ -1,33 +0,0 @@
1
- import { PacketType } from "../deps.js";
2
- /**
3
- * Handles incoming MQTT publish packets based on their QoS level
4
- * @param ctx - The MQTT connection context
5
- * @param packet - The incoming publish packet to handle
6
- * @returns Promise that resolves when packet is handled
7
- */
8
- export async function handlePublish(ctx, packet) {
9
- const qos = packet.qos || 0;
10
- if (qos === 0) {
11
- ctx.receivePublish(packet);
12
- return;
13
- }
14
- if (packet.id !== undefined) {
15
- // qos 1
16
- if (qos === 1) {
17
- ctx.receivePublish(packet);
18
- await ctx.send({
19
- type: PacketType.puback,
20
- id: packet.id,
21
- });
22
- return;
23
- }
24
- // qos 2
25
- if (ctx.store) {
26
- ctx.store.pendingIncoming.set(packet.id, packet);
27
- await ctx.send({
28
- type: PacketType.pubrec,
29
- id: packet.id,
30
- });
31
- }
32
- }
33
- }
@@ -1,26 +0,0 @@
1
- import { PacketType } from "../deps.js";
2
- /**
3
- * Handles PUBREC (Publish Received) packets for QoS 2 message flow
4
- * It is the second packet of the QoS 2 protocol exchange.
5
- * @param ctx - The connection context containing message stores and send function
6
- * @param packet - The received PUBREC packet
7
- * @description
8
- * When a PUBREC packet is received:
9
- * 1. Checks if there is a pending outgoing message with matching packet ID
10
- * 2. Creates a PUBREL packet to acknowledge the PUBREC
11
- * 3. Add the packet ID to pendingAckOutgoing store
12
- * 4. Removes the message from pendingOutgoing store
13
- * 5. Sends the PUBREL packet
14
- */
15
- export async function handlePubrec(ctx, packet) {
16
- const id = packet.id;
17
- const ack = {
18
- type: PacketType.pubrel,
19
- id,
20
- };
21
- if (ctx.store.pendingOutgoing.has(id)) {
22
- ctx.store.pendingAckOutgoing.set(id, ack);
23
- ctx.store.pendingOutgoing.delete(id);
24
- await ctx.send(ack);
25
- }
26
- }
@@ -1,31 +0,0 @@
1
- import { PacketType } from "../deps.js";
2
- /**
3
- * Handles a PUBREL packet in the MQTT QoS 2 flow
4
- * It is the third packet of the QoS 2 protocol exchange
5
- * and a response to the PUBREC packet
6
- *
7
- * It uses Method A from the MQTT specification
8
- * @param ctx - The MQTT client context
9
- * @param packet - The PUBREL packet received
10
- * @description
11
- * When a PUBREL packet is received:
12
- * 1. If there is a matching pending incoming message:
13
- * - Delivers the stored message to the application
14
- * - Removes the message from pending incoming store
15
- * - Sends PUBCOMP packet as acknowledgement
16
- * 2. If no matching message found, silently ignores
17
- */
18
- export async function handlePubrel(ctx, packet) {
19
- const id = packet.id;
20
- if (ctx.store.pendingIncoming.has(id)) {
21
- const storedPacket = ctx.store.pendingIncoming.get(id);
22
- if (storedPacket) {
23
- ctx.receivePublish(storedPacket);
24
- ctx.store.pendingIncoming.delete(id);
25
- await ctx.send({
26
- type: PacketType.pubcomp,
27
- id,
28
- });
29
- }
30
- }
31
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Handles SUBACK packets received from the server
3
- * @param ctx - The MQTT client context
4
- * @param packet - The SUBACK packet containing subscription confirmations
5
- * @description
6
- * - Processes SUBACK packets sent by server to confirm SUBSCRIBE requests
7
- * - Removes the packet ID from pending outgoing messages
8
- * - Notifies the client about granted QoS levels for each subscription
9
- */
10
- export function handleSuback(ctx, packet) {
11
- const id = packet.id;
12
- ctx.store.pendingOutgoing.delete(id);
13
- ctx.receiveSuback(id, packet.returnCodes);
14
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * Handles the UNSUBACK packet received from the server
3
- * @param ctx - The MQTT client context
4
- * @param packet - The UNSUBACK packet received from the server
5
- * @description
6
- * The UNSUBACK Packet is sent by the Server to the Client to confirm receipt of
7
- * an UNSUBSCRIBE Packet.
8
- * When received, it removes the pending outgoing request and completes the corresponding
9
- * unsubscribe operation.
10
- */
11
- export function handleUnsuback(ctx, packet) {
12
- const id = packet.id;
13
- ctx.store.pendingOutgoing.delete(id);
14
- ctx.receiveUnsuback(id);
15
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * This module provides an MQTT Client interface see the /bin folder for examples
3
- * @module
4
- */
5
- export { Client, DEFAULT_URL } from "./client.js";
@@ -1 +0,0 @@
1
- export { assert } from "../../utils/mod.js";
@@ -1,58 +0,0 @@
1
- /**
2
- * @module memoryStore
3
- */
4
- import { assert } from "./deps.js";
5
- import { maxPacketId, } from "./store.js";
6
- /**
7
- * In-memory implementation of the IStore interface for managing MQTT packet storage
8
- */
9
- export class MemoryStore {
10
- /** Current packet ID counter */
11
- packetId;
12
- /** Map of pending incoming packets */
13
- pendingIncoming;
14
- /** Map of pending outgoing packets */
15
- pendingOutgoing;
16
- /** Map of pending acknowledgment outgoing packets */
17
- pendingAckOutgoing;
18
- /**
19
- * Creates a new MemoryStore instance
20
- */
21
- constructor() {
22
- this.packetId = 0;
23
- this.pendingIncoming = new Map();
24
- this.pendingOutgoing = new Map();
25
- this.pendingAckOutgoing = new Map();
26
- }
27
- /**
28
- * Generates the next available packet ID
29
- * @returns {PacketId} The next available packet ID
30
- * @throws {Error} If no unused packet ID is available
31
- */
32
- nextId() {
33
- const currentId = this.packetId;
34
- do {
35
- this.packetId++;
36
- if (this.packetId > maxPacketId) {
37
- this.packetId = 1;
38
- }
39
- } while ((this.pendingIncoming.has(this.packetId) ||
40
- this.pendingOutgoing.has(this.packetId) ||
41
- this.pendingAckOutgoing.has(this.packetId)) &&
42
- this.packetId !== currentId);
43
- assert(this.packetId !== currentId, "No unused packetId available");
44
- return this.packetId;
45
- }
46
- /**
47
- * Asynchronously yields all pending outgoing packets
48
- * @yields {PendingOutgoingPackets} Pending outgoing packets
49
- */
50
- async *pendingOutgoingPackets() {
51
- for (const [_id, packet] of this.pendingAckOutgoing) {
52
- yield packet;
53
- }
54
- for (const [_id, packet] of this.pendingOutgoing) {
55
- yield packet;
56
- }
57
- }
58
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * Maximum value for MQTT packet IDs (65535)
3
- */
4
- export const maxPacketId = 0xffff;
@@ -1,104 +0,0 @@
1
- import { decodePayload, encode, getLengthDecoder, } from "../mqttPacket/mod.js";
2
- import { assert } from "../utils/mod.js";
3
- import { Conn } from "../socket/socket.js";
4
- export const MqttConnError = {
5
- invalidPacket: "Invalid Packet",
6
- packetTooLarge: "Packet too large",
7
- UnexpectedEof: "Unexpected EOF",
8
- };
9
- async function readByte(conn) {
10
- const buf = new Uint8Array(1);
11
- const bytesRead = await conn.read(buf);
12
- assert(bytesRead !== null, MqttConnError.UnexpectedEof);
13
- assert(bytesRead !== 0, MqttConnError.UnexpectedEof);
14
- return buf[0];
15
- }
16
- async function readFull(conn, buf) {
17
- let bytesRead = 0;
18
- while (bytesRead < buf.length) {
19
- const read = await conn.read(buf.subarray(bytesRead));
20
- assert(read !== null, MqttConnError.UnexpectedEof);
21
- assert(read !== 0, MqttConnError.UnexpectedEof);
22
- bytesRead += read;
23
- }
24
- }
25
- /** Read MQTT packet
26
- * @throws `Error` if packet is invalid
27
- */
28
- export async function readPacket(conn, maxPacketSize) {
29
- // fixed header is 1 byte of type + flags
30
- // + a maximum of 4 bytes to encode the remaining length
31
- const decodeLength = getLengthDecoder();
32
- const firstByte = await readByte(conn);
33
- let result;
34
- do {
35
- const byte = await readByte(conn);
36
- result = decodeLength(byte);
37
- } while (!result.done);
38
- const remainingLength = result.length;
39
- assert(remainingLength < maxPacketSize - 1, MqttConnError.packetTooLarge);
40
- const packetBuf = new Uint8Array(remainingLength);
41
- // read the rest of the packet
42
- await readFull(conn, packetBuf);
43
- const packet = decodePayload(firstByte, packetBuf);
44
- assert(packet !== null, MqttConnError.UnexpectedEof);
45
- return packet;
46
- }
47
- export class MqttConn {
48
- conn;
49
- maxPacketSize;
50
- _reason = undefined;
51
- _isClosed = false;
52
- constructor({ conn, maxPacketSize, }) {
53
- this.conn = new Conn(conn);
54
- this.maxPacketSize = maxPacketSize || 2 * 1024 * 1024;
55
- }
56
- get reason() {
57
- return this._reason;
58
- }
59
- async *[Symbol.asyncIterator]() {
60
- while (!this._isClosed) {
61
- try {
62
- yield await readPacket(this.conn, this.maxPacketSize);
63
- }
64
- catch (err) {
65
- if (err instanceof Error) {
66
- if (err.name === "PartialReadError") {
67
- err.message = MqttConnError.UnexpectedEof;
68
- }
69
- this._reason = err.message;
70
- }
71
- // packet too large, malformed packet or connection closed
72
- this.close();
73
- break;
74
- }
75
- }
76
- }
77
- async send(data) {
78
- try {
79
- await this.conn.write(encode(data));
80
- }
81
- catch (err) {
82
- if (err instanceof Error) {
83
- this._reason = err.message;
84
- }
85
- this.close();
86
- }
87
- }
88
- get isClosed() {
89
- return this._isClosed;
90
- }
91
- close() {
92
- if (this.isClosed)
93
- return;
94
- try {
95
- this.conn.close();
96
- }
97
- catch (e) {
98
- console.error(e);
99
- }
100
- finally {
101
- this._isClosed = true;
102
- }
103
- }
104
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Possible MQTT authentication results
3
- */
4
- export const AuthenticationResult = {
5
- ok: 0,
6
- unacceptableProtocol: 1,
7
- rejectedUsername: 2,
8
- serverUnavailable: 3,
9
- badUsernameOrPassword: 4,
10
- notAuthorized: 5,
11
- };
12
- /**
13
- * Reverse lookup for AuthenticationResult
14
- */
15
- export const AuthenticationResultByNumber = Object
16
- .fromEntries(Object.entries(AuthenticationResult).map(([k, v]) => [v, k]));
@@ -1,10 +0,0 @@
1
- export const BitMask = {
2
- bit0: 2 ** 0,
3
- bit1: 2 ** 1,
4
- bit2: 2 ** 2,
5
- bit3: 2 ** 3,
6
- bit4: 2 ** 4,
7
- bit5: 2 ** 5,
8
- bit6: 2 ** 6,
9
- bit7: 2 ** 7,
10
- };
@@ -1,18 +0,0 @@
1
- export const PacketType = {
2
- reserved: 0,
3
- connect: 1,
4
- connack: 2,
5
- publish: 3,
6
- puback: 4,
7
- pubrec: 5,
8
- pubrel: 6,
9
- pubcomp: 7,
10
- subscribe: 8,
11
- suback: 9,
12
- unsubscribe: 10,
13
- unsuback: 11,
14
- pingreq: 12,
15
- pingres: 13,
16
- disconnect: 14,
17
- };
18
- export const PacketNameByType = Object.fromEntries(Object.entries(PacketType).map(([k, v]) => [v, k]));
@@ -1,27 +0,0 @@
1
- import { PacketType } from "./PacketType.js";
2
- import { BitMask } from "./BitMask.js";
3
- import { booleanFlag, Decoder, DecoderError } from "./decoder.js";
4
- import { AuthenticationResultByNumber } from "./AuthenticationResult.js";
5
- export const connack = {
6
- encode(packet) {
7
- const flags = 0;
8
- return {
9
- flags,
10
- bytes: [packet.sessionPresent ? 1 : 0, packet.returnCode || 0],
11
- };
12
- },
13
- decode(buffer, _flags) {
14
- const decoder = new Decoder(buffer);
15
- const sessionPresent = booleanFlag(decoder.getByte(), BitMask.bit0);
16
- const returnCode = decoder.getByte();
17
- decoder.done();
18
- if (!AuthenticationResultByNumber[returnCode]) {
19
- throw new DecoderError("Invalid return code");
20
- }
21
- return {
22
- type: PacketType.connack,
23
- sessionPresent,
24
- returnCode,
25
- };
26
- },
27
- };
@@ -1,115 +0,0 @@
1
- import { PacketType } from "./PacketType.js";
2
- import { BitMask } from "./BitMask.js";
3
- import { Encoder } from "./encoder.js";
4
- import { booleanFlag, Decoder, DecoderError, hasEmptyFlags, } from "./decoder.js";
5
- function invalidProtocolName(version, name) {
6
- if (version === 4 && name !== "MQTT") {
7
- return true;
8
- }
9
- return false;
10
- }
11
- export const connect = {
12
- encode(packet) {
13
- const flags = 0;
14
- const protocolLevel = 4;
15
- const protocolName = protocolLevel === 4 ? "MQTT" : "MQIsdp";
16
- const clientId = packet.clientId || "";
17
- const usernameFlag = !!packet.username;
18
- const passwordFlag = !!packet.password;
19
- const willRetain = !!packet.will?.retain;
20
- const willQoS = packet.will?.qos || 0;
21
- const willFlag = !!packet.will;
22
- const cleanSession = packet.clean !== false;
23
- const connectFlags = (usernameFlag ? BitMask.bit7 : 0) +
24
- (passwordFlag ? BitMask.bit6 : 0) +
25
- (willRetain ? BitMask.bit5 : 0) +
26
- (willQoS & 2 ? BitMask.bit4 : 0) +
27
- (willQoS & 1 ? BitMask.bit3 : 0) +
28
- (willFlag ? BitMask.bit2 : 0) +
29
- (cleanSession ? BitMask.bit1 : 0);
30
- const keepAlive = packet.keepAlive || 0;
31
- const encoder = new Encoder();
32
- encoder
33
- .setUtf8String(protocolName)
34
- .setByte(protocolLevel)
35
- .setByte(connectFlags)
36
- .setInt16(keepAlive)
37
- .setUtf8String(clientId);
38
- if (packet.will) {
39
- encoder.setTopic(packet.will.topic).setByteArray(packet.will.payload);
40
- }
41
- if (packet.username) {
42
- encoder.setUtf8String(packet.username);
43
- }
44
- if (packet.password) {
45
- encoder.setByteArray(packet.password);
46
- }
47
- return { flags, bytes: encoder.done() };
48
- },
49
- decode(buffer, flags) {
50
- const decoder = new Decoder(buffer);
51
- const protocolName = decoder.getUtf8String();
52
- const protocolLevel = decoder.getByte();
53
- if (invalidProtocolName(protocolLevel, protocolName)) {
54
- throw new DecoderError("Invalid protocol name");
55
- }
56
- const connectFlags = decoder.getByte();
57
- const usernameFlag = booleanFlag(connectFlags, BitMask.bit7);
58
- const passwordFlag = booleanFlag(connectFlags, BitMask.bit6);
59
- const willRetain = booleanFlag(connectFlags, BitMask.bit5);
60
- const willQoS = (connectFlags & (BitMask.bit4 + BitMask.bit3)) >> 3;
61
- const willFlag = booleanFlag(connectFlags, BitMask.bit2);
62
- const cleanSession = booleanFlag(connectFlags, BitMask.bit1);
63
- const reservedBit = booleanFlag(connectFlags, BitMask.bit0);
64
- hasEmptyFlags(flags);
65
- // The Server MUST validate that the reserved flag in the CONNECT Control Packet
66
- // is set to zero and disconnect the Client if it is not zero [MQTT-3.1.2-3].
67
- if (reservedBit) {
68
- throw new DecoderError("Invalid reserved bit");
69
- }
70
- if (willQoS !== 0 && willQoS !== 1 && willQoS !== 2) {
71
- throw new DecoderError("Invalid will qos");
72
- }
73
- const keepAlive = decoder.getInt16();
74
- const clientId = decoder.getUtf8String();
75
- let willTopic;
76
- let willPayload;
77
- if (willFlag) {
78
- willTopic = decoder.getTopic();
79
- willPayload = decoder.getByteArray();
80
- }
81
- let username;
82
- let password;
83
- if (usernameFlag) {
84
- username = decoder.getUtf8String();
85
- }
86
- if (passwordFlag) {
87
- password = decoder.getByteArray();
88
- }
89
- decoder.done();
90
- if (!willFlag && (willQoS !== 0 || willRetain === true)) {
91
- throw new DecoderError("Will QoS must be 0 and Will retain to false when Will flag is false");
92
- }
93
- if (clientId.length === 0 && cleanSession === false) {
94
- throw new DecoderError("Clean session must be true if clientID is empty");
95
- }
96
- return {
97
- type: PacketType.connect,
98
- protocolName: protocolName,
99
- protocolLevel,
100
- clientId: clientId,
101
- username: username ? username : undefined,
102
- password: password ? password : undefined,
103
- will: willFlag
104
- ? {
105
- topic: willTopic || "",
106
- payload: willPayload || Uint8Array.from([0]),
107
- retain: willRetain,
108
- qos: willQoS,
109
- }
110
- : undefined,
111
- clean: cleanSession,
112
- keepAlive,
113
- };
114
- },
115
- };
@@ -1,89 +0,0 @@
1
- import { invalidTopic, invalidTopicFilter } from "./validators.js";
2
- const utf8Decoder = new TextDecoder("utf-8");
3
- export function booleanFlag(byte, mask) {
4
- return !!(byte & mask);
5
- }
6
- export function isEmptyBuf(buf) {
7
- if (buf.length > 0) {
8
- throw new DecoderError("Packet too long");
9
- }
10
- }
11
- export function hasEmptyFlags(flags) {
12
- if (flags !== 0) {
13
- throw new DecoderError("Invalid fixed header flags");
14
- }
15
- }
16
- export class DecoderError extends Error {
17
- constructor(message) {
18
- super(message);
19
- this.name = "DecoderError";
20
- }
21
- }
22
- export class Decoder {
23
- buf;
24
- pos;
25
- len;
26
- constructor(buf, pos = 0) {
27
- this.buf = buf;
28
- this.pos = pos;
29
- this.len = buf.length;
30
- }
31
- checkpos(pos) {
32
- if (pos > this.len) {
33
- throw new DecoderError("Packet too short");
34
- }
35
- }
36
- getByte() {
37
- this.checkpos(this.pos);
38
- return this.buf[this.pos++];
39
- }
40
- getInt16() {
41
- const msb = this.getByte();
42
- const lsb = this.getByte();
43
- return (msb << 8) | lsb;
44
- }
45
- getByteArray() {
46
- const len = this.getInt16();
47
- const start = this.pos;
48
- const end = this.pos + len;
49
- this.pos = end;
50
- this.checkpos(end);
51
- return this.buf.subarray(start, end);
52
- }
53
- getUtf8String() {
54
- const str = utf8Decoder.decode(this.getByteArray());
55
- return str;
56
- }
57
- getTopic() {
58
- const topic = this.getUtf8String();
59
- if (invalidTopic(topic)) {
60
- throw new DecoderError("Topic must contain valid UTF-8 and contain more than 1 byte and no wildcards");
61
- }
62
- return topic;
63
- }
64
- getTopicFilter() {
65
- const topicFilter = this.getUtf8String();
66
- if (invalidTopicFilter(topicFilter)) {
67
- throw new DecoderError("Topicfilter must contain valid UTF-8 and contain more than 1 byte and valid wildcards");
68
- }
69
- return topicFilter;
70
- }
71
- getRemainder() {
72
- const start = this.pos;
73
- const end = this.len;
74
- this.pos = end;
75
- return this.buf.subarray(start, end);
76
- }
77
- atEnd() {
78
- if (this.len === this.pos) {
79
- return true;
80
- }
81
- return false;
82
- }
83
- done() {
84
- if (this.atEnd()) {
85
- return true;
86
- }
87
- throw new DecoderError("Packet too long");
88
- }
89
- }
@@ -1,14 +0,0 @@
1
- import { PacketType } from "./PacketType.js";
2
- import { isEmptyBuf } from "./decoder.js";
3
- export const disconnect = {
4
- encode(_packet) {
5
- const flags = 0;
6
- return { flags, bytes: [] };
7
- },
8
- decode(buffer, _flags) {
9
- isEmptyBuf(buffer);
10
- return {
11
- type: PacketType.disconnect,
12
- };
13
- },
14
- };