@camstack/addon-provider-homeassistant 1.2.12 → 1.2.13
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/addon.js +42 -3
- package/dist/addon.mjs +42 -3
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -18843,6 +18843,20 @@ var GetInputSchema = object({ id: string() });
|
|
|
18843
18843
|
var AddInputSchema = object({
|
|
18844
18844
|
kind: string().min(1),
|
|
18845
18845
|
name: string().min(1),
|
|
18846
|
+
/**
|
|
18847
|
+
* ADOPT an existing id instead of minting a new one.
|
|
18848
|
+
*
|
|
18849
|
+
* Written the day this cost an outage. A broker's id is not a detail: HA
|
|
18850
|
+
* devices carry it inside their `stableId` (`ha:ha_004:dev:…`), so a broker
|
|
18851
|
+
* lost from config and re-added as `ha_001` leaves every one of its devices
|
|
18852
|
+
* bound to a broker that no longer exists. Re-entering the password under the
|
|
18853
|
+
* ORIGINAL id turns a multi-step device migration back into re-entering a
|
|
18854
|
+
* password.
|
|
18855
|
+
*
|
|
18856
|
+
* A provider MUST refuse an id that is already in use — adopting a live
|
|
18857
|
+
* broker's id would silently take it over.
|
|
18858
|
+
*/
|
|
18859
|
+
id: string().min(1).optional(),
|
|
18846
18860
|
/** Kind-specific settings (e.g. MQTT `{url,username,password}` or HA
|
|
18847
18861
|
* `{baseUrl,accessToken}`). Validated by the kind-specific provider
|
|
18848
18862
|
* branch on receipt — invalid shape rejects the add. */
|
|
@@ -36117,6 +36131,27 @@ var HaBrokerRegistry = class {
|
|
|
36117
36131
|
this.nextIdCounter += 1;
|
|
36118
36132
|
return id;
|
|
36119
36133
|
}
|
|
36134
|
+
/**
|
|
36135
|
+
* Take a caller-supplied id, or refuse.
|
|
36136
|
+
*
|
|
36137
|
+
* Two refusals, and both matter more than they look:
|
|
36138
|
+
*
|
|
36139
|
+
* - **An id already in use** would SILENTLY take over a live broker: the new
|
|
36140
|
+
* entry replaces it in config while its devices keep pointing at the id,
|
|
36141
|
+
* now serving someone else's Home Assistant. Recovery is re-creating a
|
|
36142
|
+
* broker that is GONE, never overwriting one that is here.
|
|
36143
|
+
* - **The progressive counter is advanced past an adopted id.** Adopting
|
|
36144
|
+
* `ha_004` while the counter sits at 2 would let the next automatic
|
|
36145
|
+
* allocation mint `ha_004` a second time — two brokers, one id, and every
|
|
36146
|
+
* device bound to whichever won. The counter is only seeded from stored
|
|
36147
|
+
* entries at load, so it cannot discover this on its own.
|
|
36148
|
+
*/
|
|
36149
|
+
adoptId(id) {
|
|
36150
|
+
if (this.managers.has(id)) throw new Error(`broker id "${id}" is already in use — adopt an id only to restore a broker that is gone`);
|
|
36151
|
+
const match = id.match(/^ha_(\d+)$/);
|
|
36152
|
+
if (match) this.nextIdCounter = Math.max(this.nextIdCounter, Number.parseInt(match[1], 10) + 1);
|
|
36153
|
+
return id;
|
|
36154
|
+
}
|
|
36120
36155
|
seedCounterFromEntries(entries) {
|
|
36121
36156
|
let maxSeen = 0;
|
|
36122
36157
|
for (const e of entries) {
|
|
@@ -36136,7 +36171,7 @@ var HaBrokerRegistry = class {
|
|
|
36136
36171
|
async createEntry(name, settings, options = {}) {
|
|
36137
36172
|
const auth = settingsToAuth(settings);
|
|
36138
36173
|
const entry = {
|
|
36139
|
-
id: this.allocateId(),
|
|
36174
|
+
id: options.id !== void 0 ? this.adoptId(options.id) : this.allocateId(),
|
|
36140
36175
|
name,
|
|
36141
36176
|
auth,
|
|
36142
36177
|
...options.integrationId !== void 0 ? { integrationId: options.integrationId } : {}
|
|
@@ -38500,9 +38535,13 @@ var HaProviderAddon = class HaProviderAddon extends BaseDeviceProvider {
|
|
|
38500
38535
|
label: "Home Assistant"
|
|
38501
38536
|
}]
|
|
38502
38537
|
}],
|
|
38503
|
-
add: async ({ kind, name, settings }) => {
|
|
38538
|
+
add: async ({ kind, name, settings, id }) => {
|
|
38504
38539
|
if (kind !== HA_KIND) throw new Error(`provider-homeassistant: only kind '${HA_KIND}' is handled here (got '${kind}')`);
|
|
38505
|
-
const entry = await this.requireRegistry().createEntry(name, settings);
|
|
38540
|
+
const entry = await this.requireRegistry().createEntry(name, settings, { ...id !== void 0 ? { id } : {} });
|
|
38541
|
+
if (id !== void 0) this.ctx.logger.info("broker restored under an adopted id", { meta: {
|
|
38542
|
+
brokerId: entry.id,
|
|
38543
|
+
name
|
|
38544
|
+
} });
|
|
38506
38545
|
await this.updateGlobalSettings({ brokers: [...this.config.brokers, entry] });
|
|
38507
38546
|
return { id: entry.id };
|
|
38508
38547
|
},
|
package/dist/addon.mjs
CHANGED
|
@@ -18842,6 +18842,20 @@ var GetInputSchema = object({ id: string() });
|
|
|
18842
18842
|
var AddInputSchema = object({
|
|
18843
18843
|
kind: string().min(1),
|
|
18844
18844
|
name: string().min(1),
|
|
18845
|
+
/**
|
|
18846
|
+
* ADOPT an existing id instead of minting a new one.
|
|
18847
|
+
*
|
|
18848
|
+
* Written the day this cost an outage. A broker's id is not a detail: HA
|
|
18849
|
+
* devices carry it inside their `stableId` (`ha:ha_004:dev:…`), so a broker
|
|
18850
|
+
* lost from config and re-added as `ha_001` leaves every one of its devices
|
|
18851
|
+
* bound to a broker that no longer exists. Re-entering the password under the
|
|
18852
|
+
* ORIGINAL id turns a multi-step device migration back into re-entering a
|
|
18853
|
+
* password.
|
|
18854
|
+
*
|
|
18855
|
+
* A provider MUST refuse an id that is already in use — adopting a live
|
|
18856
|
+
* broker's id would silently take it over.
|
|
18857
|
+
*/
|
|
18858
|
+
id: string().min(1).optional(),
|
|
18845
18859
|
/** Kind-specific settings (e.g. MQTT `{url,username,password}` or HA
|
|
18846
18860
|
* `{baseUrl,accessToken}`). Validated by the kind-specific provider
|
|
18847
18861
|
* branch on receipt — invalid shape rejects the add. */
|
|
@@ -36116,6 +36130,27 @@ var HaBrokerRegistry = class {
|
|
|
36116
36130
|
this.nextIdCounter += 1;
|
|
36117
36131
|
return id;
|
|
36118
36132
|
}
|
|
36133
|
+
/**
|
|
36134
|
+
* Take a caller-supplied id, or refuse.
|
|
36135
|
+
*
|
|
36136
|
+
* Two refusals, and both matter more than they look:
|
|
36137
|
+
*
|
|
36138
|
+
* - **An id already in use** would SILENTLY take over a live broker: the new
|
|
36139
|
+
* entry replaces it in config while its devices keep pointing at the id,
|
|
36140
|
+
* now serving someone else's Home Assistant. Recovery is re-creating a
|
|
36141
|
+
* broker that is GONE, never overwriting one that is here.
|
|
36142
|
+
* - **The progressive counter is advanced past an adopted id.** Adopting
|
|
36143
|
+
* `ha_004` while the counter sits at 2 would let the next automatic
|
|
36144
|
+
* allocation mint `ha_004` a second time — two brokers, one id, and every
|
|
36145
|
+
* device bound to whichever won. The counter is only seeded from stored
|
|
36146
|
+
* entries at load, so it cannot discover this on its own.
|
|
36147
|
+
*/
|
|
36148
|
+
adoptId(id) {
|
|
36149
|
+
if (this.managers.has(id)) throw new Error(`broker id "${id}" is already in use — adopt an id only to restore a broker that is gone`);
|
|
36150
|
+
const match = id.match(/^ha_(\d+)$/);
|
|
36151
|
+
if (match) this.nextIdCounter = Math.max(this.nextIdCounter, Number.parseInt(match[1], 10) + 1);
|
|
36152
|
+
return id;
|
|
36153
|
+
}
|
|
36119
36154
|
seedCounterFromEntries(entries) {
|
|
36120
36155
|
let maxSeen = 0;
|
|
36121
36156
|
for (const e of entries) {
|
|
@@ -36135,7 +36170,7 @@ var HaBrokerRegistry = class {
|
|
|
36135
36170
|
async createEntry(name, settings, options = {}) {
|
|
36136
36171
|
const auth = settingsToAuth(settings);
|
|
36137
36172
|
const entry = {
|
|
36138
|
-
id: this.allocateId(),
|
|
36173
|
+
id: options.id !== void 0 ? this.adoptId(options.id) : this.allocateId(),
|
|
36139
36174
|
name,
|
|
36140
36175
|
auth,
|
|
36141
36176
|
...options.integrationId !== void 0 ? { integrationId: options.integrationId } : {}
|
|
@@ -38499,9 +38534,13 @@ var HaProviderAddon = class HaProviderAddon extends BaseDeviceProvider {
|
|
|
38499
38534
|
label: "Home Assistant"
|
|
38500
38535
|
}]
|
|
38501
38536
|
}],
|
|
38502
|
-
add: async ({ kind, name, settings }) => {
|
|
38537
|
+
add: async ({ kind, name, settings, id }) => {
|
|
38503
38538
|
if (kind !== HA_KIND) throw new Error(`provider-homeassistant: only kind '${HA_KIND}' is handled here (got '${kind}')`);
|
|
38504
|
-
const entry = await this.requireRegistry().createEntry(name, settings);
|
|
38539
|
+
const entry = await this.requireRegistry().createEntry(name, settings, { ...id !== void 0 ? { id } : {} });
|
|
38540
|
+
if (id !== void 0) this.ctx.logger.info("broker restored under an adopted id", { meta: {
|
|
38541
|
+
brokerId: entry.id,
|
|
38542
|
+
name
|
|
38543
|
+
} });
|
|
38505
38544
|
await this.updateGlobalSettings({ brokers: [...this.config.brokers, entry] });
|
|
38506
38545
|
return { id: entry.id };
|
|
38507
38546
|
},
|