iobroker.zigbee2mqtt 2.1.1 → 2.2.1

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.
@@ -1,80 +1,80 @@
1
1
  class Z2mController {
2
- constructor(adapter, deviceCache, groupCache, logCustomizations) {
3
- this.adapter = adapter;
4
- this.groupCache = groupCache;
5
- this.deviceCache = deviceCache;
6
- this.logCustomizations = logCustomizations;
7
- }
2
+ constructor(adapter, deviceCache, groupCache, logCustomizations) {
3
+ this.adapter = adapter;
4
+ this.groupCache = groupCache;
5
+ this.deviceCache = deviceCache;
6
+ this.logCustomizations = logCustomizations;
7
+ }
8
8
 
9
- async createZ2MMessage(id, state) {
10
- const splitedID = id.split('.');
11
- if (splitedID.length < 4) {
12
- this.adapter.log.warn(`state ${id} not valid`);
13
- return;
14
- }
9
+ async createZ2MMessage(id, state) {
10
+ const splitedID = id.split('.');
11
+ if (splitedID.length < 4) {
12
+ this.adapter.log.warn(`state ${id} not valid`);
13
+ return;
14
+ }
15
15
 
16
- const ieee_address = splitedID[2];
17
- const stateName = splitedID[3];
16
+ const ieee_address = splitedID[2];
17
+ const stateName = splitedID[3];
18
18
 
19
- const device = this.groupCache.concat(this.deviceCache).find(d => d.ieee_address == ieee_address);
20
- if (!device) {
21
- return;
22
- }
19
+ const device = this.groupCache.concat(this.deviceCache).find(d => d.ieee_address == ieee_address);
20
+ if (!device) {
21
+ return;
22
+ }
23
23
 
24
- const deviceState = device.states.find(s => s.id == stateName);
25
- if (!deviceState) {
26
- return;
27
- }
24
+ const deviceState = device.states.find(s => s.id == stateName);
25
+ if (!deviceState) {
26
+ return;
27
+ }
28
28
 
29
- let stateVal = state.val;
30
- if (deviceState.setter) {
31
- stateVal = deviceState.setter(state.val);
32
- }
29
+ let stateVal = state.val;
30
+ if (deviceState.setter) {
31
+ stateVal = deviceState.setter(state.val);
32
+ }
33
33
 
34
- let stateID = deviceState.id;
35
- if (deviceState.prop) {
36
- stateID = deviceState.prop;
37
- }
34
+ let stateID = deviceState.id;
35
+ if (deviceState.prop) {
36
+ stateID = deviceState.prop;
37
+ }
38
38
 
39
- let topic = `${device.ieee_address}/set`;
40
- if (device.ieee_address.includes('group_')) {
41
- topic = `${device.id}/set`;
42
- }
39
+ const controlObj = {
40
+ payload: {
41
+ [stateID]: stateVal
42
+ },
43
+ topic: `${device.id}/set`
44
+ };
43
45
 
44
- const controlObj = {
45
- payload: {
46
- [stateID]: stateVal
47
- },
48
- topic: topic
49
- };
50
- // set stats with the mentioned role or ids always immediately to ack = true, because these are not reported back by Zigbee2MQTT
51
- if (['button'].includes(deviceState.role) || ['brightness_move', 'color_temp_move'].includes(stateID)) {
52
- this.adapter.setState(id, state, true);
53
- }
46
+ // set stats with the mentioned role or ids always immediately to ack = true, because these are not reported back by Zigbee2MQTT
47
+ if (['button'].includes(deviceState.role) || ['brightness_move', 'color_temp_move'].includes(stateID)) {
48
+ this.adapter.setState(id, state, true);
49
+ }
54
50
 
55
- return controlObj;
56
- }
51
+ if (this.logCustomizations.debugDevices.includes(device.ieee_address)) {
52
+ this.adapter.log.warn(`<<<--- toZ2M -> ${device.ieee_address} states: ${JSON.stringify(controlObj)}`);
53
+ }
57
54
 
58
- async proxyZ2MLogs(messageObj) {
59
- const logMessage = messageObj.payload.message;
60
- if (this.logCustomizations.logfilter.some(x => logMessage.includes(x))) {
61
- return;
62
- }
55
+ return controlObj;
56
+ }
63
57
 
64
- const logLevel = messageObj.payload.level;
65
- switch (logLevel) {
66
- case 'debug':
67
- case 'info':
68
- case 'error':
69
- this.adapter.log[logLevel](logMessage);
70
- break;
71
- case 'warning':
72
- this.adapter.log.warn(logMessage);
73
- break;
74
- }
75
- }
58
+ async proxyZ2MLogs(messageObj) {
59
+ const logMessage = messageObj.payload.message;
60
+ if (this.logCustomizations.logfilter.some(x => logMessage.includes(x))) {
61
+ return;
62
+ }
63
+
64
+ const logLevel = messageObj.payload.level;
65
+ switch (logLevel) {
66
+ case 'debug':
67
+ case 'info':
68
+ case 'error':
69
+ this.adapter.log[logLevel](logMessage);
70
+ break;
71
+ case 'warning':
72
+ this.adapter.log.warn(logMessage);
73
+ break;
74
+ }
75
+ }
76
76
  }
77
77
 
78
78
  module.exports = {
79
- Z2mController: Z2mController
79
+ Z2mController: Z2mController
80
80
  };
package/main.js CHANGED
@@ -23,6 +23,7 @@ let mqttClient;
23
23
  let deviceCache = [];
24
24
  // eslint-disable-next-line prefer-const
25
25
  let groupCache = [];
26
+ const createCache = {};
26
27
  const logCustomizations = { debugDevices: '', logfilter: [] };
27
28
  let showInfo = true;
28
29
  let statesController;
@@ -33,233 +34,233 @@ let mqttServerController;
33
34
 
34
35
  class Zigbee2mqtt extends core.Adapter {
35
36
 
36
- constructor(options) {
37
- super({
38
- ...options,
39
- name: 'zigbee2mqtt',
40
- });
41
- this.on('ready', this.onReady.bind(this));
42
- this.on('stateChange', this.onStateChange.bind(this));
43
- this.on('unload', this.onUnload.bind(this));
44
- }
37
+ constructor(options) {
38
+ super({
39
+ ...options,
40
+ name: 'zigbee2mqtt',
41
+ });
42
+ this.on('ready', this.onReady.bind(this));
43
+ this.on('stateChange', this.onStateChange.bind(this));
44
+ this.on('unload', this.onUnload.bind(this));
45
+ }
45
46
 
46
- async onReady() {
47
- statesController = new StatesController(this, deviceCache, groupCache, logCustomizations);
48
- deviceController = new DeviceController(this, deviceCache, groupCache, this.config);
49
- z2mController = new Z2mController(this, deviceCache, groupCache, logCustomizations);
47
+ async onReady() {
48
+ statesController = new StatesController(this, deviceCache, groupCache, logCustomizations, createCache);
49
+ deviceController = new DeviceController(this, deviceCache, groupCache, this.config, createCache);
50
+ z2mController = new Z2mController(this, deviceCache, groupCache, logCustomizations);
50
51
 
51
- // Initialize your adapter here
52
- adapterInfo(this.config, this.log);
52
+ // Initialize your adapter here
53
+ adapterInfo(this.config, this.log);
53
54
 
54
- this.setStateAsync('info.connection', false, true);
55
+ this.setStateAsync('info.connection', false, true);
55
56
 
56
- const debugDevicesState = await this.getStateAsync('info.debugmessages');
57
- if (debugDevicesState && debugDevicesState.val) {
58
- logCustomizations.debugDevices = String(debugDevicesState.val);
59
- }
57
+ const debugDevicesState = await this.getStateAsync('info.debugmessages');
58
+ if (debugDevicesState && debugDevicesState.val) {
59
+ logCustomizations.debugDevices = String(debugDevicesState.val);
60
+ }
60
61
 
61
- const logfilterState = await this.getStateAsync('info.logfilter');
62
- if (logfilterState && logfilterState.val) {
63
- // @ts-ignore
64
- logCustomizations.logfilter = String(logfilterState.val).split(';').filter(x => x); // filter removes empty strings here
65
- }
66
- // MQTT
67
- if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
68
- // External MQTT-Server
69
- if (this.config.connectionType == 'exmqtt') {
70
- if (this.config.externalMqttServerIP == '') {
71
- this.log.warn('Please configure the External MQTT-Server connection!');
72
- return;
73
- }
74
- mqttClient = mqtt.connect(`mqtt://${this.config.externalMqttServerIP}:${this.config.externalMqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
62
+ const logfilterState = await this.getStateAsync('info.logfilter');
63
+ if (logfilterState && logfilterState.val) {
64
+ // @ts-ignore
65
+ logCustomizations.logfilter = String(logfilterState.val).split(';').filter(x => x); // filter removes empty strings here
66
+ }
67
+ // MQTT
68
+ if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
69
+ // External MQTT-Server
70
+ if (this.config.connectionType == 'exmqtt') {
71
+ if (this.config.externalMqttServerIP == '') {
72
+ this.log.warn('Please configure the External MQTT-Server connection!');
73
+ return;
74
+ }
75
+ mqttClient = mqtt.connect(`mqtt://${this.config.externalMqttServerIP}:${this.config.externalMqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
75
76
 
76
- }
77
- // Internal MQTT-Server
78
- else {
79
- mqttServerController = new MqttServerController(this);
80
- await mqttServerController.createMQTTServer();
81
- await this.delay(1500);
82
- mqttClient = mqtt.connect(`mqtt://${this.config.mqttServerIPBind}:${this.config.mqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
83
- }
77
+ }
78
+ // Internal MQTT-Server
79
+ else {
80
+ mqttServerController = new MqttServerController(this);
81
+ await mqttServerController.createMQTTServer();
82
+ await this.delay(1500);
83
+ mqttClient = mqtt.connect(`mqtt://${this.config.mqttServerIPBind}:${this.config.mqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
84
+ }
84
85
 
85
- // MQTT Client
86
- mqttClient.on('connect', () => {
87
- this.log.info(`Connect to Zigbee2MQTT over ${this.config.connectionType == 'exmqtt' ? 'external mqtt' : 'internal mqtt'} connection.`);
88
- });
86
+ // MQTT Client
87
+ mqttClient.on('connect', () => {
88
+ this.log.info(`Connect to Zigbee2MQTT over ${this.config.connectionType == 'exmqtt' ? 'external mqtt' : 'internal mqtt'} connection.`);
89
+ });
89
90
 
90
- mqttClient.subscribe('zigbee2mqtt/#');
91
+ mqttClient.subscribe('zigbee2mqtt/#');
91
92
 
92
- mqttClient.on('message', (topic, payload) => {
93
- const newMessage = `{"payload":${payload.toString() == '' ? '"null"' : payload.toString()},"topic":"${topic.slice(topic.search('/') + 1)}"}`;
94
- this.messageParse(newMessage);
95
- });
96
- }
97
- // Websocket
98
- else if (this.config.connectionType == 'ws') {
99
- if (this.config.wsServerIP == '') {
100
- this.log.warn('Please configure the Websoket connection!');
101
- return;
102
- }
93
+ mqttClient.on('message', (topic, payload) => {
94
+ const newMessage = `{"payload":${payload.toString() == '' ? '"null"' : payload.toString()},"topic":"${topic.slice(topic.search('/') + 1)}"}`;
95
+ this.messageParse(newMessage);
96
+ });
97
+ }
98
+ // Websocket
99
+ else if (this.config.connectionType == 'ws') {
100
+ if (this.config.wsServerIP == '') {
101
+ this.log.warn('Please configure the Websoket connection!');
102
+ return;
103
+ }
103
104
 
104
- // Dummy MQTT-Server
105
- if (this.config.dummyMqtt == true) {
106
- mqttServerController = new MqttServerController(this);
107
- await mqttServerController.createDummyMQTTServer();
108
- await this.delay(1500);
109
- }
105
+ // Dummy MQTT-Server
106
+ if (this.config.dummyMqtt == true) {
107
+ mqttServerController = new MqttServerController(this);
108
+ await mqttServerController.createDummyMQTTServer();
109
+ await this.delay(1500);
110
+ }
110
111
 
111
- this.startWebsocket();
112
- }
113
- }
112
+ this.startWebsocket();
113
+ }
114
+ }
114
115
 
115
- startWebsocket() {
116
- websocketController = new WebsocketController(this);
117
- const wsClient = websocketController.initWsClient();
116
+ startWebsocket() {
117
+ websocketController = new WebsocketController(this);
118
+ const wsClient = websocketController.initWsClient();
118
119
 
119
- wsClient.on('open', () => {
120
- this.log.info('Connect to Zigbee2MQTT over websocket connection.');
121
- });
120
+ wsClient.on('open', () => {
121
+ this.log.info('Connect to Zigbee2MQTT over websocket connection.');
122
+ });
122
123
 
123
- wsClient.on('message', (message) => {
124
- this.messageParse(message);
125
- });
124
+ wsClient.on('message', (message) => {
125
+ this.messageParse(message);
126
+ });
126
127
 
127
- wsClient.on('close', async () => {
128
- this.setStateChangedAsync('info.connection', false, true);
129
- await statesController.setAllAvailableToFalse();
130
- this.log.warn('Websocket disconnectet');
131
- });
132
- }
128
+ wsClient.on('close', async () => {
129
+ this.setStateChangedAsync('info.connection', false, true);
130
+ await statesController.setAllAvailableToFalse();
131
+ this.log.warn('Websocket disconnectet');
132
+ });
133
+ }
133
134
 
134
- async messageParse(message) {
135
- const messageObj = JSON.parse(message);
135
+ async messageParse(message) {
136
+ const messageObj = JSON.parse(message);
136
137
 
137
- switch (messageObj.topic) {
138
- case 'bridge/config':
139
- break;
140
- case 'bridge/info':
141
- if (showInfo) {
142
- zigbee2mqttInfo(messageObj.payload, this.log);
143
- checkConfig(messageObj.payload.config, this.log);
144
- showInfo = false;
145
- }
146
- break;
147
- case 'bridge/state':
148
- if (messageObj.payload.state != 'online') {
149
- statesController.setAllAvailableToFalse();
150
- }
151
- this.setStateChangedAsync('info.connection', messageObj.payload.state == 'online', true);
152
- break;
153
- case 'bridge/devices':
154
- await deviceController.createDeviceDefinitions(messageObj.payload);
155
- await deviceController.createOrUpdateDevices();
156
- await statesController.subscribeWritableStates();
157
- statesController.processQueue();
158
- break;
159
- case 'bridge/groups':
160
- await deviceController.createGroupDefinitions(messageObj.payload);
161
- await deviceController.createOrUpdateDevices();
162
- await statesController.subscribeWritableStates();
163
- statesController.processQueue();
164
- break;
165
- case 'bridge/event':
166
- console.log(JSON.stringify(messageObj));
167
- deviceController.processRemoveEvent(messageObj);
168
- break;
169
- case 'bridge/response/device/remove':
170
- deviceController.processRemoveEvent(messageObj);
171
- break;
172
- case 'bridge/extensions':
173
- break;
174
- case 'bridge/logging':
175
- if (this.config.proxyZ2MLogs == true) {
176
- z2mController.proxyZ2MLogs(messageObj);
177
- }
178
- break;
179
- case 'bridge/response/device/rename':
180
- await deviceController.renameDeviceInCache(messageObj);
181
- await deviceController.createOrUpdateDevices();
182
- statesController.processQueue();
183
- break;
184
- case 'bridge/response/networkmap':
185
- break;
186
- case 'bridge/response/touchlink/scan':
187
- break;
188
- case 'bridge/response/touchlink/identify':
189
- break;
190
- case 'bridge/response/touchlink/factory_reset':
191
- break;
192
- default:
193
- {
194
- // {"payload":{"state":"online"},"topic":"FL.Licht.Links/availability"} ----> {"payload":{"available":true},"topic":"FL.Licht.Links"}
195
- if (messageObj.topic.endsWith('/availability')) {
196
- const topicSplit = messageObj.topic.split('/');
138
+ switch (messageObj.topic) {
139
+ case 'bridge/config':
140
+ break;
141
+ case 'bridge/info':
142
+ if (showInfo) {
143
+ zigbee2mqttInfo(messageObj.payload, this.log);
144
+ checkConfig(messageObj.payload.config, this.log);
145
+ showInfo = false;
146
+ }
147
+ break;
148
+ case 'bridge/state':
149
+ if (messageObj.payload.state != 'online') {
150
+ statesController.setAllAvailableToFalse();
151
+ }
152
+ this.setStateChangedAsync('info.connection', messageObj.payload.state == 'online', true);
153
+ break;
154
+ case 'bridge/devices':
155
+ await deviceController.createDeviceDefinitions(messageObj.payload);
156
+ await deviceController.createOrUpdateDevices();
157
+ await statesController.subscribeWritableStates();
158
+ statesController.processQueue();
159
+ break;
160
+ case 'bridge/groups':
161
+ await deviceController.createGroupDefinitions(messageObj.payload);
162
+ await deviceController.createOrUpdateDevices();
163
+ await statesController.subscribeWritableStates();
164
+ statesController.processQueue();
165
+ break;
166
+ case 'bridge/event':
167
+ deviceController.processRemoveEvent(messageObj);
168
+ break;
169
+ case 'bridge/response/device/remove':
170
+ deviceController.processRemoveEvent(messageObj);
171
+ break;
172
+ case 'bridge/extensions':
173
+ break;
174
+ case 'bridge/logging':
175
+ if (this.config.proxyZ2MLogs == true) {
176
+ z2mController.proxyZ2MLogs(messageObj);
177
+ }
178
+ break;
179
+ case 'bridge/response/device/rename':
180
+ await deviceController.renameDeviceInCache(messageObj);
181
+ await deviceController.createOrUpdateDevices();
182
+ statesController.processQueue();
183
+ break;
184
+ case 'bridge/response/networkmap':
185
+ break;
186
+ case 'bridge/response/touchlink/scan':
187
+ break;
188
+ case 'bridge/response/touchlink/identify':
189
+ break;
190
+ case 'bridge/response/touchlink/factory_reset':
191
+ break;
192
+ default:
193
+ {
194
+ // {"payload":{"state":"online"},"topic":"FL.Licht.Links/availability"} ----> {"payload":{"available":true},"topic":"FL.Licht.Links"}
195
+ if (messageObj.topic.endsWith('/availability')) {
196
+ const topicSplit = messageObj.topic.split('/');
197
197
 
198
- // If an availability message for an old device ID comes with a payload of NULL, this is the indicator that a device has been unnamed.
199
- // If this is then still available in the cache, the messages must first be cached.
200
- if (messageObj.payload == 'null') {
201
- break;
202
- }
198
+ // If an availability message for an old device ID comes with a payload of NULL, this is the indicator that a device has been unnamed.
199
+ // If this is then still available in the cache, the messages must first be cached.
200
+ if (messageObj.payload == 'null') {
201
+ break;
202
+ }
203
203
 
204
- if (topicSplit.length == 2 && messageObj.payload && messageObj.payload.state) {
205
- const newMessage = {
206
- payload: { available: messageObj.payload.state == 'online' },
207
- topic: topicSplit[0]
208
- };
209
- statesController.processDeviceMessage(newMessage);
210
- }
211
- // States
212
- } else if (!messageObj.topic.includes('/')) {
213
- statesController.processDeviceMessage(messageObj);
214
- }
215
- }
216
- break;
217
- }
218
- }
204
+ if (topicSplit.length == 2 && messageObj.payload && messageObj.payload.state) {
205
+ const newMessage = {
206
+ payload: { available: messageObj.payload.state == 'online' },
207
+ topic: topicSplit[0]
208
+ };
209
+ statesController.processDeviceMessage(newMessage);
210
+ }
211
+ // States
212
+ } else if (!messageObj.topic.includes('/')) {
213
+ statesController.processDeviceMessage(messageObj);
214
+ //console.log(JSON.stringify(messageObj));
215
+ }
216
+ }
217
+ break;
218
+ }
219
+ }
219
220
 
220
- async onUnload(callback) {
221
- try {
222
- await statesController.setAllAvailableToFalse();
223
- await websocketController.allTimerClear();
224
- await statesController.allTimerClear();
225
- callback();
226
- } catch (e) {
227
- callback();
228
- }
229
- }
221
+ async onUnload(callback) {
222
+ try {
223
+ await statesController.setAllAvailableToFalse();
224
+ await websocketController.allTimerClear();
225
+ await statesController.allTimerClear();
226
+ callback();
227
+ } catch (e) {
228
+ callback();
229
+ }
230
+ }
230
231
 
231
- async onStateChange(id, state) {
232
- if (state && state.ack == false) {
233
- if (id.includes('info.debugmessages')) {
234
- logCustomizations.debugDevices = state.val;
235
- this.setState(id, state.val, true);
236
- return;
237
- }
238
- if (id.includes('info.logfilter')) {
239
- logCustomizations.logfilter = state.val.split(';').filter(x => x); // filter removes empty strings here
240
- this.setState(id, state.val, true);
241
- return;
242
- }
232
+ async onStateChange(id, state) {
233
+ if (state && state.ack == false) {
234
+ if (id.includes('info.debugmessages')) {
235
+ logCustomizations.debugDevices = state.val;
236
+ this.setState(id, state.val, true);
237
+ return;
238
+ }
239
+ if (id.includes('info.logfilter')) {
240
+ logCustomizations.logfilter = state.val.split(';').filter(x => x); // filter removes empty strings here
241
+ this.setState(id, state.val, true);
242
+ return;
243
+ }
243
244
 
244
- const message = await z2mController.createZ2MMessage(id, state) || { topic: '', payload: '' };
245
+ const message = await z2mController.createZ2MMessage(id, state) || { topic: '', payload: '' };
245
246
 
246
- if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
247
- mqttClient.publish(`zigbee2mqtt/${message.topic}`, JSON.stringify(message.payload));
248
- } else if (this.config.connectionType == 'ws') {
249
- websocketController.send(JSON.stringify(message));
250
- }
251
- }
252
- }
247
+ if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
248
+ mqttClient.publish(`zigbee2mqtt/${message.topic}`, JSON.stringify(message.payload));
249
+ } else if (this.config.connectionType == 'ws') {
250
+ websocketController.send(JSON.stringify(message));
251
+ }
252
+ }
253
+ }
253
254
  }
254
255
 
255
256
 
256
257
  if (require.main !== module) {
257
- // Export the constructor in compact mode
258
- /**
259
- * @param {Partial<core.AdapterOptions>} [options={}]
260
- */
261
- module.exports = (options) => new Zigbee2mqtt(options);
258
+ // Export the constructor in compact mode
259
+ /**
260
+ * @param {Partial<core.AdapterOptions>} [options={}]
261
+ */
262
+ module.exports = (options) => new Zigbee2mqtt(options);
262
263
  } else {
263
- // otherwise start the instance directly
264
- new Zigbee2mqtt();
264
+ // otherwise start the instance directly
265
+ new Zigbee2mqtt();
265
266
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee2mqtt",
3
- "version": "2.1.1",
3
+ "version": "2.2.1",
4
4
  "description": "Zigbee2MQTT adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen",
@@ -36,13 +36,13 @@
36
36
  "@types/chai": "^4.3.3",
37
37
  "@types/chai-as-promised": "^7.1.5",
38
38
  "@types/mocha": "^10.0.0",
39
- "@types/node": "^18.11.0",
39
+ "@types/node": "^18.11.3",
40
40
  "@types/proxyquire": "^1.3.28",
41
41
  "@types/sinon": "^10.0.13",
42
42
  "@types/sinon-chai": "^3.2.8",
43
43
  "chai": "^4.3.6",
44
44
  "chai-as-promised": "^7.1.1",
45
- "eslint": "^8.25.0",
45
+ "eslint": "^8.26.0",
46
46
  "eslint-config-prettier": "^8.5.0",
47
47
  "eslint-plugin-prettier": "^4.2.1",
48
48
  "mocha": "^10.1.0",