matterbridge 3.3.9-dev-20251119-ea13a99 → 3.4.0-dev-20251120-1b65c89

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 CHANGED
@@ -28,7 +28,7 @@ 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.9] - Not published
31
+ ## [3.4.0] - Not published
32
32
 
33
33
  ### Development Breaking Changes
34
34
 
@@ -38,9 +38,19 @@ Removed the following long deprecated elements:
38
38
  - [endpoint]: uniqueStorageKey instead of id in MatterbridgeEndpointOptions (deprecated since months).
39
39
  - [endpoint]: endpointId instead of number in MatterbridgeEndpointOptions (deprecated since months).
40
40
 
41
+ ### Added
42
+
43
+ - [endpoint]: Added getChildEndpointById() and getChildEndpointByOriginalId().
44
+ - [endpoint]: Deprecated getChildEndpointByName(). Use getChildEndpointById() or getChildEndpointByOriginalId().
45
+ - [platform]: Added wssSendSnackbarMessage method to MatterbridgePlatform for sending snackbar notifications to the frontend.
46
+
41
47
  ### Changed
42
48
 
43
49
  - [package]: Updated dependencies.
50
+ - [deviceManager]: Bumped DeviceManager v.1.1.1.
51
+ - [broadcastServer]: Bumped BroadcastServer v.1.0.3.
52
+ - [jest]: Bumped jestHelpers v.1.0.13.
53
+ - [spawn]: Bumped spawn module v.1.2.0.
44
54
 
45
55
  <a href="https://www.buymeacoffee.com/luligugithub">
46
56
  <img src="bmc-button.svg" alt="Buy me a coffee" width="80">
@@ -70,7 +70,7 @@ export class BroadcastServer extends EventEmitter {
70
70
  this.log.debug(`Broadcasting response message: ${debugStringify(message)}`);
71
71
  this.broadcastChannel.postMessage(message);
72
72
  }
73
- async fetch(message, timeout = 100) {
73
+ async fetch(message, timeout = 250) {
74
74
  if (message.id === undefined) {
75
75
  message.id = this.getUniqueId();
76
76
  }
@@ -2,6 +2,31 @@ import { AnsiLogger, BLUE, CYAN, db, debugStringify, er } from 'node-ansi-logger
2
2
  import { dev } from './matterbridgeTypes.js';
3
3
  import { BroadcastServer } from './broadcastServer.js';
4
4
  import { hasParameter } from './utils/commandLine.js';
5
+ export function toBaseDevice(device) {
6
+ return {
7
+ mode: device.mode,
8
+ plugin: device.plugin,
9
+ configUrl: device.configUrl,
10
+ deviceName: device.deviceName,
11
+ serialNumber: device.serialNumber,
12
+ uniqueId: device.uniqueId,
13
+ vendorId: device.vendorId,
14
+ vendorName: device.vendorName,
15
+ productId: device.productId,
16
+ productName: device.productName,
17
+ softwareVersion: device.softwareVersion,
18
+ softwareVersionString: device.softwareVersionString,
19
+ hardwareVersion: device.hardwareVersion,
20
+ hardwareVersionString: device.hardwareVersionString,
21
+ productUrl: device.productUrl,
22
+ tagList: device.tagList,
23
+ originalId: device.originalId,
24
+ name: device.name,
25
+ deviceType: device.deviceType,
26
+ number: device.number,
27
+ id: device.id,
28
+ };
29
+ }
5
30
  export class DeviceManager {
6
31
  _devices = new Map();
7
32
  log;
@@ -40,13 +65,16 @@ export class DeviceManager {
40
65
  this.server.respond({ ...msg, response: { has: this.has(msg.params.uniqueId) } });
41
66
  break;
42
67
  case 'devices_get':
43
- this.server.respond({ ...msg, response: { device: this.get(msg.params.uniqueId) } });
68
+ {
69
+ const endpoint = this.get(msg.params.uniqueId);
70
+ this.server.respond({ ...msg, response: { device: endpoint ? toBaseDevice(endpoint) : undefined } });
71
+ }
44
72
  break;
45
73
  case 'devices_set':
46
- this.server.respond({ ...msg, response: { device: this.set(msg.params.device) } });
74
+ this.server.respond({ ...msg, response: { device: this.set(toBaseDevice(msg.params.device)) } });
47
75
  break;
48
76
  case 'devices_remove':
49
- this.server.respond({ ...msg, response: { success: this.remove(msg.params.device) } });
77
+ this.server.respond({ ...msg, response: { success: this.remove(toBaseDevice(msg.params.device)) } });
50
78
  break;
51
79
  case 'devices_clear':
52
80
  this.clear();
@@ -92,24 +120,14 @@ export class DeviceManager {
92
120
  this._devices.clear();
93
121
  }
94
122
  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
- };
123
+ return toBaseDevice(device);
106
124
  }
107
125
  array() {
108
126
  return Array.from(this._devices.values());
109
127
  }
110
128
  baseArray(pluginName) {
111
129
  const devices = [];
112
- for (const device of this._devices.values()) {
130
+ for (const device of Array.from(this._devices.values())) {
113
131
  if (pluginName && pluginName !== device.plugin)
114
132
  continue;
115
133
  devices.push(this.toBaseDevice(device));
package/dist/frontend.js CHANGED
@@ -89,6 +89,10 @@ export class Frontend extends EventEmitter {
89
89
  this.wssSendAttributeChangedMessage(msg.params.plugin, msg.params.serialNumber, msg.params.uniqueId, msg.params.number, msg.params.id, msg.params.cluster, msg.params.attribute, msg.params.value);
90
90
  this.server.respond({ ...msg, response: { success: true } });
91
91
  break;
92
+ case 'frontend_logmessage':
93
+ this.wssSendLogMessage(msg.params.level, msg.params.time, msg.params.name, msg.params.message);
94
+ this.server.respond({ ...msg, response: { success: true } });
95
+ break;
92
96
  default:
93
97
  if (this.verbose)
94
98
  this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
@@ -689,15 +693,23 @@ export class Frontend extends EventEmitter {
689
693
  this.log.info(`File ${plg}${filename}${nf} uploaded successfully`);
690
694
  if (filename.endsWith('.tgz')) {
691
695
  const { spawnCommand } = await import('./utils/spawn.js');
692
- await spawnCommand(this.matterbridge, 'npm', ['install', '-g', filePath, '--omit=dev', '--verbose'], 'install', filename);
693
- this.log.info(`Plugin package ${plg}${filename}${nf} installed successfully. Full restart required.`);
694
- this.wssSendCloseSnackbarMessage(`Installing package ${filename}. Please wait...`);
695
- this.wssSendSnackbarMessage(`Installed package ${filename}`, 10, 'success');
696
- this.wssSendRestartRequired();
697
- res.send(`Plugin package ${filename} uploaded and installed successfully`);
696
+ if (await spawnCommand('npm', ['install', '-g', filePath, '--omit=dev', '--verbose'], 'install', filename)) {
697
+ this.log.info(`Plugin package ${plg}${filename}${nf} installed successfully. Full restart required.`);
698
+ this.wssSendCloseSnackbarMessage(`Installing package ${filename}. Please wait...`);
699
+ this.wssSendSnackbarMessage(`Installed package ${filename}`, 10, 'success');
700
+ this.wssSendRestartRequired();
701
+ res.send(`Plugin package ${filename} uploaded and installed successfully`);
702
+ }
703
+ else {
704
+ this.log.error(`Error uploading or installing plugin package file ${plg}${filename}${er}`);
705
+ this.wssSendCloseSnackbarMessage(`Installing package ${filename}. Please wait...`);
706
+ this.wssSendSnackbarMessage(`Error uploading or installing plugin package ${filename}`, 10, 'error');
707
+ res.status(500).send(`Error uploading or installing plugin package ${filename}`);
708
+ }
698
709
  }
699
- else
710
+ else {
700
711
  res.send(`File ${filename} uploaded successfully`);
712
+ }
701
713
  }
702
714
  catch (err) {
703
715
  this.log.error(`Error uploading or installing plugin package file ${plg}${filename}${er}:`, err);
@@ -28,7 +28,6 @@ import { bridge } from './matterbridgeDeviceTypes.js';
28
28
  import { Frontend } from './frontend.js';
29
29
  import { addVirtualDevices } from './helpers.js';
30
30
  import { BroadcastServer } from './broadcastServer.js';
31
- import { inspectError } from './utils/error.js';
32
31
  export class Matterbridge extends EventEmitter {
33
32
  systemInformation = {
34
33
  interfaceName: '',
@@ -462,14 +461,13 @@ export class Matterbridge extends EventEmitter {
462
461
  for (const plugin of this.plugins) {
463
462
  if (!fs.existsSync(plugin.path) && !hasParameter('add') && !hasParameter('remove') && !hasParameter('enable') && !hasParameter('disable') && !hasParameter('reset') && !hasParameter('factoryreset')) {
464
463
  this.log.info(`Error parsing plugin ${plg}${plugin.name}${nf}. Trying to reinstall it from npm...`);
465
- try {
466
- const { spawnCommand } = await import('./utils/spawn.js');
467
- await spawnCommand(this, 'npm', ['install', '-g', plugin.name, '--omit=dev', '--verbose'], 'install', plugin.name);
464
+ const { spawnCommand } = await import('./utils/spawn.js');
465
+ if (await spawnCommand('npm', ['install', '-g', plugin.name, '--omit=dev', '--verbose'], 'install', plugin.name)) {
468
466
  this.log.info(`Plugin ${plg}${plugin.name}${nf} reinstalled.`);
469
467
  plugin.error = false;
470
468
  }
471
- catch (error) {
472
- inspectError(this.log, `Error installing plugin ${plg}${plugin.name}${er}. The plugin is disabled.`, error);
469
+ else {
470
+ this.log.error(`Error reinstalling plugin ${plg}${plugin.name}${nf}. The plugin is disabled.`);
473
471
  plugin.error = true;
474
472
  plugin.enabled = false;
475
473
  continue;
@@ -905,13 +903,12 @@ export class Matterbridge extends EventEmitter {
905
903
  }
906
904
  async updateProcess() {
907
905
  this.log.info('Updating matterbridge...');
908
- try {
909
- const { spawnCommand } = await import('./utils/spawn.js');
910
- await spawnCommand(this, 'npm', ['install', '-g', 'matterbridge', '--omit=dev', '--verbose'], 'install', 'matterbridge');
906
+ const { spawnCommand } = await import('./utils/spawn.js');
907
+ if (await spawnCommand('npm', ['install', '-g', 'matterbridge', '--omit=dev', '--verbose'], 'install', 'matterbridge')) {
911
908
  this.log.info('Matterbridge has been updated. Full restart required.');
912
909
  }
913
- catch (error) {
914
- this.log.error(`Error updating matterbridge: ${error instanceof Error ? error.message : error}`);
910
+ else {
911
+ this.log.error('Error updating matterbridge.');
915
912
  }
916
913
  this.frontend.wssSendRestartRequired();
917
914
  await this.cleanup('updating...', false);
@@ -368,6 +368,12 @@ export class MatterbridgeEndpoint extends Endpoint {
368
368
  getChildEndpointByName(endpointName) {
369
369
  return this.parts.find((part) => part.id === endpointName);
370
370
  }
371
+ getChildEndpointById(id) {
372
+ return this.parts.find((part) => part.id === id);
373
+ }
374
+ getChildEndpointByOriginalId(originalId) {
375
+ return this.parts.find((part) => part.originalId === originalId);
376
+ }
371
377
  getChildEndpoint(endpointNumber) {
372
378
  return this.parts.find((part) => part.number === endpointNumber);
373
379
  }
@@ -370,8 +370,7 @@ export class PluginManager extends EventEmitter {
370
370
  async install(packageName) {
371
371
  this.log.debug(`Installing plugin ${plg}${packageName}${db}...`);
372
372
  const { spawnCommand } = await import('./utils/spawn.js');
373
- try {
374
- await spawnCommand(this.matterbridge, 'npm', ['install', '-g', packageName, '--omit=dev', '--verbose'], 'install', packageName);
373
+ if (await spawnCommand('npm', ['install', '-g', packageName, '--omit=dev', '--verbose'], 'install', packageName)) {
375
374
  this.matterbridge.restartRequired = true;
376
375
  this.matterbridge.fixedRestartRequired = true;
377
376
  packageName = packageName.replace(/@.*$/, '');
@@ -387,12 +386,11 @@ export class PluginManager extends EventEmitter {
387
386
  await this.matterbridge.shutdownProcess();
388
387
  }
389
388
  }
390
- this.log.debug(`Installed plugin ${plg}${packageName}${db} successfully`);
389
+ this.log.info(`Installed plugin ${plg}${packageName}${db} successfully`);
391
390
  return true;
392
391
  }
393
- catch (error) {
394
- inspectError(this.log, `Failed to install package ${plg}${packageName}${er}`, error);
395
- this.log.debug(`Failed to install plugin ${plg}${packageName}${db}`);
392
+ else {
393
+ this.log.error(`Failed to install plugin ${plg}${packageName}${er}`);
396
394
  return false;
397
395
  }
398
396
  }
@@ -402,20 +400,18 @@ export class PluginManager extends EventEmitter {
402
400
  packageName = packageName.replace(/@.*$/, '');
403
401
  if (packageName === 'matterbridge')
404
402
  return false;
405
- try {
406
- if (this.has(packageName)) {
407
- const plugin = this.get(packageName);
408
- if (plugin && plugin.loaded)
409
- await this.shutdown(plugin, 'Matterbridge is uninstalling the plugin');
410
- await this.remove(packageName);
411
- }
412
- await spawnCommand(this.matterbridge, 'npm', ['uninstall', '-g', packageName, '--verbose'], 'uninstall', packageName);
413
- this.log.debug(`Uninstalled plugin ${plg}${packageName}${db} successfully`);
403
+ if (this.has(packageName)) {
404
+ const plugin = this.get(packageName);
405
+ if (plugin && plugin.loaded)
406
+ await this.shutdown(plugin, 'Matterbridge is uninstalling the plugin');
407
+ await this.remove(packageName);
408
+ }
409
+ if (await spawnCommand('npm', ['uninstall', '-g', packageName, '--verbose'], 'uninstall', packageName)) {
410
+ this.log.info(`Uninstalled plugin ${plg}${packageName}${db} successfully`);
414
411
  return true;
415
412
  }
416
- catch (error) {
417
- inspectError(this.log, `Failed to uninstall package ${plg}${packageName}${er}`, error);
418
- this.log.debug(`Failed to uninstall plugin ${plg}${packageName}${db}`);
413
+ else {
414
+ this.log.error(`Failed to uninstall plugin ${plg}${packageName}${er}`);
419
415
  return false;
420
416
  }
421
417
  }
@@ -741,7 +737,7 @@ export class PluginManager extends EventEmitter {
741
737
  plugin.author = this.getAuthor(packageJson);
742
738
  plugin.configJson = config;
743
739
  plugin.schemaJson = await this.loadSchema(plugin);
744
- config.name = plugin.name;
740
+ config.name = packageJson.name;
745
741
  config.version = packageJson.version;
746
742
  const log = new AnsiLogger({ logName: plugin.description, logTimestampFormat: 4, logLevel: config.debug ? "debug" : this.matterbridge.log.logLevel });
747
743
  const platform = pluginInstance.default(this.matterbridge, log, config);
@@ -1,5 +1,4 @@
1
- import { AnsiLogger } from '../logger/export.js';
2
- export async function copyDirectory(srcDir, destDir) {
1
+ export async function copyDirectory(srcDir, destDir, log) {
3
2
  if (srcDir === '') {
4
3
  throw new Error('Source directory must be specified.');
5
4
  }
@@ -15,10 +14,9 @@ export async function copyDirectory(srcDir, destDir) {
15
14
  if (srcDir === destDir) {
16
15
  throw new Error('Source and destination directories must be different.');
17
16
  }
18
- const log = new AnsiLogger({ logName: 'CopyDirectory', logTimestampFormat: 4, logLevel: "info" });
19
17
  const fs = await import('node:fs').then((mod) => mod.promises);
20
18
  const path = await import('node:path');
21
- log.debug(`copyDirectory: copying directory from ${srcDir} to ${destDir}`);
19
+ log?.debug(`copyDirectory: copying directory from ${srcDir} to ${destDir}`);
22
20
  try {
23
21
  await fs.mkdir(destDir, { recursive: true });
24
22
  const entries = await fs.readdir(srcDir, { withFileTypes: true });
@@ -35,7 +33,7 @@ export async function copyDirectory(srcDir, destDir) {
35
33
  return true;
36
34
  }
37
35
  catch (error) {
38
- log.error(`copyDirectory error copying from ${srcDir} to ${destDir}: ${error instanceof Error ? error.message : error}`);
36
+ log?.error(`copyDirectory error copying from ${srcDir} to ${destDir}: ${error instanceof Error ? error.message : error}`);
39
37
  return false;
40
38
  }
41
39
  }
@@ -1,6 +1,17 @@
1
+ import { AnsiLogger } from 'node-ansi-logger';
2
+ import { BroadcastServer } from '../broadcastServer.js';
1
3
  import { hasParameter } from './commandLine.js';
2
- export async function spawnCommand(matterbridge, command, args, packageCommand, packageName) {
4
+ export async function spawnCommand(command, args, packageCommand, packageName) {
3
5
  const { spawn } = await import('node:child_process');
6
+ const debug = hasParameter('debug') || hasParameter('verbose');
7
+ const verbose = hasParameter('verbose');
8
+ const log = new AnsiLogger({ logName: 'Spawn', logTimestampFormat: 4, logLevel: debug ? "debug" : "info" });
9
+ const server = new BroadcastServer('spawn', log);
10
+ const sendLog = (name, message) => {
11
+ server.request({ type: 'frontend_logmessage', src: 'spawn', dst: 'frontend', params: { level: 'spawn', time: log.now(), name, message } });
12
+ };
13
+ if (verbose)
14
+ log.debug(`Spawning command: ${command} with ${args.join(' ')} ${packageCommand} ${packageName}`);
4
15
  const cmdLine = command + ' ' + args.join(' ');
5
16
  if (process.platform === 'win32' && command === 'npm') {
6
17
  const argstring = 'npm ' + args.join(' ');
@@ -11,46 +22,46 @@ export async function spawnCommand(matterbridge, command, args, packageCommand,
11
22
  args.unshift(command);
12
23
  command = 'sudo';
13
24
  }
14
- matterbridge.log.debug(`Spawn command ${command} with ${args.join(' ')}`);
15
- return new Promise((resolve, reject) => {
25
+ log.debug(`Spawn command ${command} with ${args.join(' ')}`);
26
+ const success = await new Promise((resolve) => {
16
27
  if (packageCommand === 'install')
17
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-init', `Installing ${packageName}`);
28
+ sendLog('Matterbridge:spawn-init', `Installing ${packageName}`);
18
29
  else if (packageCommand === 'uninstall')
19
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-init', `Uninstalling ${packageName}`);
30
+ sendLog('Matterbridge:spawn-init', `Uninstalling ${packageName}`);
20
31
  const childProcess = spawn(command, args, {
21
32
  stdio: ['inherit', 'pipe', 'pipe'],
22
33
  });
23
34
  childProcess.on('error', (err) => {
24
- matterbridge.log.error(`Failed to start child process "${cmdLine}": ${err.message}`);
25
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-error', 'Spawn process error');
26
- reject(err);
35
+ log.error(`Failed to start child process "${cmdLine}": ${err.message}`);
36
+ sendLog('Matterbridge:spawn-exit-error', 'Spawn process error');
37
+ resolve(false);
27
38
  });
28
39
  childProcess.on('close', (code, signal) => {
29
40
  if (code === 0) {
30
- matterbridge.log.debug(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
31
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-success', 'Child process closed');
41
+ log.debug(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
42
+ sendLog('Matterbridge:spawn-exit-success', 'Child process closed');
32
43
  resolve(true);
33
44
  }
34
45
  else {
35
- matterbridge.log.error(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
36
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-error', 'Child process closed');
37
- reject(new Error(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`));
46
+ log.error(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
47
+ sendLog('Matterbridge:spawn-exit-error', 'Child process closed');
48
+ resolve(false);
38
49
  }
39
50
  });
40
51
  childProcess.on('exit', (code, signal) => {
41
52
  if (code === 0) {
42
- matterbridge.log.debug(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
43
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-success', 'Child process exited');
53
+ log.debug(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
54
+ sendLog('Matterbridge:spawn-exit-success', 'Child process exited');
44
55
  resolve(true);
45
56
  }
46
57
  else {
47
- matterbridge.log.error(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
48
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-error', 'Child process exited');
49
- reject(new Error(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`));
58
+ log.error(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
59
+ sendLog('Matterbridge:spawn-exit-error', 'Child process exited');
60
+ resolve(false);
50
61
  }
51
62
  });
52
63
  childProcess.on('disconnect', () => {
53
- matterbridge.log.debug(`Child process "${cmdLine}" has been disconnected from the parent`);
64
+ log.debug(`Child process "${cmdLine}" has been disconnected from the parent`);
54
65
  resolve(true);
55
66
  });
56
67
  if (childProcess.stdout) {
@@ -58,8 +69,8 @@ export async function spawnCommand(matterbridge, command, args, packageCommand,
58
69
  const message = data.toString().trim();
59
70
  const lines = message.split('\n');
60
71
  for (const line of lines) {
61
- matterbridge.log.debug(`Spawn output (stdout): ${line}`);
62
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', line);
72
+ log.debug(`Spawn output (stdout): ${line}`);
73
+ sendLog('Matterbridge:spawn', line);
63
74
  }
64
75
  });
65
76
  }
@@ -68,10 +79,12 @@ export async function spawnCommand(matterbridge, command, args, packageCommand,
68
79
  const message = data.toString().trim();
69
80
  const lines = message.split('\n');
70
81
  for (const line of lines) {
71
- matterbridge.log.debug(`Spawn verbose (stderr): ${line}`);
72
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', line);
82
+ log.debug(`Spawn verbose (stderr): ${line}`);
83
+ sendLog('Matterbridge:spawn', line);
73
84
  }
74
85
  });
75
86
  }
76
87
  });
88
+ server.close();
89
+ return success;
77
90
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.3.9-dev-20251119-ea13a99",
3
+ "version": "3.4.0-dev-20251120-1b65c89",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.3.9-dev-20251119-ea13a99",
9
+ "version": "3.4.0-dev-20251120-1b65c89",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.15.6",
@@ -284,9 +284,9 @@
284
284
  }
285
285
  },
286
286
  "node_modules/archiver-utils/node_modules/glob": {
287
- "version": "10.4.5",
288
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
289
- "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
287
+ "version": "10.5.0",
288
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
289
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
290
290
  "license": "ISC",
291
291
  "dependencies": {
292
292
  "foreground-child": "^3.1.0",
@@ -581,15 +581,16 @@
581
581
  }
582
582
  },
583
583
  "node_modules/content-disposition": {
584
- "version": "1.0.0",
585
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
586
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
584
+ "version": "1.0.1",
585
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
586
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
587
587
  "license": "MIT",
588
- "dependencies": {
589
- "safe-buffer": "5.2.1"
590
- },
591
588
  "engines": {
592
- "node": ">= 0.6"
589
+ "node": ">=18"
590
+ },
591
+ "funding": {
592
+ "type": "opencollective",
593
+ "url": "https://opencollective.com/express"
593
594
  }
594
595
  },
595
596
  "node_modules/content-type": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.3.9-dev-20251119-ea13a99",
3
+ "version": "3.4.0-dev-20251120-1b65c89",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",