matterbridge 1.6.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -1
- package/README.md +4 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/defaultConfigSchema.d.ts +1 -1
- package/dist/defaultConfigSchema.js +1 -1
- package/dist/deviceManager.d.ts +1 -1
- package/dist/deviceManager.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/matterbridge.d.ts +21 -10
- package/dist/matterbridge.d.ts.map +1 -1
- package/dist/matterbridge.js +146 -37
- package/dist/matterbridge.js.map +1 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts +1 -1
- package/dist/matterbridgeAccessoryPlatform.js +1 -1
- package/dist/matterbridgeController.d.ts +1 -1
- package/dist/matterbridgeController.js +1 -1
- package/dist/matterbridgeDynamicPlatform.d.ts +1 -1
- package/dist/matterbridgeDynamicPlatform.js +1 -1
- package/dist/matterbridgeEdge.d.ts +1 -1
- package/dist/matterbridgeEdge.js +1 -1
- package/dist/matterbridgeEndpoint.d.ts +11 -42
- package/dist/matterbridgeEndpoint.d.ts.map +1 -1
- package/dist/matterbridgeEndpoint.js +1 -1
- package/dist/matterbridgePlatform.d.ts +1 -1
- package/dist/matterbridgePlatform.js +1 -1
- package/dist/matterbridgeWebsocket.d.ts.map +1 -1
- package/dist/matterbridgeWebsocket.js +36 -0
- package/dist/matterbridgeWebsocket.js.map +1 -1
- package/dist/pluginManager.d.ts +1 -1
- package/dist/pluginManager.js +1 -1
- package/dist/utils/colorUtils.d.ts +1 -1
- package/dist/utils/colorUtils.js +1 -1
- package/dist/utils/utils.d.ts +21 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +57 -1
- package/dist/utils/utils.js.map +1 -1
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,7 +10,7 @@ The Home Assistant Community Add-ons and plugins are not verified to work with M
|
|
|
10
10
|
|
|
11
11
|
If you want to run Matterbridge in Home Assistant please use the official add-on https://github.com/Luligu/matterbridge-home-assistant-addon that also has Ingress and side panel.
|
|
12
12
|
|
|
13
|
-
### New Apple firmware v. 18.
|
|
13
|
+
### New Apple firmware v. 18.x
|
|
14
14
|
|
|
15
15
|
Please read this: https://github.com/Luligu/matterbridge/discussions/135
|
|
16
16
|
|
|
@@ -20,6 +20,24 @@ Tamer (https://github.com/tammeryousef1006) has created the Matterbridge Discord
|
|
|
20
20
|
|
|
21
21
|
Feel free to join (the link is now permanent)!
|
|
22
22
|
|
|
23
|
+
## [1.6.1] - 2024-11-02
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- [matterbridge]: Added automatic recovery for matterbridge node storage when it gets corrupted for a power outage or hardware failure. Unattended setups can automatically recover restoring the previous automatic backup.
|
|
28
|
+
- [matterbridge]: Added automatic recovery for matter storage when it gets corrupted for a power outage or hardware failure. Unattended setups can automatically recover restoring the previous automatic backup.
|
|
29
|
+
- [matterbridge]: Added parameter "-norestore" to avoid to restore automatically. In this case you need to manually restore the storages from a full backup made from the frontend.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- [loggers]: Logging on file keeps the logger level of the logger (matterbridge and matter logs).
|
|
34
|
+
- [matterbridge]: Added more api to WebSocket for the Matterbridge cockpit dashboard (Shelly gateway).
|
|
35
|
+
- [package]: Update dependencies.
|
|
36
|
+
|
|
37
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
38
|
+
<img src="./yellow-button.png" alt="Buy me a coffee" width="120">
|
|
39
|
+
</a>
|
|
40
|
+
|
|
23
41
|
## [1.6.0] - 2024-10-28
|
|
24
42
|
|
|
25
43
|
### Added
|
package/README.md
CHANGED
|
@@ -380,6 +380,8 @@ The HomePods, being a WiFi devices, sometimes pruduce message trasmission errors
|
|
|
380
380
|
|
|
381
381
|
All issues have been solved from the version 17.5 of the HomePod/AppleTV. Now they are stable.
|
|
382
382
|
|
|
383
|
+
If you have more then one Apple TV or Home Pod, you can herve better results setting to disabled "Automatic Selection" in "Home Setting", "Home Hubs & Bridges". When "Automatic selection" is disabled, select your Apple Tv if you have one or any of your Home Pod. In this way you should not have anymore more then one session for fabric.
|
|
384
|
+
|
|
383
385
|
## Home Assistant
|
|
384
386
|
|
|
385
387
|
So far is the only controller supporting some Matter 1.2 and 1.3 device type:
|
|
@@ -409,6 +411,8 @@ Other supported cluster:
|
|
|
409
411
|
|
|
410
412
|
If you face a problem pairing to Google Home from Ios app the solution is there https://github.com/Luligu/matterbridge/issues/61.
|
|
411
413
|
|
|
414
|
+
If you face a problem changing the brightness check this for the explanation: https://github.com/Luligu/matterbridge-zigbee2mqtt/issues/80
|
|
415
|
+
|
|
412
416
|
No other issues reported so far.
|
|
413
417
|
|
|
414
418
|
## Alexa
|
package/dist/cli.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @date 2023-12-29
|
|
8
8
|
* @version 1.0.11
|
|
9
9
|
*
|
|
10
|
-
* Copyright 2023, 2024 Luca Liguori.
|
|
10
|
+
* Copyright 2023, 2024, 2025 Luca Liguori.
|
|
11
11
|
*
|
|
12
12
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
13
|
* you may not use this file except in compliance with the License.
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @date 2023-12-29
|
|
8
8
|
* @version 1.0.11
|
|
9
9
|
*
|
|
10
|
-
* Copyright 2023, 2024 Luca Liguori.
|
|
10
|
+
* Copyright 2023, 2024, 2025 Luca Liguori.
|
|
11
11
|
*
|
|
12
12
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
13
|
* you may not use this file except in compliance with the License.
|
|
@@ -59,10 +59,12 @@ async function restart() {
|
|
|
59
59
|
async function update() {
|
|
60
60
|
if (process.argv.includes('-debug'))
|
|
61
61
|
console.log(cli + 'CLI: received update event, updating...' + rs);
|
|
62
|
+
// TODO: Implement update logic outside of matterbridge
|
|
62
63
|
instance = await Matterbridge.loadInstance(true);
|
|
63
64
|
registerHandlers();
|
|
64
65
|
}
|
|
65
66
|
process.title = 'matterbridge';
|
|
67
|
+
// Run the main function
|
|
66
68
|
main().catch((error) => {
|
|
67
69
|
console.error(er + `CLI: Matterbridge.loadInstance() failed with error: ${error}` + rs);
|
|
68
70
|
});
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,+BAA+B;AAC/B,6BAA6B;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,IAAI,QAAkC,CAAC;AACvC,MAAM,GAAG,GAAG,YAAY,CAAC;AACzB,MAAM,EAAE,GAAG,gBAAgB,CAAC;AAC5B,MAAM,EAAE,GAAG,cAAc,CAAC;AAE1B,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;IACvG,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC;IACnB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;AACzG,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,QAAQ;QAAE,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,IAAI,QAAQ;QAAE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5D,IAAI,QAAQ;QAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,QAAQ;IACrB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,0CAA0C,GAAG,EAAE,CAAC,CAAC;IACxG,cAAc;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,OAAO;IACpB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;IACvG,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,MAAM;IACnB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;IACvG,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC;AACrB,CAAC;AAED,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC;AAE/B,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,uDAAuD,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AAC1F,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,+BAA+B;AAC/B,6BAA6B;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,IAAI,QAAkC,CAAC;AACvC,MAAM,GAAG,GAAG,YAAY,CAAC;AACzB,MAAM,EAAE,GAAG,gBAAgB,CAAC;AAC5B,MAAM,EAAE,GAAG,cAAc,CAAC;AAE1B,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;IACvG,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC;IACnB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;AACzG,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,QAAQ;QAAE,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,IAAI,QAAQ;QAAE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5D,IAAI,QAAQ;QAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,QAAQ;IACrB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,0CAA0C,GAAG,EAAE,CAAC,CAAC;IACxG,cAAc;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,OAAO;IACpB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;IACvG,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,MAAM;IACnB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,yCAAyC,GAAG,EAAE,CAAC,CAAC;IACvG,uDAAuD;IACvD,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC;AACrB,CAAC;AAED,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC;AAE/B,wBAAwB;AACxB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,uDAAuD,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AAC1F,CAAC,CAAC,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @date 2024-05-07
|
|
7
7
|
* @version 1.0.1
|
|
8
8
|
*
|
|
9
|
-
* Copyright 2024 Luca Liguori.
|
|
9
|
+
* Copyright 2024, 2025, 2026 Luca Liguori.
|
|
10
10
|
*
|
|
11
11
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
12
|
* you may not use this file except in compliance with the License.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @date 2024-05-07
|
|
7
7
|
* @version 1.0.1
|
|
8
8
|
*
|
|
9
|
-
* Copyright 2024 Luca Liguori.
|
|
9
|
+
* Copyright 2024, 2025, 2026 Luca Liguori.
|
|
10
10
|
*
|
|
11
11
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
12
|
* you may not use this file except in compliance with the License.
|
package/dist/deviceManager.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @date 2024-07-26
|
|
7
7
|
* @version 1.0.8
|
|
8
8
|
*
|
|
9
|
-
* Copyright 2024, 2025 Luca Liguori.
|
|
9
|
+
* Copyright 2024, 2025, 2026 Luca Liguori.
|
|
10
10
|
*
|
|
11
11
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
12
|
* you may not use this file except in compliance with the License.
|
package/dist/deviceManager.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @date 2024-07-26
|
|
7
7
|
* @version 1.0.8
|
|
8
8
|
*
|
|
9
|
-
* Copyright 2024, 2025 Luca Liguori.
|
|
9
|
+
* Copyright 2024, 2025, 2026 Luca Liguori.
|
|
10
10
|
*
|
|
11
11
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
12
|
* you may not use this file except in compliance with the License.
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @date 2023-12-29
|
|
7
7
|
* @version 1.0.6
|
|
8
8
|
*
|
|
9
|
-
* Copyright 2023, 2024 Luca Liguori.
|
|
9
|
+
* Copyright 2023, 2024, 2025 Luca Liguori.
|
|
10
10
|
*
|
|
11
11
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
12
|
* you may not use this file except in compliance with the License.
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @date 2023-12-29
|
|
7
7
|
* @version 1.0.6
|
|
8
8
|
*
|
|
9
|
-
* Copyright 2023, 2024 Luca Liguori.
|
|
9
|
+
* Copyright 2023, 2024, 2025 Luca Liguori.
|
|
10
10
|
*
|
|
11
11
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
12
|
* you may not use this file except in compliance with the License.
|
package/dist/matterbridge.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ import { BaseRegisteredPlugin, MatterbridgeInformation, SanitizedExposedFabricIn
|
|
|
29
29
|
import { PluginManager } from './pluginManager.js';
|
|
30
30
|
import { DeviceManager } from './deviceManager.js';
|
|
31
31
|
import { CommissioningController, CommissioningServer, MatterServer } from '@project-chip/matter-node.js';
|
|
32
|
-
import { DeviceTypeId } from '@project-chip/matter-node.js/datatype';
|
|
32
|
+
import { DeviceTypeId, VendorId } from '@project-chip/matter-node.js/datatype';
|
|
33
33
|
import { Aggregator } from '@project-chip/matter-node.js/device';
|
|
34
34
|
import { StorageContext, StorageManager } from '@project-chip/matter-node.js/storage';
|
|
35
35
|
/**
|
|
@@ -72,6 +72,8 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
72
72
|
private reachabilityTimeout;
|
|
73
73
|
private sigintHandler;
|
|
74
74
|
private sigtermHandler;
|
|
75
|
+
private exceptionHandler;
|
|
76
|
+
private rejectionHandler;
|
|
75
77
|
private expressApp;
|
|
76
78
|
private httpServer;
|
|
77
79
|
private httpsServer;
|
|
@@ -89,6 +91,8 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
89
91
|
protected matterAggregator: Aggregator | undefined;
|
|
90
92
|
protected commissioningServer: CommissioningServer | undefined;
|
|
91
93
|
protected commissioningController: CommissioningController | undefined;
|
|
94
|
+
protected aggregatorVendorId: VendorId;
|
|
95
|
+
protected aggregatorProductId: number;
|
|
92
96
|
protected static instance: Matterbridge | undefined;
|
|
93
97
|
protected constructor();
|
|
94
98
|
matterbridgeMessageHandler: (client: WebSocket, message: WebSocket.RawData) => Promise<void>;
|
|
@@ -136,14 +140,14 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
136
140
|
*/
|
|
137
141
|
private startPlugins;
|
|
138
142
|
/**
|
|
139
|
-
* Registers the
|
|
143
|
+
* Registers the process handlers for uncaughtException, unhandledRejection, SIGINT and SIGTERM.
|
|
140
144
|
* When either of these signals are received, the cleanup method is called with an appropriate message.
|
|
141
145
|
*/
|
|
142
|
-
private
|
|
146
|
+
private registerProcessHandlers;
|
|
143
147
|
/**
|
|
144
|
-
* Deregisters the SIGINT and SIGTERM signal handlers.
|
|
148
|
+
* Deregisters the process uncaughtException, unhandledRejection, SIGINT and SIGTERM signal handlers.
|
|
145
149
|
*/
|
|
146
|
-
private
|
|
150
|
+
private deregisterProcesslHandlers;
|
|
147
151
|
/**
|
|
148
152
|
* Logs the node and system information.
|
|
149
153
|
*/
|
|
@@ -193,15 +197,15 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
193
197
|
/**
|
|
194
198
|
* Update matterbridge and cleanup.
|
|
195
199
|
*/
|
|
196
|
-
|
|
200
|
+
protected updateProcess(): Promise<void>;
|
|
197
201
|
/**
|
|
198
202
|
* Restarts the process by spawning a new process and exiting the current process.
|
|
199
203
|
*/
|
|
200
|
-
|
|
204
|
+
protected restartProcess(): Promise<void>;
|
|
201
205
|
/**
|
|
202
206
|
* Shut down the process by exiting the current process.
|
|
203
207
|
*/
|
|
204
|
-
|
|
208
|
+
protected shutdownProcess(): Promise<void>;
|
|
205
209
|
/**
|
|
206
210
|
* Shut down the process and reset.
|
|
207
211
|
*/
|
|
@@ -277,6 +281,13 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
277
281
|
* @param backupName - The name of the backup file to be created.
|
|
278
282
|
*/
|
|
279
283
|
protected backupMatterStorage(storageName: string, backupName: string): Promise<void>;
|
|
284
|
+
/**
|
|
285
|
+
* Restore the specified matter JSON storage file.
|
|
286
|
+
*
|
|
287
|
+
* @param backupName - The name of the backup file to restore from.
|
|
288
|
+
* @param storageName - The name of the JSON storage file to restored.
|
|
289
|
+
*/
|
|
290
|
+
protected restoreMatterStorage(backupName: string, storageName: string): Promise<void>;
|
|
280
291
|
/**
|
|
281
292
|
* Stops the matter storage.
|
|
282
293
|
* @returns {Promise<void>} A promise that resolves when the storage is stopped.
|
|
@@ -391,9 +402,9 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
391
402
|
* Spawns a child process with the given command and arguments.
|
|
392
403
|
* @param {string} command - The command to execute.
|
|
393
404
|
* @param {string[]} args - The arguments to pass to the command (default: []).
|
|
394
|
-
* @returns {Promise<
|
|
405
|
+
* @returns {Promise<boolean>} A promise that resolves when the child process exits successfully, or rejects if there is an error.
|
|
395
406
|
*/
|
|
396
|
-
|
|
407
|
+
protected spawnCommand(command: string, args?: string[]): Promise<boolean>;
|
|
397
408
|
/**
|
|
398
409
|
* Sends a WebSocket message to all connected clients.
|
|
399
410
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matterbridge.d.ts","sourceRoot":"","sources":["../src/matterbridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,OAAO,YAAY,MAAM,QAAQ,CAAC;AAIlC,OAAO,SAA8B,MAAM,IAAI,CAAC;AAGhD,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAyK,MAAM,kBAAkB,CAAC;AAGrN,OAAO,EAAE,kBAAkB,EAAgC,MAAM,yBAAyB,CAAC;AAE3F,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAoB,iCAAiC,EAAE,2BAA2B,EAAsB,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChN,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,YAAY,EAA4B,MAAM,8BAA8B,CAAC;AAapI,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"matterbridge.d.ts","sourceRoot":"","sources":["../src/matterbridge.ts"],"names":[],"mappings":"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"}
|
package/dist/matterbridge.js
CHANGED
|
@@ -36,7 +36,7 @@ import { NodeStorageManager } from 'node-persist-manager';
|
|
|
36
36
|
import { AnsiLogger, UNDERLINE, UNDERLINEOFF, YELLOW, db, debugStringify, stringify, BRIGHT, RESET, er, nf, rs, wr, RED, GREEN, zb, hk, or, idn, BLUE, CYAN, nt } from 'node-ansi-logger';
|
|
37
37
|
// Matterbridge
|
|
38
38
|
import { MatterbridgeDevice } from './matterbridgeDevice.js';
|
|
39
|
-
import { logInterfaces, wait, waiter, createZip } from './utils/utils.js';
|
|
39
|
+
import { logInterfaces, wait, waiter, createZip, copyDirectory } from './utils/utils.js';
|
|
40
40
|
import { PluginManager } from './pluginManager.js';
|
|
41
41
|
import { DeviceManager } from './deviceManager.js';
|
|
42
42
|
// @project-chip/matter-node.js
|
|
@@ -136,6 +136,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
136
136
|
reachabilityTimeout;
|
|
137
137
|
sigintHandler;
|
|
138
138
|
sigtermHandler;
|
|
139
|
+
exceptionHandler;
|
|
140
|
+
rejectionHandler;
|
|
139
141
|
// Frontend
|
|
140
142
|
expressApp;
|
|
141
143
|
httpServer;
|
|
@@ -155,6 +157,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
155
157
|
matterAggregator;
|
|
156
158
|
commissioningServer;
|
|
157
159
|
commissioningController;
|
|
160
|
+
aggregatorVendorId = VendorId(0xfff1);
|
|
161
|
+
aggregatorProductId = 0x8000;
|
|
158
162
|
static instance;
|
|
159
163
|
// We load asyncronously so is private
|
|
160
164
|
constructor() {
|
|
@@ -221,19 +225,54 @@ export class Matterbridge extends EventEmitter {
|
|
|
221
225
|
// Set the matterbridge directory
|
|
222
226
|
this.homeDirectory = getParameter('homedir') ?? os.homedir();
|
|
223
227
|
this.matterbridgeDirectory = path.join(this.homeDirectory, '.matterbridge');
|
|
224
|
-
// Initialize nodeStorage and nodeContext
|
|
225
|
-
// this.log.debug(`Creating node storage manager: ${CYAN}${this.nodeStorageName}${db}`);
|
|
226
|
-
this.nodeStorage = new NodeStorageManager({ dir: path.join(this.matterbridgeDirectory, this.nodeStorageName), writeQueue: false, expiredInterval: undefined, logging: false });
|
|
227
|
-
// this.log.debug('Creating node storage context for matterbridge');
|
|
228
|
-
this.nodeContext = await this.nodeStorage.createStorage('matterbridge');
|
|
229
|
-
// Check if the storage is corrupted and remove it
|
|
230
|
-
// TODO: Check if the storage is corrupted and remove it
|
|
231
228
|
// Create matterbridge logger
|
|
232
|
-
this.log = new AnsiLogger({ logName: 'Matterbridge', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: "info" /* LogLevel.INFO */ });
|
|
233
|
-
//
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.
|
|
229
|
+
this.log = new AnsiLogger({ logName: 'Matterbridge', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: hasParameter('debug') ? "debug" /* LogLevel.DEBUG */ : "info" /* LogLevel.INFO */ });
|
|
230
|
+
// Initialize nodeStorage and nodeContext
|
|
231
|
+
try {
|
|
232
|
+
this.log.debug(`Creating node storage manager: ${CYAN}${this.nodeStorageName}${db}`);
|
|
233
|
+
this.nodeStorage = new NodeStorageManager({ dir: path.join(this.matterbridgeDirectory, this.nodeStorageName), writeQueue: false, expiredInterval: undefined, logging: false });
|
|
234
|
+
this.log.debug('Creating node storage context for matterbridge');
|
|
235
|
+
this.nodeContext = await this.nodeStorage.createStorage('matterbridge');
|
|
236
|
+
// TODO: Remove this code when node-persist-manager is updated
|
|
237
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
238
|
+
const keys = (await this.nodeStorage?.storage.keys());
|
|
239
|
+
for (const key of keys) {
|
|
240
|
+
this.log.debug(`Checking node storage manager key: ${CYAN}${key}${db}`);
|
|
241
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
242
|
+
await this.nodeStorage?.storage.get(key);
|
|
243
|
+
}
|
|
244
|
+
const storages = await this.nodeStorage.getStorageNames();
|
|
245
|
+
for (const storage of storages) {
|
|
246
|
+
this.log.debug(`Checking storage: ${CYAN}${storage}${db}`);
|
|
247
|
+
const nodeContext = await this.nodeStorage?.createStorage(storage);
|
|
248
|
+
// TODO: Remove this code when node-persist-manager is updated
|
|
249
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
250
|
+
const keys = (await nodeContext?.storage.keys());
|
|
251
|
+
keys.forEach(async (key) => {
|
|
252
|
+
this.log.debug(`Checking key: ${CYAN}${storage}:${key}${db}`);
|
|
253
|
+
await nodeContext?.get(key);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
// Creating a backup of the node storage since it is not corrupted
|
|
257
|
+
this.log.debug('Creating node storage backup...');
|
|
258
|
+
await copyDirectory(path.join(this.matterbridgeDirectory, this.nodeStorageName), path.join(this.matterbridgeDirectory, this.nodeStorageName + '.backup'));
|
|
259
|
+
this.log.debug('Created node storage backup');
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
// Restoring the backup of the node storage since it is corrupted
|
|
263
|
+
this.log.error(`Error creating node storage manager and context: ${error instanceof Error ? error.message : error}`);
|
|
264
|
+
if (hasParameter('norestore')) {
|
|
265
|
+
this.log.fatal(`The matterbridge node storage is corrupted. Parameter -norestore found: exiting...`);
|
|
266
|
+
await this.cleanup('Fatal error creating node storage manager and context for matterbridge');
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
this.log.notice(`The matterbridge storage is corrupted. Restoring it with backup...`);
|
|
270
|
+
await copyDirectory(path.join(this.matterbridgeDirectory, this.nodeStorageName + '.backup'), path.join(this.matterbridgeDirectory, this.nodeStorageName));
|
|
271
|
+
this.log.notice(`The matterbridge storage has been restored with backup`);
|
|
272
|
+
}
|
|
273
|
+
if (!this.nodeStorage || !this.nodeContext) {
|
|
274
|
+
this.log.fatal('Fatal error creating node storage manager and context for matterbridge');
|
|
275
|
+
throw new Error('Fatal error creating node storage manager and context for matterbridge');
|
|
237
276
|
}
|
|
238
277
|
// Set matterbridge logger level (context: matterbridgeLogLevel)
|
|
239
278
|
if (hasParameter('logger')) {
|
|
@@ -265,6 +304,11 @@ export class Matterbridge extends EventEmitter {
|
|
|
265
304
|
this.log.logLevel = await this.nodeContext.get('matterbridgeLogLevel', "info" /* LogLevel.INFO */);
|
|
266
305
|
}
|
|
267
306
|
MatterbridgeDevice.logLevel = this.log.logLevel;
|
|
307
|
+
// Create the file logger for matterbridge (context: matterbridgeFileLog)
|
|
308
|
+
if (hasParameter('filelogger') || (await this.nodeContext.get('matterbridgeFileLog', false))) {
|
|
309
|
+
AnsiLogger.setGlobalLogfile(path.join(this.matterbridgeDirectory, this.matterbrideLoggerFile), this.log.logLevel, true);
|
|
310
|
+
this.matterbridgeInformation.fileLogger = true;
|
|
311
|
+
}
|
|
268
312
|
this.log.notice('Matterbridge is starting...');
|
|
269
313
|
this.log.debug(`Matterbridge logLevel: ${this.log.logLevel} fileLoger: ${this.matterbridgeInformation.fileLogger}.`);
|
|
270
314
|
// Set matter.js logger level, format and logger (context: matterLogLevel)
|
|
@@ -302,7 +346,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
302
346
|
if (hasParameter('matterfilelogger') || (await this.nodeContext.get('matterFileLog', false))) {
|
|
303
347
|
this.matterbridgeInformation.matterFileLogger = true;
|
|
304
348
|
Logger.addLogger('matterfilelogger', await this.createMatterFileLogger(path.join(this.matterbridgeDirectory, this.matterLoggerFile), true), {
|
|
305
|
-
defaultLogLevel:
|
|
349
|
+
defaultLogLevel: Logger.defaultLogLevel,
|
|
306
350
|
logFormat: Format.PLAIN,
|
|
307
351
|
});
|
|
308
352
|
}
|
|
@@ -347,7 +391,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
347
391
|
// We don't do this when the add parameter is set because we shut down the process after adding the plugin
|
|
348
392
|
this.log.info(`Error parsing plugin ${plg}${plugin.name}${nf}. Trying to reinstall it from npm.`);
|
|
349
393
|
try {
|
|
350
|
-
await this.spawnCommand('npm', ['install', '-g', '--omit=dev',
|
|
394
|
+
await this.spawnCommand('npm', ['install', '-g', plugin.name, '--omit=dev', '--verbose']);
|
|
351
395
|
this.log.info(`Plugin ${plg}${plugin.name}${nf} reinstalled.`);
|
|
352
396
|
plugin.error = false;
|
|
353
397
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -383,8 +427,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
383
427
|
this.log.error(`Node version ${versionMajor} is not supported. Please upgrade to ${minNodeVersion} or above.`);
|
|
384
428
|
throw new Error(`Node version ${versionMajor} is not supported. Please upgrade to ${minNodeVersion} or above.`);
|
|
385
429
|
}
|
|
386
|
-
// Register
|
|
387
|
-
this.
|
|
430
|
+
// Register process handlers
|
|
431
|
+
this.registerProcessHandlers();
|
|
388
432
|
// Parse command line
|
|
389
433
|
await this.parseCommandLine();
|
|
390
434
|
this.initialized = true;
|
|
@@ -415,6 +459,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
415
459
|
- logstorage: log the node storage
|
|
416
460
|
- sudo: force the use of sudo to install or update packages if the internal logic fails
|
|
417
461
|
- nosudo: force not to use sudo to install or update packages if the internal logic fails
|
|
462
|
+
- norestore: force not to automatically restore the matterbridge node storage and the matter storage from backup if it is corrupted
|
|
418
463
|
- ssl: enable SSL for the frontend and WebSockerServer (certificates in .matterbridge/certs directory cert.pem, key.pem and ca.pem (optional))
|
|
419
464
|
- add [plugin path]: register the plugin from the given absolute or relative path
|
|
420
465
|
- add [plugin name]: register the globally installed plugin with the given name
|
|
@@ -522,7 +567,13 @@ export class Matterbridge extends EventEmitter {
|
|
|
522
567
|
return;
|
|
523
568
|
}
|
|
524
569
|
// Start the matter storage and create the matterbridge context
|
|
525
|
-
|
|
570
|
+
try {
|
|
571
|
+
await this.startMatterStorage('json', path.join(this.matterbridgeDirectory, this.matterStorageName));
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
this.log.fatal(`Fatal error creating matter storage: ${error instanceof Error ? error.message : error}`);
|
|
575
|
+
throw new Error(`Fatal error creating matter storage: ${error instanceof Error ? error.message : error}`);
|
|
576
|
+
}
|
|
526
577
|
if (hasParameter('reset') && getParameter('reset') === undefined) {
|
|
527
578
|
this.log.info('Resetting Matterbridge commissioning information...');
|
|
528
579
|
await this.matterbridgeContext?.clearAll();
|
|
@@ -635,10 +686,23 @@ export class Matterbridge extends EventEmitter {
|
|
|
635
686
|
this.wssSendRefreshRequired();
|
|
636
687
|
}
|
|
637
688
|
/**
|
|
638
|
-
* Registers the
|
|
689
|
+
* Registers the process handlers for uncaughtException, unhandledRejection, SIGINT and SIGTERM.
|
|
639
690
|
* When either of these signals are received, the cleanup method is called with an appropriate message.
|
|
640
691
|
*/
|
|
641
|
-
|
|
692
|
+
registerProcessHandlers() {
|
|
693
|
+
this.log.debug(`Registering uncaughtException and unhandledRejection handlers...`);
|
|
694
|
+
process.removeAllListeners('uncaughtException');
|
|
695
|
+
process.removeAllListeners('unhandledRejection');
|
|
696
|
+
this.exceptionHandler = async (error) => {
|
|
697
|
+
this.log.fatal('Unhandled Exception detected at:', error.stack || error, rs);
|
|
698
|
+
await this.cleanup('Unhandled Exception detected, cleaning up...');
|
|
699
|
+
};
|
|
700
|
+
process.on('uncaughtException', this.exceptionHandler);
|
|
701
|
+
this.rejectionHandler = async (reason, promise) => {
|
|
702
|
+
this.log.fatal('Unhandled Rejection detected at:', promise, 'reason:', reason instanceof Error ? reason.stack : reason, rs);
|
|
703
|
+
await this.cleanup('Unhandled Rejection detected, cleaning up...');
|
|
704
|
+
};
|
|
705
|
+
process.on('unhandledRejection', this.rejectionHandler);
|
|
642
706
|
this.log.debug(`Registering SIGINT and SIGTERM signal handlers...`);
|
|
643
707
|
this.sigintHandler = async () => {
|
|
644
708
|
await this.cleanup('SIGINT received, cleaning up...');
|
|
@@ -650,9 +714,16 @@ export class Matterbridge extends EventEmitter {
|
|
|
650
714
|
process.on('SIGTERM', this.sigtermHandler);
|
|
651
715
|
}
|
|
652
716
|
/**
|
|
653
|
-
* Deregisters the SIGINT and SIGTERM signal handlers.
|
|
717
|
+
* Deregisters the process uncaughtException, unhandledRejection, SIGINT and SIGTERM signal handlers.
|
|
654
718
|
*/
|
|
655
|
-
|
|
719
|
+
deregisterProcesslHandlers() {
|
|
720
|
+
this.log.debug(`Deregistering uncaughtException and unhandledRejection handlers...`);
|
|
721
|
+
if (this.exceptionHandler)
|
|
722
|
+
process.off('uncaughtException', this.exceptionHandler);
|
|
723
|
+
this.exceptionHandler = undefined;
|
|
724
|
+
if (this.rejectionHandler)
|
|
725
|
+
process.off('unhandledRejection', this.rejectionHandler);
|
|
726
|
+
this.rejectionHandler = undefined;
|
|
656
727
|
this.log.debug(`Deregistering SIGINT and SIGTERM signal handlers...`);
|
|
657
728
|
if (this.sigintHandler)
|
|
658
729
|
process.off('SIGINT', this.sigintHandler);
|
|
@@ -1053,8 +1124,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
1053
1124
|
if (this.initialized && !this.hasCleanupStarted) {
|
|
1054
1125
|
this.hasCleanupStarted = true;
|
|
1055
1126
|
this.log.info(message);
|
|
1056
|
-
// Deregisters the
|
|
1057
|
-
this.
|
|
1127
|
+
// Deregisters the process handlers
|
|
1128
|
+
this.deregisterProcesslHandlers();
|
|
1058
1129
|
// Clear the start matter interval
|
|
1059
1130
|
if (this.startMatterInterval) {
|
|
1060
1131
|
clearInterval(this.startMatterInterval);
|
|
@@ -1717,7 +1788,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1717
1788
|
* @returns {Promise<void>} - A promise that resolves when the storage process is started.
|
|
1718
1789
|
*/
|
|
1719
1790
|
async startMatterStorage(storageType, storageName) {
|
|
1720
|
-
this.log.debug(`Starting ${storageType} storage ${CYAN}${storageName}${db}`);
|
|
1791
|
+
this.log.debug(`Starting matter ${storageType} storage ${CYAN}${storageName}${db}`);
|
|
1721
1792
|
if (storageType === 'disk') {
|
|
1722
1793
|
const storageDisk = new StorageBackendDisk(storageName);
|
|
1723
1794
|
this.storageManager = new StorageManager(storageDisk);
|
|
@@ -1729,22 +1800,34 @@ export class Matterbridge extends EventEmitter {
|
|
|
1729
1800
|
this.storageManager = new StorageManager(storageJson);
|
|
1730
1801
|
}
|
|
1731
1802
|
else {
|
|
1732
|
-
this.log.error(`Unsupported storage type ${storageType}`);
|
|
1733
|
-
await this.cleanup('Unsupported storage type');
|
|
1803
|
+
this.log.error(`Unsupported matter storage type ${storageType}`);
|
|
1804
|
+
await this.cleanup('Unsupported matter storage type');
|
|
1734
1805
|
return;
|
|
1735
1806
|
}
|
|
1736
1807
|
try {
|
|
1737
1808
|
await this.storageManager.initialize();
|
|
1738
|
-
this.log.debug('
|
|
1809
|
+
this.log.debug('Matter storage initialized');
|
|
1739
1810
|
if (storageType === 'json') {
|
|
1740
1811
|
await this.backupMatterStorage(storageName, storageName.replace('.json', '') + '.backup.json');
|
|
1741
1812
|
}
|
|
1742
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1743
1813
|
}
|
|
1744
1814
|
catch (error) {
|
|
1745
|
-
this.log.error(`
|
|
1746
|
-
|
|
1747
|
-
|
|
1815
|
+
this.log.error(`Matter storage initialize error! The file .matterbridge/${storageName} may be corrupted: ${error instanceof Error ? error.message : error}`);
|
|
1816
|
+
if (hasParameter('norestore')) {
|
|
1817
|
+
this.log.fatal(`Please delete it and rename ${storageName.replace('.json', '.backup.json')} to ${storageName} and try to restart Matterbridge.`);
|
|
1818
|
+
await this.cleanup('Matter storage initialize error and -norestore parameter found!');
|
|
1819
|
+
return;
|
|
1820
|
+
}
|
|
1821
|
+
await this.restoreMatterStorage(storageName.replace('.json', '') + '.backup.json', storageName);
|
|
1822
|
+
try {
|
|
1823
|
+
await this.storageManager.initialize();
|
|
1824
|
+
this.log.notice('Matter storage initialized from the backup file');
|
|
1825
|
+
}
|
|
1826
|
+
catch (error) {
|
|
1827
|
+
this.log.error(`Matter storage initialize error! The backup file for .matterbridge/${storageName} may be corrupted too:`, error instanceof Error ? error.message : error);
|
|
1828
|
+
await this.cleanup('Matter storage initialize error from backup!');
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1748
1831
|
}
|
|
1749
1832
|
this.log.debug(`Creating commissioning server context for ${plg}Matterbridge${db}`);
|
|
1750
1833
|
this.matterbridgeContext = await this.createCommissioningServerContext('Matterbridge', 'Matterbridge', DeviceTypes.AGGREGATOR.code, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge aggregator');
|
|
@@ -1764,7 +1847,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1764
1847
|
catch (err) {
|
|
1765
1848
|
if (err instanceof Error && 'code' in err) {
|
|
1766
1849
|
if (err.code === 'ENOENT') {
|
|
1767
|
-
this.log.
|
|
1850
|
+
this.log.debug(`No existing file to back up for ${storageName}. This is expected on the first run.`);
|
|
1768
1851
|
}
|
|
1769
1852
|
else {
|
|
1770
1853
|
this.log.error(`Error making backup copy of ${storageName}: ${err.message}`);
|
|
@@ -1775,6 +1858,32 @@ export class Matterbridge extends EventEmitter {
|
|
|
1775
1858
|
}
|
|
1776
1859
|
}
|
|
1777
1860
|
}
|
|
1861
|
+
/**
|
|
1862
|
+
* Restore the specified matter JSON storage file.
|
|
1863
|
+
*
|
|
1864
|
+
* @param backupName - The name of the backup file to restore from.
|
|
1865
|
+
* @param storageName - The name of the JSON storage file to restored.
|
|
1866
|
+
*/
|
|
1867
|
+
async restoreMatterStorage(backupName, storageName) {
|
|
1868
|
+
try {
|
|
1869
|
+
this.log.notice(`Restoring the backup copy of ${storageName}`);
|
|
1870
|
+
await fs.copyFile(backupName, storageName);
|
|
1871
|
+
this.log.notice(`Successfully restored ${backupName} to ${storageName}`);
|
|
1872
|
+
}
|
|
1873
|
+
catch (err) {
|
|
1874
|
+
if (err instanceof Error && 'code' in err) {
|
|
1875
|
+
if (err.code === 'ENOENT') {
|
|
1876
|
+
this.log.info(`No existing file to restore: ${backupName}.`);
|
|
1877
|
+
}
|
|
1878
|
+
else {
|
|
1879
|
+
this.log.error(`Error restoring ${backupName}: ${err.message}`);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
else {
|
|
1883
|
+
this.log.error(`An unexpected error occurred during the restore of ${backupName}: ${String(err)}`);
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1778
1887
|
/**
|
|
1779
1888
|
* Stops the matter storage.
|
|
1780
1889
|
* @returns {Promise<void>} A promise that resolves when the storage is stopped.
|
|
@@ -2376,7 +2485,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2376
2485
|
* Spawns a child process with the given command and arguments.
|
|
2377
2486
|
* @param {string} command - The command to execute.
|
|
2378
2487
|
* @param {string[]} args - The arguments to pass to the command (default: []).
|
|
2379
|
-
* @returns {Promise<
|
|
2488
|
+
* @returns {Promise<boolean>} A promise that resolves when the child process exits successfully, or rejects if there is an error.
|
|
2380
2489
|
*/
|
|
2381
2490
|
async spawnCommand(command, args = []) {
|
|
2382
2491
|
/*
|
|
@@ -2421,7 +2530,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2421
2530
|
if (cmdLine.startsWith('npm install -g'))
|
|
2422
2531
|
this.log.notice(`Package ${cmdLine.replace('npm install -g ', '').replace('--verbose', '').replace('--omit=dev', '')} installed correctly`);
|
|
2423
2532
|
this.log.debug(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
|
|
2424
|
-
resolve();
|
|
2533
|
+
resolve(true);
|
|
2425
2534
|
}
|
|
2426
2535
|
else {
|
|
2427
2536
|
this.log.error(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
|
|
@@ -2432,7 +2541,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2432
2541
|
this.wssSendMessage('spawn', this.log.now(), 'Matterbridge:spawn', `child process exited with code ${code} and signal ${signal}`);
|
|
2433
2542
|
if (code === 0) {
|
|
2434
2543
|
this.log.debug(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
|
|
2435
|
-
resolve();
|
|
2544
|
+
resolve(true);
|
|
2436
2545
|
}
|
|
2437
2546
|
else {
|
|
2438
2547
|
this.log.error(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
|
|
@@ -2441,7 +2550,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2441
2550
|
});
|
|
2442
2551
|
childProcess.on('disconnect', () => {
|
|
2443
2552
|
this.log.debug(`Child process "${cmdLine}" has been disconnected from the parent`);
|
|
2444
|
-
resolve();
|
|
2553
|
+
resolve(true);
|
|
2445
2554
|
});
|
|
2446
2555
|
if (childProcess.stdout) {
|
|
2447
2556
|
childProcess.stdout.on('data', (data) => {
|