matterbridge 3.4.1-dev-20251126-9e86094 → 3.4.1-dev-20251128-441f8db

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.
@@ -26,7 +26,7 @@ import { DeviceManager } from './deviceManager.js';
26
26
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
27
27
  import { bridge } from './matterbridgeDeviceTypes.js';
28
28
  import { Frontend } from './frontend.js';
29
- import { addVirtualDevices } from './helpers.js';
29
+ import { addVirtualDevice, addVirtualDevices } from './helpers.js';
30
30
  import { BroadcastServer } from './broadcastServer.js';
31
31
  export class Matterbridge extends EventEmitter {
32
32
  systemInformation = {
@@ -144,6 +144,24 @@ export class Matterbridge extends EventEmitter {
144
144
  this.log.logLevel = msg.params.logLevel;
145
145
  this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
146
146
  break;
147
+ case 'matterbridge_latest_version':
148
+ this.matterbridgeLatestVersion = msg.params.version;
149
+ await this.nodeContext?.set('matterbridgeLatestVersion', msg.params.version);
150
+ this.server.respond({ ...msg, response: { success: true } });
151
+ break;
152
+ case 'matterbridge_dev_version':
153
+ this.matterbridgeDevVersion = msg.params.version;
154
+ await this.nodeContext?.set('matterbridgeDevVersion', msg.params.version);
155
+ this.server.respond({ ...msg, response: { success: true } });
156
+ break;
157
+ case 'matterbridge_sys_update':
158
+ this.shellySysUpdate = true;
159
+ this.server.respond({ ...msg, response: { success: true } });
160
+ break;
161
+ case 'matterbridge_main_update':
162
+ this.shellyMainUpdate = true;
163
+ this.server.respond({ ...msg, response: { success: true } });
164
+ break;
147
165
  default:
148
166
  if (this.verbose)
149
167
  this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
@@ -1695,6 +1713,33 @@ export class Matterbridge extends EventEmitter {
1695
1713
  if (delay > 0)
1696
1714
  await wait(2000);
1697
1715
  }
1716
+ async addVirtualEndpoint(pluginName, name, type, callback) {
1717
+ const plugin = this.plugins.get(pluginName);
1718
+ if (!plugin) {
1719
+ this.log.error(`Error adding virtual endpoint ${dev}${name}${er} for plugin ${plg}${pluginName}${er}: plugin not found`);
1720
+ return false;
1721
+ }
1722
+ let aggregator;
1723
+ if (this.bridgeMode === 'bridge') {
1724
+ aggregator = this.aggregatorNode;
1725
+ }
1726
+ else if (this.bridgeMode === 'childbridge' && plugin.type === 'DynamicPlatform') {
1727
+ aggregator = plugin.aggregatorNode;
1728
+ }
1729
+ if (aggregator) {
1730
+ if (aggregator.parts.has(name.replaceAll(' ', '') + ':' + type)) {
1731
+ this.log.error(`Virtual endpoint ${dev}${name}${er} already registered for plugin ${plg}${pluginName}${er}. Please use a different name.`);
1732
+ return false;
1733
+ }
1734
+ else {
1735
+ await addVirtualDevice(aggregator, name.slice(0, 32), type, callback);
1736
+ this.log.info(`Created virtual endpoint ${dev}${name}${nf} for plugin ${plg}${pluginName}${nf}`);
1737
+ return true;
1738
+ }
1739
+ }
1740
+ this.log.error(`Virtual endpoint ${dev}${name}${er} for plugin ${plg}${pluginName}${er} not created. Virtual endpoints are only supported in bridge mode and childbridge mode with a DynamicPlatform.`);
1741
+ return false;
1742
+ }
1698
1743
  async subscribeAttributeChanged(plugin, device) {
1699
1744
  if (!plugin || !device || !device.plugin || !device.serialNumber || !device.uniqueId || !device.maybeNumber)
1700
1745
  return;
@@ -8,7 +8,6 @@ import { BridgedDeviceBasicInformation } from '@matter/types/clusters/bridged-de
8
8
  import { checkNotLatinCharacters } from './matterbridgeEndpointHelpers.js';
9
9
  import { bridgedNode } from './matterbridgeDeviceTypes.js';
10
10
  import { isValidArray, isValidObject, isValidString } from './utils/isvalid.js';
11
- import { addVirtualDevice } from './helpers.js';
12
11
  import { hasParameter } from './utils/commandLine.js';
13
12
  import { BroadcastServer } from './broadcastServer.js';
14
13
  export class MatterbridgePlatform {
@@ -167,26 +166,7 @@ export class MatterbridgePlatform {
167
166
  return this.#registeredEndpoints.has(deviceUniqueId);
168
167
  }
169
168
  async registerVirtualDevice(name, type, callback) {
170
- let aggregator;
171
- if (this.matterbridge.bridgeMode === 'bridge') {
172
- aggregator = this.matterbridge.aggregatorNode;
173
- }
174
- else if (this.matterbridge.bridgeMode === 'childbridge' && this.type === 'DynamicPlatform') {
175
- aggregator = this.matterbridge.plugins.get(this.name)?.aggregatorNode;
176
- }
177
- if (aggregator) {
178
- if (aggregator.parts.has(name.replaceAll(' ', '') + ':' + type)) {
179
- this.log.warn(`Virtual device ${name} already registered. Please use a different name.`);
180
- return false;
181
- }
182
- else {
183
- await addVirtualDevice(aggregator, name.slice(0, 32), type, callback);
184
- this.log.info(`Virtual device ${name} created.`);
185
- return true;
186
- }
187
- }
188
- this.log.warn(`Virtual device ${name} not created. Virtual devices are only supported in bridge mode and childbridge mode with a DynamicPlatform.`);
189
- return false;
169
+ return await this.matterbridge.addVirtualEndpoint(this.name, name, type, callback);
190
170
  }
191
171
  async registerDevice(device) {
192
172
  device.plugin = this.name;
@@ -194,6 +194,30 @@ export class PluginManager extends EventEmitter {
194
194
  }
195
195
  }
196
196
  break;
197
+ case 'plugins_set_latest_version':
198
+ {
199
+ const plugin = this.get(msg.params.plugin.name);
200
+ if (plugin) {
201
+ plugin.latestVersion = msg.params.version;
202
+ this.server.respond({ ...msg, response: { success: true } });
203
+ }
204
+ else {
205
+ this.server.respond({ ...msg, response: { success: false } });
206
+ }
207
+ }
208
+ break;
209
+ case 'plugins_set_dev_version':
210
+ {
211
+ const plugin = this.get(msg.params.plugin.name);
212
+ if (plugin) {
213
+ plugin.devVersion = msg.params.version;
214
+ this.server.respond({ ...msg, response: { success: true } });
215
+ }
216
+ else {
217
+ this.server.respond({ ...msg, response: { success: false } });
218
+ }
219
+ }
220
+ break;
197
221
  default:
198
222
  if (this.verbose)
199
223
  this.log.debug(`Unknown broadcast message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
package/dist/shelly.js CHANGED
@@ -7,22 +7,22 @@ export function setVerifyIntervalSecs(seconds) {
7
7
  export function setVerifyTimeoutSecs(seconds) {
8
8
  verifyTimeoutSecs = seconds;
9
9
  }
10
- export async function getShellySysUpdate(matterbridge) {
10
+ export async function getShellySysUpdate(matterbridge, log, server) {
11
11
  try {
12
12
  const updates = (await getShelly('/api/updates/sys/check'));
13
13
  if (updates.length === 0)
14
14
  return;
15
- matterbridge.shellySysUpdate = true;
16
- matterbridge.frontend.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_sys_update', success: true, response: { available: true } });
15
+ server.request({ type: 'matterbridge_sys_update', src: server.name, dst: 'matterbridge' });
16
+ server.request({ type: 'frontend_broadcast_message', src: server.name, dst: 'frontend', params: { msg: { id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_sys_update', success: true, response: { available: true } } } });
17
17
  for (const { name } of updates) {
18
18
  if (!name)
19
19
  continue;
20
- matterbridge.log.notice(`Shelly system update available: ${name}`);
21
- matterbridge.frontend.wssSendSnackbarMessage(`Shelly system update available: ${name}`, 10);
20
+ log.notice(`Shelly system update available: ${name}`);
21
+ server.request({ type: 'frontend_snackbarmessage', src: server.name, dst: 'frontend', params: { message: `Shelly system update available: ${name}`, timeout: 10 } });
22
22
  }
23
23
  }
24
24
  catch (err) {
25
- matterbridge.log.error(`Error getting Shelly system updates: ${err instanceof Error ? err.message : String(err)}`);
25
+ log.error(`Error getting Shelly system updates: ${err instanceof Error ? err.message : String(err)}`);
26
26
  }
27
27
  }
28
28
  export async function triggerShellySysUpdate(matterbridge) {
@@ -38,22 +38,22 @@ export async function triggerShellySysUpdate(matterbridge) {
38
38
  matterbridge.log.error(`Error triggering Shelly system update: ${err instanceof Error ? err.message : String(err)}`);
39
39
  }
40
40
  }
41
- export async function getShellyMainUpdate(matterbridge) {
41
+ export async function getShellyMainUpdate(matterbridge, log, server) {
42
42
  try {
43
43
  const updates = (await getShelly('/api/updates/main/check'));
44
44
  if (updates.length === 0)
45
45
  return;
46
- matterbridge.shellyMainUpdate = true;
47
- matterbridge.frontend.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_main_update', success: true, response: { available: true } });
46
+ server.request({ type: 'matterbridge_main_update', src: server.name, dst: 'matterbridge' });
47
+ server.request({ type: 'frontend_broadcast_message', src: server.name, dst: 'frontend', params: { msg: { id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_main_update', success: true, response: { available: true } } } });
48
48
  for (const { name } of updates) {
49
49
  if (!name)
50
50
  continue;
51
- matterbridge.log.notice(`Shelly software update available: ${name}`);
52
- matterbridge.frontend.wssSendSnackbarMessage(`Shelly software update available: ${name}`, 10);
51
+ log.notice(`Shelly software update available: ${name}`);
52
+ server.request({ type: 'frontend_snackbarmessage', src: server.name, dst: 'frontend', params: { message: `Shelly software update available: ${name}`, timeout: 10 } });
53
53
  }
54
54
  }
55
55
  catch (err) {
56
- matterbridge.log.error(`Error getting Shelly main updates: ${err instanceof Error ? err.message : String(err)}`);
56
+ log.error(`Error getting Shelly main updates: ${err instanceof Error ? err.message : String(err)}`);
57
57
  }
58
58
  }
59
59
  export async function triggerShellyMainUpdate(matterbridge) {
package/dist/update.js CHANGED
@@ -1,121 +1,137 @@
1
- import { db, debugStringify, nt, wr } from 'node-ansi-logger';
1
+ import { AnsiLogger, db, debugStringify, nt, wr } from 'node-ansi-logger';
2
2
  import { plg } from './matterbridgeTypes.js';
3
+ import { BroadcastServer } from './broadcastServer.js';
4
+ import { hasParameter } from './utils/commandLine.js';
5
+ import { isValidString } from './utils/isvalid.js';
3
6
  export async function checkUpdates(matterbridge) {
4
- const { hasParameter } = await import('./utils/commandLine.js');
5
- const update = checkUpdatesAndLog(matterbridge);
6
- const latestVersion = getMatterbridgeLatestVersion(matterbridge);
7
- const devVersion = getMatterbridgeDevVersion(matterbridge);
8
- const pluginsVersions = [];
9
- const pluginsDevVersions = [];
10
- const shellyUpdates = [];
11
- for (const plugin of matterbridge.plugins) {
12
- const pluginVersion = getPluginLatestVersion(matterbridge, plugin);
13
- pluginsVersions.push(pluginVersion);
14
- const pluginDevVersion = getPluginDevVersion(matterbridge, plugin);
15
- pluginsDevVersions.push(pluginDevVersion);
7
+ const log = new AnsiLogger({ logName: 'MatterbridgeUpdates', logTimestampFormat: 4, logLevel: matterbridge.logLevel });
8
+ const server = new BroadcastServer('updates', log);
9
+ const checkUpdatePromise = checkUpdatesAndLog(matterbridge, log, server);
10
+ const latestVersionPromise = getMatterbridgeLatestVersion(matterbridge, log, server);
11
+ const devVersionPromise = getMatterbridgeDevVersion(matterbridge, log, server);
12
+ const pluginsVersionPromises = [];
13
+ const pluginsDevVersionPromises = [];
14
+ const shellyUpdatesPromises = [];
15
+ const plugins = (await server.fetch({ type: 'plugins_apipluginarray', src: server.name, dst: 'plugins', params: {} })).response.plugins;
16
+ for (const plugin of plugins) {
17
+ pluginsVersionPromises.push(getPluginLatestVersion(log, server, plugin));
18
+ pluginsDevVersionPromises.push(getPluginDevVersion(log, server, plugin));
16
19
  }
17
20
  if (hasParameter('shelly')) {
18
21
  const { getShellySysUpdate, getShellyMainUpdate } = await import('./shelly.js');
19
- const systemUpdate = getShellySysUpdate(matterbridge);
20
- shellyUpdates.push(systemUpdate);
21
- const mainUpdate = getShellyMainUpdate(matterbridge);
22
- shellyUpdates.push(mainUpdate);
22
+ shellyUpdatesPromises.push(getShellySysUpdate(matterbridge, log, server));
23
+ shellyUpdatesPromises.push(getShellyMainUpdate(matterbridge, log, server));
23
24
  }
24
- await Promise.all([update, latestVersion, devVersion, ...pluginsVersions, ...pluginsDevVersions, ...shellyUpdates]);
25
+ await Promise.all([checkUpdatePromise, latestVersionPromise, devVersionPromise, ...pluginsVersionPromises, ...pluginsDevVersionPromises, ...shellyUpdatesPromises]);
26
+ server.close();
25
27
  }
26
- export async function checkUpdatesAndLog(matterbridge) {
28
+ export async function checkUpdatesAndLog(matterbridge, log, server) {
27
29
  const { getGitHubUpdate } = await import('./utils/network.js');
28
- const { isValidString } = await import('./utils/isvalid.js');
29
30
  const branch = matterbridge.matterbridgeVersion.includes('-dev-') ? 'dev' : 'main';
30
31
  try {
31
32
  const updateJson = await getGitHubUpdate(branch, 'update.json', 5_000);
32
- matterbridge.log.debug(`GitHub ${branch} update status: ${debugStringify(updateJson)}.`);
33
+ log.debug(`GitHub ${branch} update status: ${debugStringify(updateJson)}.`);
33
34
  if (isValidString(branch === 'main' ? updateJson.latestMessage : updateJson.devMessage, 1) &&
34
35
  isValidString(branch === 'main' ? updateJson.latestMessageSeverity : updateJson.devMessageSeverity, 4) &&
35
36
  ['info', 'warning', 'error', 'success'].includes(branch === 'main' ? updateJson.latestMessageSeverity : updateJson.devMessageSeverity)) {
36
- matterbridge.log.notice(`GitHub ${branch} update message: ${branch === 'main' ? updateJson.latestMessage : updateJson.devMessage}`);
37
- matterbridge.frontend.wssSendSnackbarMessage(branch === 'main' ? updateJson.latestMessage : updateJson.devMessage, 0, branch === 'main' ? updateJson.latestMessageSeverity : updateJson.devMessageSeverity);
37
+ log.notice(`GitHub ${branch} update message: ${branch === 'main' ? updateJson.latestMessage : updateJson.devMessage}`);
38
+ server.request({
39
+ type: 'frontend_snackbarmessage',
40
+ src: server.name,
41
+ dst: 'frontend',
42
+ params: { message: branch === 'main' ? updateJson.latestMessage : updateJson.devMessage, timeout: 0, severity: branch === 'main' ? updateJson.latestMessageSeverity : updateJson.devMessageSeverity },
43
+ });
38
44
  }
39
45
  }
40
46
  catch (error) {
41
- matterbridge.log.debug(`Error checking GitHub ${branch} updates: ${error instanceof Error ? error.message : error}`);
47
+ log.debug(`Error checking GitHub ${branch} updates: ${error instanceof Error ? error.message : error}`);
42
48
  }
43
49
  }
44
- export async function getMatterbridgeLatestVersion(matterbridge) {
50
+ export async function getMatterbridgeLatestVersion(matterbridge, log, server) {
45
51
  const { getNpmPackageVersion } = await import('./utils/network.js');
46
52
  try {
47
53
  const version = await getNpmPackageVersion('matterbridge');
48
- matterbridge.matterbridgeLatestVersion = version;
49
- await matterbridge.nodeContext?.set('matterbridgeLatestVersion', matterbridge.matterbridgeLatestVersion);
50
- if (matterbridge.matterbridgeVersion !== matterbridge.matterbridgeLatestVersion) {
51
- matterbridge.log.notice(`Matterbridge is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${matterbridge.matterbridgeLatestVersion}.`);
52
- matterbridge.frontend.wssSendSnackbarMessage('Matterbridge latest update available', 0, 'info');
53
- matterbridge.frontend.wssSendUpdateRequired();
54
- matterbridge.frontend.wssSendRefreshRequired('settings');
54
+ server.request({ type: 'matterbridge_latest_version', src: server.name, dst: 'matterbridge', params: { version } });
55
+ if (matterbridge.matterbridgeVersion !== version) {
56
+ log.notice(`Matterbridge is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${version}.`);
57
+ server.request({
58
+ type: 'frontend_snackbarmessage',
59
+ src: server.name,
60
+ dst: 'frontend',
61
+ params: { message: 'Matterbridge latest update available', timeout: 0, severity: 'info' },
62
+ });
63
+ server.request({ type: 'frontend_updaterequired', src: server.name, dst: 'frontend', params: { devVersion: false } });
64
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'settings' } });
55
65
  }
56
66
  else {
57
- matterbridge.log.debug(`Matterbridge is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${matterbridge.matterbridgeLatestVersion}.`);
67
+ log.debug(`Matterbridge is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${version}.`);
58
68
  }
59
69
  return version;
60
70
  }
61
71
  catch (error) {
62
- matterbridge.log.warn(`Error getting Matterbridge latest version: ${error instanceof Error ? error.message : error}`);
72
+ log.warn(`Error getting Matterbridge latest version: ${error instanceof Error ? error.message : error}`);
63
73
  }
64
74
  }
65
- export async function getMatterbridgeDevVersion(matterbridge) {
75
+ export async function getMatterbridgeDevVersion(matterbridge, log, server) {
66
76
  const { getNpmPackageVersion } = await import('./utils/network.js');
67
77
  try {
68
78
  const version = await getNpmPackageVersion('matterbridge', 'dev');
69
- matterbridge.matterbridgeDevVersion = version;
70
- await matterbridge.nodeContext?.set('matterbridgeDevVersion', version);
79
+ server.request({ type: 'matterbridge_dev_version', src: server.name, dst: 'matterbridge', params: { version } });
71
80
  if (matterbridge.matterbridgeVersion.includes('-dev-') && matterbridge.matterbridgeVersion !== version) {
72
- matterbridge.log.notice(`Matterbridge@dev is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${matterbridge.matterbridgeDevVersion}.`);
73
- matterbridge.frontend.wssSendSnackbarMessage('Matterbridge dev update available', 0, 'info');
74
- matterbridge.frontend.wssSendUpdateRequired(true);
75
- matterbridge.frontend.wssSendRefreshRequired('settings');
81
+ log.notice(`Matterbridge@dev is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${version}.`);
82
+ server.request({
83
+ type: 'frontend_snackbarmessage',
84
+ src: server.name,
85
+ dst: 'frontend',
86
+ params: { message: 'Matterbridge dev update available', timeout: 0, severity: 'info' },
87
+ });
88
+ server.request({ type: 'frontend_updaterequired', src: server.name, dst: 'frontend', params: { devVersion: true } });
89
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'settings' } });
76
90
  }
77
91
  else if (matterbridge.matterbridgeVersion.includes('-dev-') && matterbridge.matterbridgeVersion === version) {
78
- matterbridge.log.debug(`Matterbridge@dev is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${matterbridge.matterbridgeDevVersion}.`);
92
+ log.debug(`Matterbridge@dev is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${version}.`);
79
93
  }
80
94
  return version;
81
95
  }
82
96
  catch (error) {
83
- matterbridge.log.warn(`Error getting Matterbridge latest dev version: ${error instanceof Error ? error.message : error}`);
97
+ log.warn(`Error getting Matterbridge latest dev version: ${error instanceof Error ? error.message : error}`);
84
98
  }
85
99
  }
86
- export async function getPluginLatestVersion(matterbridge, plugin) {
100
+ export async function getPluginLatestVersion(log, server, plugin) {
87
101
  const { getNpmPackageVersion } = await import('./utils/network.js');
88
102
  try {
89
103
  const version = await getNpmPackageVersion(plugin.name);
90
104
  plugin.latestVersion = version;
105
+ server.request({ type: 'plugins_set_latest_version', src: server.name, dst: 'plugins', params: { plugin, version } });
91
106
  if (plugin.version !== plugin.latestVersion) {
92
- matterbridge.log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
93
- matterbridge.frontend.wssSendRefreshRequired('plugins');
107
+ log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
108
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'plugins' } });
94
109
  }
95
110
  else {
96
- matterbridge.log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
111
+ log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
97
112
  }
98
113
  return version;
99
114
  }
100
115
  catch (error) {
101
- matterbridge.log.warn(`Error getting plugin ${plg}${plugin.name}${wr} latest version: ${error instanceof Error ? error.message : error}`);
116
+ log.warn(`Error getting plugin ${plg}${plugin.name}${wr} latest version: ${error instanceof Error ? error.message : error}`);
102
117
  }
103
118
  }
104
- export async function getPluginDevVersion(matterbridge, plugin) {
119
+ export async function getPluginDevVersion(log, server, plugin) {
105
120
  const { getNpmPackageVersion } = await import('./utils/network.js');
106
121
  try {
107
122
  const version = await getNpmPackageVersion(plugin.name, 'dev');
108
123
  plugin.devVersion = version;
124
+ server.request({ type: 'plugins_set_dev_version', src: server.name, dst: 'plugins', params: { plugin, version } });
109
125
  if (plugin.version.includes('-dev-') && plugin.version !== plugin.devVersion) {
110
- matterbridge.log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest dev version: ${plugin.devVersion}.`);
111
- matterbridge.frontend.wssSendRefreshRequired('plugins');
126
+ log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest dev version: ${plugin.devVersion}.`);
127
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'plugins' } });
112
128
  }
113
129
  else if (plugin.version.includes('-dev-') && plugin.version === plugin.devVersion) {
114
- matterbridge.log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest dev version: ${plugin.devVersion}.`);
130
+ log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest dev version: ${plugin.devVersion}.`);
115
131
  }
116
132
  return version;
117
133
  }
118
134
  catch (error) {
119
- matterbridge.log.debug(`Error getting plugin ${plg}${plugin.name}${db} latest dev version: ${error instanceof Error ? error.message : error}`);
135
+ log.debug(`Error getting plugin ${plg}${plugin.name}${db} latest dev version: ${error instanceof Error ? error.message : error}`);
120
136
  }
121
137
  }
@@ -1 +1 @@
1
- body{font-family:Roboto,sans-serif}[frontend-theme=classic]{--main-bg-color: #c4c2c2;--main-text-color: black;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: #4d4d4d;--main-log-color: var(--main-text-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: #26292d;--main-menu-bg-color: #e2e2e2;--main-menu-hover-color: #959595;--main-label-color: var(--main-grey-color);--primary-color: #009a00;--secondary-color: #92771f;--header-bg-color: var(--primary-color);--header-text-color: white;--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: #ddd;--table-text-color: black;--table-even-bg-color: #bdbdbd;--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #5f8c9e;--table-selected-bg-color: #5f8c9e;--div-bg-color: #adadad;--div-text-color: black;--div-shadow-color: #888;--div-border-color: rgb(139, 139, 139);--div-border-radius: 0px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: black;background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=dark]{--main-bg-color: #26292d;--main-text-color: #ffffff;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: var(--main-light-color);--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-light-color);--main-menu-bg-color: var(--main-bg-color);--main-menu-hover-color: var(--div-bg-color);--main-label-color: var(--main-grey-color);--primary-color: #1976d2;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--primary-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: var(--main-bg-color);--table-selected-bg-color: var(--main-bg-color);--div-bg-color: #1b1d21;--div-text-color: var(--main-light-color);--div-shadow-color: #34373d;--div-border-color: #1b1d21;--div-border-radius: 5px;--div-title-bg-color: #1b1d21;--div-title-text-color: var(--primary-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=light]{--main-bg-color: #f0f0f0;--main-text-color: #212121;--main-grey-color: #616161;--main-light-color: #363636;--main-icon-color: #7a7a7a;--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-text-color);--main-menu-bg-color: var(--div-bg-color);--main-menu-hover-color: #85c0d8;--main-label-color: var(--main-grey-color);--primary-color: #2196f3;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--div-text-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #85c0d8;--table-selected-bg-color: #85c0d8;--div-bg-color: #ffffff;--div-text-color: #212121;--div-shadow-color: #bfbfbf;--div-border-color: var(--div-bg-color);--div-border-radius: 5px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: var(--div-text-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-thumb:hover{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-track{background:"inherit"}html,.thin-scroll{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--div-bg-color)}.thin-scroll::-webkit-scrollbar{width:5px;height:5px}.thin-scroll::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}.tooltip-container{position:relative;display:inline-block;z-index:10}.tooltip-text{visibility:hidden;background-color:var(--ttip-bg-color);color:var(--ttip-text-color);text-align:center;padding:5px;border-radius:6px;position:absolute;z-index:10;bottom:calc(100% + 10px);left:50%;margin-left:-60px;opacity:0;transition:opacity .3s;font-size:12px}.tooltip-container:hover{cursor:pointer;z-index:10}.tooltip-container:hover .tooltip-text{visibility:visible;opacity:1;z-index:10}.status-enabled{background-color:green;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-disabled{background-color:red;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-information{background-color:#9e9e9e;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-warning{background-color:#e9db18;color:#000;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-sponsor{background-color:#b6409c;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-blue{background-color:#5f8c9e;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:20px;margin:0;padding:0;height:40px}.sub-header{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;gap:20px;margin:0;padding:0;height:40px}nav{display:flex;align-items:center;gap:10px}.nav-link{margin:0;font-size:20px;text-decoration:none;color:var(--main-icon-color);transition:color .3s ease}.nav-link:hover{color:var(--primary-color)}table{border-collapse:collapse;width:100%;table-layout:auto}thead{position:sticky;top:0;border:1px solid var(--table-border-color);z-index:10}thead th{border:1px solid var(--table-border-color);padding:5px 10px;color:var(--header-text-color);background:var(--header-bg-color);text-align:left;z-index:10}tbody td{border:1px solid var(--table-border-color);margin:0;padding:5px 10px;text-align:left;font-size:14px}tbody tr:hover{color:var(--table-text-color);background-color:var(--table-hover-bg-color)}.table-content-even{color:var(--table-text-color);background-color:var(--table-even-bg-color)}.table-content-odd{color:var(--table-text-color);background-color:var(--table-odd-bg-color)}.table-content-selected{color:var(--table-text-color);background-color:var(--table-selected-bg-color)}h3{margin:0}.MbfScreen{display:flex;flex-direction:column;width:calc(100vw - 40px);height:calc(100vh - 40px);gap:20px;margin:0;padding:20px;background-color:var(--main-bg-color)}.MbfPageDiv{display:flex;flex-direction:column;height:100%;width:100%;margin:0;padding:0;gap:20px}.MbfWindowDiv{display:flex;flex-direction:column;box-shadow:5px 5px 10px var(--div-shadow-color);border:1px solid var(--table-border-color);border-radius:var(--div-border-radius);box-sizing:border-box;background-color:var(--div-bg-color)}.MbfWindowDivTable{display:block;flex:1 1 auto;overflow:auto;margin:-1px;padding:0;gap:0}.MbfWindowHeaderFooterIcons{display:flex;flex-direction:row;margin:0;padding:0 10px;gap:10px}.MbfWindowHeader{display:flex;flex-direction:row;align-items:center;width:100%;border-bottom:1px solid var(--table-border-color);color:var(--header-text-color);background-color:var(--header-bg-color);margin:0;padding:0;box-sizing:border-box}.MbfWindowHeaderText{color:var(--header-text-color);font-weight:700;margin:0;padding:5px 10px}.MbfWindowFooter{display:flex;flex-direction:row;align-items:center;justify-content:center;color:var(--footer-text-color);background-color:var(--footer-bg-color);margin:0;padding:0}.MbfWindowFooterText{color:var(--footer-text-color);background-color:var(--footer-bg-color);font-weight:700;text-align:center;margin:0;padding:5px 10px}.MbfWindowBody{display:flex;flex:1 1 auto;margin:0;padding:10px;gap:10px}.MbfWindowBodyColumn{display:flex;flex-direction:column;flex:1 1 auto;width:100%;margin:0;padding:10px 0;gap:0px;overflow:auto}.MbfWindowBodyRow{display:flex;flex-direction:row;flex:1 1 auto;height:100%;margin:0;padding:0 10px;gap:0px;overflow:auto}.configSubmitButton{display:flex;flex-direction:row;justify-content:center;width:auto;margin:20px}.configSubmitButton button{width:auto}@media(max-width:1300px){.MbfScreen{width:1300px;height:1024px}.xxxheader{flex-direction:column;align-items:start;justify-content:start}.xxxsub-header{align-items:start;justify-content:start}}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}
1
+ body{font-family:Roboto,sans-serif}[frontend-theme=classic]{--main-bg-color: #c4c2c2;--main-text-color: black;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: #4d4d4d;--main-log-color: var(--main-text-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: #26292d;--main-menu-bg-color: #e2e2e2;--main-menu-hover-color: #959595;--main-label-color: var(--main-grey-color);--primary-color: #009a00;--secondary-color: #92771f;--header-bg-color: var(--primary-color);--header-text-color: white;--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: #ddd;--table-text-color: black;--table-even-bg-color: #bdbdbd;--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #5f8c9e;--table-selected-bg-color: #5f8c9e;--div-bg-color: #adadad;--div-text-color: black;--div-shadow-color: #888;--div-border-color: rgb(139, 139, 139);--div-border-radius: 0px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: black;background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=dark]{--main-bg-color: #26292d;--main-text-color: #ffffff;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: var(--main-light-color);--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-light-color);--main-menu-bg-color: var(--main-bg-color);--main-menu-hover-color: var(--div-bg-color);--main-label-color: var(--main-grey-color);--primary-color: #1976d2;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--primary-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: var(--main-bg-color);--table-selected-bg-color: var(--main-bg-color);--div-bg-color: #1b1d21;--div-text-color: var(--main-light-color);--div-shadow-color: #34373d;--div-border-color: #1b1d21;--div-border-radius: 5px;--div-title-bg-color: #1b1d21;--div-title-text-color: var(--primary-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=light]{--main-bg-color: #f0f0f0;--main-text-color: #212121;--main-grey-color: #616161;--main-light-color: #363636;--main-icon-color: #7a7a7a;--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-text-color);--main-menu-bg-color: var(--div-bg-color);--main-menu-hover-color: #85c0d8;--main-label-color: var(--main-grey-color);--primary-color: #2196f3;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--div-text-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #85c0d8;--table-selected-bg-color: #85c0d8;--div-bg-color: #ffffff;--div-text-color: #212121;--div-shadow-color: #bfbfbf;--div-border-color: var(--div-bg-color);--div-border-radius: 5px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: var(--div-text-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-thumb:hover{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-track{background:"inherit"}html,.thin-scroll{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--div-bg-color)}.thin-scroll::-webkit-scrollbar{width:5px;height:5px}.thin-scroll::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}.tooltip-container{position:relative;display:inline-block;z-index:10}.tooltip-text{visibility:hidden;background-color:var(--ttip-bg-color);color:var(--ttip-text-color);text-align:center;padding:5px;border-radius:6px;position:absolute;z-index:10;bottom:calc(100% + 10px);left:50%;margin-left:-60px;opacity:0;transition:opacity .3s;font-size:12px}.tooltip-container:hover{cursor:pointer;z-index:10}.tooltip-container:hover .tooltip-text{visibility:visible;opacity:1;z-index:10}.status-enabled{background-color:green;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-disabled{background-color:red;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-information{background-color:#9e9e9e;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-warning{background-color:#e9db18;color:#000;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-sponsor{background-color:#b6409c;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-blue{background-color:#5f8c9e;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:20px;margin:0;padding:0;height:40px}.sub-header{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;gap:20px;margin:0;padding:0;height:40px}nav{display:flex;align-items:center;gap:10px}.nav-link{margin:0;font-size:20px;text-decoration:none;color:var(--main-icon-color);transition:color .3s ease}.nav-link:hover{color:var(--primary-color)}table{border-collapse:collapse;width:100%;table-layout:auto}thead{position:sticky;top:0;border:1px solid var(--table-border-color);z-index:10}thead th{border:1px solid var(--table-border-color);padding:5px 10px;color:var(--header-text-color);background:var(--header-bg-color);text-align:left;z-index:10}tbody td{border:1px solid var(--table-border-color);margin:0;padding:5px 10px;text-align:left;font-size:14px}tbody tr:hover{color:var(--table-text-color);background-color:var(--table-hover-bg-color)}.table-content-even{color:var(--table-text-color);background-color:var(--table-even-bg-color)}.table-content-odd{color:var(--table-text-color);background-color:var(--table-odd-bg-color)}.table-content-selected{color:var(--table-text-color);background-color:var(--table-selected-bg-color)}h3{margin:0}.MbfScreen{display:flex;flex-direction:column;width:calc(100vw - 40px);height:calc(100vh - 40px);gap:20px;margin:0;padding:20px;background-color:var(--main-bg-color)}.MbfPageDiv{display:flex;flex-direction:column;height:100%;width:100%;margin:0;padding:0;gap:20px}.MbfWindowDiv{display:flex;flex-direction:column;box-shadow:5px 5px 10px var(--div-shadow-color);border:1px solid var(--table-border-color);border-radius:var(--div-border-radius);box-sizing:border-box;background-color:var(--div-bg-color)}.MbfWindowDivTable{display:block;flex:1 1 auto;overflow:auto;margin:-1px;padding:0;gap:0}.MbfWindowHeaderFooterIcons{display:flex;flex-direction:row;margin:0;padding:0 10px;gap:10px}.MbfWindowHeader{display:flex;flex-direction:row;align-items:center;width:100%;border-bottom:1px solid var(--table-border-color);color:var(--header-text-color);background-color:var(--header-bg-color);margin:0;padding:0;box-sizing:border-box}.MbfWindowHeaderText{color:var(--header-text-color);font-weight:700;margin:0;padding:5px 10px}.MbfWindowFooter{display:flex;flex-direction:row;align-items:center;justify-content:center;color:var(--footer-text-color);background-color:var(--footer-bg-color);margin:0;padding:0}.MbfWindowFooterText{color:var(--footer-text-color);background-color:var(--footer-bg-color);font-weight:700;text-align:center;margin:0;padding:5px 10px}.MbfWindowBody{display:flex;flex:1 1 auto;margin:0;padding:10px;gap:10px}.MbfWindowBodyColumn{display:flex;flex-direction:column;flex:1 1 auto;width:100%;margin:0;padding:10px 0;gap:0px;overflow:auto}.MbfWindowBodyRow{display:flex;flex-direction:row;flex:1 1 auto;height:100%;margin:0;padding:0 10px;gap:0px;overflow:auto}.configSubmitButton{display:flex;flex-direction:row;justify-content:center;width:auto;margin:20px}.configSubmitButton button{width:auto}@media(max-width:1300px){.MbfScreen{width:1300px;height:1024px}}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}