@camstack/addon-matter-broker 0.2.158 → 0.2.159
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 +6 -0
- package/dist/addon.js +126 -125
- package/dist/addon.mjs +127 -126
- package/dist/index.mjs +1 -1
- package/i18n/en.json +0 -3
- package/i18n/it.json +0 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.159] - 2026-11-05
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- The integration form is declared as the instance form (the connection form); fabrics and their stored values are unchanged.
|
|
15
|
+
|
|
10
16
|
## [0.2.158] - 2026-11-05
|
|
11
17
|
|
|
12
18
|
### Changed
|
package/dist/addon.js
CHANGED
|
@@ -13508,12 +13508,22 @@ var RecordIntegrationInstances = class {
|
|
|
13508
13508
|
...this.hooks.description,
|
|
13509
13509
|
mintsId: true
|
|
13510
13510
|
};
|
|
13511
|
-
|
|
13511
|
+
/**
|
|
13512
|
+
* The record an id names. A caller holding the `integrations` registry id (the Integrations
|
|
13513
|
+
* page) reaches a kind whose body links to it through `integrationId`; an id that is itself a
|
|
13514
|
+
* record id answers as it is. An id that names nothing comes back unchanged.
|
|
13515
|
+
*/
|
|
13516
|
+
async resolveRecordId(id) {
|
|
13517
|
+
if (await this.handle.get(id) !== null) return id;
|
|
13518
|
+
const linked = (await this.handle.query({ limit: INSTANCES_LIST_MAX })).records.find((record) => record.data["integrationId"] === id);
|
|
13519
|
+
return linked === void 0 ? id : linked.id;
|
|
13520
|
+
}
|
|
13521
|
+
instanceFormSchema = async ({ id }) => this.hooks.formSchema(id === null ? null : await this.resolveRecordId(id));
|
|
13512
13522
|
listInstances = async () => {
|
|
13513
13523
|
return (await this.handle.query({ limit: INSTANCES_LIST_MAX })).records.map((record) => this.viewOf(record));
|
|
13514
13524
|
};
|
|
13515
13525
|
getInstance = async ({ id }) => {
|
|
13516
|
-
const record = await this.handle.get(id);
|
|
13526
|
+
const record = await this.handle.get(await this.resolveRecordId(id));
|
|
13517
13527
|
return record === null ? null : this.viewOf(record);
|
|
13518
13528
|
};
|
|
13519
13529
|
/** Insert ONE row (`ifRev: 0`: an existing id is refused, never overwritten). */
|
|
@@ -13530,7 +13540,8 @@ var RecordIntegrationInstances = class {
|
|
|
13530
13540
|
await this.hooks.onChanged?.(minted, "created");
|
|
13531
13541
|
return { id: minted };
|
|
13532
13542
|
};
|
|
13533
|
-
updateInstance = async ({ id, name, values }) => {
|
|
13543
|
+
updateInstance = async ({ id: askedId, name, values }) => {
|
|
13544
|
+
const id = await this.resolveRecordId(askedId);
|
|
13534
13545
|
const patch = {};
|
|
13535
13546
|
for (const [key, value] of Object.entries(values)) {
|
|
13536
13547
|
if (value === void 0) continue;
|
|
@@ -13565,7 +13576,10 @@ var RecordIntegrationInstances = class {
|
|
|
13565
13576
|
status: "unsupported",
|
|
13566
13577
|
error: "This integration declares no connection test"
|
|
13567
13578
|
};
|
|
13568
|
-
return this.hooks.test(input
|
|
13579
|
+
return this.hooks.test(input.id === null ? input : {
|
|
13580
|
+
...input,
|
|
13581
|
+
id: await this.resolveRecordId(input.id)
|
|
13582
|
+
});
|
|
13569
13583
|
};
|
|
13570
13584
|
/** The flat provider object to hand to `registerProvider`. */
|
|
13571
13585
|
toProvider() {
|
|
@@ -97165,6 +97179,111 @@ object({
|
|
|
97165
97179
|
commands: record(string$2(), unknown())
|
|
97166
97180
|
});
|
|
97167
97181
|
//#endregion
|
|
97182
|
+
//#region src/config.ts
|
|
97183
|
+
/**
|
|
97184
|
+
* Matter broker connection settings for ONE fabric/controller (one broker entry).
|
|
97185
|
+
* v1 is intentionally minimal: optional Thread / Wi-Fi credentials supplied up
|
|
97186
|
+
* front for wireless commissioning. The pairing code itself is NOT stored here —
|
|
97187
|
+
* it is passed transiently to the commissioning action.
|
|
97188
|
+
*
|
|
97189
|
+
* The fabric credentials (root cert / NOC / node registry) live in the addon
|
|
97190
|
+
* `dataDir` via the controller's storage, NEVER in this typed KV.
|
|
97191
|
+
*/
|
|
97192
|
+
var matterConnectionSchema = object({
|
|
97193
|
+
/** Optional Thread operational dataset (hex) for Thread device onboarding. */
|
|
97194
|
+
threadDataset: string$2().default("").describe("Thread operational dataset (hex) — required only for Thread devices").meta({ secret: true }),
|
|
97195
|
+
/** Optional Wi-Fi SSID for Wi-Fi device onboarding over BLE. */
|
|
97196
|
+
wifiSsid: string$2().default("").describe("Wi-Fi SSID — required only for BLE Wi-Fi onboarding"),
|
|
97197
|
+
/** Optional Wi-Fi password for Wi-Fi device onboarding over BLE. */
|
|
97198
|
+
wifiPassword: string$2().default("").describe("Wi-Fi password (optional)").meta({ secret: true }),
|
|
97199
|
+
/** PULL-reconcile interval for the commissioned-node inventory. */
|
|
97200
|
+
reconcileIntervalMs: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(1e4).max(864e5).default(3e5)).describe("Node-inventory reconcile interval (ms)")
|
|
97201
|
+
});
|
|
97202
|
+
/** A single registered Matter fabric ("broker"). */
|
|
97203
|
+
var MatterBrokerEntrySchema = object({
|
|
97204
|
+
id: string$2().min(1),
|
|
97205
|
+
name: string$2().min(1),
|
|
97206
|
+
connection: matterConnectionSchema,
|
|
97207
|
+
integrationId: string$2().optional(),
|
|
97208
|
+
/** Absent means on; the instances page switches a fabric off without deleting it. */
|
|
97209
|
+
enabled: boolean().optional()
|
|
97210
|
+
});
|
|
97211
|
+
/** Top-level addon config — the fabrics are records, so nothing is left here. */
|
|
97212
|
+
var matterAddonConfigSchema = object({});
|
|
97213
|
+
/** Narrow an `unknown` to a shallow plain-object record (cast-free boundary). */
|
|
97214
|
+
function toRecord(value) {
|
|
97215
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) return Object.fromEntries(Object.entries(value));
|
|
97216
|
+
return {};
|
|
97217
|
+
}
|
|
97218
|
+
/** Coerce a loose settings blob through the connection schema, applying defaults. */
|
|
97219
|
+
function settingsToMatterConnection(settings) {
|
|
97220
|
+
return matterConnectionSchema.parse(toRecord(settings));
|
|
97221
|
+
}
|
|
97222
|
+
/**
|
|
97223
|
+
* Settings readers see an empty string for both secrets. The stored value
|
|
97224
|
+
* stays in the keychain (records `secret` meta). An empty round-trip must
|
|
97225
|
+
* not wipe it — see {@link mergeMatterSecrets}.
|
|
97226
|
+
*/
|
|
97227
|
+
function publicMatterConnection(connection) {
|
|
97228
|
+
return {
|
|
97229
|
+
...connection,
|
|
97230
|
+
wifiPassword: "",
|
|
97231
|
+
threadDataset: ""
|
|
97232
|
+
};
|
|
97233
|
+
}
|
|
97234
|
+
/** Keep a stored secret when the form sent back the redacted empty string. */
|
|
97235
|
+
function mergeMatterSecrets(existing, incoming) {
|
|
97236
|
+
return {
|
|
97237
|
+
...incoming,
|
|
97238
|
+
wifiPassword: incoming.wifiPassword.length > 0 ? incoming.wifiPassword : existing.wifiPassword,
|
|
97239
|
+
threadDataset: incoming.threadDataset.length > 0 ? incoming.threadDataset : existing.threadDataset
|
|
97240
|
+
};
|
|
97241
|
+
}
|
|
97242
|
+
/** Hand-written connection form for the broker/integration creation UI. */
|
|
97243
|
+
function buildConnectionFormSchema() {
|
|
97244
|
+
return { sections: [{
|
|
97245
|
+
id: "matter-fabric",
|
|
97246
|
+
title: "Matter fabric",
|
|
97247
|
+
titleKey: "matter-broker:connection.s_matter-fabric.title",
|
|
97248
|
+
description: "CamStack owns a Matter fabric on this hub. Add wireless onboarding credentials only if you will commission Thread or BLE-Wi-Fi devices. On-network (Ethernet/Wi-Fi) Matter devices need none of these.",
|
|
97249
|
+
descriptionKey: "matter-broker:connection.s_matter-fabric.description",
|
|
97250
|
+
columns: 1,
|
|
97251
|
+
fields: [
|
|
97252
|
+
{
|
|
97253
|
+
type: "password",
|
|
97254
|
+
key: "threadDataset",
|
|
97255
|
+
secret: true,
|
|
97256
|
+
showToggle: true,
|
|
97257
|
+
label: "Thread operational dataset (hex, optional)",
|
|
97258
|
+
labelKey: "matter-broker:connection.s_matter-fabric.threadDataset.label",
|
|
97259
|
+
placeholder: "0e08000000000001…"
|
|
97260
|
+
},
|
|
97261
|
+
{
|
|
97262
|
+
type: "text",
|
|
97263
|
+
key: "wifiSsid",
|
|
97264
|
+
label: "Wi-Fi SSID (optional)",
|
|
97265
|
+
labelKey: "matter-broker:connection.s_matter-fabric.wifiSsid.label"
|
|
97266
|
+
},
|
|
97267
|
+
{
|
|
97268
|
+
type: "password",
|
|
97269
|
+
key: "wifiPassword",
|
|
97270
|
+
label: "Wi-Fi password (optional)",
|
|
97271
|
+
labelKey: "matter-broker:connection.s_matter-fabric.wifiPassword.label",
|
|
97272
|
+
showToggle: true
|
|
97273
|
+
},
|
|
97274
|
+
{
|
|
97275
|
+
type: "number",
|
|
97276
|
+
key: "reconcileIntervalMs",
|
|
97277
|
+
label: "Node reconcile interval (ms)",
|
|
97278
|
+
labelKey: "matter-broker:connection.s_matter-fabric.reconcileIntervalMs.label",
|
|
97279
|
+
min: 1e4,
|
|
97280
|
+
max: 864e5,
|
|
97281
|
+
default: 3e5
|
|
97282
|
+
}
|
|
97283
|
+
]
|
|
97284
|
+
}] };
|
|
97285
|
+
}
|
|
97286
|
+
//#endregion
|
|
97168
97287
|
//#region ../../node_modules/@matter/general/dist/esm/net/tcp/TcpConnection.js
|
|
97169
97288
|
/**
|
|
97170
97289
|
* @license
|
|
@@ -207680,111 +207799,6 @@ var MatterBrokerRegistry = class {
|
|
|
207680
207799
|
}
|
|
207681
207800
|
};
|
|
207682
207801
|
//#endregion
|
|
207683
|
-
//#region src/config.ts
|
|
207684
|
-
/**
|
|
207685
|
-
* Matter broker connection settings for ONE fabric/controller (one broker entry).
|
|
207686
|
-
* v1 is intentionally minimal: optional Thread / Wi-Fi credentials supplied up
|
|
207687
|
-
* front for wireless commissioning. The pairing code itself is NOT stored here —
|
|
207688
|
-
* it is passed transiently to the commissioning action.
|
|
207689
|
-
*
|
|
207690
|
-
* The fabric credentials (root cert / NOC / node registry) live in the addon
|
|
207691
|
-
* `dataDir` via the controller's storage, NEVER in this typed KV.
|
|
207692
|
-
*/
|
|
207693
|
-
var matterConnectionSchema = object({
|
|
207694
|
-
/** Optional Thread operational dataset (hex) for Thread device onboarding. */
|
|
207695
|
-
threadDataset: string$2().default("").describe("Thread operational dataset (hex) — required only for Thread devices").meta({ secret: true }),
|
|
207696
|
-
/** Optional Wi-Fi SSID for Wi-Fi device onboarding over BLE. */
|
|
207697
|
-
wifiSsid: string$2().default("").describe("Wi-Fi SSID — required only for BLE Wi-Fi onboarding"),
|
|
207698
|
-
/** Optional Wi-Fi password for Wi-Fi device onboarding over BLE. */
|
|
207699
|
-
wifiPassword: string$2().default("").describe("Wi-Fi password (optional)").meta({ secret: true }),
|
|
207700
|
-
/** PULL-reconcile interval for the commissioned-node inventory. */
|
|
207701
|
-
reconcileIntervalMs: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(1e4).max(864e5).default(3e5)).describe("Node-inventory reconcile interval (ms)")
|
|
207702
|
-
});
|
|
207703
|
-
/** A single registered Matter fabric ("broker"). */
|
|
207704
|
-
var MatterBrokerEntrySchema = object({
|
|
207705
|
-
id: string$2().min(1),
|
|
207706
|
-
name: string$2().min(1),
|
|
207707
|
-
connection: matterConnectionSchema,
|
|
207708
|
-
integrationId: string$2().optional(),
|
|
207709
|
-
/** Absent means on; the instances page switches a fabric off without deleting it. */
|
|
207710
|
-
enabled: boolean().optional()
|
|
207711
|
-
});
|
|
207712
|
-
/** Top-level addon config — the fabrics are records, so nothing is left here. */
|
|
207713
|
-
var matterAddonConfigSchema = object({});
|
|
207714
|
-
/** Narrow an `unknown` to a shallow plain-object record (cast-free boundary). */
|
|
207715
|
-
function toRecord(value) {
|
|
207716
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value)) return Object.fromEntries(Object.entries(value));
|
|
207717
|
-
return {};
|
|
207718
|
-
}
|
|
207719
|
-
/** Coerce a loose settings blob through the connection schema, applying defaults. */
|
|
207720
|
-
function settingsToMatterConnection(settings) {
|
|
207721
|
-
return matterConnectionSchema.parse(toRecord(settings));
|
|
207722
|
-
}
|
|
207723
|
-
/**
|
|
207724
|
-
* Settings readers see an empty string for both secrets. The stored value
|
|
207725
|
-
* stays in the keychain (records `secret` meta). An empty round-trip must
|
|
207726
|
-
* not wipe it — see {@link mergeMatterSecrets}.
|
|
207727
|
-
*/
|
|
207728
|
-
function publicMatterConnection(connection) {
|
|
207729
|
-
return {
|
|
207730
|
-
...connection,
|
|
207731
|
-
wifiPassword: "",
|
|
207732
|
-
threadDataset: ""
|
|
207733
|
-
};
|
|
207734
|
-
}
|
|
207735
|
-
/** Keep a stored secret when the form sent back the redacted empty string. */
|
|
207736
|
-
function mergeMatterSecrets(existing, incoming) {
|
|
207737
|
-
return {
|
|
207738
|
-
...incoming,
|
|
207739
|
-
wifiPassword: incoming.wifiPassword.length > 0 ? incoming.wifiPassword : existing.wifiPassword,
|
|
207740
|
-
threadDataset: incoming.threadDataset.length > 0 ? incoming.threadDataset : existing.threadDataset
|
|
207741
|
-
};
|
|
207742
|
-
}
|
|
207743
|
-
/** Hand-written connection form for the broker/integration creation UI. */
|
|
207744
|
-
function buildConnectionFormSchema() {
|
|
207745
|
-
return { sections: [{
|
|
207746
|
-
id: "matter-fabric",
|
|
207747
|
-
title: "Matter fabric",
|
|
207748
|
-
titleKey: "matter-broker:connection.s_matter-fabric.title",
|
|
207749
|
-
description: "CamStack owns a Matter fabric on this hub. Add wireless onboarding credentials only if you will commission Thread or BLE-Wi-Fi devices. On-network (Ethernet/Wi-Fi) Matter devices need none of these.",
|
|
207750
|
-
descriptionKey: "matter-broker:connection.s_matter-fabric.description",
|
|
207751
|
-
columns: 1,
|
|
207752
|
-
fields: [
|
|
207753
|
-
{
|
|
207754
|
-
type: "password",
|
|
207755
|
-
key: "threadDataset",
|
|
207756
|
-
secret: true,
|
|
207757
|
-
showToggle: true,
|
|
207758
|
-
label: "Thread operational dataset (hex, optional)",
|
|
207759
|
-
labelKey: "matter-broker:connection.s_matter-fabric.threadDataset.label",
|
|
207760
|
-
placeholder: "0e08000000000001…"
|
|
207761
|
-
},
|
|
207762
|
-
{
|
|
207763
|
-
type: "text",
|
|
207764
|
-
key: "wifiSsid",
|
|
207765
|
-
label: "Wi-Fi SSID (optional)",
|
|
207766
|
-
labelKey: "matter-broker:connection.s_matter-fabric.wifiSsid.label"
|
|
207767
|
-
},
|
|
207768
|
-
{
|
|
207769
|
-
type: "password",
|
|
207770
|
-
key: "wifiPassword",
|
|
207771
|
-
label: "Wi-Fi password (optional)",
|
|
207772
|
-
labelKey: "matter-broker:connection.s_matter-fabric.wifiPassword.label",
|
|
207773
|
-
showToggle: true
|
|
207774
|
-
},
|
|
207775
|
-
{
|
|
207776
|
-
type: "number",
|
|
207777
|
-
key: "reconcileIntervalMs",
|
|
207778
|
-
label: "Node reconcile interval (ms)",
|
|
207779
|
-
labelKey: "matter-broker:connection.s_matter-fabric.reconcileIntervalMs.label",
|
|
207780
|
-
min: 1e4,
|
|
207781
|
-
max: 864e5,
|
|
207782
|
-
default: 3e5
|
|
207783
|
-
}
|
|
207784
|
-
]
|
|
207785
|
-
}] };
|
|
207786
|
-
}
|
|
207787
|
-
//#endregion
|
|
207788
207802
|
//#region src/matter-commissioning.ts
|
|
207789
207803
|
/** A clear validation error for a malformed pairing code. */
|
|
207790
207804
|
var InvalidPairingCodeError = class extends Error {
|
|
@@ -209346,22 +209360,9 @@ var MatterBrokerAddon = class extends BaseDeviceProvider {
|
|
|
209346
209360
|
}
|
|
209347
209361
|
});
|
|
209348
209362
|
}
|
|
209349
|
-
|
|
209350
|
-
|
|
209351
|
-
|
|
209352
|
-
title: "Matter fabric",
|
|
209353
|
-
titleKey: "matter-broker:globalSettings.s_matter-fabric.title",
|
|
209354
|
-
description: "Matter fabrics are managed in the External systems → Brokers tab.",
|
|
209355
|
-
descriptionKey: "matter-broker:globalSettings.s_matter-fabric.description",
|
|
209356
|
-
columns: 1,
|
|
209357
|
-
fields: [{
|
|
209358
|
-
type: "info",
|
|
209359
|
-
key: "fabricHelp",
|
|
209360
|
-
label: "Fabrics are managed separately",
|
|
209361
|
-
labelKey: "matter-broker:globalSettings.s_matter-fabric.fabricHelp.label",
|
|
209362
|
-
content: "This integration links to a Matter fabric broker. Add, edit, or remove fabrics from External systems → Brokers, then commission devices into the fabric. The integration only stores a reference to its broker."
|
|
209363
|
-
}]
|
|
209364
|
-
}] });
|
|
209363
|
+
/** The connection form a record carries; the values live on the record, never in `addon-settings`. */
|
|
209364
|
+
async integrationFormSchema(_instance) {
|
|
209365
|
+
return buildConnectionFormSchema();
|
|
209365
209366
|
}
|
|
209366
209367
|
async supportsManualCreation() {
|
|
209367
209368
|
return false;
|
package/dist/addon.mjs
CHANGED
|
@@ -13506,12 +13506,22 @@ var RecordIntegrationInstances = class {
|
|
|
13506
13506
|
...this.hooks.description,
|
|
13507
13507
|
mintsId: true
|
|
13508
13508
|
};
|
|
13509
|
-
|
|
13509
|
+
/**
|
|
13510
|
+
* The record an id names. A caller holding the `integrations` registry id (the Integrations
|
|
13511
|
+
* page) reaches a kind whose body links to it through `integrationId`; an id that is itself a
|
|
13512
|
+
* record id answers as it is. An id that names nothing comes back unchanged.
|
|
13513
|
+
*/
|
|
13514
|
+
async resolveRecordId(id) {
|
|
13515
|
+
if (await this.handle.get(id) !== null) return id;
|
|
13516
|
+
const linked = (await this.handle.query({ limit: INSTANCES_LIST_MAX })).records.find((record) => record.data["integrationId"] === id);
|
|
13517
|
+
return linked === void 0 ? id : linked.id;
|
|
13518
|
+
}
|
|
13519
|
+
instanceFormSchema = async ({ id }) => this.hooks.formSchema(id === null ? null : await this.resolveRecordId(id));
|
|
13510
13520
|
listInstances = async () => {
|
|
13511
13521
|
return (await this.handle.query({ limit: INSTANCES_LIST_MAX })).records.map((record) => this.viewOf(record));
|
|
13512
13522
|
};
|
|
13513
13523
|
getInstance = async ({ id }) => {
|
|
13514
|
-
const record = await this.handle.get(id);
|
|
13524
|
+
const record = await this.handle.get(await this.resolveRecordId(id));
|
|
13515
13525
|
return record === null ? null : this.viewOf(record);
|
|
13516
13526
|
};
|
|
13517
13527
|
/** Insert ONE row (`ifRev: 0`: an existing id is refused, never overwritten). */
|
|
@@ -13528,7 +13538,8 @@ var RecordIntegrationInstances = class {
|
|
|
13528
13538
|
await this.hooks.onChanged?.(minted, "created");
|
|
13529
13539
|
return { id: minted };
|
|
13530
13540
|
};
|
|
13531
|
-
updateInstance = async ({ id, name, values }) => {
|
|
13541
|
+
updateInstance = async ({ id: askedId, name, values }) => {
|
|
13542
|
+
const id = await this.resolveRecordId(askedId);
|
|
13532
13543
|
const patch = {};
|
|
13533
13544
|
for (const [key, value] of Object.entries(values)) {
|
|
13534
13545
|
if (value === void 0) continue;
|
|
@@ -13563,7 +13574,10 @@ var RecordIntegrationInstances = class {
|
|
|
13563
13574
|
status: "unsupported",
|
|
13564
13575
|
error: "This integration declares no connection test"
|
|
13565
13576
|
};
|
|
13566
|
-
return this.hooks.test(input
|
|
13577
|
+
return this.hooks.test(input.id === null ? input : {
|
|
13578
|
+
...input,
|
|
13579
|
+
id: await this.resolveRecordId(input.id)
|
|
13580
|
+
});
|
|
13567
13581
|
};
|
|
13568
13582
|
/** The flat provider object to hand to `registerProvider`. */
|
|
13569
13583
|
toProvider() {
|
|
@@ -97163,6 +97177,111 @@ object({
|
|
|
97163
97177
|
commands: record(string$2(), unknown())
|
|
97164
97178
|
});
|
|
97165
97179
|
//#endregion
|
|
97180
|
+
//#region src/config.ts
|
|
97181
|
+
/**
|
|
97182
|
+
* Matter broker connection settings for ONE fabric/controller (one broker entry).
|
|
97183
|
+
* v1 is intentionally minimal: optional Thread / Wi-Fi credentials supplied up
|
|
97184
|
+
* front for wireless commissioning. The pairing code itself is NOT stored here —
|
|
97185
|
+
* it is passed transiently to the commissioning action.
|
|
97186
|
+
*
|
|
97187
|
+
* The fabric credentials (root cert / NOC / node registry) live in the addon
|
|
97188
|
+
* `dataDir` via the controller's storage, NEVER in this typed KV.
|
|
97189
|
+
*/
|
|
97190
|
+
var matterConnectionSchema = object({
|
|
97191
|
+
/** Optional Thread operational dataset (hex) for Thread device onboarding. */
|
|
97192
|
+
threadDataset: string$2().default("").describe("Thread operational dataset (hex) — required only for Thread devices").meta({ secret: true }),
|
|
97193
|
+
/** Optional Wi-Fi SSID for Wi-Fi device onboarding over BLE. */
|
|
97194
|
+
wifiSsid: string$2().default("").describe("Wi-Fi SSID — required only for BLE Wi-Fi onboarding"),
|
|
97195
|
+
/** Optional Wi-Fi password for Wi-Fi device onboarding over BLE. */
|
|
97196
|
+
wifiPassword: string$2().default("").describe("Wi-Fi password (optional)").meta({ secret: true }),
|
|
97197
|
+
/** PULL-reconcile interval for the commissioned-node inventory. */
|
|
97198
|
+
reconcileIntervalMs: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(1e4).max(864e5).default(3e5)).describe("Node-inventory reconcile interval (ms)")
|
|
97199
|
+
});
|
|
97200
|
+
/** A single registered Matter fabric ("broker"). */
|
|
97201
|
+
var MatterBrokerEntrySchema = object({
|
|
97202
|
+
id: string$2().min(1),
|
|
97203
|
+
name: string$2().min(1),
|
|
97204
|
+
connection: matterConnectionSchema,
|
|
97205
|
+
integrationId: string$2().optional(),
|
|
97206
|
+
/** Absent means on; the instances page switches a fabric off without deleting it. */
|
|
97207
|
+
enabled: boolean().optional()
|
|
97208
|
+
});
|
|
97209
|
+
/** Top-level addon config — the fabrics are records, so nothing is left here. */
|
|
97210
|
+
var matterAddonConfigSchema = object({});
|
|
97211
|
+
/** Narrow an `unknown` to a shallow plain-object record (cast-free boundary). */
|
|
97212
|
+
function toRecord(value) {
|
|
97213
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) return Object.fromEntries(Object.entries(value));
|
|
97214
|
+
return {};
|
|
97215
|
+
}
|
|
97216
|
+
/** Coerce a loose settings blob through the connection schema, applying defaults. */
|
|
97217
|
+
function settingsToMatterConnection(settings) {
|
|
97218
|
+
return matterConnectionSchema.parse(toRecord(settings));
|
|
97219
|
+
}
|
|
97220
|
+
/**
|
|
97221
|
+
* Settings readers see an empty string for both secrets. The stored value
|
|
97222
|
+
* stays in the keychain (records `secret` meta). An empty round-trip must
|
|
97223
|
+
* not wipe it — see {@link mergeMatterSecrets}.
|
|
97224
|
+
*/
|
|
97225
|
+
function publicMatterConnection(connection) {
|
|
97226
|
+
return {
|
|
97227
|
+
...connection,
|
|
97228
|
+
wifiPassword: "",
|
|
97229
|
+
threadDataset: ""
|
|
97230
|
+
};
|
|
97231
|
+
}
|
|
97232
|
+
/** Keep a stored secret when the form sent back the redacted empty string. */
|
|
97233
|
+
function mergeMatterSecrets(existing, incoming) {
|
|
97234
|
+
return {
|
|
97235
|
+
...incoming,
|
|
97236
|
+
wifiPassword: incoming.wifiPassword.length > 0 ? incoming.wifiPassword : existing.wifiPassword,
|
|
97237
|
+
threadDataset: incoming.threadDataset.length > 0 ? incoming.threadDataset : existing.threadDataset
|
|
97238
|
+
};
|
|
97239
|
+
}
|
|
97240
|
+
/** Hand-written connection form for the broker/integration creation UI. */
|
|
97241
|
+
function buildConnectionFormSchema() {
|
|
97242
|
+
return { sections: [{
|
|
97243
|
+
id: "matter-fabric",
|
|
97244
|
+
title: "Matter fabric",
|
|
97245
|
+
titleKey: "matter-broker:connection.s_matter-fabric.title",
|
|
97246
|
+
description: "CamStack owns a Matter fabric on this hub. Add wireless onboarding credentials only if you will commission Thread or BLE-Wi-Fi devices. On-network (Ethernet/Wi-Fi) Matter devices need none of these.",
|
|
97247
|
+
descriptionKey: "matter-broker:connection.s_matter-fabric.description",
|
|
97248
|
+
columns: 1,
|
|
97249
|
+
fields: [
|
|
97250
|
+
{
|
|
97251
|
+
type: "password",
|
|
97252
|
+
key: "threadDataset",
|
|
97253
|
+
secret: true,
|
|
97254
|
+
showToggle: true,
|
|
97255
|
+
label: "Thread operational dataset (hex, optional)",
|
|
97256
|
+
labelKey: "matter-broker:connection.s_matter-fabric.threadDataset.label",
|
|
97257
|
+
placeholder: "0e08000000000001…"
|
|
97258
|
+
},
|
|
97259
|
+
{
|
|
97260
|
+
type: "text",
|
|
97261
|
+
key: "wifiSsid",
|
|
97262
|
+
label: "Wi-Fi SSID (optional)",
|
|
97263
|
+
labelKey: "matter-broker:connection.s_matter-fabric.wifiSsid.label"
|
|
97264
|
+
},
|
|
97265
|
+
{
|
|
97266
|
+
type: "password",
|
|
97267
|
+
key: "wifiPassword",
|
|
97268
|
+
label: "Wi-Fi password (optional)",
|
|
97269
|
+
labelKey: "matter-broker:connection.s_matter-fabric.wifiPassword.label",
|
|
97270
|
+
showToggle: true
|
|
97271
|
+
},
|
|
97272
|
+
{
|
|
97273
|
+
type: "number",
|
|
97274
|
+
key: "reconcileIntervalMs",
|
|
97275
|
+
label: "Node reconcile interval (ms)",
|
|
97276
|
+
labelKey: "matter-broker:connection.s_matter-fabric.reconcileIntervalMs.label",
|
|
97277
|
+
min: 1e4,
|
|
97278
|
+
max: 864e5,
|
|
97279
|
+
default: 3e5
|
|
97280
|
+
}
|
|
97281
|
+
]
|
|
97282
|
+
}] };
|
|
97283
|
+
}
|
|
97284
|
+
//#endregion
|
|
97166
97285
|
//#region ../../node_modules/@matter/general/dist/esm/net/tcp/TcpConnection.js
|
|
97167
97286
|
/**
|
|
97168
97287
|
* @license
|
|
@@ -207678,111 +207797,6 @@ var MatterBrokerRegistry = class {
|
|
|
207678
207797
|
}
|
|
207679
207798
|
};
|
|
207680
207799
|
//#endregion
|
|
207681
|
-
//#region src/config.ts
|
|
207682
|
-
/**
|
|
207683
|
-
* Matter broker connection settings for ONE fabric/controller (one broker entry).
|
|
207684
|
-
* v1 is intentionally minimal: optional Thread / Wi-Fi credentials supplied up
|
|
207685
|
-
* front for wireless commissioning. The pairing code itself is NOT stored here —
|
|
207686
|
-
* it is passed transiently to the commissioning action.
|
|
207687
|
-
*
|
|
207688
|
-
* The fabric credentials (root cert / NOC / node registry) live in the addon
|
|
207689
|
-
* `dataDir` via the controller's storage, NEVER in this typed KV.
|
|
207690
|
-
*/
|
|
207691
|
-
var matterConnectionSchema = object({
|
|
207692
|
-
/** Optional Thread operational dataset (hex) for Thread device onboarding. */
|
|
207693
|
-
threadDataset: string$2().default("").describe("Thread operational dataset (hex) — required only for Thread devices").meta({ secret: true }),
|
|
207694
|
-
/** Optional Wi-Fi SSID for Wi-Fi device onboarding over BLE. */
|
|
207695
|
-
wifiSsid: string$2().default("").describe("Wi-Fi SSID — required only for BLE Wi-Fi onboarding"),
|
|
207696
|
-
/** Optional Wi-Fi password for Wi-Fi device onboarding over BLE. */
|
|
207697
|
-
wifiPassword: string$2().default("").describe("Wi-Fi password (optional)").meta({ secret: true }),
|
|
207698
|
-
/** PULL-reconcile interval for the commissioned-node inventory. */
|
|
207699
|
-
reconcileIntervalMs: preprocess((v) => v === "" || v === null ? void 0 : v, number().int().min(1e4).max(864e5).default(3e5)).describe("Node-inventory reconcile interval (ms)")
|
|
207700
|
-
});
|
|
207701
|
-
/** A single registered Matter fabric ("broker"). */
|
|
207702
|
-
var MatterBrokerEntrySchema = object({
|
|
207703
|
-
id: string$2().min(1),
|
|
207704
|
-
name: string$2().min(1),
|
|
207705
|
-
connection: matterConnectionSchema,
|
|
207706
|
-
integrationId: string$2().optional(),
|
|
207707
|
-
/** Absent means on; the instances page switches a fabric off without deleting it. */
|
|
207708
|
-
enabled: boolean().optional()
|
|
207709
|
-
});
|
|
207710
|
-
/** Top-level addon config — the fabrics are records, so nothing is left here. */
|
|
207711
|
-
var matterAddonConfigSchema = object({});
|
|
207712
|
-
/** Narrow an `unknown` to a shallow plain-object record (cast-free boundary). */
|
|
207713
|
-
function toRecord(value) {
|
|
207714
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value)) return Object.fromEntries(Object.entries(value));
|
|
207715
|
-
return {};
|
|
207716
|
-
}
|
|
207717
|
-
/** Coerce a loose settings blob through the connection schema, applying defaults. */
|
|
207718
|
-
function settingsToMatterConnection(settings) {
|
|
207719
|
-
return matterConnectionSchema.parse(toRecord(settings));
|
|
207720
|
-
}
|
|
207721
|
-
/**
|
|
207722
|
-
* Settings readers see an empty string for both secrets. The stored value
|
|
207723
|
-
* stays in the keychain (records `secret` meta). An empty round-trip must
|
|
207724
|
-
* not wipe it — see {@link mergeMatterSecrets}.
|
|
207725
|
-
*/
|
|
207726
|
-
function publicMatterConnection(connection) {
|
|
207727
|
-
return {
|
|
207728
|
-
...connection,
|
|
207729
|
-
wifiPassword: "",
|
|
207730
|
-
threadDataset: ""
|
|
207731
|
-
};
|
|
207732
|
-
}
|
|
207733
|
-
/** Keep a stored secret when the form sent back the redacted empty string. */
|
|
207734
|
-
function mergeMatterSecrets(existing, incoming) {
|
|
207735
|
-
return {
|
|
207736
|
-
...incoming,
|
|
207737
|
-
wifiPassword: incoming.wifiPassword.length > 0 ? incoming.wifiPassword : existing.wifiPassword,
|
|
207738
|
-
threadDataset: incoming.threadDataset.length > 0 ? incoming.threadDataset : existing.threadDataset
|
|
207739
|
-
};
|
|
207740
|
-
}
|
|
207741
|
-
/** Hand-written connection form for the broker/integration creation UI. */
|
|
207742
|
-
function buildConnectionFormSchema() {
|
|
207743
|
-
return { sections: [{
|
|
207744
|
-
id: "matter-fabric",
|
|
207745
|
-
title: "Matter fabric",
|
|
207746
|
-
titleKey: "matter-broker:connection.s_matter-fabric.title",
|
|
207747
|
-
description: "CamStack owns a Matter fabric on this hub. Add wireless onboarding credentials only if you will commission Thread or BLE-Wi-Fi devices. On-network (Ethernet/Wi-Fi) Matter devices need none of these.",
|
|
207748
|
-
descriptionKey: "matter-broker:connection.s_matter-fabric.description",
|
|
207749
|
-
columns: 1,
|
|
207750
|
-
fields: [
|
|
207751
|
-
{
|
|
207752
|
-
type: "password",
|
|
207753
|
-
key: "threadDataset",
|
|
207754
|
-
secret: true,
|
|
207755
|
-
showToggle: true,
|
|
207756
|
-
label: "Thread operational dataset (hex, optional)",
|
|
207757
|
-
labelKey: "matter-broker:connection.s_matter-fabric.threadDataset.label",
|
|
207758
|
-
placeholder: "0e08000000000001…"
|
|
207759
|
-
},
|
|
207760
|
-
{
|
|
207761
|
-
type: "text",
|
|
207762
|
-
key: "wifiSsid",
|
|
207763
|
-
label: "Wi-Fi SSID (optional)",
|
|
207764
|
-
labelKey: "matter-broker:connection.s_matter-fabric.wifiSsid.label"
|
|
207765
|
-
},
|
|
207766
|
-
{
|
|
207767
|
-
type: "password",
|
|
207768
|
-
key: "wifiPassword",
|
|
207769
|
-
label: "Wi-Fi password (optional)",
|
|
207770
|
-
labelKey: "matter-broker:connection.s_matter-fabric.wifiPassword.label",
|
|
207771
|
-
showToggle: true
|
|
207772
|
-
},
|
|
207773
|
-
{
|
|
207774
|
-
type: "number",
|
|
207775
|
-
key: "reconcileIntervalMs",
|
|
207776
|
-
label: "Node reconcile interval (ms)",
|
|
207777
|
-
labelKey: "matter-broker:connection.s_matter-fabric.reconcileIntervalMs.label",
|
|
207778
|
-
min: 1e4,
|
|
207779
|
-
max: 864e5,
|
|
207780
|
-
default: 3e5
|
|
207781
|
-
}
|
|
207782
|
-
]
|
|
207783
|
-
}] };
|
|
207784
|
-
}
|
|
207785
|
-
//#endregion
|
|
207786
207800
|
//#region src/matter-commissioning.ts
|
|
207787
207801
|
/** A clear validation error for a malformed pairing code. */
|
|
207788
207802
|
var InvalidPairingCodeError = class extends Error {
|
|
@@ -209344,22 +209358,9 @@ var MatterBrokerAddon = class extends BaseDeviceProvider {
|
|
|
209344
209358
|
}
|
|
209345
209359
|
});
|
|
209346
209360
|
}
|
|
209347
|
-
|
|
209348
|
-
|
|
209349
|
-
|
|
209350
|
-
title: "Matter fabric",
|
|
209351
|
-
titleKey: "matter-broker:globalSettings.s_matter-fabric.title",
|
|
209352
|
-
description: "Matter fabrics are managed in the External systems → Brokers tab.",
|
|
209353
|
-
descriptionKey: "matter-broker:globalSettings.s_matter-fabric.description",
|
|
209354
|
-
columns: 1,
|
|
209355
|
-
fields: [{
|
|
209356
|
-
type: "info",
|
|
209357
|
-
key: "fabricHelp",
|
|
209358
|
-
label: "Fabrics are managed separately",
|
|
209359
|
-
labelKey: "matter-broker:globalSettings.s_matter-fabric.fabricHelp.label",
|
|
209360
|
-
content: "This integration links to a Matter fabric broker. Add, edit, or remove fabrics from External systems → Brokers, then commission devices into the fabric. The integration only stores a reference to its broker."
|
|
209361
|
-
}]
|
|
209362
|
-
}] });
|
|
209361
|
+
/** The connection form a record carries; the values live on the record, never in `addon-settings`. */
|
|
209362
|
+
async integrationFormSchema(_instance) {
|
|
209363
|
+
return buildConnectionFormSchema();
|
|
209363
209364
|
}
|
|
209364
209365
|
async supportsManualCreation() {
|
|
209365
209366
|
return false;
|
|
@@ -209408,4 +209409,4 @@ function endpointsEqual(a, b) {
|
|
|
209408
209409
|
return true;
|
|
209409
209410
|
}
|
|
209410
209411
|
//#endregion
|
|
209411
|
-
export { MatterBrokerAddon, parsePairingCode as a,
|
|
209412
|
+
export { MatterBrokerAddon, parsePairingCode as a, mapMatterEndpointToCamStack as c, createMatterController as d, buildConnectionFormSchema as f, settingsToMatterConnection as h, isValidPairingCode as i, MatterControllerNotWiredError as l, matterConnectionSchema as m, endpointNativeId as n, MatterClusterId as o, matterAddonConfigSchema as p, InvalidPairingCodeError as r, endpointLabel as s, buildMatterNodeCandidate as t, StubMatterController as u };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { MatterBrokerAddon, a as parsePairingCode, c as
|
|
1
|
+
import { MatterBrokerAddon, a as parsePairingCode, c as mapMatterEndpointToCamStack, d as createMatterController, f as buildConnectionFormSchema, h as settingsToMatterConnection, i as isValidPairingCode, l as MatterControllerNotWiredError, m as matterConnectionSchema, n as endpointNativeId, o as MatterClusterId, p as matterAddonConfigSchema, r as InvalidPairingCodeError, s as endpointLabel, t as buildMatterNodeCandidate, u as StubMatterController } from "./addon.mjs";
|
|
2
2
|
export { InvalidPairingCodeError, MatterBrokerAddon, MatterClusterId, MatterControllerNotWiredError, StubMatterController, buildConnectionFormSchema, buildMatterNodeCandidate, createMatterController, endpointLabel, endpointNativeId, isValidPairingCode, mapMatterEndpointToCamStack, matterAddonConfigSchema, matterConnectionSchema, parsePairingCode, settingsToMatterConnection };
|
package/i18n/en.json
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"globalSettings.s_matter-fabric.title": "Matter fabric",
|
|
3
|
-
"globalSettings.s_matter-fabric.description": "Matter fabrics are managed in the External systems → Brokers tab.",
|
|
4
|
-
"globalSettings.s_matter-fabric.fabricHelp.label": "Fabrics are managed separately",
|
|
5
2
|
"connection.s_matter-fabric.title": "Matter fabric",
|
|
6
3
|
"connection.s_matter-fabric.description": "CamStack owns a Matter fabric on this hub. Add wireless onboarding credentials only if you will commission Thread or BLE-Wi-Fi devices. On-network (Ethernet/Wi-Fi) Matter devices need none of these.",
|
|
7
4
|
"connection.s_matter-fabric.threadDataset.label": "Thread operational dataset (hex, optional)",
|
package/i18n/it.json
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"globalSettings.s_matter-fabric.title": "Fabric Matter",
|
|
3
|
-
"globalSettings.s_matter-fabric.description": "I fabric Matter si gestiscono nella scheda Sistemi esterni → Broker.",
|
|
4
|
-
"globalSettings.s_matter-fabric.fabricHelp.label": "I fabric si gestiscono separatamente",
|
|
5
2
|
"connection.s_matter-fabric.title": "Fabric Matter",
|
|
6
3
|
"connection.s_matter-fabric.description": "CamStack gestisce un fabric Matter su questo hub. Aggiungi le credenziali di onboarding wireless solo se metterai in servizio dispositivi Thread o BLE-Wi-Fi. I dispositivi Matter sulla rete (Ethernet/Wi-Fi) non ne hanno bisogno.",
|
|
7
4
|
"connection.s_matter-fabric.threadDataset.label": "Dataset operativo Thread (esadecimale, facoltativo)",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-matter-broker",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.159",
|
|
4
4
|
"description": "Matter broker addon for CamStack — owns a Matter fabric (commissioning + the long-lived controller) via the matter.js controller and brokers commissioned Matter nodes into CamStack",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
}
|
|
66
66
|
],
|
|
67
67
|
"requires": {
|
|
68
|
-
"server": ">=1.2.
|
|
68
|
+
"server": ">=1.2.777"
|
|
69
69
|
}
|
|
70
70
|
},
|
|
71
71
|
"files": [
|