@camstack/system 1.2.305 → 1.2.306
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/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-extension-linked-slot.d.ts +19 -0
- package/dist/builtins/device-manager/device-linked-devices.d.ts +26 -18
- package/dist/builtins/device-manager/device-manager.addon.js +157 -135
- package/dist/builtins/device-manager/device-manager.addon.mjs +157 -135
- package/dist/builtins/doorbell/binding-mirror.d.ts +13 -7
- package/dist/builtins/doorbell/virtual-doorbell.addon.d.ts +12 -45
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +29 -102
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +29 -102
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-Df1NhKxm.mjs → dist-CLfJMMdf.mjs} +40 -68
- package/dist/{dist-BK4iP6ab.js → dist-vecbhDzu.js} +39 -73
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{retired-settings-keys-DwWMph6F.js → retired-settings-keys-Bm2p0Rot.js} +1 -1
- package/dist/{retired-settings-keys-dC4ckbXJ.mjs → retired-settings-keys-C1ODcdnr.mjs} +1 -1
- package/package.json +1 -1
- package/dist/builtins/device-manager/device-store-sections.d.ts +0 -26
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
8
8
|
/**
|
|
9
9
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -166,13 +166,19 @@ var DoorbellTriggerEngine = class {
|
|
|
166
166
|
* not survive the next read. So a negative read ARMS the revocation and a
|
|
167
167
|
* second consecutive negative applies it.
|
|
168
168
|
*
|
|
169
|
-
* ERRING. `undefined` (never read) and `unbind-pending` both ring.
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
169
|
+
* ERRING. `undefined` (never read) and `unbind-pending` both ring. The cost
|
|
170
|
+
* of erring open is a spurious ring on a camera whose wrapper is not bound
|
|
171
|
+
* but which has trigger sources, for at most two reload cycles. The cost of
|
|
172
|
+
* erring closed is the press.
|
|
173
|
+
*
|
|
174
|
+
* D655: a configured source is NO LONGER evidence of the binding. D49 leaned
|
|
175
|
+
* on "a source can only be configured through this wrapper's own
|
|
176
|
+
* binding-gated settings surface"; that surface is retired, and the
|
|
177
|
+
* `doorbell-source` extension slot that replaced it is offered on every
|
|
178
|
+
* camera, bound or not (D648). The erring-open window above is therefore
|
|
179
|
+
* reachable by configuring sources on a never-bound camera, not only by
|
|
180
|
+
* unbinding a configured one — still bounded by two reload cycles, and the
|
|
181
|
+
* slot's card says `inactive` once the reads agree.
|
|
176
182
|
*
|
|
177
183
|
* ─────────────────────────────────────────────────────────────────────
|
|
178
184
|
* 2026-08-07 (D72). The corroboration above was DEFEATED, and the reason
|
|
@@ -380,8 +386,8 @@ function applyDoorbellSourcesPatch(current, patchValue) {
|
|
|
380
386
|
//#region src/builtins/doorbell/doorbell-extension-slot.ts
|
|
381
387
|
/**
|
|
382
388
|
* The virtual doorbell's side of `device-extension` (D648): the
|
|
383
|
-
* `doorbell-source` slot, served over the `doorbellSources` store
|
|
384
|
-
*
|
|
389
|
+
* `doorbell-source` slot, served over the wrapper's `doorbellSources` store
|
|
390
|
+
* — since D655 the only editor of a camera's trigger devices.
|
|
385
391
|
*
|
|
386
392
|
* - `list` reads the store through `parseDoorbellSources` — the parser the
|
|
387
393
|
* trigger engine's assignments are built from — so the slot's value is
|
|
@@ -401,7 +407,7 @@ function applyDoorbellSourcesPatch(current, patchValue) {
|
|
|
401
407
|
* - The picked sources are labelled with ONE batched `listAll({deviceIds})`,
|
|
402
408
|
* never a `getDevice` per id.
|
|
403
409
|
* - `set` goes through the addon's `persistDoorbellSources`, the SAME
|
|
404
|
-
* normalise-and-store path the
|
|
410
|
+
* normalise-and-store path the wrapper has, which also invalidates
|
|
405
411
|
* the assignment cache so the binding mirror is re-read off the ring path
|
|
406
412
|
* (D49). A `setSlot` call is NOT evidence that the wrapper is bound (the
|
|
407
413
|
* contract reaches this provider through `device-extension`'s own
|
|
@@ -622,9 +628,9 @@ function parseDoorbellSlice(slice) {
|
|
|
622
628
|
*
|
|
623
629
|
* 1. The operator binds the wrapper to a camera in the bindings UI
|
|
624
630
|
* (`defaultActive: false` — never auto-bound).
|
|
625
|
-
* 2. In the camera's
|
|
626
|
-
* operator picks one or more SOURCE devices
|
|
627
|
-
*
|
|
631
|
+
* 2. In the camera's Extensions section (the `doorbell-source` slot,
|
|
632
|
+
* D648/D655) the operator picks one or more SOURCE devices — that is
|
|
633
|
+
* the ONLY choice. The reaction is derived automatically per
|
|
628
634
|
* device type: a binary sensor rings when it goes active, a switch
|
|
629
635
|
* rings when it turns on (see `trigger-engine.ts`). The persisted
|
|
630
636
|
* shape (`doorbellSources: [{deviceId}]`) stays extensible for a
|
|
@@ -671,20 +677,15 @@ var VirtualDoorbellAddon = class extends require_dist.BaseAddon {
|
|
|
671
677
|
});
|
|
672
678
|
return [{
|
|
673
679
|
capability: require_dist.doorbellCapability,
|
|
674
|
-
provider: {
|
|
675
|
-
getStatus: (input) => this.getStatus(input.deviceId),
|
|
676
|
-
getDeviceSettingsContribution: (input) => this.buildDeviceSettingsContribution(input.deviceId),
|
|
677
|
-
getDeviceLiveContribution: async () => null,
|
|
678
|
-
applyDeviceSettingsPatch: (input) => this.saveDeviceSettingsPatch(input.deviceId, input.patch)
|
|
679
|
-
}
|
|
680
|
+
provider: { getStatus: (input) => this.getStatus(input.deviceId) }
|
|
680
681
|
}, {
|
|
681
682
|
capability: require_dist.deviceExtensionCapability,
|
|
682
683
|
provider: this.buildExtensionProvider()
|
|
683
684
|
}];
|
|
684
685
|
}
|
|
685
686
|
/**
|
|
686
|
-
* The `device-extension` provider: the
|
|
687
|
-
*
|
|
687
|
+
* The `device-extension` provider: the only editor of a camera's trigger
|
|
688
|
+
* devices since D655 (see `doorbell-extension-slot.ts`).
|
|
688
689
|
*/
|
|
689
690
|
buildExtensionProvider() {
|
|
690
691
|
const toSlotDevice = (d) => ({
|
|
@@ -969,19 +970,10 @@ var VirtualDoorbellAddon = class extends require_dist.BaseAddon {
|
|
|
969
970
|
}
|
|
970
971
|
}
|
|
971
972
|
/**
|
|
972
|
-
* Record a binding we observed FIRST-HAND. Both callers are cap methods
|
|
973
|
-
* the router only reaches by resolving this wrapper for this device —
|
|
974
|
-
* which it can only do through the binding — so a call is direct evidence
|
|
975
|
-
* and outranks anything the store says.
|
|
976
|
-
*/
|
|
977
|
-
confirmBindingFromCapCall(deviceId) {
|
|
978
|
-
this.bindingMirror.set(deviceId, nextBindingState(this.bindingMirror.get(deviceId), true));
|
|
979
|
-
}
|
|
980
|
-
/**
|
|
981
973
|
* Lazily (re)build the camera→source assignment set from every
|
|
982
974
|
* camera's device store. TTL-bounded so devices/settings appearing
|
|
983
|
-
* after boot are picked up without a
|
|
984
|
-
*
|
|
975
|
+
* after boot are picked up without a save; invalidated eagerly by
|
|
976
|
+
* `persistDoorbellSources`.
|
|
985
977
|
*/
|
|
986
978
|
async ensureAssignments() {
|
|
987
979
|
const now = Date.now();
|
|
@@ -1052,75 +1044,10 @@ var VirtualDoorbellAddon = class extends require_dist.BaseAddon {
|
|
|
1052
1044
|
return parseDoorbellSources(await this.ctx.settings.readDeviceStore(deviceId));
|
|
1053
1045
|
}
|
|
1054
1046
|
/**
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1059
|
-
*/
|
|
1060
|
-
async lookupDevice(deviceId) {
|
|
1061
|
-
try {
|
|
1062
|
-
const found = await this.ctx.api.deviceManager.getDevice.query({ deviceId });
|
|
1063
|
-
return found ? { type: found.type } : null;
|
|
1064
|
-
} catch (err) {
|
|
1065
|
-
this.ctx.logger.debug("virtual-doorbell: getDevice failed during contribution", {
|
|
1066
|
-
tags: { deviceId },
|
|
1067
|
-
meta: { error: require_dist.errMsg(err) }
|
|
1068
|
-
});
|
|
1069
|
-
return null;
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
/**
|
|
1073
|
-
* Settings section for the device-detail page — contributed into the
|
|
1074
|
-
* GENERAL settings surface (no `tab`, so it lands in the same tab as
|
|
1075
|
-
* "Linked devices", ordered just after it). Camera-only: the doorbell
|
|
1076
|
-
* cap also applies to Button accessories (native providers) where a
|
|
1077
|
-
* virtual-source picker is meaningless.
|
|
1078
|
-
*
|
|
1079
|
-
* A SINGLE `device-multiselect` field carries only a declarative
|
|
1080
|
-
* `deviceFilter` — the admin-ui renders the SHARED searchable device
|
|
1081
|
-
* picker (same idiom as "Linked devices") whose options come from
|
|
1082
|
-
* `deviceManager.listAll` filtered CLIENT-SIDE. The addon NO LONGER
|
|
1083
|
-
* computes the option list server-side: the old path enumerated
|
|
1084
|
-
* `deviceManager.getAllBindings`, which returns an empty set on the live
|
|
1085
|
-
* cluster and left the picker blank. The reaction is still derived
|
|
1086
|
-
* automatically per device type — no trigger/eventType controls.
|
|
1087
|
-
*/
|
|
1088
|
-
async buildDeviceSettingsContribution(deviceId) {
|
|
1089
|
-
const device = await this.lookupDevice(deviceId);
|
|
1090
|
-
if (device && device.type !== require_dist.DeviceType.Camera) return null;
|
|
1091
|
-
this.confirmBindingFromCapCall(deviceId);
|
|
1092
|
-
const sources = await this.readDeviceSources(deviceId);
|
|
1093
|
-
return { sections: [{
|
|
1094
|
-
id: "virtual-doorbell",
|
|
1095
|
-
title: "Virtual doorbell",
|
|
1096
|
-
description: "Ring this camera’s doorbell when a chosen device becomes active — a contact opening, a switch turning on, or a sensor firing. Pick any binary sensor or switch below; the reaction is automatic per device type.",
|
|
1097
|
-
order: 71,
|
|
1098
|
-
fields: [{
|
|
1099
|
-
type: "device-multiselect",
|
|
1100
|
-
key: KEY_SOURCES,
|
|
1101
|
-
label: "Trigger devices",
|
|
1102
|
-
description: "Any of these becoming active rings this camera. Binary sensors ring when they go active; switches ring when they turn on.",
|
|
1103
|
-
deviceFilter: {
|
|
1104
|
-
caps: require_dist.SOURCE_CAPS,
|
|
1105
|
-
types: require_dist.SOURCE_DEVICE_TYPES,
|
|
1106
|
-
excludeDeviceId: deviceId
|
|
1107
|
-
},
|
|
1108
|
-
value: sources.map((s) => String(s.deviceId))
|
|
1109
|
-
}]
|
|
1110
|
-
}] };
|
|
1111
|
-
}
|
|
1112
|
-
async saveDeviceSettingsPatch(deviceId, patch) {
|
|
1113
|
-
if (!this.ctx.settings) throw new Error("[virtual-doorbell] settings store unavailable — cannot persist per-device settings");
|
|
1114
|
-
this.confirmBindingFromCapCall(deviceId);
|
|
1115
|
-
if ("doorbellSources" in patch) await this.persistDoorbellSources(deviceId, patch[KEY_SOURCES]);
|
|
1116
|
-
return { success: true };
|
|
1117
|
-
}
|
|
1118
|
-
/**
|
|
1119
|
-
* THE write path for a camera's trigger sources — the settings save above
|
|
1120
|
-
* and the `doorbell-source` extension slot both land here (D648), so the
|
|
1121
|
-
* two surfaces cannot store different shapes: normalise to
|
|
1122
|
-
* `doorbellSources: [{deviceId}]`, strip the legacy keys, and invalidate the
|
|
1123
|
-
* assignment cache so the next rise (and the binding mirror's next
|
|
1047
|
+
* THE write path for a camera's trigger sources — the `doorbell-source`
|
|
1048
|
+
* extension slot lands here (D648; its only caller since D655): normalise
|
|
1049
|
+
* to `doorbellSources: [{deviceId}]`, strip the legacy keys, and invalidate
|
|
1050
|
+
* the assignment cache so the next rise (and the binding mirror's next
|
|
1124
1051
|
* refresh, off the ring path) sees the new wiring.
|
|
1125
1052
|
*/
|
|
1126
1053
|
async persistDoorbellSources(deviceId, value) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ct as isSourceCap, D as SOURCE_CAPS, H as bareAddonId, Sn as DeviceType, St as isSameAddonId, Un as EventCategory, X as createDeviceExtensionProvider, et as defineExtensionSlotProvider, gn as BaseAddon, kn as createEvent, mn as errMsg, nt as deviceExtensionCapability, ot as doorbellCapability, ut as evaluateSensorEdge } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
3
3
|
/**
|
|
4
4
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -161,13 +161,19 @@ var DoorbellTriggerEngine = class {
|
|
|
161
161
|
* not survive the next read. So a negative read ARMS the revocation and a
|
|
162
162
|
* second consecutive negative applies it.
|
|
163
163
|
*
|
|
164
|
-
* ERRING. `undefined` (never read) and `unbind-pending` both ring.
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
164
|
+
* ERRING. `undefined` (never read) and `unbind-pending` both ring. The cost
|
|
165
|
+
* of erring open is a spurious ring on a camera whose wrapper is not bound
|
|
166
|
+
* but which has trigger sources, for at most two reload cycles. The cost of
|
|
167
|
+
* erring closed is the press.
|
|
168
|
+
*
|
|
169
|
+
* D655: a configured source is NO LONGER evidence of the binding. D49 leaned
|
|
170
|
+
* on "a source can only be configured through this wrapper's own
|
|
171
|
+
* binding-gated settings surface"; that surface is retired, and the
|
|
172
|
+
* `doorbell-source` extension slot that replaced it is offered on every
|
|
173
|
+
* camera, bound or not (D648). The erring-open window above is therefore
|
|
174
|
+
* reachable by configuring sources on a never-bound camera, not only by
|
|
175
|
+
* unbinding a configured one — still bounded by two reload cycles, and the
|
|
176
|
+
* slot's card says `inactive` once the reads agree.
|
|
171
177
|
*
|
|
172
178
|
* ─────────────────────────────────────────────────────────────────────
|
|
173
179
|
* 2026-08-07 (D72). The corroboration above was DEFEATED, and the reason
|
|
@@ -375,8 +381,8 @@ function applyDoorbellSourcesPatch(current, patchValue) {
|
|
|
375
381
|
//#region src/builtins/doorbell/doorbell-extension-slot.ts
|
|
376
382
|
/**
|
|
377
383
|
* The virtual doorbell's side of `device-extension` (D648): the
|
|
378
|
-
* `doorbell-source` slot, served over the `doorbellSources` store
|
|
379
|
-
*
|
|
384
|
+
* `doorbell-source` slot, served over the wrapper's `doorbellSources` store
|
|
385
|
+
* — since D655 the only editor of a camera's trigger devices.
|
|
380
386
|
*
|
|
381
387
|
* - `list` reads the store through `parseDoorbellSources` — the parser the
|
|
382
388
|
* trigger engine's assignments are built from — so the slot's value is
|
|
@@ -396,7 +402,7 @@ function applyDoorbellSourcesPatch(current, patchValue) {
|
|
|
396
402
|
* - The picked sources are labelled with ONE batched `listAll({deviceIds})`,
|
|
397
403
|
* never a `getDevice` per id.
|
|
398
404
|
* - `set` goes through the addon's `persistDoorbellSources`, the SAME
|
|
399
|
-
* normalise-and-store path the
|
|
405
|
+
* normalise-and-store path the wrapper has, which also invalidates
|
|
400
406
|
* the assignment cache so the binding mirror is re-read off the ring path
|
|
401
407
|
* (D49). A `setSlot` call is NOT evidence that the wrapper is bound (the
|
|
402
408
|
* contract reaches this provider through `device-extension`'s own
|
|
@@ -617,9 +623,9 @@ function parseDoorbellSlice(slice) {
|
|
|
617
623
|
*
|
|
618
624
|
* 1. The operator binds the wrapper to a camera in the bindings UI
|
|
619
625
|
* (`defaultActive: false` — never auto-bound).
|
|
620
|
-
* 2. In the camera's
|
|
621
|
-
* operator picks one or more SOURCE devices
|
|
622
|
-
*
|
|
626
|
+
* 2. In the camera's Extensions section (the `doorbell-source` slot,
|
|
627
|
+
* D648/D655) the operator picks one or more SOURCE devices — that is
|
|
628
|
+
* the ONLY choice. The reaction is derived automatically per
|
|
623
629
|
* device type: a binary sensor rings when it goes active, a switch
|
|
624
630
|
* rings when it turns on (see `trigger-engine.ts`). The persisted
|
|
625
631
|
* shape (`doorbellSources: [{deviceId}]`) stays extensible for a
|
|
@@ -666,20 +672,15 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
666
672
|
});
|
|
667
673
|
return [{
|
|
668
674
|
capability: doorbellCapability,
|
|
669
|
-
provider: {
|
|
670
|
-
getStatus: (input) => this.getStatus(input.deviceId),
|
|
671
|
-
getDeviceSettingsContribution: (input) => this.buildDeviceSettingsContribution(input.deviceId),
|
|
672
|
-
getDeviceLiveContribution: async () => null,
|
|
673
|
-
applyDeviceSettingsPatch: (input) => this.saveDeviceSettingsPatch(input.deviceId, input.patch)
|
|
674
|
-
}
|
|
675
|
+
provider: { getStatus: (input) => this.getStatus(input.deviceId) }
|
|
675
676
|
}, {
|
|
676
677
|
capability: deviceExtensionCapability,
|
|
677
678
|
provider: this.buildExtensionProvider()
|
|
678
679
|
}];
|
|
679
680
|
}
|
|
680
681
|
/**
|
|
681
|
-
* The `device-extension` provider: the
|
|
682
|
-
*
|
|
682
|
+
* The `device-extension` provider: the only editor of a camera's trigger
|
|
683
|
+
* devices since D655 (see `doorbell-extension-slot.ts`).
|
|
683
684
|
*/
|
|
684
685
|
buildExtensionProvider() {
|
|
685
686
|
const toSlotDevice = (d) => ({
|
|
@@ -964,19 +965,10 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
964
965
|
}
|
|
965
966
|
}
|
|
966
967
|
/**
|
|
967
|
-
* Record a binding we observed FIRST-HAND. Both callers are cap methods
|
|
968
|
-
* the router only reaches by resolving this wrapper for this device —
|
|
969
|
-
* which it can only do through the binding — so a call is direct evidence
|
|
970
|
-
* and outranks anything the store says.
|
|
971
|
-
*/
|
|
972
|
-
confirmBindingFromCapCall(deviceId) {
|
|
973
|
-
this.bindingMirror.set(deviceId, nextBindingState(this.bindingMirror.get(deviceId), true));
|
|
974
|
-
}
|
|
975
|
-
/**
|
|
976
968
|
* Lazily (re)build the camera→source assignment set from every
|
|
977
969
|
* camera's device store. TTL-bounded so devices/settings appearing
|
|
978
|
-
* after boot are picked up without a
|
|
979
|
-
*
|
|
970
|
+
* after boot are picked up without a save; invalidated eagerly by
|
|
971
|
+
* `persistDoorbellSources`.
|
|
980
972
|
*/
|
|
981
973
|
async ensureAssignments() {
|
|
982
974
|
const now = Date.now();
|
|
@@ -1047,75 +1039,10 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
1047
1039
|
return parseDoorbellSources(await this.ctx.settings.readDeviceStore(deviceId));
|
|
1048
1040
|
}
|
|
1049
1041
|
/**
|
|
1050
|
-
*
|
|
1051
|
-
*
|
|
1052
|
-
*
|
|
1053
|
-
*
|
|
1054
|
-
*/
|
|
1055
|
-
async lookupDevice(deviceId) {
|
|
1056
|
-
try {
|
|
1057
|
-
const found = await this.ctx.api.deviceManager.getDevice.query({ deviceId });
|
|
1058
|
-
return found ? { type: found.type } : null;
|
|
1059
|
-
} catch (err) {
|
|
1060
|
-
this.ctx.logger.debug("virtual-doorbell: getDevice failed during contribution", {
|
|
1061
|
-
tags: { deviceId },
|
|
1062
|
-
meta: { error: errMsg(err) }
|
|
1063
|
-
});
|
|
1064
|
-
return null;
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
/**
|
|
1068
|
-
* Settings section for the device-detail page — contributed into the
|
|
1069
|
-
* GENERAL settings surface (no `tab`, so it lands in the same tab as
|
|
1070
|
-
* "Linked devices", ordered just after it). Camera-only: the doorbell
|
|
1071
|
-
* cap also applies to Button accessories (native providers) where a
|
|
1072
|
-
* virtual-source picker is meaningless.
|
|
1073
|
-
*
|
|
1074
|
-
* A SINGLE `device-multiselect` field carries only a declarative
|
|
1075
|
-
* `deviceFilter` — the admin-ui renders the SHARED searchable device
|
|
1076
|
-
* picker (same idiom as "Linked devices") whose options come from
|
|
1077
|
-
* `deviceManager.listAll` filtered CLIENT-SIDE. The addon NO LONGER
|
|
1078
|
-
* computes the option list server-side: the old path enumerated
|
|
1079
|
-
* `deviceManager.getAllBindings`, which returns an empty set on the live
|
|
1080
|
-
* cluster and left the picker blank. The reaction is still derived
|
|
1081
|
-
* automatically per device type — no trigger/eventType controls.
|
|
1082
|
-
*/
|
|
1083
|
-
async buildDeviceSettingsContribution(deviceId) {
|
|
1084
|
-
const device = await this.lookupDevice(deviceId);
|
|
1085
|
-
if (device && device.type !== DeviceType.Camera) return null;
|
|
1086
|
-
this.confirmBindingFromCapCall(deviceId);
|
|
1087
|
-
const sources = await this.readDeviceSources(deviceId);
|
|
1088
|
-
return { sections: [{
|
|
1089
|
-
id: "virtual-doorbell",
|
|
1090
|
-
title: "Virtual doorbell",
|
|
1091
|
-
description: "Ring this camera’s doorbell when a chosen device becomes active — a contact opening, a switch turning on, or a sensor firing. Pick any binary sensor or switch below; the reaction is automatic per device type.",
|
|
1092
|
-
order: 71,
|
|
1093
|
-
fields: [{
|
|
1094
|
-
type: "device-multiselect",
|
|
1095
|
-
key: KEY_SOURCES,
|
|
1096
|
-
label: "Trigger devices",
|
|
1097
|
-
description: "Any of these becoming active rings this camera. Binary sensors ring when they go active; switches ring when they turn on.",
|
|
1098
|
-
deviceFilter: {
|
|
1099
|
-
caps: SOURCE_CAPS,
|
|
1100
|
-
types: SOURCE_DEVICE_TYPES,
|
|
1101
|
-
excludeDeviceId: deviceId
|
|
1102
|
-
},
|
|
1103
|
-
value: sources.map((s) => String(s.deviceId))
|
|
1104
|
-
}]
|
|
1105
|
-
}] };
|
|
1106
|
-
}
|
|
1107
|
-
async saveDeviceSettingsPatch(deviceId, patch) {
|
|
1108
|
-
if (!this.ctx.settings) throw new Error("[virtual-doorbell] settings store unavailable — cannot persist per-device settings");
|
|
1109
|
-
this.confirmBindingFromCapCall(deviceId);
|
|
1110
|
-
if ("doorbellSources" in patch) await this.persistDoorbellSources(deviceId, patch[KEY_SOURCES]);
|
|
1111
|
-
return { success: true };
|
|
1112
|
-
}
|
|
1113
|
-
/**
|
|
1114
|
-
* THE write path for a camera's trigger sources — the settings save above
|
|
1115
|
-
* and the `doorbell-source` extension slot both land here (D648), so the
|
|
1116
|
-
* two surfaces cannot store different shapes: normalise to
|
|
1117
|
-
* `doorbellSources: [{deviceId}]`, strip the legacy keys, and invalidate the
|
|
1118
|
-
* assignment cache so the next rise (and the binding mirror's next
|
|
1042
|
+
* THE write path for a camera's trigger sources — the `doorbell-source`
|
|
1043
|
+
* extension slot lands here (D648; its only caller since D655): normalise
|
|
1044
|
+
* to `doorbellSources: [{deviceId}]`, strip the legacy keys, and invalidate
|
|
1045
|
+
* the assignment cache so the next rise (and the binding mirror's next
|
|
1119
1046
|
* refresh, off the ring path) sees the new wiring.
|
|
1120
1047
|
*/
|
|
1121
1048
|
async persistDoorbellSources(deviceId, value) {
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gn as BaseAddon, jt as logDestinationCapability } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
4
4
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
5
5
|
var NO_DEVICES = "liveness:no-devices";
|
|
6
6
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as RECORDING_SOURCE_CAMSTACK_ADDON, E as RecordingStatusSchema, Un as EventCategory, gn as BaseAddon, kn as createEvent, mn as errMsg } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
3
3
|
var NO_DEVICES = "liveness:no-devices";
|
|
4
4
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
9
9
|
let crypto$1 = require("crypto");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { A as ScopedTokenSchema, B as authProviderCapability, F as UserRecordSchema, gn as BaseAddon, ln as userManagementCapability, r as ApiKeyRecordSchema } from "../../dist-CLfJMMdf.mjs";
|
|
3
3
|
import * as crypto$2 from "node:crypto";
|
|
4
4
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
5
5
|
import nodeCrypto from "crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
4
4
|
const require_tls = require("../../tls-D_wUeOTD.js");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Un as EventCategory, gn as BaseAddon, kt as localNetworkCapability } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
import { S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, i as writeExtraSans, l as reissueTlsLeaf, n as readTlsAccessStatus, o as validateUploadedTls, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, y as applyLanHttp } from "../../tls-IM-v7JV4.mjs";
|
|
3
3
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
8
8
|
/**
|
|
9
9
|
* Loki rejects a label name that is not a valid Prometheus label
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gn as BaseAddon, jt as logDestinationCapability } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
3
3
|
/**
|
|
4
4
|
* Loki rejects a label name that is not a valid Prometheus label
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
let node_fs_promises = require("node:fs/promises");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { It as metricsProviderCapability, Kt as reducePoints, Un as EventCategory, gn as BaseAddon, ht as foldSnapshotByFunction, kn as createEvent, mn as errMsg, qt as resolveBucketMs } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
import { access, readFile, readdir } from "node:fs/promises";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { constants, readFileSync } from "node:fs";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_child_process = require("node:child_process");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as __toESM } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { $t as scoreRuntimes, Un as EventCategory, Ut as platformProbeCapability, gn as BaseAddon, jn as emitReadiness, mn as errMsg, st as enumerateInferenceDevices } from "../../dist-CLfJMMdf.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { execFile } from "node:child_process";
|
|
5
5
|
import * as os from "node:os";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
8
8
|
/**
|
|
9
9
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Un as EventCategory, gn as BaseAddon } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
3
3
|
/**
|
|
4
4
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
const require_snapshot_courtesy = require("../../snapshot-courtesy-Cqs7GkOV.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { H as bareAddonId, In as nodePin, Sn as DeviceType, U as batteryCapability, Un as EventCategory, a as BatteryStatusSchema, bn as DeviceFeature, cn as streamQualityLabel, gn as BaseAddon, mn as errMsg, nn as snapshotCapability, tt as deriveBatteryPresence } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg } from "../../snapshot-courtesy-CZPvteq2.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gn as BaseAddon, mt as filesystemBrowseCapability, on as storageProviderCapability } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
Binary file
|
|
Binary file
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
const require_hub_cap_forward = require("../../hub-cap-forward-DmHNjbB0.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dt as legacyModeOf, Ft as mayWriteToLocation, Jt as resolveLocationMode, K as collectSecretConfigKeys, Ln as parseJsonObject, Lt as modeMayWrite, M as StorageLocationModeSchema, N as StorageLocationTypeSchema, P as StorageMigrationJobSchema, Pt as mayReadLocation, Un as EventCategory, _t as gbToBytes, bt as isLocationEnabled, dt as evictionPolicyOfLocation, en as settingsStoreCapability, gn as BaseAddon, in as storageMigrationCapability, j as StorageCleanupJobSchema, pn as withLocationMode, rn as storageCapability, v as LegacyStorageLocationDefaultSchema, w as REDACTED_SECRET } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
import { t as HUB_CAP_FWD_ACTION } from "../../hub-cap-forward-BdT320dq.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Nn as hydrateSchema, gn as BaseAddon, mn as errMsg } from "../../dist-CLfJMMdf.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-vecbhDzu.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|