matterbridge 3.3.7-dev-20251104-7c779b9 → 3.3.7-dev-20251106-de2d9ea
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.
- package/CHANGELOG.md +7 -2
- package/README-SERVICE-LOCAL.md +4 -2
- package/README-SERVICE-OPT.md +168 -0
- package/README.md +4 -2
- package/dist/broadcastServer.js +18 -8
- package/dist/deviceManager.js +31 -2
- package/dist/frontend.js +16 -11
- package/dist/matterbridge.js +10 -4
- package/dist/pluginManager.js +178 -36
- package/frontend/package-lock.json +14 -55
- package/frontend/package.json +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -28,17 +28,22 @@ Advantages:
|
|
|
28
28
|
- individual plugin isolation in childbridge mode;
|
|
29
29
|
- ability to update the plugin in childbridge mode without restarting matterbridge;
|
|
30
30
|
|
|
31
|
-
## [3.3.7] - 2025-11
|
|
31
|
+
## [3.3.7] - 2025-11-07
|
|
32
32
|
|
|
33
33
|
### Breaking Changes
|
|
34
34
|
|
|
35
|
+
- [frontend]: When a plugin is first added, it will not be anymore started to allow to configure it before restarting.
|
|
36
|
+
|
|
35
37
|
### Added
|
|
36
38
|
|
|
37
|
-
- [matterbridge]: Added a first check for plugin existence (docker pull) and reinstall it before parsing the plugin.
|
|
39
|
+
- [matterbridge]: Added a first check for plugin existence (docker pull or Hass add-on rebuild) and reinstall it before parsing the plugin. The error messages have been removed.
|
|
40
|
+
- [service]: Added [configuration](README-SERVICE-OPT.md) to run matterbridge as a daemon with systemctl (Linux only) and with private global node_modules (user matterbridge and no sudo required).
|
|
38
41
|
|
|
39
42
|
### Changed
|
|
40
43
|
|
|
41
44
|
- [frontend]: Bumped `frontend` version to 3.3.1.
|
|
45
|
+
- [PluginManager]: Bumped `PluginManager` version to 1.3.0.
|
|
46
|
+
- [DeviceManager]: Bumped `DeviceManager` version to 1.1.0.
|
|
42
47
|
- [frontend]: Readded password dialog when running in Ingress.
|
|
43
48
|
|
|
44
49
|
### Fixed
|
package/README-SERVICE-LOCAL.md
CHANGED
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
|
|
19
19
|
## Run matterbridge as a daemon with systemctl (Linux only) with local global node_modules
|
|
20
20
|
|
|
21
|
-
The advantage of this setup is that the global node_modules are private for
|
|
21
|
+
The advantage of this setup is that the global node_modules are private for the user and sudo is not required.
|
|
22
22
|
|
|
23
|
-
The service runs rootless.
|
|
23
|
+
The service runs rootless like the current user.
|
|
24
24
|
|
|
25
25
|
The storage position is compatible with the traditional setup (~/Matterbridge ~/.matterbridge ~/.mattercert).
|
|
26
26
|
|
|
@@ -37,6 +37,8 @@ chown -R $USER:$USER ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global
|
|
|
37
37
|
chmod -R 755 ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global # ✅ Secure permissions
|
|
38
38
|
NPM_CONFIG_PREFIX=~/.npm-global npm install matterbridge --omit=dev --verbose --global # ✅ Install matterbridge in the local global node_modules, no sudo
|
|
39
39
|
sudo ln -sf /home/$USER/.npm-global/bin/matterbridge /usr/local/bin/matterbridge # ✅ Create a link to matterbridge bin
|
|
40
|
+
sudo ln -sf /home/$USER/.npm-global/bin/mb_mdns /usr/local/bin/mb_mdns # ✅ Create a link to mb_mdns bin
|
|
41
|
+
sudo ln -sf /home/$USER/.npm-global/bin/mb_coap /usr/local/bin/mb_coap # ✅ Create a link to mb_coap bin
|
|
40
42
|
hash -r # ✅ Clear bash command cache as a precaution
|
|
41
43
|
which matterbridge # ✅ Check it
|
|
42
44
|
matterbridge --version # ✅ Will output the matterbridge version
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# <img src="frontend/public/matterbridge.svg" alt="Matterbridge Logo" width="64px" height="64px"> Matterbridge systemd configuration with private global node_modules
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/matterbridge)
|
|
4
|
+
[](https://www.npmjs.com/package/matterbridge)
|
|
5
|
+
[](https://hub.docker.com/r/luligu/matterbridge)
|
|
6
|
+
[](https://hub.docker.com/r/luligu/matterbridge)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
[](https://codecov.io/gh/Luligu/matterbridge)
|
|
10
|
+
|
|
11
|
+
[](https://www.npmjs.com/package/matter-history)
|
|
12
|
+
[](https://www.npmjs.com/package/node-ansi-logger)
|
|
13
|
+
[](https://www.npmjs.com/package/node-persist-manager)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Advanced configuration
|
|
18
|
+
|
|
19
|
+
## Run matterbridge as a daemon with systemctl (Linux only) with user matterbridge and private global node_modules
|
|
20
|
+
|
|
21
|
+
The advantage of this setup is that the global node_modules are private for matterbridge and sudo is not required.
|
|
22
|
+
|
|
23
|
+
The service runs with user matterbridge and the system has full protection.
|
|
24
|
+
|
|
25
|
+
The storage position is **not compatible** with the traditional setup (~/Matterbridge ~/.matterbridge ~/.mattercert).
|
|
26
|
+
|
|
27
|
+
### 1 - Create the matterbridge user and group
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
sudo groupadd --system matterbridge 2>/dev/null || true
|
|
31
|
+
sudo useradd --system \
|
|
32
|
+
--home-dir /opt/matterbridge \
|
|
33
|
+
--shell /usr/sbin/nologin \
|
|
34
|
+
--gid matterbridge \
|
|
35
|
+
matterbridge 2>/dev/null || true
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2 - Create the Matterbridge directories and set the correct permissions
|
|
39
|
+
|
|
40
|
+
This will create the required directories if they don't exist
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cd ~
|
|
44
|
+
# ✅ Safe precaution if matterbridge was already running with the traditional setup
|
|
45
|
+
sudo systemctl stop matterbridge
|
|
46
|
+
# ✅ We need to uninstall from the global node_modules
|
|
47
|
+
sudo npm uninstall matterbridge -g
|
|
48
|
+
# ✅ Creates all needed dirs
|
|
49
|
+
sudo mkdir -p /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global
|
|
50
|
+
# ✅ Ensures ownership
|
|
51
|
+
sudo chown -R matterbridge:matterbridge /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global
|
|
52
|
+
# ✅ Secure permissions
|
|
53
|
+
sudo chmod -R 755 /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global
|
|
54
|
+
# make sure the “bin” dir exists for global executables
|
|
55
|
+
sudo -u matterbridge mkdir -p /opt/matterbridge/.npm-global/bin
|
|
56
|
+
# ✅ Install matterbridge in the private global node_modules
|
|
57
|
+
sudo -u matterbridge NPM_CONFIG_PREFIX=/opt/matterbridge/.npm-global npm install matterbridge --omit=dev --verbose --global
|
|
58
|
+
# ✅ Create a link to matterbridge bin
|
|
59
|
+
sudo ln -sf /opt/matterbridge/.npm-global/bin/matterbridge /usr/bin/matterbridge
|
|
60
|
+
sudo ln -sf /opt/matterbridge/.npm-global/bin/mb_mdns /usr/bin/mb_mdns
|
|
61
|
+
sudo ln -sf /opt/matterbridge/.npm-global/bin/mb_coap /usr/bin/mb_coap
|
|
62
|
+
# ✅ Clear bash command cache as a precaution
|
|
63
|
+
hash -r
|
|
64
|
+
# ✅ Check if matterbridge is /usr/bin/matterbridge
|
|
65
|
+
which matterbridge
|
|
66
|
+
# ✅ Will output the matterbridge version
|
|
67
|
+
matterbridge --version
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The storage position is **not compatible** with the traditional setup (~/Matterbridge ~/.matterbridge ~/.mattercert).
|
|
71
|
+
|
|
72
|
+
You may want to copy the contents to the new directories.
|
|
73
|
+
|
|
74
|
+
### 3 - Create a systemctl configuration file for Matterbridge
|
|
75
|
+
|
|
76
|
+
Create a systemctl configuration file for Matterbridge
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
sudo nano /etc/systemd/system/matterbridge.service
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Add the following to this file:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
[Unit]
|
|
86
|
+
Description=matterbridge
|
|
87
|
+
After=network.target
|
|
88
|
+
Wants=network.target
|
|
89
|
+
|
|
90
|
+
[Service]
|
|
91
|
+
Type=simple
|
|
92
|
+
Environment=NODE_ENV=production
|
|
93
|
+
Environment="NPM_CONFIG_PREFIX=/opt/matterbridge/.npm-global"
|
|
94
|
+
ExecStart=matterbridge --service --nosudo
|
|
95
|
+
WorkingDirectory=/opt/matterbridge/Matterbridge
|
|
96
|
+
StandardOutput=inherit
|
|
97
|
+
StandardError=inherit
|
|
98
|
+
Restart=always
|
|
99
|
+
User=matterbridge
|
|
100
|
+
Group=matterbridge
|
|
101
|
+
NoNewPrivileges=true
|
|
102
|
+
PrivateTmp=true
|
|
103
|
+
ProtectSystem=full
|
|
104
|
+
ProtectHome=true
|
|
105
|
+
ReadWritePaths=/opt/matterbridge
|
|
106
|
+
|
|
107
|
+
[Install]
|
|
108
|
+
WantedBy=multi-user.target
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
If you use the frontend with **-ssl** -frontend 443 and get an error message: "Port 443 requires elevated privileges",
|
|
112
|
+
add this:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
[Service]
|
|
116
|
+
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If you use the **matterbridge-bthome** plugin add this:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
[Service]
|
|
123
|
+
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Now and if you modify matterbridge.service after, run:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
sudo systemctl daemon-reload
|
|
130
|
+
sudo systemctl restart matterbridge.service
|
|
131
|
+
sudo systemctl status matterbridge.service
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Start Matterbridge
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
sudo systemctl start matterbridge
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Stop Matterbridge
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
sudo systemctl stop matterbridge
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Show Matterbridge status
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
sudo systemctl status matterbridge.service
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Enable Matterbridge to start automatically on boot
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
sudo systemctl enable matterbridge.service
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Disable Matterbridge from starting automatically on boot
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
sudo systemctl disable matterbridge.service
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### View the log of Matterbridge in real time (this will show the log with colors)
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
sudo journalctl -u matterbridge.service -n 1000 -f --output cat
|
|
168
|
+
```
|
package/README.md
CHANGED
|
@@ -30,11 +30,11 @@ Matterbridge creates a device that can be paired with any ecosystem, such as App
|
|
|
30
30
|
|
|
31
31
|
You don't need a hub or a dedicated new machine.
|
|
32
32
|
|
|
33
|
-
No complex setup: just copy paste the installation scripts.
|
|
33
|
+
No complex setup: just copy paste the installation scripts (available for Docker, Nginx, Linux systemctl and macOS launchctl).
|
|
34
34
|
|
|
35
35
|
Matterbridge is lightweight and also runs on slow Linux machines with as little as 512MB of memory.
|
|
36
36
|
|
|
37
|
-
It
|
|
37
|
+
It runs perfectly on Linux, macOS and Windows.
|
|
38
38
|
|
|
39
39
|
If you like this project and find it useful, please consider giving it a star on GitHub at https://github.com/Luligu/matterbridge and sponsoring it.
|
|
40
40
|
|
|
@@ -64,6 +64,8 @@ https://www.matteralpha.com/how-to/how-to-configure-an-open-source-matter-bridge
|
|
|
64
64
|
|
|
65
65
|
https://matter-smarthome.de/en/interview/an-alternative-to-the-official-matter-sdk/
|
|
66
66
|
|
|
67
|
+
https://blog.adafruit.com/2025/11/03/matterbridge-a-matter-plugin-manager/
|
|
68
|
+
|
|
67
69
|
## Prerequisites
|
|
68
70
|
|
|
69
71
|
To run Matterbridge, you need either a [Node.js](https://nodejs.org/en) environment or [Docker](https://docs.docker.com/get-started/get-docker/) installed on your system.
|
package/dist/broadcastServer.js
CHANGED
|
@@ -3,11 +3,14 @@ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
|
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
import { BroadcastChannel } from 'node:worker_threads';
|
|
5
5
|
import { debugStringify } from 'node-ansi-logger';
|
|
6
|
+
import { hasParameter } from './utils/commandLine.js';
|
|
6
7
|
export class BroadcastServer extends EventEmitter {
|
|
7
8
|
name;
|
|
8
9
|
log;
|
|
9
10
|
channel;
|
|
10
11
|
broadcastChannel;
|
|
12
|
+
debug = hasParameter('debug') || hasParameter('verbose');
|
|
13
|
+
verbose = hasParameter('verbose');
|
|
11
14
|
constructor(name, log, channel = 'broadcast-channel') {
|
|
12
15
|
super();
|
|
13
16
|
this.name = name;
|
|
@@ -31,10 +34,13 @@ export class BroadcastServer extends EventEmitter {
|
|
|
31
34
|
}
|
|
32
35
|
broadcastMessageHandler(event) {
|
|
33
36
|
const data = event.data;
|
|
34
|
-
this.
|
|
37
|
+
if (this.verbose)
|
|
38
|
+
this.log.debug(`Received broadcast message: ${debugStringify(data)}`);
|
|
35
39
|
this.emit('broadcast_message', data);
|
|
36
40
|
}
|
|
37
41
|
broadcast(message) {
|
|
42
|
+
if (this.verbose)
|
|
43
|
+
this.log.debug(`Broadcasting message: ${debugStringify(message)}`);
|
|
38
44
|
this.broadcastChannel.postMessage(message);
|
|
39
45
|
}
|
|
40
46
|
request(message) {
|
|
@@ -48,7 +54,8 @@ export class BroadcastServer extends EventEmitter {
|
|
|
48
54
|
this.log.error(`Invalid request message format for broadcast: ${debugStringify(message)}`);
|
|
49
55
|
return;
|
|
50
56
|
}
|
|
51
|
-
this.
|
|
57
|
+
if (this.verbose)
|
|
58
|
+
this.log.debug(`Broadcasting request message: ${debugStringify(message)}`);
|
|
52
59
|
this.broadcastChannel.postMessage(message);
|
|
53
60
|
}
|
|
54
61
|
respond(message) {
|
|
@@ -59,23 +66,26 @@ export class BroadcastServer extends EventEmitter {
|
|
|
59
66
|
this.log.error(`Invalid response message format for broadcast: ${debugStringify(message)}`);
|
|
60
67
|
return;
|
|
61
68
|
}
|
|
62
|
-
this.
|
|
69
|
+
if (this.verbose)
|
|
70
|
+
this.log.debug(`Broadcasting response message: ${debugStringify(message)}`);
|
|
63
71
|
this.broadcastChannel.postMessage(message);
|
|
64
72
|
}
|
|
65
|
-
async fetch(message) {
|
|
73
|
+
async fetch(message, timeout = 100) {
|
|
66
74
|
if (message.id === undefined) {
|
|
67
75
|
message.id = this.getUniqueId();
|
|
68
76
|
}
|
|
69
77
|
if (message.timestamp === undefined) {
|
|
70
78
|
message.timestamp = Date.now();
|
|
71
79
|
}
|
|
72
|
-
this.
|
|
80
|
+
if (this.verbose)
|
|
81
|
+
this.log.debug(`Fetching message: ${debugStringify(message)}`);
|
|
73
82
|
return new Promise((resolve, reject) => {
|
|
74
83
|
const responseHandler = (msg) => {
|
|
75
84
|
if (this.isWorkerResponse(msg, message.type) && msg.id === message.id) {
|
|
76
85
|
clearTimeout(timeoutId);
|
|
77
86
|
this.off('broadcast_message', responseHandler);
|
|
78
|
-
this.
|
|
87
|
+
if (this.verbose)
|
|
88
|
+
this.log.debug(`Fetch response: ${debugStringify(msg)}`);
|
|
79
89
|
resolve(msg);
|
|
80
90
|
}
|
|
81
91
|
};
|
|
@@ -83,8 +93,8 @@ export class BroadcastServer extends EventEmitter {
|
|
|
83
93
|
this.request(message);
|
|
84
94
|
const timeoutId = setTimeout(() => {
|
|
85
95
|
this.off('broadcast_message', responseHandler);
|
|
86
|
-
reject(new Error(`Fetch timeout after
|
|
87
|
-
},
|
|
96
|
+
reject(new Error(`Fetch timeout after ${timeout}ms for message id ${message.id}`));
|
|
97
|
+
}, timeout);
|
|
88
98
|
});
|
|
89
99
|
}
|
|
90
100
|
}
|
package/dist/deviceManager.js
CHANGED
|
@@ -6,6 +6,8 @@ export class DeviceManager {
|
|
|
6
6
|
_devices = new Map();
|
|
7
7
|
log;
|
|
8
8
|
server;
|
|
9
|
+
debug = hasParameter('debug') || hasParameter('verbose');
|
|
10
|
+
verbose = hasParameter('verbose');
|
|
9
11
|
constructor() {
|
|
10
12
|
this.log = new AnsiLogger({ logName: 'DeviceManager', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
11
13
|
this.log.debug('Matterbridge device manager starting...');
|
|
@@ -18,7 +20,8 @@ export class DeviceManager {
|
|
|
18
20
|
}
|
|
19
21
|
async msgHandler(msg) {
|
|
20
22
|
if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'devices')) {
|
|
21
|
-
this.
|
|
23
|
+
if (this.verbose)
|
|
24
|
+
this.log.debug(`Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
22
25
|
switch (msg.type) {
|
|
23
26
|
case 'get_log_level':
|
|
24
27
|
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
@@ -49,8 +52,12 @@ export class DeviceManager {
|
|
|
49
52
|
this.clear();
|
|
50
53
|
this.server.respond({ ...msg, response: { success: true } });
|
|
51
54
|
break;
|
|
55
|
+
case 'devices_basearray':
|
|
56
|
+
this.server.respond({ ...msg, response: { devices: this.baseArray(msg.params.pluginName) } });
|
|
57
|
+
break;
|
|
52
58
|
default:
|
|
53
|
-
this.
|
|
59
|
+
if (this.verbose)
|
|
60
|
+
this.log.debug(`Unknown broadcast message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
}
|
|
@@ -84,9 +91,31 @@ export class DeviceManager {
|
|
|
84
91
|
clear() {
|
|
85
92
|
this._devices.clear();
|
|
86
93
|
}
|
|
94
|
+
toBaseDevice(device) {
|
|
95
|
+
return {
|
|
96
|
+
pluginName: device.plugin,
|
|
97
|
+
deviceType: device.deviceType,
|
|
98
|
+
number: device.maybeNumber,
|
|
99
|
+
id: device.maybeId,
|
|
100
|
+
deviceName: device.deviceName,
|
|
101
|
+
serialNumber: device.serialNumber,
|
|
102
|
+
uniqueId: device.uniqueId,
|
|
103
|
+
productUrl: device.productUrl,
|
|
104
|
+
configUrl: device.configUrl,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
87
107
|
array() {
|
|
88
108
|
return Array.from(this._devices.values());
|
|
89
109
|
}
|
|
110
|
+
baseArray(pluginName) {
|
|
111
|
+
const devices = [];
|
|
112
|
+
for (const device of this._devices.values()) {
|
|
113
|
+
if (pluginName && pluginName !== device.plugin)
|
|
114
|
+
continue;
|
|
115
|
+
devices.push(this.toBaseDevice(device));
|
|
116
|
+
}
|
|
117
|
+
return devices;
|
|
118
|
+
}
|
|
90
119
|
[Symbol.iterator]() {
|
|
91
120
|
return this._devices.values();
|
|
92
121
|
}
|
package/dist/frontend.js
CHANGED
|
@@ -32,6 +32,8 @@ export class Frontend extends EventEmitter {
|
|
|
32
32
|
httpsServer;
|
|
33
33
|
webSocketServer;
|
|
34
34
|
server;
|
|
35
|
+
debug = hasParameter('debug') || hasParameter('verbose');
|
|
36
|
+
verbose = hasParameter('verbose');
|
|
35
37
|
constructor(matterbridge) {
|
|
36
38
|
super();
|
|
37
39
|
this.matterbridge = matterbridge;
|
|
@@ -45,7 +47,8 @@ export class Frontend extends EventEmitter {
|
|
|
45
47
|
}
|
|
46
48
|
async msgHandler(msg) {
|
|
47
49
|
if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'frontend')) {
|
|
48
|
-
this.
|
|
50
|
+
if (this.verbose)
|
|
51
|
+
this.log.debug(`Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
49
52
|
switch (msg.type) {
|
|
50
53
|
case 'get_log_level':
|
|
51
54
|
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
@@ -87,11 +90,13 @@ export class Frontend extends EventEmitter {
|
|
|
87
90
|
this.server.respond({ ...msg, response: { success: true } });
|
|
88
91
|
break;
|
|
89
92
|
default:
|
|
90
|
-
this.
|
|
93
|
+
if (this.verbose)
|
|
94
|
+
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
if (this.server.isWorkerResponse(msg, msg.type)) {
|
|
94
|
-
this.
|
|
98
|
+
if (this.verbose)
|
|
99
|
+
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
95
100
|
switch (msg.type) {
|
|
96
101
|
case 'get_log_level':
|
|
97
102
|
case 'set_log_level':
|
|
@@ -119,7 +124,8 @@ export class Frontend extends EventEmitter {
|
|
|
119
124
|
}
|
|
120
125
|
break;
|
|
121
126
|
default:
|
|
122
|
-
this.
|
|
127
|
+
if (this.verbose)
|
|
128
|
+
this.log.debug(`Unknown broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
123
129
|
}
|
|
124
130
|
}
|
|
125
131
|
}
|
|
@@ -1192,22 +1198,19 @@ export class Frontend extends EventEmitter {
|
|
|
1192
1198
|
this.wssSendSnackbarMessage(`Plugin ${data.params.pluginNameOrPath} not added`, 10, 'error');
|
|
1193
1199
|
return;
|
|
1194
1200
|
}
|
|
1201
|
+
this.wssSendSnackbarMessage(`Adding plugin ${data.params.pluginNameOrPath}...`, 5);
|
|
1202
|
+
this.log.debug(`Adding plugin ${data.params.pluginNameOrPath}...`);
|
|
1195
1203
|
data.params.pluginNameOrPath = data.params.pluginNameOrPath.replace(/@.*$/, '');
|
|
1196
|
-
if (this.matterbridge.plugins.has(data.params.pluginNameOrPath)) {
|
|
1197
|
-
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: `Plugin ${data.params.pluginNameOrPath} already added` });
|
|
1198
|
-
this.wssSendSnackbarMessage(`Plugin ${data.params.pluginNameOrPath} already added`, 10, 'warning');
|
|
1199
|
-
return;
|
|
1200
|
-
}
|
|
1201
1204
|
const plugin = await this.matterbridge.plugins.add(data.params.pluginNameOrPath);
|
|
1202
1205
|
if (plugin) {
|
|
1203
1206
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1204
1207
|
this.wssSendSnackbarMessage(`Added plugin ${data.params.pluginNameOrPath}`, 5, 'success');
|
|
1205
1208
|
this.matterbridge.plugins
|
|
1206
|
-
.load(plugin
|
|
1209
|
+
.load(plugin)
|
|
1207
1210
|
.then(() => {
|
|
1208
1211
|
this.wssSendRefreshRequired('plugins');
|
|
1209
1212
|
this.wssSendRefreshRequired('devices');
|
|
1210
|
-
this.wssSendSnackbarMessage(`
|
|
1213
|
+
this.wssSendSnackbarMessage(`Loaded plugin ${localData.params.pluginNameOrPath}`, 5, 'success');
|
|
1211
1214
|
return;
|
|
1212
1215
|
})
|
|
1213
1216
|
.catch((_error) => {
|
|
@@ -1223,6 +1226,8 @@ export class Frontend extends EventEmitter {
|
|
|
1223
1226
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Wrong parameter pluginName in /api/removeplugin' });
|
|
1224
1227
|
return;
|
|
1225
1228
|
}
|
|
1229
|
+
this.wssSendSnackbarMessage(`Removing plugin ${data.params.pluginName}...`, 5);
|
|
1230
|
+
this.log.debug(`Removing plugin ${data.params.pluginName}...`);
|
|
1226
1231
|
const plugin = this.matterbridge.plugins.get(data.params.pluginName);
|
|
1227
1232
|
await this.matterbridge.plugins.shutdown(plugin, 'The plugin has been removed.', true);
|
|
1228
1233
|
await this.matterbridge.plugins.remove(data.params.pluginName);
|
package/dist/matterbridge.js
CHANGED
|
@@ -120,6 +120,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
120
120
|
aggregatorUniqueId = getParameter('uniqueId');
|
|
121
121
|
advertisingNodes = new Map();
|
|
122
122
|
server;
|
|
123
|
+
debug = hasParameter('debug') || hasParameter('verbose');
|
|
124
|
+
verbose = hasParameter('verbose');
|
|
123
125
|
constructor() {
|
|
124
126
|
super();
|
|
125
127
|
this.log.logNameColor = '\x1b[38;5;115m';
|
|
@@ -131,7 +133,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
131
133
|
}
|
|
132
134
|
async msgHandler(msg) {
|
|
133
135
|
if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'matterbridge')) {
|
|
134
|
-
this.
|
|
136
|
+
if (this.verbose)
|
|
137
|
+
this.log.debug(`Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
135
138
|
switch (msg.type) {
|
|
136
139
|
case 'get_log_level':
|
|
137
140
|
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
@@ -141,17 +144,20 @@ export class Matterbridge extends EventEmitter {
|
|
|
141
144
|
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
142
145
|
break;
|
|
143
146
|
default:
|
|
144
|
-
this.
|
|
147
|
+
if (this.verbose)
|
|
148
|
+
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
145
149
|
}
|
|
146
150
|
}
|
|
147
151
|
if (this.server.isWorkerResponse(msg, msg.type)) {
|
|
148
|
-
this.
|
|
152
|
+
if (this.verbose)
|
|
153
|
+
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
149
154
|
switch (msg.type) {
|
|
150
155
|
case 'get_log_level':
|
|
151
156
|
case 'set_log_level':
|
|
152
157
|
break;
|
|
153
158
|
default:
|
|
154
|
-
this.
|
|
159
|
+
if (this.verbose)
|
|
160
|
+
this.log.debug(`Unknown broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
155
161
|
}
|
|
156
162
|
}
|
|
157
163
|
}
|
package/dist/pluginManager.js
CHANGED
|
@@ -5,10 +5,12 @@ import { inspectError, logError } from './utils/error.js';
|
|
|
5
5
|
import { hasParameter } from './utils/commandLine.js';
|
|
6
6
|
import { BroadcastServer } from './broadcastServer.js';
|
|
7
7
|
export class PluginManager extends EventEmitter {
|
|
8
|
-
_plugins = new Map();
|
|
9
8
|
matterbridge;
|
|
9
|
+
_plugins = new Map();
|
|
10
10
|
log;
|
|
11
11
|
server;
|
|
12
|
+
debug = hasParameter('debug') || hasParameter('verbose');
|
|
13
|
+
verbose = hasParameter('verbose');
|
|
12
14
|
constructor(matterbridge) {
|
|
13
15
|
super();
|
|
14
16
|
this.matterbridge = matterbridge;
|
|
@@ -23,7 +25,8 @@ export class PluginManager extends EventEmitter {
|
|
|
23
25
|
}
|
|
24
26
|
async msgHandler(msg) {
|
|
25
27
|
if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'plugins')) {
|
|
26
|
-
this.
|
|
28
|
+
if (this.verbose)
|
|
29
|
+
this.log.debug(`Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
27
30
|
switch (msg.type) {
|
|
28
31
|
case 'get_log_level':
|
|
29
32
|
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
@@ -42,13 +45,24 @@ export class PluginManager extends EventEmitter {
|
|
|
42
45
|
this.server.respond({ ...msg, response: { has: this.has(msg.params.name) } });
|
|
43
46
|
break;
|
|
44
47
|
case 'plugins_get':
|
|
45
|
-
|
|
48
|
+
{
|
|
49
|
+
const plugin = this.get(msg.params.name);
|
|
50
|
+
if (plugin) {
|
|
51
|
+
this.server.respond({ ...msg, response: { plugin: this.toApiPlugin(plugin) } });
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.server.respond({ ...msg, response: { plugin: undefined } });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
46
57
|
break;
|
|
47
58
|
case 'plugins_set':
|
|
48
59
|
this.server.respond({ ...msg, response: { plugin: this.set(msg.params.plugin) } });
|
|
49
60
|
break;
|
|
50
|
-
case '
|
|
51
|
-
this.server.respond({ ...msg, response: { plugins: this.
|
|
61
|
+
case 'plugins_storagepluginarray':
|
|
62
|
+
this.server.respond({ ...msg, response: { plugins: this.storagePluginArray() } });
|
|
63
|
+
break;
|
|
64
|
+
case 'plugins_apipluginarray':
|
|
65
|
+
this.server.respond({ ...msg, response: { plugins: this.apiPluginArray() } });
|
|
52
66
|
break;
|
|
53
67
|
case 'plugins_install':
|
|
54
68
|
this.server.respond({ ...msg, response: { packageName: msg.params.packageName, success: await this.install(msg.params.packageName) } });
|
|
@@ -56,8 +70,75 @@ export class PluginManager extends EventEmitter {
|
|
|
56
70
|
case 'plugins_uninstall':
|
|
57
71
|
this.server.respond({ ...msg, response: { packageName: msg.params.packageName, success: await this.uninstall(msg.params.packageName) } });
|
|
58
72
|
break;
|
|
73
|
+
case 'plugins_add':
|
|
74
|
+
{
|
|
75
|
+
const plugin = await this.add(msg.params.nameOrPath);
|
|
76
|
+
if (plugin) {
|
|
77
|
+
this.server.respond({ ...msg, response: { plugin: this.toApiPlugin(plugin) } });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.server.respond({ ...msg, response: { plugin } });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
case 'plugins_remove':
|
|
85
|
+
{
|
|
86
|
+
const plugin = await this.remove(msg.params.nameOrPath);
|
|
87
|
+
if (plugin) {
|
|
88
|
+
this.server.respond({ ...msg, response: { plugin: this.toApiPlugin(plugin) } });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.server.respond({ ...msg, response: { plugin } });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
case 'plugins_enable':
|
|
96
|
+
{
|
|
97
|
+
const plugin = await this.enable(msg.params.nameOrPath);
|
|
98
|
+
if (plugin) {
|
|
99
|
+
this.server.respond({ ...msg, response: { plugin: this.toApiPlugin(plugin) } });
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
this.server.respond({ ...msg, response: { plugin } });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
case 'plugins_disable':
|
|
107
|
+
{
|
|
108
|
+
const plugin = await this.disable(msg.params.nameOrPath);
|
|
109
|
+
if (plugin) {
|
|
110
|
+
this.server.respond({ ...msg, response: { plugin: this.toApiPlugin(plugin) } });
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.server.respond({ ...msg, response: { plugin } });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
case 'plugins_load':
|
|
118
|
+
{
|
|
119
|
+
const platform = await this.load(msg.params.plugin);
|
|
120
|
+
if (platform) {
|
|
121
|
+
this.server.respond({ ...msg, params: {}, response: { platform: {} } });
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.server.respond({ ...msg, response: { platform } });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
case 'plugins_shutdown':
|
|
129
|
+
{
|
|
130
|
+
const plugin = await this.shutdown(msg.params.plugin, msg.params.reason, msg.params.removeAllDevices, msg.params.force);
|
|
131
|
+
if (plugin) {
|
|
132
|
+
this.server.respond({ ...msg, params: {}, response: { plugin: this.toApiPlugin(plugin) } });
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.server.respond({ ...msg, response: { plugin } });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
59
139
|
default:
|
|
60
|
-
this.
|
|
140
|
+
if (this.verbose)
|
|
141
|
+
this.log.debug(`Unknown broadcast message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
61
142
|
}
|
|
62
143
|
}
|
|
63
144
|
}
|
|
@@ -80,41 +161,62 @@ export class PluginManager extends EventEmitter {
|
|
|
80
161
|
clear() {
|
|
81
162
|
this._plugins.clear();
|
|
82
163
|
}
|
|
164
|
+
toStoragePlugin(plugin) {
|
|
165
|
+
return {
|
|
166
|
+
name: plugin.name,
|
|
167
|
+
path: plugin.path,
|
|
168
|
+
type: plugin.type,
|
|
169
|
+
version: plugin.version,
|
|
170
|
+
description: plugin.description,
|
|
171
|
+
author: plugin.author,
|
|
172
|
+
enabled: plugin.enabled,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
toApiPlugin(plugin) {
|
|
176
|
+
return {
|
|
177
|
+
name: plugin.name,
|
|
178
|
+
version: plugin.version,
|
|
179
|
+
description: plugin.description,
|
|
180
|
+
author: plugin.author,
|
|
181
|
+
path: plugin.path,
|
|
182
|
+
type: plugin.type,
|
|
183
|
+
latestVersion: plugin.latestVersion,
|
|
184
|
+
devVersion: plugin.devVersion,
|
|
185
|
+
homepage: plugin.homepage,
|
|
186
|
+
help: plugin.help,
|
|
187
|
+
changelog: plugin.changelog,
|
|
188
|
+
funding: plugin.funding,
|
|
189
|
+
locked: plugin.locked,
|
|
190
|
+
error: plugin.error,
|
|
191
|
+
enabled: plugin.enabled,
|
|
192
|
+
loaded: plugin.loaded,
|
|
193
|
+
started: plugin.started,
|
|
194
|
+
configured: plugin.configured,
|
|
195
|
+
restartRequired: plugin.restartRequired,
|
|
196
|
+
registeredDevices: plugin.registeredDevices,
|
|
197
|
+
configJson: plugin.configJson,
|
|
198
|
+
schemaJson: plugin.schemaJson,
|
|
199
|
+
hasWhiteList: plugin.hasWhiteList,
|
|
200
|
+
hasBlackList: plugin.hasBlackList,
|
|
201
|
+
matter: plugin.serverNode ? this.matterbridge.getServerNodeData(plugin.serverNode) : undefined,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
83
204
|
array() {
|
|
84
205
|
return Array.from(this._plugins.values());
|
|
85
206
|
}
|
|
86
|
-
|
|
87
|
-
const
|
|
207
|
+
storagePluginArray() {
|
|
208
|
+
const storagePlugins = [];
|
|
88
209
|
for (const plugin of this._plugins.values()) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
devVersion: plugin.devVersion,
|
|
98
|
-
homepage: plugin.homepage,
|
|
99
|
-
help: plugin.help,
|
|
100
|
-
changelog: plugin.changelog,
|
|
101
|
-
funding: plugin.funding,
|
|
102
|
-
locked: plugin.locked,
|
|
103
|
-
error: plugin.error,
|
|
104
|
-
enabled: plugin.enabled,
|
|
105
|
-
loaded: plugin.loaded,
|
|
106
|
-
started: plugin.started,
|
|
107
|
-
configured: plugin.configured,
|
|
108
|
-
restartRequired: plugin.restartRequired,
|
|
109
|
-
registeredDevices: plugin.registeredDevices,
|
|
110
|
-
configJson: plugin.configJson,
|
|
111
|
-
schemaJson: plugin.schemaJson,
|
|
112
|
-
hasWhiteList: plugin.hasWhiteList,
|
|
113
|
-
hasBlackList: plugin.hasBlackList,
|
|
114
|
-
matter: plugin.serverNode ? this.matterbridge.getServerNodeData(plugin.serverNode) : undefined,
|
|
115
|
-
});
|
|
210
|
+
storagePlugins.push(this.toStoragePlugin(plugin));
|
|
211
|
+
}
|
|
212
|
+
return storagePlugins;
|
|
213
|
+
}
|
|
214
|
+
apiPluginArray() {
|
|
215
|
+
const apiPlugins = [];
|
|
216
|
+
for (const plugin of this._plugins.values()) {
|
|
217
|
+
apiPlugins.push(this.toApiPlugin(plugin));
|
|
116
218
|
}
|
|
117
|
-
return
|
|
219
|
+
return apiPlugins;
|
|
118
220
|
}
|
|
119
221
|
[Symbol.iterator]() {
|
|
120
222
|
return this._plugins.values();
|
|
@@ -346,6 +448,14 @@ export class PluginManager extends EventEmitter {
|
|
|
346
448
|
}
|
|
347
449
|
async parse(plugin) {
|
|
348
450
|
const { promises } = await import('node:fs');
|
|
451
|
+
if (typeof plugin === 'string') {
|
|
452
|
+
const p = this._plugins.get(plugin);
|
|
453
|
+
if (!p) {
|
|
454
|
+
this.log.error(`Plugin ${plg}${plugin}${er} not found`);
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
plugin = p;
|
|
458
|
+
}
|
|
349
459
|
try {
|
|
350
460
|
this.log.debug(`Parsing package.json of plugin ${plg}${plugin.name}${db}`);
|
|
351
461
|
const packageJson = JSON.parse(await promises.readFile(plugin.path, 'utf8'));
|
|
@@ -570,6 +680,14 @@ export class PluginManager extends EventEmitter {
|
|
|
570
680
|
async load(plugin, start = false, message = '', configure = false) {
|
|
571
681
|
const { promises } = await import('node:fs');
|
|
572
682
|
const { default: path } = await import('node:path');
|
|
683
|
+
if (typeof plugin === 'string') {
|
|
684
|
+
const p = this._plugins.get(plugin);
|
|
685
|
+
if (!p) {
|
|
686
|
+
this.log.error(`Plugin ${plg}${plugin}${er} not found`);
|
|
687
|
+
return undefined;
|
|
688
|
+
}
|
|
689
|
+
plugin = p;
|
|
690
|
+
}
|
|
573
691
|
if (!plugin.enabled) {
|
|
574
692
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not enabled`);
|
|
575
693
|
return undefined;
|
|
@@ -636,6 +754,14 @@ export class PluginManager extends EventEmitter {
|
|
|
636
754
|
return undefined;
|
|
637
755
|
}
|
|
638
756
|
async start(plugin, message, configure = false) {
|
|
757
|
+
if (typeof plugin === 'string') {
|
|
758
|
+
const p = this._plugins.get(plugin);
|
|
759
|
+
if (!p) {
|
|
760
|
+
this.log.error(`Plugin ${plg}${plugin}${er} not found`);
|
|
761
|
+
return undefined;
|
|
762
|
+
}
|
|
763
|
+
plugin = p;
|
|
764
|
+
}
|
|
639
765
|
if (!plugin.loaded) {
|
|
640
766
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
|
|
641
767
|
return undefined;
|
|
@@ -666,6 +792,14 @@ export class PluginManager extends EventEmitter {
|
|
|
666
792
|
return undefined;
|
|
667
793
|
}
|
|
668
794
|
async configure(plugin) {
|
|
795
|
+
if (typeof plugin === 'string') {
|
|
796
|
+
const p = this._plugins.get(plugin);
|
|
797
|
+
if (!p) {
|
|
798
|
+
this.log.error(`Plugin ${plg}${plugin}${er} not found`);
|
|
799
|
+
return undefined;
|
|
800
|
+
}
|
|
801
|
+
plugin = p;
|
|
802
|
+
}
|
|
669
803
|
if (!plugin.loaded) {
|
|
670
804
|
this.log.error(`Plugin ${plg}${plugin.name}${er} not loaded`);
|
|
671
805
|
return undefined;
|
|
@@ -697,6 +831,14 @@ export class PluginManager extends EventEmitter {
|
|
|
697
831
|
return undefined;
|
|
698
832
|
}
|
|
699
833
|
async shutdown(plugin, reason, removeAllDevices = false, force = false) {
|
|
834
|
+
if (typeof plugin === 'string') {
|
|
835
|
+
const p = this._plugins.get(plugin);
|
|
836
|
+
if (!p) {
|
|
837
|
+
this.log.error(`Plugin ${plg}${plugin}${er} not found`);
|
|
838
|
+
return undefined;
|
|
839
|
+
}
|
|
840
|
+
plugin = p;
|
|
841
|
+
}
|
|
700
842
|
this.log.debug(`Shutting down plugin ${plg}${plugin.name}${db}`);
|
|
701
843
|
if (!plugin.loaded) {
|
|
702
844
|
this.log.debug(`Plugin ${plg}${plugin.name}${db} not loaded`);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontend",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "frontend",
|
|
9
|
-
"version": "3.3.
|
|
9
|
+
"version": "3.3.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@emotion/react": "^11.14.0",
|
|
12
12
|
"@emotion/styled": "^11.14.1",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
34
34
|
"@typescript-eslint/parser": "^8.46.2",
|
|
35
35
|
"@vitejs/plugin-react": "^5.1.0",
|
|
36
|
-
"eslint": "9.
|
|
36
|
+
"eslint": "^9.39.1",
|
|
37
37
|
"eslint-config-prettier": "^10.1.8",
|
|
38
38
|
"eslint-plugin-prettier": "^5.5.4",
|
|
39
39
|
"eslint-plugin-react": "^7.37.5",
|
|
@@ -1232,7 +1232,7 @@
|
|
|
1232
1232
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
1233
1233
|
}
|
|
1234
1234
|
},
|
|
1235
|
-
"node_modules/@eslint/
|
|
1235
|
+
"node_modules/@eslint/core": {
|
|
1236
1236
|
"version": "0.17.0",
|
|
1237
1237
|
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
|
|
1238
1238
|
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
|
|
@@ -1245,19 +1245,6 @@
|
|
|
1245
1245
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
1246
1246
|
}
|
|
1247
1247
|
},
|
|
1248
|
-
"node_modules/@eslint/core": {
|
|
1249
|
-
"version": "0.16.0",
|
|
1250
|
-
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz",
|
|
1251
|
-
"integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==",
|
|
1252
|
-
"dev": true,
|
|
1253
|
-
"license": "Apache-2.0",
|
|
1254
|
-
"dependencies": {
|
|
1255
|
-
"@types/json-schema": "^7.0.15"
|
|
1256
|
-
},
|
|
1257
|
-
"engines": {
|
|
1258
|
-
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
1259
|
-
}
|
|
1260
|
-
},
|
|
1261
1248
|
"node_modules/@eslint/eslintrc": {
|
|
1262
1249
|
"version": "3.3.1",
|
|
1263
1250
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
|
|
@@ -1341,9 +1328,9 @@
|
|
|
1341
1328
|
}
|
|
1342
1329
|
},
|
|
1343
1330
|
"node_modules/@eslint/js": {
|
|
1344
|
-
"version": "9.
|
|
1345
|
-
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.
|
|
1346
|
-
"integrity": "sha512-
|
|
1331
|
+
"version": "9.39.1",
|
|
1332
|
+
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz",
|
|
1333
|
+
"integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==",
|
|
1347
1334
|
"dev": true,
|
|
1348
1335
|
"license": "MIT",
|
|
1349
1336
|
"engines": {
|
|
@@ -1377,19 +1364,6 @@
|
|
|
1377
1364
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
1378
1365
|
}
|
|
1379
1366
|
},
|
|
1380
|
-
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
|
|
1381
|
-
"version": "0.17.0",
|
|
1382
|
-
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
|
|
1383
|
-
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
|
|
1384
|
-
"dev": true,
|
|
1385
|
-
"license": "Apache-2.0",
|
|
1386
|
-
"dependencies": {
|
|
1387
|
-
"@types/json-schema": "^7.0.15"
|
|
1388
|
-
},
|
|
1389
|
-
"engines": {
|
|
1390
|
-
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
1391
|
-
}
|
|
1392
|
-
},
|
|
1393
1367
|
"node_modules/@humanfs/core": {
|
|
1394
1368
|
"version": "0.19.1",
|
|
1395
1369
|
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
|
@@ -3878,9 +3852,9 @@
|
|
|
3878
3852
|
}
|
|
3879
3853
|
},
|
|
3880
3854
|
"node_modules/eslint": {
|
|
3881
|
-
"version": "9.
|
|
3882
|
-
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.
|
|
3883
|
-
"integrity": "sha512-
|
|
3855
|
+
"version": "9.39.1",
|
|
3856
|
+
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz",
|
|
3857
|
+
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
|
|
3884
3858
|
"dev": true,
|
|
3885
3859
|
"license": "MIT",
|
|
3886
3860
|
"peer": true,
|
|
@@ -3888,11 +3862,11 @@
|
|
|
3888
3862
|
"@eslint-community/eslint-utils": "^4.8.0",
|
|
3889
3863
|
"@eslint-community/regexpp": "^4.12.1",
|
|
3890
3864
|
"@eslint/config-array": "^0.21.1",
|
|
3891
|
-
"@eslint/config-helpers": "^0.4.
|
|
3892
|
-
"@eslint/core": "^0.
|
|
3865
|
+
"@eslint/config-helpers": "^0.4.2",
|
|
3866
|
+
"@eslint/core": "^0.17.0",
|
|
3893
3867
|
"@eslint/eslintrc": "^3.3.1",
|
|
3894
|
-
"@eslint/js": "9.
|
|
3895
|
-
"@eslint/plugin-kit": "^0.4.
|
|
3868
|
+
"@eslint/js": "9.39.1",
|
|
3869
|
+
"@eslint/plugin-kit": "^0.4.1",
|
|
3896
3870
|
"@humanfs/node": "^0.16.6",
|
|
3897
3871
|
"@humanwhocodes/module-importer": "^1.0.1",
|
|
3898
3872
|
"@humanwhocodes/retry": "^0.4.2",
|
|
@@ -7766,21 +7740,6 @@
|
|
|
7766
7740
|
"dev": true,
|
|
7767
7741
|
"license": "ISC"
|
|
7768
7742
|
},
|
|
7769
|
-
"node_modules/yaml": {
|
|
7770
|
-
"version": "2.8.1",
|
|
7771
|
-
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
|
|
7772
|
-
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
|
|
7773
|
-
"dev": true,
|
|
7774
|
-
"license": "ISC",
|
|
7775
|
-
"optional": true,
|
|
7776
|
-
"peer": true,
|
|
7777
|
-
"bin": {
|
|
7778
|
-
"yaml": "bin.mjs"
|
|
7779
|
-
},
|
|
7780
|
-
"engines": {
|
|
7781
|
-
"node": ">= 14.6"
|
|
7782
|
-
}
|
|
7783
|
-
},
|
|
7784
7743
|
"node_modules/yocto-queue": {
|
|
7785
7744
|
"version": "0.1.0",
|
|
7786
7745
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
package/frontend/package.json
CHANGED
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
67
67
|
"@typescript-eslint/parser": "^8.46.2",
|
|
68
68
|
"@vitejs/plugin-react": "^5.1.0",
|
|
69
|
-
"eslint": "9.
|
|
69
|
+
"eslint": "^9.39.1",
|
|
70
70
|
"eslint-config-prettier": "^10.1.8",
|
|
71
71
|
"eslint-plugin-prettier": "^5.5.4",
|
|
72
72
|
"eslint-plugin-react": "^7.37.5",
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge",
|
|
3
|
-
"version": "3.3.7-dev-
|
|
3
|
+
"version": "3.3.7-dev-20251106-de2d9ea",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge",
|
|
9
|
-
"version": "3.3.7-dev-
|
|
9
|
+
"version": "3.3.7-dev-20251106-de2d9ea",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@matter/main": "0.15.6",
|
package/package.json
CHANGED