@camstack/addon-provider-homeassistant 1.2.173 → 1.2.602

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("./dist-DTt9hwTQ.js");
2
+ const require_dist = require("./dist-xuu2eG_W.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_zlib = require("node:zlib");
5
5
  //#region src/ha-admin-link.ts
@@ -6783,6 +6783,54 @@ function createHaIconRouteProvider() {
6783
6783
  }]);
6784
6784
  }
6785
6785
  //#endregion
6786
+ //#region src/broker-record-kinds.ts
6787
+ /**
6788
+ * Broker entry kind (B2): credentials live in records; integrations keep brokerId.
6789
+ */
6790
+ var HA_BROKERS_KIND = "brokers";
6791
+ var HA_BROKERS_OWNER = "provider-homeassistant";
6792
+ var HaBrokerBodySchema = require_dist.entryBody({
6793
+ auth: HaBrokerEntrySchema.shape.auth,
6794
+ integrationId: require_dist.string().optional()
6795
+ });
6796
+ var haBrokersEntryKind = require_dist.defineEntryKind(HA_BROKERS_KIND, {
6797
+ title: "Home Assistant brokers",
6798
+ schema: HaBrokerBodySchema,
6799
+ writeTrigger: "an operator adds, edits or removes a Home Assistant broker connection",
6800
+ adoptsFrom: require_dist.settingsBrokersAdoptsFrom(HA_BROKERS_OWNER)
6801
+ });
6802
+ //#endregion
6803
+ //#region src/record-kinds.ts
6804
+ /**
6805
+ * Body of one stored HA notification target. The record id IS the target id
6806
+ * and is not repeated in the body.
6807
+ * No `.meta({ secret: true })` fields: HA notify targets carry no standalone
6808
+ * credential — delivery reuses the broker WebSocket connection (the token
6809
+ * lives in the broker config, not in the target).
6810
+ */
6811
+ var HaTargetBodySchema = require_dist.TargetSchema.omit({ id: true });
6812
+ var haRecordKinds = require_dist.defineRecordKinds({
6813
+ /**
6814
+ * One row per configured Home Assistant push target. Operator-managed via the
6815
+ * notification-output cap CRUD; no TTL.
6816
+ * The legacy collection name is `provider-homeassistant:ha-notification-targets`.
6817
+ */
6818
+ "ha-notification-targets": {
6819
+ schema: HaTargetBodySchema,
6820
+ class: "config",
6821
+ writeTrigger: "an operator creates, updates, enables/disables or deletes a HA notification target",
6822
+ device: "none",
6823
+ at: "none",
6824
+ retention: { none: "a row is removed only on an explicit operator delete; bounded by the number of HA notify targets the operator configures" },
6825
+ adoptsFrom: "provider-homeassistant:ha-notification-targets",
6826
+ entry: { title: "Home Assistant notification targets" }
6827
+ } });
6828
+ /** All record kinds this addon declares (targets + B2 broker entries). */
6829
+ var haAllRecordKinds = {
6830
+ ...haRecordKinds,
6831
+ [haBrokersEntryKind.name]: haBrokersEntryKind
6832
+ };
6833
+ //#endregion
6786
6834
  //#region src/ha-notification-output.ts
6787
6835
  /**
6788
6836
  * `homeassistant` notification-output kind — hosted BY the HA provider addon.
@@ -6816,8 +6864,6 @@ function createHaIconRouteProvider() {
6816
6864
  */
6817
6865
  /** The single kind this provider contributes to the shared catalog. */
6818
6866
  var HA_NOTIFICATION_KIND = "homeassistant";
6819
- /** addonId-namespaced settings-store collection holding HA notify targets. */
6820
- var HA_TARGETS_COLLECTION = "provider-homeassistant:ha-notification-targets";
6821
6867
  function haConfigSchema() {
6822
6868
  return { sections: [{
6823
6869
  id: "connection",
@@ -6997,71 +7043,59 @@ function parseNotifyServices(result, brokerId) {
6997
7043
  }
6998
7044
  }));
6999
7045
  }
7000
- /** KV JSON-blob shape — a single `data` column routes the row through the
7001
- * settings backend's canonical key/value path (id TEXT PK, data TEXT). */
7002
- var KV_BLOB_COLUMNS = [{
7003
- name: "data",
7004
- type: "TEXT",
7005
- notNull: true
7006
- }];
7007
- function rowToTarget(row) {
7008
- const parsed = require_dist.TargetSchema.safeParse({
7009
- id: row.id,
7010
- ...row.data
7011
- });
7012
- return parsed.success ? parsed.data : null;
7013
- }
7014
- function targetToData(target) {
7015
- return {
7016
- name: target.name,
7017
- kind: target.kind,
7018
- addonId: target.addonId,
7019
- enabled: target.enabled,
7020
- config: target.config
7021
- };
7022
- }
7023
- /** CRUD over one settings-store collection of `homeassistant` notify targets. */
7024
- var HaTargetStore = class {
7025
- store;
7026
- collection;
7027
- constructor(store, collection = HA_TARGETS_COLLECTION) {
7028
- this.store = store;
7029
- this.collection = collection;
7046
+ /**
7047
+ * CRUD over the `ha-notification-targets` record kind.
7048
+ *
7049
+ * `HaTargetStore.of(records)` is the production factory; the test helper
7050
+ * (`makeFakeHaRecords`) supplies a fake transport so nothing hits SQLite.
7051
+ * No `init()` method: kinds are declared at addon boot via
7052
+ * `ctx.records.declare(haRecordKinds)`.
7053
+ */
7054
+ var HaTargetStore = class HaTargetStore {
7055
+ kind;
7056
+ constructor(kind) {
7057
+ this.kind = kind;
7030
7058
  }
7031
- /** Declare the backing collection before any read/write. The SQLite settings
7032
- * backend rejects undeclared collections (fail-fast), so this MUST run before
7033
- * `list`/`getById`/`upsert`/`delete` — mirrors addon-ai's ProfileStore.init. */
7034
- async init() {
7035
- await this.store.declareCollection(this.collection, KV_BLOB_COLUMNS);
7059
+ /** Factory: build from a declared `RecordsAccess` (after `ctx.records.declare`). */
7060
+ static of(records) {
7061
+ return new HaTargetStore(records.kind(haRecordKinds["ha-notification-targets"]));
7036
7062
  }
7037
7063
  async list() {
7038
- const rows = await this.store.query(this.collection);
7064
+ const page = await this.kind.query({ limit: 1e3 });
7039
7065
  const out = [];
7040
- for (const row of rows) {
7041
- const target = rowToTarget(row);
7042
- if (target) out.push(target);
7066
+ for (const record of page.records) {
7067
+ const parsed = require_dist.TargetSchema.safeParse({
7068
+ id: record.id,
7069
+ ...record.data
7070
+ });
7071
+ if (parsed.success) out.push(parsed.data);
7043
7072
  }
7044
7073
  return out;
7045
7074
  }
7046
7075
  async getById(id) {
7047
- const row = (await this.store.query(this.collection)).find((r) => r.id === id);
7048
- return row ? rowToTarget(row) : null;
7076
+ const row = await this.kind.get(id);
7077
+ if (row === null) return null;
7078
+ const parsed = require_dist.TargetSchema.safeParse({
7079
+ id: row.id,
7080
+ ...row.data
7081
+ });
7082
+ return parsed.success ? parsed.data : null;
7049
7083
  }
7050
7084
  async upsert(target) {
7051
- const exists = (await this.store.query(this.collection)).some((r) => r.id === target.id);
7052
- const data = targetToData(target);
7053
- if (exists) await this.store.update(this.collection, target.id, data);
7054
- else await this.store.insert(this.collection, {
7055
- id: target.id,
7056
- data
7085
+ const { id, ...rest } = target;
7086
+ const parsed = haRecordKinds["ha-notification-targets"].schema.safeParse(rest);
7087
+ if (!parsed.success) throw new Error(`invalid HA target '${id}': ${parsed.error.message}`);
7088
+ await this.kind.put({
7089
+ id,
7090
+ data: parsed.data
7057
7091
  });
7058
7092
  }
7059
7093
  async delete(id) {
7060
- await this.store.remove(this.collection, id);
7094
+ await this.kind.delete(id);
7061
7095
  }
7062
7096
  async setEnabled(id, enabled) {
7063
7097
  const target = await this.getById(id);
7064
- if (!target) return null;
7098
+ if (target === null) return null;
7065
7099
  const next = {
7066
7100
  ...target,
7067
7101
  enabled
@@ -7070,78 +7104,6 @@ var HaTargetStore = class {
7070
7104
  return next;
7071
7105
  }
7072
7106
  };
7073
- /** Adapt the tRPC-shaped `settings-store` cap client to the narrow port. */
7074
- function createApiHaSettingsStorePort(api) {
7075
- return {
7076
- query: async (collection) => {
7077
- return (await api.settingsStore.query.query({ collection })).map((r) => ({
7078
- id: r.id,
7079
- data: r.data
7080
- }));
7081
- },
7082
- insert: async (collection, record) => {
7083
- await api.settingsStore.insert.mutate({
7084
- collection,
7085
- record: {
7086
- id: record.id,
7087
- data: { ...record.data }
7088
- }
7089
- });
7090
- },
7091
- update: async (collection, id, data) => {
7092
- await api.settingsStore.update.mutate({
7093
- collection,
7094
- id,
7095
- data
7096
- });
7097
- },
7098
- remove: async (collection, id) => {
7099
- await api.settingsStore.delete.mutate({
7100
- collection,
7101
- key: id
7102
- });
7103
- },
7104
- declareCollection: async (collection, columns) => {
7105
- await api.settingsStore.declareCollection.mutate({
7106
- collection,
7107
- columns: columns.map((c) => ({ ...c }))
7108
- });
7109
- }
7110
- };
7111
- }
7112
- /** In-memory port — a resilient fallback when no `api` is wired. */
7113
- function createMemoryHaSettingsStorePort() {
7114
- const collections = /* @__PURE__ */ new Map();
7115
- const bucket = (collection) => {
7116
- let map = collections.get(collection);
7117
- if (!map) {
7118
- map = /* @__PURE__ */ new Map();
7119
- collections.set(collection, map);
7120
- }
7121
- return map;
7122
- };
7123
- return {
7124
- query: async (collection) => [...bucket(collection).values()],
7125
- insert: async (collection, record) => {
7126
- bucket(collection).set(record.id, {
7127
- id: record.id,
7128
- data: { ...record.data }
7129
- });
7130
- },
7131
- update: async (collection, id, data) => {
7132
- bucket(collection).set(id, {
7133
- id,
7134
- data: { ...data }
7135
- });
7136
- },
7137
- remove: async (collection, id) => {
7138
- bucket(collection).delete(id);
7139
- },
7140
- declareCollection: async (collection) => {
7141
- bucket(collection);
7142
- }
7143
- };
7144
- }
7145
7107
  /** The canned notification `testTarget` sends when the caller omits a sample. */
7146
7108
  function cannedNotification() {
7147
7109
  return {
@@ -7291,6 +7253,78 @@ function createHaNotificationOutputProvider(deps) {
7291
7253
  };
7292
7254
  }
7293
7255
  //#endregion
7256
+ //#region src/ha-broker-store.ts
7257
+ /**
7258
+ * CRUD for HA brokers over the `brokers` entry record kind (B2).
7259
+ */
7260
+ function rowToEntry(id, data) {
7261
+ const parsed = HaBrokerEntrySchema.safeParse({
7262
+ id,
7263
+ name: data.name,
7264
+ auth: data.auth,
7265
+ integrationId: data.integrationId
7266
+ });
7267
+ return parsed.success ? parsed.data : null;
7268
+ }
7269
+ var HaBrokerStore = class HaBrokerStore {
7270
+ kind;
7271
+ constructor(kind) {
7272
+ this.kind = kind;
7273
+ }
7274
+ static of(records) {
7275
+ return new HaBrokerStore(records.kind(haBrokersEntryKind));
7276
+ }
7277
+ async listResolved() {
7278
+ const page = await this.kind.query({ limit: 1e3 });
7279
+ const out = [];
7280
+ for (const record of page.records) {
7281
+ let data = record.data;
7282
+ try {
7283
+ const resolved = await this.kind.getResolved(record.id);
7284
+ if (resolved !== null) data = resolved.data;
7285
+ } catch (err) {
7286
+ if (!(err instanceof require_dist.RecordSecretUnavailableError)) throw err;
7287
+ }
7288
+ const entry = rowToEntry(record.id, data);
7289
+ if (entry !== null) out.push(entry);
7290
+ }
7291
+ return out;
7292
+ }
7293
+ async getById(id) {
7294
+ try {
7295
+ const row = await this.kind.getResolved(id);
7296
+ if (row === null) return null;
7297
+ return rowToEntry(row.id, row.data);
7298
+ } catch (err) {
7299
+ if (err instanceof require_dist.RecordSecretUnavailableError) return null;
7300
+ throw err;
7301
+ }
7302
+ }
7303
+ async upsert(entry) {
7304
+ const { id, name, auth, integrationId } = entry;
7305
+ const body = {
7306
+ name,
7307
+ auth,
7308
+ ...integrationId === void 0 ? {} : { integrationId }
7309
+ };
7310
+ const parsed = haBrokersEntryKind.schema.safeParse(body);
7311
+ if (!parsed.success) throw new Error(`invalid HA broker '${id}': ${parsed.error.message}`);
7312
+ await this.kind.put({
7313
+ id,
7314
+ data: parsed.data
7315
+ });
7316
+ }
7317
+ async delete(id) {
7318
+ await this.kind.delete(id);
7319
+ }
7320
+ async replaceAll(entries) {
7321
+ const page = await this.kind.query({ limit: 1e3 });
7322
+ const nextIds = new Set(entries.map((e) => e.id));
7323
+ for (const row of page.records) if (!nextIds.has(row.id)) await this.kind.delete(row.id);
7324
+ for (const entry of entries) await this.upsert(entry);
7325
+ }
7326
+ };
7327
+ //#endregion
7294
7328
  //#region src/ha-calendar-source.ts
7295
7329
  function isCalendarEntity(entityId) {
7296
7330
  return entityId.startsWith("calendar.");
@@ -7951,6 +7985,9 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
7951
7985
  return `ha:${String(config?.["brokerId"] ?? "unknown")}:dev:${String(config?.["haDeviceId"] ?? Date.now())}`;
7952
7986
  }
7953
7987
  registry = null;
7988
+ brokerStore = null;
7989
+ /** Runtime broker rows (records when B2 is live, else settings). */
7990
+ activeBrokers = [];
7954
7991
  /** Periodic re-sync sweep handle (cleared on shutdown). */
7955
7992
  resyncTimer = null;
7956
7993
  /** `brokerId → aggregator deviceId` cache for the per-broker generic
@@ -7964,6 +8001,11 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
7964
8001
  super({ ...DEFAULT_CONFIG });
7965
8002
  }
7966
8003
  async onInitialize() {
8004
+ const records = this.ctx.records;
8005
+ if (records === void 0) throw new Error("provider-homeassistant: ctx.records is required (hub-only addon)");
8006
+ await records.declare(haAllRecordKinds);
8007
+ this.brokerStore = HaBrokerStore.of(records);
8008
+ this.activeBrokers = await this.loadPersistedBrokers();
7967
8009
  this.registry = new HaBrokerRegistry(this.ctx.logger, this.ctx.eventBus);
7968
8010
  this.registry.setOnBrokerConnected((brokerId) => {
7969
8011
  this.reconcileBroker(brokerId);
@@ -7974,11 +8016,11 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
7974
8016
  this.registry.setOnBusEvent((brokerId, ev) => {
7975
8017
  this.routeBusEvent(brokerId, ev);
7976
8018
  });
7977
- await this.registry.restore(this.config.brokers);
8019
+ await this.registry.restore(this.activeBrokers);
7978
8020
  this.resyncTimer = setInterval(() => {
7979
8021
  this.reconcileAllConnectedBrokers();
7980
8022
  }, HaProviderAddon.RESYNC_INTERVAL_MS);
7981
- this.ctx.logger.info("ha provider initialised", { meta: { brokerCount: this.config.brokers.length } });
8023
+ this.ctx.logger.info("ha provider initialised", { meta: { brokerCount: this.activeBrokers.length } });
7982
8024
  await this.reconcileIntegrationsToBrokers();
7983
8025
  this.subscribeIntegrationLifecycle();
7984
8026
  return [
@@ -8009,11 +8051,9 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8009
8051
  ];
8010
8052
  }
8011
8053
  async buildNotificationOutputProvider() {
8012
- const api = this.ctx.api;
8013
- const port = api ? createApiHaSettingsStorePort(api) : createMemoryHaSettingsStorePort();
8014
- if (!api) this.ctx.logger.warn("ha notification-output: no ctx.api — targets persist in-memory only");
8015
- const store = new HaTargetStore(port);
8016
- await store.init();
8054
+ const records = this.ctx.records;
8055
+ if (records === void 0) throw new Error("ha notification-output: ctx.records is required (hub-only addon)");
8056
+ const store = HaTargetStore.of(records);
8017
8057
  return createHaNotificationOutputProvider({
8018
8058
  addonId: this.ctx.id,
8019
8059
  iconUrl: HA_NOTIFICATION_ICON_URL,
@@ -8030,7 +8070,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8030
8070
  if (!manager) throw new Error(`ha-broker '${brokerId}' not found`);
8031
8071
  return manager.sendMessage({ type: "get_services" });
8032
8072
  },
8033
- listBrokerIds: () => this.config.brokers.map((b) => b.id),
8073
+ listBrokerIds: () => this.activeBrokers.map((b) => b.id),
8034
8074
  logger: this.ctx.logger.child("notification-output")
8035
8075
  });
8036
8076
  }
@@ -8091,7 +8131,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8091
8131
  const settings = await api.integrations.getSettings.query({ id: integration.id });
8092
8132
  const brokerId = typeof settings["brokerId"] === "string" ? settings["brokerId"] : null;
8093
8133
  if (!brokerId) continue;
8094
- if (!this.config.brokers.find((b) => b.id === brokerId)) {
8134
+ if (!this.activeBrokers.find((b) => b.id === brokerId)) {
8095
8135
  this.ctx.logger.warn("integration→broker: linked broker not found", { meta: {
8096
8136
  integrationId: integration.id,
8097
8137
  brokerId
@@ -8104,11 +8144,11 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8104
8144
  brokerId
8105
8145
  });
8106
8146
  }
8107
- const linkedBrokers = linkBrokersToIntegrations(this.config.brokers, integrationsWithBrokerId);
8108
- if (linkedBrokers.some((b, i) => b !== this.config.brokers[i])) await this.updateGlobalSettings({ brokers: linkedBrokers });
8109
- const orphans = computeBrokerCleanup(this.config.brokers, survivingIntegrationIds);
8147
+ const linkedBrokers = linkBrokersToIntegrations(this.activeBrokers, integrationsWithBrokerId);
8148
+ if (linkedBrokers.some((b, i) => b !== this.activeBrokers[i])) await this.persistBrokerEntries(linkedBrokers);
8149
+ const orphans = computeBrokerCleanup(this.activeBrokers, survivingIntegrationIds);
8110
8150
  this.ctx.logger.info("integration→broker reconcile", { meta: {
8111
- brokerCount: this.config.brokers.length,
8151
+ brokerCount: this.activeBrokers.length,
8112
8152
  integrationCount: haIntegrations.length,
8113
8153
  orphans: orphans.length
8114
8154
  } });
@@ -8205,7 +8245,8 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8205
8245
  async onConfigChanged() {
8206
8246
  const reg = this.registry;
8207
8247
  if (!reg) return;
8208
- const persisted = this.config.brokers;
8248
+ this.activeBrokers = await this.loadPersistedBrokers();
8249
+ const persisted = this.activeBrokers;
8209
8250
  const liveIds = new Set(reg.list().map((b) => b.id));
8210
8251
  const persistedIds = new Set(persisted.map((e) => e.id));
8211
8252
  for (const liveId of liveIds) if (!persistedIds.has(liveId)) try {
@@ -8243,7 +8284,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8243
8284
  ...b,
8244
8285
  id: created.id
8245
8286
  } : b);
8246
- await this.updateGlobalSettings({ brokers: next });
8287
+ await this.persistBrokerEntries(next);
8247
8288
  }
8248
8289
  } catch (err) {
8249
8290
  this.ctx.logger.warn("ha onConfigChanged: failed to start new broker", { meta: {
@@ -8253,9 +8294,26 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8253
8294
  }
8254
8295
  }
8255
8296
  }
8297
+ async loadPersistedBrokers() {
8298
+ const store = this.brokerStore;
8299
+ if (store !== null) {
8300
+ const fromRecords = await store.listResolved();
8301
+ if (fromRecords.length > 0) return fromRecords;
8302
+ }
8303
+ return this.config.brokers;
8304
+ }
8305
+ async persistBrokerEntries(entries) {
8306
+ this.activeBrokers = [...entries];
8307
+ const store = this.brokerStore;
8308
+ if (store !== null) {
8309
+ await store.replaceAll(entries);
8310
+ return;
8311
+ }
8312
+ await this.updateGlobalSettings({ brokers: entries });
8313
+ }
8256
8314
  buildBrokerProvider() {
8257
8315
  const ownerAddonId = this.ctx.id;
8258
- const owns = (id) => this.config.brokers.some((b) => b.id === id);
8316
+ const owns = (id) => this.activeBrokers.some((b) => b.id === id);
8259
8317
  return {
8260
8318
  list: async ({ kind }) => {
8261
8319
  if (kind && kind !== HA_KIND) return [];
@@ -8285,7 +8343,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8285
8343
  brokerId: entry.id,
8286
8344
  name
8287
8345
  } });
8288
- await this.updateGlobalSettings({ brokers: [...this.config.brokers, entry] });
8346
+ await this.persistBrokerEntries([...this.activeBrokers, entry]);
8289
8347
  return { id: entry.id };
8290
8348
  },
8291
8349
  remove: async ({ id }) => {
@@ -8300,8 +8358,8 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8300
8358
  brokerId: id,
8301
8359
  logger: this.ctx.logger
8302
8360
  });
8303
- const nextBrokers = this.config.brokers.filter((b) => b.id !== id);
8304
- await this.updateGlobalSettings({ brokers: nextBrokers });
8361
+ const nextBrokers = this.activeBrokers.filter((b) => b.id !== id);
8362
+ await this.persistBrokerEntries(nextBrokers);
8305
8363
  },
8306
8364
  testConnection: async ({ id }) => {
8307
8365
  if (!owns(id)) return {
@@ -8323,18 +8381,18 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
8323
8381
  };
8324
8382
  },
8325
8383
  getSettings: async ({ id }) => {
8326
- const entry = this.config.brokers.find((b) => b.id === id);
8384
+ const entry = this.activeBrokers.find((b) => b.id === id);
8327
8385
  if (!entry) return null;
8328
8386
  return authToSettings(entry.auth);
8329
8387
  },
8330
8388
  setSettings: async ({ id, settings }) => {
8331
8389
  if (!owns(id)) return;
8332
8390
  const entry = await this.requireRegistry().updateEntry(id, settings);
8333
- const next = this.config.brokers.map((b) => b.id === id ? entry : b);
8334
- await this.updateGlobalSettings({ brokers: next });
8391
+ const next = this.activeBrokers.map((b) => b.id === id ? entry : b);
8392
+ await this.persistBrokerEntries(next);
8335
8393
  },
8336
8394
  getBrokerConfig: async ({ id }) => {
8337
- const entry = this.config.brokers.find((b) => b.id === id);
8395
+ const entry = this.activeBrokers.find((b) => b.id === id);
8338
8396
  if (!entry) return null;
8339
8397
  return authToSettings(entry.auth);
8340
8398
  },