@matterbridge/core 3.6.1-dev-20260309-6341dee → 3.6.1-dev-20260310-7887380
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/dist/cli.js +1 -0
- package/dist/devices/closure.js +1 -1
- package/dist/devices/closurePanel.js +1 -1
- package/dist/frontend.js +50 -22
- package/dist/matterbridge.d.ts +0 -1
- package/dist/matterbridge.js +38 -26
- package/dist/pluginManager.d.ts +3 -3
- package/dist/pluginManager.js +77 -46
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -175,6 +175,7 @@ function help() {
|
|
|
175
175
|
--delay [seconds]: set a delay in seconds before starting Matterbridge in the first 5 minutes from a reboot (default 120)
|
|
176
176
|
--fixed_delay [seconds]: set a fixed delay in seconds before starting Matterbridge (default 120)
|
|
177
177
|
--no-ansi: disable ANSI color output in the logs
|
|
178
|
+
--no-reset-sessions: disable resetting of sessions and resumption records on shutdown
|
|
178
179
|
`);
|
|
179
180
|
process.exit(0);
|
|
180
181
|
}
|
package/dist/devices/closure.js
CHANGED
|
@@ -9,7 +9,7 @@ const ClosureControlSchema = ClusterElement({
|
|
|
9
9
|
id: ClosureControl.Cluster.id,
|
|
10
10
|
name: ClosureControl.Cluster.name,
|
|
11
11
|
classification: 'application',
|
|
12
|
-
}, AttributeElement({ id: 0xfffd, name: 'ClusterRevision', type: 'ClusterRevision', conformance: 'M', default: ClosureControl.Base.revision
|
|
12
|
+
}, AttributeElement({ id: 0xfffd, name: 'ClusterRevision', type: 'ClusterRevision', conformance: 'M', default: ClosureControl.Base.revision }), AttributeElement({ id: 0xfffc, name: 'FeatureMap', type: 'FeatureMap', conformance: 'M' }, FieldElement({ name: 'POS', constraint: '0', title: 'Positioning' }), FieldElement({ name: 'ML', constraint: '1', title: 'MotionLatching' }), FieldElement({ name: 'INS', constraint: '2', title: 'Instantaneous' }), FieldElement({ name: 'SPD', constraint: '3', title: 'Speed' }), FieldElement({ name: 'VNT', constraint: '4', title: 'Ventilation' }), FieldElement({ name: 'PED', constraint: '5', title: 'Pedestrian' }), FieldElement({ name: 'CAL', constraint: '6', title: 'Calibration' }), FieldElement({ name: 'PRT', constraint: '7', title: 'Protection' }), FieldElement({ name: 'MAN', constraint: '8', title: 'ManuallyOperable' })), AttributeElement({ name: 'CountdownTime', id: 0x0000, type: 'uint32', conformance: 'POS', default: null, quality: 'X' }), AttributeElement({ name: 'MainState', id: 0x0001, type: 'MainStateEnum', conformance: 'M', constraint: 'desc' }), AttributeElement({ name: 'CurrentErrorList', id: 0x0002, type: 'list', conformance: 'M', default: [] }, FieldElement({ name: 'entry', type: 'ClosureErrorEnum' })), AttributeElement({ name: 'OverallCurrentState', id: 0x0003, type: 'OverallCurrentStateStruct', conformance: 'M', default: null, quality: 'X' }), AttributeElement({ name: 'OverallTargetState', id: 0x0004, type: 'OverallTargetStateStruct', conformance: 'M', default: null, quality: 'X' }), CommandElement({ name: 'Stop', id: 0x0000, conformance: 'M', direction: 'request', response: 'status' }), CommandElement({ name: 'MoveTo', id: 0x0001, conformance: 'M', direction: 'request', response: 'status' }, FieldElement({ name: 'Position', id: 0, type: 'TargetPositionEnum', conformance: 'O' }), FieldElement({ name: 'Latch', id: 1, type: 'bool', conformance: 'O' }), FieldElement({ name: 'Speed', id: 2, type: 'ThreeLevelAutoEnum', conformance: 'O' })), EventElement({ name: 'OperationalError', id: 0x0000, conformance: 'M', priority: 'critical' }, FieldElement({ name: 'ErrorState', id: 0, type: 'list', conformance: 'M', constraint: 'max 10' }, FieldElement({ name: 'entry', type: 'ClosureErrorEnum' }))), EventElement({ name: 'MovementCompleted', id: 0x0001, conformance: 'M', priority: 'info' }), EventElement({ name: 'SecureStateChanged', id: 0x0003, conformance: 'M', priority: 'info' }, FieldElement({ name: 'SecureValue', id: 0, type: 'bool', conformance: 'M' })), DatatypeElement({ name: 'ClosureErrorEnum', type: 'enum8' }, FieldElement({ name: 'PhysicallyBlocked', id: 0, conformance: 'M' }), FieldElement({ name: 'BlockedBySensor', id: 1, conformance: 'M' }), FieldElement({ name: 'TemperatureLimited', id: 2, conformance: 'M' }), FieldElement({ name: 'MaintenanceRequired', id: 3, conformance: 'M' }), FieldElement({ name: 'InternalInterference', id: 4, conformance: 'M' })), DatatypeElement({ name: 'CurrentPositionEnum', type: 'enum8' }, FieldElement({ name: 'FullyClosed', id: 0, conformance: 'M' }), FieldElement({ name: 'FullyOpened', id: 1, conformance: 'M' }), FieldElement({ name: 'PartiallyOpened', id: 2, conformance: 'M' }), FieldElement({ name: 'OpenedForPedestrian', id: 3, conformance: 'M' }), FieldElement({ name: 'OpenedForVentilation', id: 4, conformance: 'M' }), FieldElement({ name: 'OpenedAtSignature', id: 5, conformance: 'M' })), DatatypeElement({ name: 'MainStateEnum', type: 'enum8' }, FieldElement({ name: 'Stopped', id: 0, conformance: 'M' }), FieldElement({ name: 'Moving', id: 1, conformance: 'M' }), FieldElement({ name: 'WaitingForMotion', id: 2, conformance: 'M' }), FieldElement({ name: 'Error', id: 3, conformance: 'M' }), FieldElement({ name: 'Calibrating', id: 4, conformance: 'M' }), FieldElement({ name: 'Protected', id: 5, conformance: 'M' }), FieldElement({ name: 'Disengaged', id: 6, conformance: 'M' }), FieldElement({ name: 'SetupRequired', id: 7, conformance: 'M' })), DatatypeElement({ name: 'TargetPositionEnum', type: 'enum8' }, FieldElement({ name: 'MoveToFullyClosed', id: 0, conformance: 'M' }), FieldElement({ name: 'MoveToFullyOpen', id: 1, conformance: 'M' }), FieldElement({ name: 'MoveToPedestrianPosition', id: 2, conformance: 'M' }), FieldElement({ name: 'MoveToVentilationPosition', id: 3, conformance: 'M' }), FieldElement({ name: 'MoveToSignaturePosition', id: 4, conformance: 'M' })), DatatypeElement({ name: 'OverallCurrentStateStruct', type: 'struct' }, FieldElement({ name: 'Position', id: 0, type: 'CurrentPositionEnum', conformance: 'O', default: null, quality: 'X' }), FieldElement({ name: 'Latch', id: 1, type: 'bool', conformance: 'O', default: null, quality: 'X' }), FieldElement({ name: 'Speed', id: 2, type: 'ThreeLevelAutoEnum', conformance: 'O' }), FieldElement({ name: 'SecureState', id: 3, type: 'bool', conformance: 'O', default: null, quality: 'X' })), DatatypeElement({ name: 'OverallTargetStateStruct', type: 'struct' }, FieldElement({ name: 'Position', id: 0, type: 'TargetPositionEnum', conformance: 'O', default: null, quality: 'X' }), FieldElement({ name: 'Latch', id: 1, type: 'bool', conformance: 'O', default: null, quality: 'X' }), FieldElement({ name: 'Speed', id: 2, type: 'ThreeLevelAutoEnum', conformance: 'O' })));
|
|
13
13
|
const ClosureControlBehavior = ClusterBehavior.for(ClusterType(ClosureControl.Base), new ClusterModel(ClosureControlSchema));
|
|
14
14
|
export class ClosureControlServer extends ClosureControlBehavior.with(ClosureControl.Feature.Positioning) {
|
|
15
15
|
moveTo = (request) => {
|
|
@@ -9,7 +9,7 @@ const ClosureDimensionSchema = ClusterElement({
|
|
|
9
9
|
id: ClosureDimension.Cluster.id,
|
|
10
10
|
name: ClosureDimension.Cluster.name,
|
|
11
11
|
classification: 'application',
|
|
12
|
-
}, AttributeElement({ id: 0xfffd, name: 'ClusterRevision', type: 'ClusterRevision', conformance: 'M', default: ClosureDimension.Base.revision
|
|
12
|
+
}, AttributeElement({ id: 0xfffd, name: 'ClusterRevision', type: 'ClusterRevision', conformance: 'M', default: ClosureDimension.Base.revision }), AttributeElement({ id: 0xfffc, name: 'FeatureMap', type: 'FeatureMap', conformance: 'M' }, FieldElement({ name: 'POS', constraint: '0', title: 'Positioning' }), FieldElement({ name: 'ML', constraint: '1', title: 'MotionLatching' }), FieldElement({ name: 'UNI', constraint: '2', title: 'Unit' }), FieldElement({ name: 'LIM', constraint: '3', title: 'Limitation' }), FieldElement({ name: 'SPD', constraint: '4', title: 'Speed' }), FieldElement({ name: 'TRN', constraint: '5', title: 'Translation' }), FieldElement({ name: 'ROT', constraint: '6', title: 'Rotation' }), FieldElement({ name: 'MOD', constraint: '7', title: 'Modulation' })), AttributeElement({ name: 'CurrentState', id: 0x0000, type: 'DimensionStateStruct', conformance: 'M', default: null, quality: 'X' }), AttributeElement({ name: 'TargetState', id: 0x0001, type: 'DimensionStateStruct', conformance: 'M', default: null, quality: 'X' }), AttributeElement({ name: 'Resolution', id: 0x0002, type: 'percent100ths', conformance: 'POS', default: 1 }), AttributeElement({ name: 'StepValue', id: 0x0003, type: 'percent100ths', conformance: 'POS', default: 1 }), CommandElement({ name: 'SetTarget', id: 0x0000, conformance: 'M', direction: 'request', response: 'status' }, FieldElement({ name: 'Position', id: 0, type: 'percent100ths', conformance: 'O' }), FieldElement({ name: 'Latch', id: 1, type: 'bool', conformance: 'O' }), FieldElement({ name: 'Speed', id: 2, type: 'ThreeLevelAutoEnum', conformance: 'O' })), CommandElement({ name: 'Step', id: 0x0001, conformance: 'POS', direction: 'request', response: 'status' }, FieldElement({ name: 'Direction', id: 0, type: 'StepDirectionEnum', conformance: 'M' }), FieldElement({ name: 'NumberOfSteps', id: 1, type: 'uint16', conformance: 'M', constraint: { min: 1 } }), FieldElement({ name: 'Speed', id: 2, type: 'ThreeLevelAutoEnum', conformance: 'O' })), DatatypeElement({ name: 'StepDirectionEnum', type: 'enum8' }, FieldElement({ name: 'Decrease', id: 0, conformance: 'M' }), FieldElement({ name: 'Increase', id: 1, conformance: 'M' })), DatatypeElement({ name: 'DimensionStateStruct', type: 'struct' }, FieldElement({ name: 'Position', id: 0, type: 'percent100ths', conformance: 'O', default: null, quality: 'X' }), FieldElement({ name: 'Latch', id: 1, type: 'bool', conformance: 'O', default: null, quality: 'X' }), FieldElement({ name: 'Speed', id: 2, type: 'ThreeLevelAutoEnum', conformance: 'O' })));
|
|
13
13
|
const ClosureDimensionBehavior = ClusterBehavior.for(ClusterType(ClosureDimension.Base), new ClusterModel(ClosureDimensionSchema));
|
|
14
14
|
export class ClosureDimensionServer extends ClosureDimensionBehavior.with(ClosureDimension.Feature.Positioning) {
|
|
15
15
|
setTarget = (request) => {
|
package/dist/frontend.js
CHANGED
|
@@ -108,30 +108,30 @@ export class Frontend extends EventEmitter {
|
|
|
108
108
|
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
if (this.server.isWorkerResponse(msg) && msg.
|
|
111
|
+
if (this.server.isWorkerResponse(msg) && (msg.dst === 'all' || msg.dst === 'frontend')) {
|
|
112
112
|
if (this.verbose)
|
|
113
113
|
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
114
114
|
switch (msg.type) {
|
|
115
|
-
case '
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
break;
|
|
126
|
-
case 'plugins_uninstall':
|
|
127
|
-
this.wssSendCloseSnackbarMessage(`Uninstalling package ${msg.result.packageName}...`);
|
|
128
|
-
if (msg.result.success) {
|
|
129
|
-
this.wssSendRestartRequired(true, true);
|
|
130
|
-
this.wssSendRefreshRequired('plugins');
|
|
131
|
-
this.wssSendSnackbarMessage(`Uninstalled package ${msg.result.packageName}`, 5, 'success');
|
|
115
|
+
case 'manager_spawn_response':
|
|
116
|
+
if (msg.result && msg.result.packageCommand === 'install') {
|
|
117
|
+
this.wssSendCloseSnackbarMessage(`Installing package ${msg.result.packageName}...`);
|
|
118
|
+
if (msg.result.success) {
|
|
119
|
+
this.wssSendRestartRequired(true, true);
|
|
120
|
+
this.wssSendSnackbarMessage(`Installed package ${msg.result.packageName}`, 5, 'success');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
this.wssSendSnackbarMessage(`Package ${msg.result.packageName} not installed`, 10, 'error');
|
|
124
|
+
}
|
|
132
125
|
}
|
|
133
|
-
|
|
134
|
-
this.
|
|
126
|
+
if (msg.result && msg.result.packageCommand === 'uninstall') {
|
|
127
|
+
this.wssSendCloseSnackbarMessage(`Uninstalling package ${msg.result.packageName}...`);
|
|
128
|
+
if (msg.result.success) {
|
|
129
|
+
this.wssSendRestartRequired(true, true);
|
|
130
|
+
this.wssSendSnackbarMessage(`Uninstalled package ${msg.result.packageName}`, 5, 'success');
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
this.wssSendSnackbarMessage(`Package ${msg.result.packageName} not uninstalled`, 10, 'error');
|
|
134
|
+
}
|
|
135
135
|
}
|
|
136
136
|
break;
|
|
137
137
|
}
|
|
@@ -1266,7 +1266,21 @@ export class Frontend extends EventEmitter {
|
|
|
1266
1266
|
else if (data.method === '/api/install') {
|
|
1267
1267
|
if (isValidString(data.params.packageName, 12) && isValidBoolean(data.params.restart)) {
|
|
1268
1268
|
this.wssSendSnackbarMessage(`Installing package ${data.params.packageName}...`, 0);
|
|
1269
|
-
this.server.request({
|
|
1269
|
+
this.server.request({
|
|
1270
|
+
type: 'manager_run',
|
|
1271
|
+
src: 'frontend',
|
|
1272
|
+
dst: 'manager',
|
|
1273
|
+
params: {
|
|
1274
|
+
name: 'SpawnCommand',
|
|
1275
|
+
workerData: {
|
|
1276
|
+
threadName: 'SpawnCommand',
|
|
1277
|
+
command: 'npm',
|
|
1278
|
+
args: ['install', '-g', data.params.packageName, '--omit=dev', '--verbose'],
|
|
1279
|
+
packageCommand: 'install',
|
|
1280
|
+
packageName: data.params.packageName,
|
|
1281
|
+
},
|
|
1282
|
+
},
|
|
1283
|
+
});
|
|
1270
1284
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1271
1285
|
}
|
|
1272
1286
|
else {
|
|
@@ -1276,7 +1290,21 @@ export class Frontend extends EventEmitter {
|
|
|
1276
1290
|
else if (data.method === '/api/uninstall') {
|
|
1277
1291
|
if (isValidString(data.params.packageName, 12)) {
|
|
1278
1292
|
this.wssSendSnackbarMessage(`Uninstalling package ${data.params.packageName}...`, 0);
|
|
1279
|
-
this.server.request({
|
|
1293
|
+
this.server.request({
|
|
1294
|
+
type: 'manager_run',
|
|
1295
|
+
src: 'frontend',
|
|
1296
|
+
dst: 'manager',
|
|
1297
|
+
params: {
|
|
1298
|
+
name: 'SpawnCommand',
|
|
1299
|
+
workerData: {
|
|
1300
|
+
threadName: 'SpawnCommand',
|
|
1301
|
+
command: 'npm',
|
|
1302
|
+
args: ['uninstall', '-g', data.params.packageName, '--omit=dev', '--verbose'],
|
|
1303
|
+
packageCommand: 'uninstall',
|
|
1304
|
+
packageName: data.params.packageName,
|
|
1305
|
+
},
|
|
1306
|
+
},
|
|
1307
|
+
});
|
|
1280
1308
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1281
1309
|
}
|
|
1282
1310
|
else {
|
package/dist/matterbridge.d.ts
CHANGED
|
@@ -117,7 +117,6 @@ export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
|
|
|
117
117
|
private msgHandler;
|
|
118
118
|
static loadInstance(initialize?: boolean): Promise<Matterbridge>;
|
|
119
119
|
private initialize;
|
|
120
|
-
resolveWorkerDistFilePath(fileName: string): string;
|
|
121
120
|
private parseCommandLine;
|
|
122
121
|
private startPlugins;
|
|
123
122
|
private registerProcessHandlers;
|
package/dist/matterbridge.js
CHANGED
|
@@ -15,6 +15,7 @@ import { PaseClient, Read, Subscribe } from '@matter/protocol';
|
|
|
15
15
|
import { DeviceTypeId, VendorId } from '@matter/types/datatype';
|
|
16
16
|
import { BroadcastServer } from '@matterbridge/thread/server';
|
|
17
17
|
import { dev, MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg, typ } from '@matterbridge/types';
|
|
18
|
+
import { wait } from '@matterbridge/utils';
|
|
18
19
|
import { getIntParameter, getParameter, hasParameter } from '@matterbridge/utils/cli';
|
|
19
20
|
import { copyDirectory } from '@matterbridge/utils/copy-dir';
|
|
20
21
|
import { createDirectory } from '@matterbridge/utils/create-dir';
|
|
@@ -242,6 +243,23 @@ export class Matterbridge extends EventEmitter {
|
|
|
242
243
|
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
243
244
|
}
|
|
244
245
|
}
|
|
246
|
+
if (this.server.isWorkerResponse(msg) && (msg.dst === 'all' || msg.dst === 'matterbridge')) {
|
|
247
|
+
if (this.verbose)
|
|
248
|
+
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
249
|
+
switch (msg.type) {
|
|
250
|
+
case 'manager_spawn_response':
|
|
251
|
+
if (msg.result && msg.result.success && msg.result.packageCommand === 'install') {
|
|
252
|
+
this.restartRequired = true;
|
|
253
|
+
this.fixedRestartRequired = true;
|
|
254
|
+
if (msg.result.packageName === 'matterbridge') {
|
|
255
|
+
this.log.info('Matterbridge has been updated. Full restart required.');
|
|
256
|
+
if (this.restartMode !== '')
|
|
257
|
+
await this.cleanup('updating...', false);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
245
263
|
}
|
|
246
264
|
static async loadInstance(initialize = false) {
|
|
247
265
|
if (!Matterbridge.instance) {
|
|
@@ -601,19 +619,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
601
619
|
this.emit('initialize_completed');
|
|
602
620
|
this.initialized = true;
|
|
603
621
|
}
|
|
604
|
-
resolveWorkerDistFilePath(fileName) {
|
|
605
|
-
const currentModuleDirectory = path.dirname(fileURLToPath(import.meta.url));
|
|
606
|
-
const candidates = [
|
|
607
|
-
path.join(currentModuleDirectory, fileName),
|
|
608
|
-
path.join(currentModuleDirectory, '..', 'dist', fileName),
|
|
609
|
-
path.join(this.rootDirectory, 'node_modules', '@matterbridge', 'thread', 'dist', fileName),
|
|
610
|
-
];
|
|
611
|
-
for (const candidate of candidates) {
|
|
612
|
-
if (fs.existsSync(candidate))
|
|
613
|
-
return candidate;
|
|
614
|
-
}
|
|
615
|
-
return candidates[0];
|
|
616
|
-
}
|
|
617
622
|
async parseCommandLine() {
|
|
618
623
|
if (hasParameter('list')) {
|
|
619
624
|
this.log.info(`│ Registered plugins (${this.plugins.length})`);
|
|
@@ -651,6 +656,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
651
656
|
if (hasParameter('systemcheck')) {
|
|
652
657
|
const { systemCheck } = await import('@matterbridge/thread');
|
|
653
658
|
await systemCheck();
|
|
659
|
+
await wait(1000);
|
|
654
660
|
this.shutdown = true;
|
|
655
661
|
return;
|
|
656
662
|
}
|
|
@@ -730,15 +736,15 @@ export class Matterbridge extends EventEmitter {
|
|
|
730
736
|
return;
|
|
731
737
|
}
|
|
732
738
|
clearTimeout(this.systemCheckTimeout);
|
|
733
|
-
this.systemCheckTimeout = setTimeout(
|
|
739
|
+
this.systemCheckTimeout = setTimeout(() => {
|
|
734
740
|
this.server.request({ type: 'manager_run', src: 'matterbridge', dst: 'manager', params: { name: 'SystemCheck' } });
|
|
735
741
|
}, 120 * 1000).unref();
|
|
736
742
|
clearTimeout(this.checkUpdateTimeout);
|
|
737
|
-
this.checkUpdateTimeout = setTimeout(
|
|
743
|
+
this.checkUpdateTimeout = setTimeout(() => {
|
|
738
744
|
this.server.request({ type: 'manager_run', src: 'matterbridge', dst: 'manager', params: { name: 'CheckUpdates' } });
|
|
739
745
|
}, 300 * 1000).unref();
|
|
740
746
|
clearInterval(this.checkUpdateInterval);
|
|
741
|
-
this.checkUpdateInterval = setInterval(
|
|
747
|
+
this.checkUpdateInterval = setInterval(() => {
|
|
742
748
|
this.server.request({ type: 'manager_run', src: 'matterbridge', dst: 'manager', params: { name: 'CheckUpdates' } });
|
|
743
749
|
}, 12 * 60 * 60 * 1000).unref();
|
|
744
750
|
if (hasParameter('test')) {
|
|
@@ -1026,15 +1032,21 @@ export class Matterbridge extends EventEmitter {
|
|
|
1026
1032
|
}
|
|
1027
1033
|
async updateProcess() {
|
|
1028
1034
|
this.log.info('Updating matterbridge...');
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1035
|
+
this.server.request({
|
|
1036
|
+
type: 'manager_run',
|
|
1037
|
+
src: 'matterbridge',
|
|
1038
|
+
dst: 'manager',
|
|
1039
|
+
params: {
|
|
1040
|
+
name: 'SpawnCommand',
|
|
1041
|
+
workerData: {
|
|
1042
|
+
threadName: 'SpawnCommand',
|
|
1043
|
+
command: 'npm',
|
|
1044
|
+
args: ['install', '-g', 'matterbridge', '--omit=dev', '--verbose'],
|
|
1045
|
+
packageCommand: 'install',
|
|
1046
|
+
packageName: 'matterbridge',
|
|
1047
|
+
},
|
|
1048
|
+
},
|
|
1049
|
+
});
|
|
1038
1050
|
}
|
|
1039
1051
|
async unregisterAndShutdownProcess(timeout = 1000) {
|
|
1040
1052
|
const { wait } = await import('@matterbridge/utils/wait');
|
|
@@ -1176,7 +1188,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1176
1188
|
catch {
|
|
1177
1189
|
}
|
|
1178
1190
|
}
|
|
1179
|
-
if (
|
|
1191
|
+
if (!hasParameter('no-reset-sessions')) {
|
|
1180
1192
|
this.log.debug(`Cleaning matter storage context for ${GREEN}Matterbridge${db}...`);
|
|
1181
1193
|
unlinkSafe(path.join(this.matterbridgeDirectory, MATTER_STORAGE_NAME, 'Matterbridge', 'sessions.resumptionRecords'), this.log);
|
|
1182
1194
|
unlinkSafe(path.join(this.matterbridgeDirectory, MATTER_STORAGE_NAME, 'Matterbridge', 'root.subscriptions.subscriptions'), this.log);
|
package/dist/pluginManager.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { ApiPlugin, PlatformConfig, PlatformSchema, PluginName, StoragePlug
|
|
|
6
6
|
import { LogLevel } from 'node-ansi-logger';
|
|
7
7
|
import type { NodeStorage } from 'node-persist-manager';
|
|
8
8
|
import type { Matterbridge } from './matterbridge.js';
|
|
9
|
-
import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
|
|
9
|
+
import type { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
|
|
10
10
|
import { type MatterbridgePlatform } from './matterbridgePlatform.js';
|
|
11
11
|
export interface Plugin extends ApiPlugin {
|
|
12
12
|
nodeContext?: NodeStorage;
|
|
@@ -56,8 +56,8 @@ export declare class PluginManager extends EventEmitter<PluginManagerEvents> {
|
|
|
56
56
|
loadFromStorage(): Promise<StoragePlugin[]>;
|
|
57
57
|
saveToStorage(): Promise<number>;
|
|
58
58
|
resolve(nameOrPath: string): Promise<string | null>;
|
|
59
|
-
install(packageName: string):
|
|
60
|
-
uninstall(packageName: string):
|
|
59
|
+
install(packageName: string): void;
|
|
60
|
+
uninstall(packageName: string): void;
|
|
61
61
|
getAuthor(packageJson: Record<string, string | number | Record<string, string | number | object>>): string;
|
|
62
62
|
getHomepage(packageJson: Record<string, string | number | Record<string, string | number | object>>): string | undefined;
|
|
63
63
|
getHelp(packageJson: Record<string, string | number | Record<string, string | number | object>>): string | undefined;
|
package/dist/pluginManager.js
CHANGED
|
@@ -72,10 +72,12 @@ export class PluginManager extends EventEmitter {
|
|
|
72
72
|
this.server.respond({ ...msg, result: { plugins: this.apiPluginArray() } });
|
|
73
73
|
break;
|
|
74
74
|
case 'plugins_install':
|
|
75
|
-
this.
|
|
75
|
+
this.install(msg.params.packageName);
|
|
76
|
+
this.server.respond({ ...msg, result: { packageName: msg.params.packageName } });
|
|
76
77
|
break;
|
|
77
78
|
case 'plugins_uninstall':
|
|
78
|
-
this.
|
|
79
|
+
this.uninstall(msg.params.packageName);
|
|
80
|
+
this.server.respond({ ...msg, result: { packageName: msg.params.packageName } });
|
|
79
81
|
break;
|
|
80
82
|
case 'plugins_add':
|
|
81
83
|
{
|
|
@@ -229,6 +231,47 @@ export class PluginManager extends EventEmitter {
|
|
|
229
231
|
this.log.debug(`Unknown broadcast message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
230
232
|
}
|
|
231
233
|
}
|
|
234
|
+
if (this.server.isWorkerResponse(msg) && (msg.dst === 'all' || msg.dst === 'plugins')) {
|
|
235
|
+
if (this.verbose)
|
|
236
|
+
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
237
|
+
switch (msg.type) {
|
|
238
|
+
case 'manager_spawn_response':
|
|
239
|
+
if (msg.result && msg.result.packageCommand === 'install') {
|
|
240
|
+
if (msg.result.success) {
|
|
241
|
+
msg.result.packageName = msg.result.packageName.replace(/@.*$/, '');
|
|
242
|
+
if (msg.result.packageName !== 'matterbridge') {
|
|
243
|
+
if (!this.has(msg.result.packageName))
|
|
244
|
+
await this.add(msg.result.packageName);
|
|
245
|
+
const plugin = this.get(msg.result.packageName);
|
|
246
|
+
if (plugin && !plugin.loaded) {
|
|
247
|
+
await this.load(plugin);
|
|
248
|
+
this.server.request({ type: 'frontend_refreshrequired', src: 'plugins', dst: 'frontend', params: { changed: 'plugins' } });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
this.log.info(`Installed plugin ${plg}${msg.result.packageName}${db} successfully`);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
this.log.error(`Failed to install plugin ${plg}${msg.result.packageName}${er}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (msg.result && msg.result.packageCommand === 'uninstall') {
|
|
258
|
+
if (msg.result.success) {
|
|
259
|
+
if (this.has(msg.result.packageName)) {
|
|
260
|
+
const plugin = this.get(msg.result.packageName);
|
|
261
|
+
if (plugin && plugin.loaded)
|
|
262
|
+
await this.shutdown(plugin, 'Matterbridge is uninstalling the plugin');
|
|
263
|
+
await this.remove(msg.result.packageName);
|
|
264
|
+
this.server.request({ type: 'frontend_refreshrequired', src: 'plugins', dst: 'frontend', params: { changed: 'plugins' } });
|
|
265
|
+
}
|
|
266
|
+
this.log.info(`Uninstalled plugin ${plg}${msg.result.packageName}${db} successfully`);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
this.log.error(`Failed to uninstall plugin ${plg}${msg.result.packageName}${er}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
232
275
|
}
|
|
233
276
|
get length() {
|
|
234
277
|
return this._plugins.size;
|
|
@@ -484,53 +527,41 @@ export class PluginManager extends EventEmitter {
|
|
|
484
527
|
return null;
|
|
485
528
|
}
|
|
486
529
|
}
|
|
487
|
-
|
|
530
|
+
install(packageName) {
|
|
488
531
|
this.log.debug(`Installing plugin ${plg}${packageName}${db}...`);
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
this.log.info(`Installed plugin ${plg}${packageName}${db} successfully`);
|
|
507
|
-
return true;
|
|
508
|
-
}
|
|
509
|
-
else {
|
|
510
|
-
this.log.error(`Failed to install plugin ${plg}${packageName}${er}`);
|
|
511
|
-
return false;
|
|
512
|
-
}
|
|
532
|
+
this.server.request({
|
|
533
|
+
type: 'manager_run',
|
|
534
|
+
src: 'plugins',
|
|
535
|
+
dst: 'manager',
|
|
536
|
+
params: {
|
|
537
|
+
name: 'SpawnCommand',
|
|
538
|
+
workerData: {
|
|
539
|
+
threadName: 'SpawnCommand',
|
|
540
|
+
command: 'npm',
|
|
541
|
+
args: ['install', '-g', packageName, '--omit=dev', '--verbose'],
|
|
542
|
+
packageCommand: 'install',
|
|
543
|
+
packageName: packageName,
|
|
544
|
+
},
|
|
545
|
+
},
|
|
546
|
+
});
|
|
513
547
|
}
|
|
514
|
-
|
|
548
|
+
uninstall(packageName) {
|
|
515
549
|
this.log.debug(`Uninstalling plugin ${plg}${packageName}${db}...`);
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
this.log.error(`Failed to uninstall plugin ${plg}${packageName}${er}`);
|
|
532
|
-
return false;
|
|
533
|
-
}
|
|
550
|
+
this.server.request({
|
|
551
|
+
type: 'manager_run',
|
|
552
|
+
src: 'plugins',
|
|
553
|
+
dst: 'manager',
|
|
554
|
+
params: {
|
|
555
|
+
name: 'SpawnCommand',
|
|
556
|
+
workerData: {
|
|
557
|
+
threadName: 'SpawnCommand',
|
|
558
|
+
command: 'npm',
|
|
559
|
+
args: ['uninstall', '-g', packageName, '--omit=dev', '--verbose'],
|
|
560
|
+
packageCommand: 'uninstall',
|
|
561
|
+
packageName: packageName,
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
});
|
|
534
565
|
}
|
|
535
566
|
getAuthor(packageJson) {
|
|
536
567
|
if (packageJson.author && typeof packageJson.author === 'string')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.6.1-dev-
|
|
3
|
+
"version": "3.6.1-dev-20260310-7887380",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -122,10 +122,10 @@
|
|
|
122
122
|
],
|
|
123
123
|
"dependencies": {
|
|
124
124
|
"@matter/main": "0.16.10",
|
|
125
|
-
"@matterbridge/dgram": "3.6.1-dev-
|
|
126
|
-
"@matterbridge/thread": "3.6.1-dev-
|
|
127
|
-
"@matterbridge/types": "3.6.1-dev-
|
|
128
|
-
"@matterbridge/utils": "3.6.1-dev-
|
|
125
|
+
"@matterbridge/dgram": "3.6.1-dev-20260310-7887380",
|
|
126
|
+
"@matterbridge/thread": "3.6.1-dev-20260310-7887380",
|
|
127
|
+
"@matterbridge/types": "3.6.1-dev-20260310-7887380",
|
|
128
|
+
"@matterbridge/utils": "3.6.1-dev-20260310-7887380",
|
|
129
129
|
"archiver": "7.0.1",
|
|
130
130
|
"express": "5.2.1",
|
|
131
131
|
"glob": "13.0.6",
|