matter-server 0.2.2 → 0.2.4-alpha.0-20260116-d0b21f3
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/esm/MatterServer.js +2 -1
- package/dist/esm/MatterServer.js.map +1 -1
- package/dist/esm/cli.d.ts.map +1 -1
- package/dist/esm/cli.js +39 -10
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/version.d.ts +8 -0
- package/dist/esm/version.d.ts.map +1 -0
- package/dist/esm/version.js +30 -0
- package/dist/esm/version.js.map +6 -0
- package/package.json +7 -7
- package/src/MatterServer.ts +2 -1
- package/src/cli.ts +76 -19
- package/src/version.ts +46 -0
package/dist/esm/MatterServer.js
CHANGED
|
@@ -24,6 +24,7 @@ import { StaticFileHandler } from "./server/StaticFileHandler.js";
|
|
|
24
24
|
import { WebServer } from "./server/WebServer.js";
|
|
25
25
|
import "@matter-server/custom-clusters";
|
|
26
26
|
import { initializeOta } from "./ota.js";
|
|
27
|
+
import { MATTER_SERVER_VERSION } from "./version.js";
|
|
27
28
|
async function createFileLogger(path) {
|
|
28
29
|
const fileHandle = await open(path, "a");
|
|
29
30
|
const writer = fileHandle.createWriteStream();
|
|
@@ -140,7 +141,7 @@ async function start() {
|
|
|
140
141
|
});
|
|
141
142
|
logger.info("Legacy data event handlers configured for node commissioning/decommissioning");
|
|
142
143
|
}
|
|
143
|
-
const handlers = [new WebSocketControllerHandler(controller, config)];
|
|
144
|
+
const handlers = [new WebSocketControllerHandler(controller, config, MATTER_SERVER_VERSION)];
|
|
144
145
|
if (!cliOptions.disableDashboard) {
|
|
145
146
|
handlers.push(new StaticFileHandler());
|
|
146
147
|
} else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/MatterServer.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA,EACI;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACG;AACP,SAAS,YAAY;AACrB,SAAS,qBAAmD;AAC5D;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AACP,SAAS,yBAAyB;AAClC,SAAS,iBAAiB;AAG1B,OAAO;AACP,SAAS,qBAAqB;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/esm/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,QAAA,MAAM,UAAU,uEAAwE,CAAC;AAGzF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,WAAW,UAAU;IAEvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAG7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAG/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAGvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,gBAAgB,EAAE,OAAO,CAAC;IAG1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAG9B,gBAAgB,EAAE,OAAO,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,QAAA,MAAM,UAAU,uEAAwE,CAAC;AAGzF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,WAAW,UAAU;IAEvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAG7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAG/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAGvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,gBAAgB,EAAE,OAAO,CAAC;IAG1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAG9B,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AA6BD,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,CAkHxD;AAKD,wBAAgB,aAAa,IAAI,UAAU,CAK1C"}
|
package/dist/esm/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2025-2026 Open Home Foundation
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { Command, Option } from "commander";
|
|
6
|
+
import { Command, InvalidArgumentError, Option } from "commander";
|
|
7
7
|
import { readFileSync } from "node:fs";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
@@ -28,6 +28,12 @@ function parseIntOption(value) {
|
|
|
28
28
|
function collectAddresses(value, previous) {
|
|
29
29
|
return previous.concat(value);
|
|
30
30
|
}
|
|
31
|
+
function parseBooleanEnv(value) {
|
|
32
|
+
const lower = (value ?? "").toLowerCase().trim();
|
|
33
|
+
if (lower === "" || ["false", "0", "no", "off"].includes(lower)) return false;
|
|
34
|
+
if (["true", "1", "yes", "on"].includes(lower)) return true;
|
|
35
|
+
throw new InvalidArgumentError(`Invalid boolean value: "${value}". Use true/false, 1/0, yes/no, or on/off.`);
|
|
36
|
+
}
|
|
31
37
|
const DEPRECATED_OPTIONS = {
|
|
32
38
|
logLevelSdk: "--log-level-sdk",
|
|
33
39
|
logNodeIds: "--log-node-ids",
|
|
@@ -37,17 +43,34 @@ const DEPRECATED_OPTIONS = {
|
|
|
37
43
|
function parseCliArgs(argv) {
|
|
38
44
|
const program = new Command();
|
|
39
45
|
program.name("matter-server").description("Matter Controller Server using WebSockets.").version(VERSION);
|
|
40
|
-
program.
|
|
41
|
-
"--
|
|
42
|
-
|
|
43
|
-
parseIntOption
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
program.addOption(
|
|
47
|
+
new Option("--vendorid <id>", "Vendor ID for the Fabric").argParser(parseIntOption).default(DEFAULT_VENDOR_ID).env("VENDOR_ID")
|
|
48
|
+
).addOption(
|
|
49
|
+
new Option("--fabricid <id>", "Fabric ID for the Fabric (random if not specified)").argParser(parseIntOption).default(DEFAULT_FABRIC_ID).env("FABRIC_ID")
|
|
50
|
+
).addOption(
|
|
51
|
+
new Option("--storage-path <path>", "Storage path to keep persistent data").default(DEFAULT_STORAGE_PATH).env("STORAGE_PATH")
|
|
52
|
+
).addOption(
|
|
53
|
+
new Option("--port <port>", "TCP Port for WebSocket server").argParser(parseIntOption).default(DEFAULT_PORT).env("PORT")
|
|
54
|
+
).option(
|
|
46
55
|
"--listen-address <address>",
|
|
47
|
-
"IP address to bind WebSocket server (repeatable,
|
|
56
|
+
"IP address to bind WebSocket server (repeatable via CLI, single value via env: LISTEN_ADDRESS)",
|
|
48
57
|
collectAddresses,
|
|
49
58
|
[]
|
|
50
|
-
).addOption(
|
|
59
|
+
).addOption(
|
|
60
|
+
new Option("--log-level <level>", "Global logging level").choices(LOG_LEVELS).default("info").env("LOG_LEVEL")
|
|
61
|
+
).addOption(new Option("--log-file <path>", "Log file path (optional)").env("LOG_FILE")).addOption(
|
|
62
|
+
new Option("--primary-interface <interface>", "Primary network interface for link-local addresses").env(
|
|
63
|
+
"PRIMARY_INTERFACE"
|
|
64
|
+
)
|
|
65
|
+
).addOption(
|
|
66
|
+
new Option("--enable-test-net-dcl", "Enable test-net DCL certificates").argParser(parseBooleanEnv).default(false).env("ENABLE_TEST_NET_DCL")
|
|
67
|
+
).addOption(
|
|
68
|
+
new Option("--bluetooth-adapter <id>", "Bluetooth adapter HCI ID (e.g., 0 for hci0)").argParser(parseIntOption).env("BLUETOOTH_ADAPTER")
|
|
69
|
+
).addOption(
|
|
70
|
+
new Option("--disable-ota", "Disable OTA update functionality").argParser(parseBooleanEnv).default(false).env("DISABLE_OTA")
|
|
71
|
+
).addOption(new Option("--ota-provider-dir <path>", "Directory for OTA Provider files").env("OTA_PROVIDER_DIR")).addOption(
|
|
72
|
+
new Option("--disable-dashboard", "Disable the web dashboard").argParser(parseBooleanEnv).default(false).env("DISABLE_DASHBOARD")
|
|
73
|
+
).addOption(
|
|
51
74
|
new Option("--log-level-sdk <level>", "Matter SDK logging level (deprecated, no longer used)").choices(SDK_LOG_LEVELS).hideHelp()
|
|
52
75
|
).option("--log-node-ids <ids...>", "Node IDs to filter logs (deprecated, no longer used)").option("--paa-root-cert-dir <path>", "Directory for PAA root certificates (deprecated, no longer used)").option("--disable-server-interactions", "Disable server cluster interactions (deprecated, no longer used)");
|
|
53
76
|
program.parse(argv);
|
|
@@ -57,12 +80,18 @@ function parseCliArgs(argv) {
|
|
|
57
80
|
console.warn(`Warning: ${flag} is deprecated and no longer supported. This option will be ignored.`);
|
|
58
81
|
}
|
|
59
82
|
}
|
|
83
|
+
let listenAddress = null;
|
|
84
|
+
if (Array.isArray(opts.listenAddress) && opts.listenAddress.length > 0) {
|
|
85
|
+
listenAddress = opts.listenAddress;
|
|
86
|
+
} else if (process.env.LISTEN_ADDRESS) {
|
|
87
|
+
listenAddress = [process.env.LISTEN_ADDRESS];
|
|
88
|
+
}
|
|
60
89
|
return {
|
|
61
90
|
vendorId: opts.vendorid,
|
|
62
91
|
fabricId: opts.fabricid ?? void 0,
|
|
63
92
|
storagePath: opts.storagePath,
|
|
64
93
|
port: opts.port,
|
|
65
|
-
listenAddress
|
|
94
|
+
listenAddress,
|
|
66
95
|
logLevel: opts.logLevel,
|
|
67
96
|
logFile: opts.logFile ?? null,
|
|
68
97
|
primaryInterface: opts.primaryInterface ?? null,
|
package/dist/esm/cli.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cli.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,SAAS,SAAS,cAAc;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwCH,mCAAmC;AACnC,eAAO,MAAM,qBAAqB,QAA2B,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
function getMatterServerVersion() {
|
|
10
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
11
|
+
let dir = dirname(thisFile);
|
|
12
|
+
while (dir !== "/") {
|
|
13
|
+
try {
|
|
14
|
+
const packageJsonPath = join(dir, "package.json");
|
|
15
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
16
|
+
const pkg = JSON.parse(content);
|
|
17
|
+
if (pkg.name === "matter-server") {
|
|
18
|
+
return pkg.version;
|
|
19
|
+
}
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
dir = dirname(dir);
|
|
23
|
+
}
|
|
24
|
+
throw new Error("Could not find matter-server package.json");
|
|
25
|
+
}
|
|
26
|
+
const MATTER_SERVER_VERSION = getMatterServerVersion();
|
|
27
|
+
export {
|
|
28
|
+
MATTER_SERVER_VERSION
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/version.ts"],
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAU9B,SAAS,yBAAiC;AAEtC,QAAM,WAAW,cAAc,YAAY,GAAG;AAC9C,MAAI,MAAM,QAAQ,QAAQ;AAG1B,SAAO,QAAQ,KAAK;AAChB,QAAI;AACA,YAAM,kBAAkB,KAAK,KAAK,cAAc;AAChD,YAAM,UAAU,aAAa,iBAAiB,OAAO;AACrD,YAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,UAAI,IAAI,SAAS,iBAAiB;AAC9B,eAAO,IAAI;AAAA,MACf;AAAA,IACJ,QAAQ;AAAA,IAER;AACA,UAAM,QAAQ,GAAG;AAAA,EACrB;AACA,QAAM,IAAI,MAAM,2CAA2C;AAC/D;AAGO,MAAM,wBAAwB,uBAAuB;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matter-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4-alpha.0-20260116-d0b21f3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "WebSocket Matter server based on matter.js",
|
|
6
6
|
"bugs": {
|
|
@@ -23,18 +23,18 @@
|
|
|
23
23
|
"node": ">=20.19.0 <22.0.0 || >=22.13.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@matter/main": "0.16.
|
|
27
|
-
"@matter-server/ws-controller": "0.2.
|
|
28
|
-
"@matter-server/dashboard": "0.2.
|
|
29
|
-
"@matter-server/custom-clusters": "0.2.
|
|
26
|
+
"@matter/main": "0.16.4",
|
|
27
|
+
"@matter-server/ws-controller": "0.2.4-alpha.0-20260116-d0b21f3",
|
|
28
|
+
"@matter-server/dashboard": "0.2.4-alpha.0-20260116-d0b21f3",
|
|
29
|
+
"@matter-server/custom-clusters": "0.2.4-alpha.0-20260116-d0b21f3",
|
|
30
30
|
"commander": "^14.0.2",
|
|
31
31
|
"express": "^5.2.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/express": "^5.0.6",
|
|
35
35
|
"@types/node": "^25.0.8",
|
|
36
|
-
"@matter/testing": "0.16.
|
|
37
|
-
"@matter-server/ws-client": "0.2.
|
|
36
|
+
"@matter/testing": "0.16.4",
|
|
37
|
+
"@matter-server/ws-client": "0.2.4-alpha.0-20260116-d0b21f3"
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
40
|
"dist/**/*",
|
package/src/MatterServer.ts
CHANGED
|
@@ -30,6 +30,7 @@ import { WebServer } from "./server/WebServer.js";
|
|
|
30
30
|
// Register the custom clusters
|
|
31
31
|
import "@matter-server/custom-clusters";
|
|
32
32
|
import { initializeOta } from "./ota.js";
|
|
33
|
+
import { MATTER_SERVER_VERSION } from "./version.js";
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Creates a file-based logger that appends to the given path.
|
|
@@ -177,7 +178,7 @@ async function start() {
|
|
|
177
178
|
logger.info("Legacy data event handlers configured for node commissioning/decommissioning");
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
const handlers: WebServerHandler[] = [new WebSocketControllerHandler(controller, config)];
|
|
181
|
+
const handlers: WebServerHandler[] = [new WebSocketControllerHandler(controller, config, MATTER_SERVER_VERSION)];
|
|
181
182
|
if (!cliOptions.disableDashboard) {
|
|
182
183
|
handlers.push(new StaticFileHandler());
|
|
183
184
|
} else {
|
package/src/cli.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Compatible with Python Matter Server CLI interface.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { Command, Option } from "commander";
|
|
12
|
+
import { Command, InvalidArgumentError, Option } from "commander";
|
|
13
13
|
import { readFileSync } from "node:fs";
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
15
|
import { dirname, join } from "node:path";
|
|
@@ -76,6 +76,13 @@ function collectAddresses(value: string, previous: string[]): string[] {
|
|
|
76
76
|
return previous.concat(value);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
function parseBooleanEnv(value: string | undefined): boolean {
|
|
80
|
+
const lower = (value ?? "").toLowerCase().trim();
|
|
81
|
+
if (lower === "" || ["false", "0", "no", "off"].includes(lower)) return false;
|
|
82
|
+
if (["true", "1", "yes", "on"].includes(lower)) return true;
|
|
83
|
+
throw new InvalidArgumentError(`Invalid boolean value: "${value}". Use true/false, 1/0, yes/no, or on/off.`);
|
|
84
|
+
}
|
|
85
|
+
|
|
79
86
|
/** Deprecated options that are still accepted but no longer used */
|
|
80
87
|
const DEPRECATED_OPTIONS: Record<string, string> = {
|
|
81
88
|
logLevelSdk: "--log-level-sdk",
|
|
@@ -90,29 +97,71 @@ export function parseCliArgs(argv?: string[]): CliOptions {
|
|
|
90
97
|
program.name("matter-server").description("Matter Controller Server using WebSockets.").version(VERSION);
|
|
91
98
|
|
|
92
99
|
program
|
|
93
|
-
.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
.addOption(
|
|
101
|
+
new Option("--vendorid <id>", "Vendor ID for the Fabric")
|
|
102
|
+
.argParser(parseIntOption)
|
|
103
|
+
.default(DEFAULT_VENDOR_ID)
|
|
104
|
+
.env("VENDOR_ID"),
|
|
105
|
+
)
|
|
106
|
+
.addOption(
|
|
107
|
+
new Option("--fabricid <id>", "Fabric ID for the Fabric (random if not specified)")
|
|
108
|
+
.argParser(parseIntOption)
|
|
109
|
+
.default(DEFAULT_FABRIC_ID)
|
|
110
|
+
.env("FABRIC_ID"),
|
|
111
|
+
)
|
|
112
|
+
.addOption(
|
|
113
|
+
new Option("--storage-path <path>", "Storage path to keep persistent data")
|
|
114
|
+
.default(DEFAULT_STORAGE_PATH)
|
|
115
|
+
.env("STORAGE_PATH"),
|
|
116
|
+
)
|
|
117
|
+
.addOption(
|
|
118
|
+
new Option("--port <port>", "TCP Port for WebSocket server")
|
|
119
|
+
.argParser(parseIntOption)
|
|
120
|
+
.default(DEFAULT_PORT)
|
|
121
|
+
.env("PORT"),
|
|
99
122
|
)
|
|
100
|
-
.option("--storage-path <path>", "Storage path to keep persistent data", DEFAULT_STORAGE_PATH)
|
|
101
|
-
.option("--port <port>", "TCP Port for WebSocket server", parseIntOption, DEFAULT_PORT)
|
|
102
123
|
.option(
|
|
103
124
|
"--listen-address <address>",
|
|
104
|
-
"IP address to bind WebSocket server (repeatable,
|
|
125
|
+
"IP address to bind WebSocket server (repeatable via CLI, single value via env: LISTEN_ADDRESS)",
|
|
105
126
|
collectAddresses,
|
|
106
127
|
[],
|
|
107
128
|
)
|
|
108
|
-
.addOption(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
.
|
|
115
|
-
.
|
|
129
|
+
.addOption(
|
|
130
|
+
new Option("--log-level <level>", "Global logging level")
|
|
131
|
+
.choices(LOG_LEVELS)
|
|
132
|
+
.default("info")
|
|
133
|
+
.env("LOG_LEVEL"),
|
|
134
|
+
)
|
|
135
|
+
.addOption(new Option("--log-file <path>", "Log file path (optional)").env("LOG_FILE"))
|
|
136
|
+
.addOption(
|
|
137
|
+
new Option("--primary-interface <interface>", "Primary network interface for link-local addresses").env(
|
|
138
|
+
"PRIMARY_INTERFACE",
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
.addOption(
|
|
142
|
+
new Option("--enable-test-net-dcl", "Enable test-net DCL certificates")
|
|
143
|
+
.argParser(parseBooleanEnv)
|
|
144
|
+
.default(false)
|
|
145
|
+
.env("ENABLE_TEST_NET_DCL"),
|
|
146
|
+
)
|
|
147
|
+
.addOption(
|
|
148
|
+
new Option("--bluetooth-adapter <id>", "Bluetooth adapter HCI ID (e.g., 0 for hci0)")
|
|
149
|
+
.argParser(parseIntOption)
|
|
150
|
+
.env("BLUETOOTH_ADAPTER"),
|
|
151
|
+
)
|
|
152
|
+
.addOption(
|
|
153
|
+
new Option("--disable-ota", "Disable OTA update functionality")
|
|
154
|
+
.argParser(parseBooleanEnv)
|
|
155
|
+
.default(false)
|
|
156
|
+
.env("DISABLE_OTA"),
|
|
157
|
+
)
|
|
158
|
+
.addOption(new Option("--ota-provider-dir <path>", "Directory for OTA Provider files").env("OTA_PROVIDER_DIR"))
|
|
159
|
+
.addOption(
|
|
160
|
+
new Option("--disable-dashboard", "Disable the web dashboard")
|
|
161
|
+
.argParser(parseBooleanEnv)
|
|
162
|
+
.default(false)
|
|
163
|
+
.env("DISABLE_DASHBOARD"),
|
|
164
|
+
)
|
|
116
165
|
// Deprecated options - still accepted for backwards compatibility
|
|
117
166
|
.addOption(
|
|
118
167
|
new Option("--log-level-sdk <level>", "Matter SDK logging level (deprecated, no longer used)")
|
|
@@ -133,12 +182,20 @@ export function parseCliArgs(argv?: string[]): CliOptions {
|
|
|
133
182
|
}
|
|
134
183
|
}
|
|
135
184
|
|
|
185
|
+
// Handle listenAddress: CLI provides an array, env var (LISTEN_ADDRESS) provides a single string
|
|
186
|
+
let listenAddress: string[] | null = null;
|
|
187
|
+
if (Array.isArray(opts.listenAddress) && opts.listenAddress.length > 0) {
|
|
188
|
+
listenAddress = opts.listenAddress;
|
|
189
|
+
} else if (process.env.LISTEN_ADDRESS) {
|
|
190
|
+
listenAddress = [process.env.LISTEN_ADDRESS];
|
|
191
|
+
}
|
|
192
|
+
|
|
136
193
|
return {
|
|
137
194
|
vendorId: opts.vendorid,
|
|
138
195
|
fabricId: opts.fabricid ?? undefined,
|
|
139
196
|
storagePath: opts.storagePath,
|
|
140
197
|
port: opts.port,
|
|
141
|
-
listenAddress
|
|
198
|
+
listenAddress,
|
|
142
199
|
logLevel: opts.logLevel,
|
|
143
200
|
logFile: opts.logFile ?? null,
|
|
144
201
|
primaryInterface: opts.primaryInterface ?? null,
|
package/src/version.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Utility to get the matter-server package version.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
|
|
15
|
+
interface PackageJson {
|
|
16
|
+
version: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get the version of the matter-server package.
|
|
22
|
+
*/
|
|
23
|
+
function getMatterServerVersion(): string {
|
|
24
|
+
// Get the directory of this module
|
|
25
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
26
|
+
let dir = dirname(thisFile);
|
|
27
|
+
|
|
28
|
+
// Navigate up to find package.json
|
|
29
|
+
while (dir !== "/") {
|
|
30
|
+
try {
|
|
31
|
+
const packageJsonPath = join(dir, "package.json");
|
|
32
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
33
|
+
const pkg = JSON.parse(content) as PackageJson;
|
|
34
|
+
if (pkg.name === "matter-server") {
|
|
35
|
+
return pkg.version;
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
// Continue searching
|
|
39
|
+
}
|
|
40
|
+
dir = dirname(dir);
|
|
41
|
+
}
|
|
42
|
+
throw new Error("Could not find matter-server package.json");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Cached matter-server version */
|
|
46
|
+
export const MATTER_SERVER_VERSION = getMatterServerVersion();
|