camstack 1.2.88 → 1.2.90
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/cli.js
CHANGED
|
@@ -38,7 +38,7 @@ async function runServe(args) {
|
|
|
38
38
|
...typeof values.data === "string" ? { data: values.data } : {}
|
|
39
39
|
};
|
|
40
40
|
Object.assign(process.env, buildServeEnv(opts));
|
|
41
|
-
await import("./launcher-
|
|
41
|
+
await import("./launcher-7KH64TCV.js");
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// src/commands/agent.ts
|
|
@@ -83,7 +83,7 @@ async function runAgent(args) {
|
|
|
83
83
|
...typeof values.port === "string" ? { port: values.port } : {}
|
|
84
84
|
};
|
|
85
85
|
Object.assign(process.env, buildAgentEnv(opts));
|
|
86
|
-
await import("./launcher-
|
|
86
|
+
await import("./launcher-7KH64TCV.js");
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// src/commands/setup.ts
|
|
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
|
|
|
23633
23633
|
}
|
|
23634
23634
|
});
|
|
23635
23635
|
|
|
23636
|
-
// ../system/dist/dist-
|
|
23637
|
-
var
|
|
23638
|
-
"../system/dist/dist-
|
|
23636
|
+
// ../system/dist/dist-DE3OH-FG.js
|
|
23637
|
+
var require_dist_DE3OH_FG = __commonJS({
|
|
23638
|
+
"../system/dist/dist-DE3OH-FG.js"(exports) {
|
|
23639
23639
|
"use strict";
|
|
23640
23640
|
var zod = require_zod();
|
|
23641
23641
|
var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
|
|
@@ -50296,9 +50296,7 @@ var require_dist_DGrXE5nL = __commonJS({
|
|
|
50296
50296
|
"leak-sensor",
|
|
50297
50297
|
"vibration-sensor",
|
|
50298
50298
|
"tamper-sensor",
|
|
50299
|
-
"sound-sensor"
|
|
50300
|
-
"binary-sensor",
|
|
50301
|
-
"binary-helper"
|
|
50299
|
+
"sound-sensor"
|
|
50302
50300
|
];
|
|
50303
50301
|
function roleRank(role) {
|
|
50304
50302
|
if (role === void 0) return CONTAINER_CHILD_ROLE_PRIORITY.length;
|
|
@@ -60081,7 +60079,7 @@ var require_alerts_addon = __commonJS({
|
|
|
60081
60079
|
[Symbol.toStringTag]: { value: "Module" }
|
|
60082
60080
|
});
|
|
60083
60081
|
require_chunk_Cek0wNdY();
|
|
60084
|
-
var require_dist10 =
|
|
60082
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
60085
60083
|
function selectExpired(alerts, cutoffMs) {
|
|
60086
60084
|
return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
|
|
60087
60085
|
}
|
|
@@ -60900,7 +60898,7 @@ var require_console_logging = __commonJS({
|
|
|
60900
60898
|
[Symbol.toStringTag]: { value: "Module" }
|
|
60901
60899
|
});
|
|
60902
60900
|
require_chunk_Cek0wNdY();
|
|
60903
|
-
var require_dist10 =
|
|
60901
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
60904
60902
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
60905
60903
|
var LEVEL_RANK = {
|
|
60906
60904
|
debug: 0,
|
|
@@ -60994,7 +60992,7 @@ var require_core_blocks_addon = __commonJS({
|
|
|
60994
60992
|
"use strict";
|
|
60995
60993
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
60996
60994
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
60997
|
-
var require_dist10 =
|
|
60995
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
60998
60996
|
var node_crypto = __require("crypto");
|
|
60999
60997
|
var node_fs_promises = __require("fs/promises");
|
|
61000
60998
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -61891,11 +61889,11 @@ var require_core_blocks = __commonJS({
|
|
|
61891
61889
|
}
|
|
61892
61890
|
});
|
|
61893
61891
|
|
|
61894
|
-
// ../system/dist/retired-settings-keys-
|
|
61895
|
-
var
|
|
61896
|
-
"../system/dist/retired-settings-keys-
|
|
61892
|
+
// ../system/dist/retired-settings-keys-BgUS9Rr3.js
|
|
61893
|
+
var require_retired_settings_keys_BgUS9Rr3 = __commonJS({
|
|
61894
|
+
"../system/dist/retired-settings-keys-BgUS9Rr3.js"(exports) {
|
|
61897
61895
|
"use strict";
|
|
61898
|
-
var require_dist10 =
|
|
61896
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
61899
61897
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
61900
61898
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
61901
61899
|
return raw === "" || raw === "hub";
|
|
@@ -64109,8 +64107,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
64109
64107
|
[Symbol.toStringTag]: { value: "Module" }
|
|
64110
64108
|
});
|
|
64111
64109
|
require_chunk_Cek0wNdY();
|
|
64112
|
-
var require_dist10 =
|
|
64113
|
-
var require_retired_settings_keys =
|
|
64110
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
64111
|
+
var require_retired_settings_keys = require_retired_settings_keys_BgUS9Rr3();
|
|
64114
64112
|
var node_crypto = __require("crypto");
|
|
64115
64113
|
var _camstack_types_node = require_node();
|
|
64116
64114
|
var JOB_HISTORY = 20;
|
|
@@ -65801,6 +65799,68 @@ var require_device_manager_addon = __commonJS({
|
|
|
65801
65799
|
return linkedIds.filter((id) => picked.has(id));
|
|
65802
65800
|
}
|
|
65803
65801
|
var LINK_CANDIDATE_PROJECTION = { projection: "slim" };
|
|
65802
|
+
function findLocationInvisibleContainers(params) {
|
|
65803
|
+
const { selfId, selfLocation, resolvedIds, candidates } = params;
|
|
65804
|
+
if (selfLocation === null || selfLocation.length === 0) return [];
|
|
65805
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
65806
|
+
for (const c of candidates) {
|
|
65807
|
+
if (c.parentDeviceId === null) continue;
|
|
65808
|
+
const bucket = byParent.get(c.parentDeviceId);
|
|
65809
|
+
if (bucket) bucket.push(c);
|
|
65810
|
+
else byParent.set(c.parentDeviceId, [c]);
|
|
65811
|
+
}
|
|
65812
|
+
const out = [];
|
|
65813
|
+
for (const c of candidates) {
|
|
65814
|
+
if (c.type !== require_dist10.DeviceType.Container) continue;
|
|
65815
|
+
if (c.id === selfId) continue;
|
|
65816
|
+
if (c.location !== selfLocation) continue;
|
|
65817
|
+
let anyResolved = false;
|
|
65818
|
+
let anyNullLocation = false;
|
|
65819
|
+
let descendantCount = 0;
|
|
65820
|
+
const visited = /* @__PURE__ */ new Set([c.id]);
|
|
65821
|
+
let frontier = [c.id];
|
|
65822
|
+
while (frontier.length > 0) {
|
|
65823
|
+
const next = [];
|
|
65824
|
+
for (const parentId of frontier) for (const child of byParent.get(parentId) ?? []) {
|
|
65825
|
+
if (visited.has(child.id)) continue;
|
|
65826
|
+
visited.add(child.id);
|
|
65827
|
+
descendantCount += 1;
|
|
65828
|
+
if (resolvedIds.has(child.id)) anyResolved = true;
|
|
65829
|
+
if (child.location === null) anyNullLocation = true;
|
|
65830
|
+
next.push(child.id);
|
|
65831
|
+
}
|
|
65832
|
+
frontier = next;
|
|
65833
|
+
}
|
|
65834
|
+
if (descendantCount > 0 && !anyResolved && anyNullLocation) out.push(c.id);
|
|
65835
|
+
}
|
|
65836
|
+
return out;
|
|
65837
|
+
}
|
|
65838
|
+
var INVISIBLE_CONTAINER_WARN_CAP = 4096;
|
|
65839
|
+
var warnedInvisibleContainers = /* @__PURE__ */ new Set();
|
|
65840
|
+
function warnLocationInvisibleContainers(pctx, cameraId, byId, all, resolved) {
|
|
65841
|
+
if (resolved.mode !== "auto") return;
|
|
65842
|
+
const selfLocation = byId.get(cameraId)?.location ?? null;
|
|
65843
|
+
if (selfLocation === null || selfLocation.length === 0) return;
|
|
65844
|
+
const invisible = findLocationInvisibleContainers({
|
|
65845
|
+
selfId: cameraId,
|
|
65846
|
+
selfLocation,
|
|
65847
|
+
resolvedIds: new Set(resolved.devices.map((d) => d.deviceId)),
|
|
65848
|
+
candidates: all
|
|
65849
|
+
});
|
|
65850
|
+
for (const containerId of invisible) {
|
|
65851
|
+
const key = `${cameraId}:${containerId}`;
|
|
65852
|
+
if (warnedInvisibleContainers.has(key)) continue;
|
|
65853
|
+
if (warnedInvisibleContainers.size >= INVISIBLE_CONTAINER_WARN_CAP) return;
|
|
65854
|
+
warnedInvisibleContainers.add(key);
|
|
65855
|
+
pctx.host.ctx.logger.warn("getLinkedDevices: container matches the camera location but is invisible to auto-link \u2014 its children carry no location; re-save the container location to realign", {
|
|
65856
|
+
tags: { deviceId: containerId },
|
|
65857
|
+
meta: {
|
|
65858
|
+
cameraId,
|
|
65859
|
+
location: selfLocation
|
|
65860
|
+
}
|
|
65861
|
+
});
|
|
65862
|
+
}
|
|
65863
|
+
}
|
|
65804
65864
|
function resolveFor(deviceId, all, byId, blob) {
|
|
65805
65865
|
const config = parseLinkedDevicesConfig(blob);
|
|
65806
65866
|
const ids = resolveLinkedDeviceIds({
|
|
@@ -65830,7 +65890,10 @@ var require_device_manager_addon = __commonJS({
|
|
|
65830
65890
|
async function getLinkedDevices(pctx, input) {
|
|
65831
65891
|
const { deviceId } = input;
|
|
65832
65892
|
const [all, blob] = await Promise.all([listAll(pctx, LINK_CANDIDATE_PROJECTION), pctx.settings.readDeviceStore(deviceId)]);
|
|
65833
|
-
|
|
65893
|
+
const byId = new Map(all.map((d) => [d.id, d]));
|
|
65894
|
+
const resolved = resolveFor(deviceId, all, byId, blob);
|
|
65895
|
+
warnLocationInvisibleContainers(pctx, deviceId, byId, all, resolved);
|
|
65896
|
+
return resolved;
|
|
65834
65897
|
}
|
|
65835
65898
|
async function getLinkedDevicesBatch(pctx, input) {
|
|
65836
65899
|
const deviceIds = [...new Set(input.deviceIds)];
|
|
@@ -65843,10 +65906,14 @@ var require_device_manager_addon = __commonJS({
|
|
|
65843
65906
|
return {};
|
|
65844
65907
|
})))]);
|
|
65845
65908
|
const byId = new Map(all.map((d) => [d.id, d]));
|
|
65846
|
-
return deviceIds.map((deviceId, index) =>
|
|
65847
|
-
deviceId,
|
|
65848
|
-
|
|
65849
|
-
|
|
65909
|
+
return deviceIds.map((deviceId, index) => {
|
|
65910
|
+
const resolved = resolveFor(deviceId, all, byId, blobs[index] ?? {});
|
|
65911
|
+
warnLocationInvisibleContainers(pctx, deviceId, byId, all, resolved);
|
|
65912
|
+
return {
|
|
65913
|
+
deviceId,
|
|
65914
|
+
...resolved
|
|
65915
|
+
};
|
|
65916
|
+
});
|
|
65850
65917
|
}
|
|
65851
65918
|
async function buildLinkedDevicesContribution(pctx, deviceId) {
|
|
65852
65919
|
const persisted = await pctx.metaStore.resolvePersistedById(deviceId);
|
|
@@ -66775,6 +66842,121 @@ var require_device_manager_addon = __commonJS({
|
|
|
66775
66842
|
roleKeysKeptAtTarget: Object.keys(target.role).toSorted()
|
|
66776
66843
|
};
|
|
66777
66844
|
}
|
|
66845
|
+
var LOCATION_BACKFILL_MARKER_KEY = "locationBackfillVersion";
|
|
66846
|
+
function nearestLocatedAncestor(byId, startParentId) {
|
|
66847
|
+
const visited = /* @__PURE__ */ new Set();
|
|
66848
|
+
let cursor = startParentId;
|
|
66849
|
+
while (cursor !== null && !visited.has(cursor)) {
|
|
66850
|
+
visited.add(cursor);
|
|
66851
|
+
const ancestor = byId.get(cursor);
|
|
66852
|
+
if (!ancestor) return null;
|
|
66853
|
+
if (ancestor.location !== null) return ancestor;
|
|
66854
|
+
cursor = ancestor.parentDeviceId;
|
|
66855
|
+
}
|
|
66856
|
+
return null;
|
|
66857
|
+
}
|
|
66858
|
+
function planNullLocationFills(rows) {
|
|
66859
|
+
const byId = new Map(rows.map((r) => [r.id, r]));
|
|
66860
|
+
const plan = [];
|
|
66861
|
+
for (const row of rows) {
|
|
66862
|
+
if (row.location !== null) continue;
|
|
66863
|
+
if (row.parentDeviceId === null) continue;
|
|
66864
|
+
const hit = nearestLocatedAncestor(byId, row.parentDeviceId);
|
|
66865
|
+
if (hit === null) continue;
|
|
66866
|
+
if (hit.type !== require_dist10.DeviceType.Container) continue;
|
|
66867
|
+
if (hit.location === null) continue;
|
|
66868
|
+
plan.push({
|
|
66869
|
+
id: row.id,
|
|
66870
|
+
location: hit.location,
|
|
66871
|
+
ancestorId: hit.id
|
|
66872
|
+
});
|
|
66873
|
+
}
|
|
66874
|
+
return plan;
|
|
66875
|
+
}
|
|
66876
|
+
async function resolveInheritedLocation(rows, parentDeviceId) {
|
|
66877
|
+
const visited = /* @__PURE__ */ new Set();
|
|
66878
|
+
let cursor = parentDeviceId;
|
|
66879
|
+
while (cursor !== null && !visited.has(cursor)) {
|
|
66880
|
+
visited.add(cursor);
|
|
66881
|
+
const ancestor = await rows.get(cursor);
|
|
66882
|
+
if (ancestor === null) return null;
|
|
66883
|
+
if (ancestor.meta.location !== null) return ancestor.meta.type === require_dist10.DeviceType.Container ? ancestor.meta.location : null;
|
|
66884
|
+
cursor = ancestor.meta.parentDeviceId;
|
|
66885
|
+
}
|
|
66886
|
+
return null;
|
|
66887
|
+
}
|
|
66888
|
+
function groupByAncestor(fills) {
|
|
66889
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
66890
|
+
for (const fill of fills) {
|
|
66891
|
+
const bucket = grouped.get(fill.ancestorId);
|
|
66892
|
+
if (bucket) bucket.push(fill);
|
|
66893
|
+
else grouped.set(fill.ancestorId, [fill]);
|
|
66894
|
+
}
|
|
66895
|
+
return grouped;
|
|
66896
|
+
}
|
|
66897
|
+
async function runLocationBackfillAtBoot(pctx, bootRows) {
|
|
66898
|
+
const logger = pctx.host.ctx.logger;
|
|
66899
|
+
const markerRaw = (await pctx.settings.readAddonStore())[LOCATION_BACKFILL_MARKER_KEY];
|
|
66900
|
+
const completedVersion = typeof markerRaw === "number" ? markerRaw : 0;
|
|
66901
|
+
let repaired = false;
|
|
66902
|
+
if (completedVersion < 1) {
|
|
66903
|
+
const patched = [];
|
|
66904
|
+
const failed = [];
|
|
66905
|
+
await pctx.metaStore.withMetaWriteLock(async () => {
|
|
66906
|
+
const plan = planNullLocationFills((await pctx.metaStore.rows.listAll()).map((r) => r.meta));
|
|
66907
|
+
for (const fill of plan) try {
|
|
66908
|
+
const current = await pctx.metaStore.rows.get(fill.id);
|
|
66909
|
+
if (current === null || current.meta.location !== null) continue;
|
|
66910
|
+
await pctx.metaStore.rows.patch(fill.id, { location: fill.location });
|
|
66911
|
+
patched.push(fill);
|
|
66912
|
+
} catch (err) {
|
|
66913
|
+
failed.push({
|
|
66914
|
+
id: fill.id,
|
|
66915
|
+
error: err
|
|
66916
|
+
});
|
|
66917
|
+
}
|
|
66918
|
+
});
|
|
66919
|
+
repaired = true;
|
|
66920
|
+
for (const [ancestorId, fills] of groupByAncestor(patched)) {
|
|
66921
|
+
pctx.host.ctx.eventBus.emit({
|
|
66922
|
+
id: (0, node_crypto.randomUUID)(),
|
|
66923
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
66924
|
+
source: {
|
|
66925
|
+
type: "device",
|
|
66926
|
+
id: ancestorId
|
|
66927
|
+
},
|
|
66928
|
+
category: require_dist10.EventCategory.DeviceMetaChanged,
|
|
66929
|
+
data: {
|
|
66930
|
+
deviceId: ancestorId,
|
|
66931
|
+
field: "location",
|
|
66932
|
+
value: fills[0]?.location ?? null
|
|
66933
|
+
}
|
|
66934
|
+
});
|
|
66935
|
+
logger.info("location backfill: aligned location-less descendants to their ancestor", {
|
|
66936
|
+
tags: { deviceId: ancestorId },
|
|
66937
|
+
meta: {
|
|
66938
|
+
location: fills[0]?.location,
|
|
66939
|
+
updatedIds: fills.map((f) => f.id)
|
|
66940
|
+
}
|
|
66941
|
+
});
|
|
66942
|
+
}
|
|
66943
|
+
if (failed.length > 0) logger.error("location backfill partially failed \u2014 retrying on the next boot", { meta: {
|
|
66944
|
+
failedIds: failed.map((f) => f.id),
|
|
66945
|
+
errors: failed.map((f) => f.error instanceof Error ? f.error.message : String(f.error))
|
|
66946
|
+
} });
|
|
66947
|
+
else await pctx.metaStore.withAddonStoreWriteLock(async () => {
|
|
66948
|
+
await pctx.settings.writeAddonStore({ [LOCATION_BACKFILL_MARKER_KEY]: 1 });
|
|
66949
|
+
});
|
|
66950
|
+
}
|
|
66951
|
+
const residual = planNullLocationFills((!repaired && bootRows !== void 0 ? bootRows : await pctx.metaStore.rows.listAll()).map((r) => r.meta));
|
|
66952
|
+
for (const [ancestorId, fills] of groupByAncestor(residual)) logger.warn("location cascade misaligned \u2014 location-less descendants under a located ancestor never match location auto-link; re-save the ancestor location to realign", {
|
|
66953
|
+
tags: { deviceId: ancestorId },
|
|
66954
|
+
meta: {
|
|
66955
|
+
location: fills[0]?.location,
|
|
66956
|
+
misalignedDescendantIds: fills.map((f) => f.id)
|
|
66957
|
+
}
|
|
66958
|
+
});
|
|
66959
|
+
}
|
|
66778
66960
|
async function stampIntegrationId(metaStore, ctx, deviceId, integrationId) {
|
|
66779
66961
|
await metaStore.withMetaWriteLock(async () => {
|
|
66780
66962
|
if (!await metaStore.resolvePersistedById(deviceId)) throw new Error(`[device-manager] stampIntegrationId: unknown device id=${deviceId}`);
|
|
@@ -66928,7 +67110,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
66928
67110
|
async function registerDevice(pctx, input) {
|
|
66929
67111
|
const { addonId, stableId, id, type, name, parentDeviceId, features, config } = input;
|
|
66930
67112
|
const featuresArr = Array.isArray(features) ? [...features] : [];
|
|
66931
|
-
const { isFirstRegistration, exportFingerprint, fingerprintChanged } = await pctx.metaStore.withMetaWriteLock(async () => {
|
|
67113
|
+
const { isFirstRegistration, exportFingerprint, fingerprintChanged, inheritedLocation, inheritedDescendantIds, inheritFailed } = await pctx.metaStore.withMetaWriteLock(async () => {
|
|
66932
67114
|
const existingRow = await pctx.metaStore.rows.get(id);
|
|
66933
67115
|
const existingMeta = existingRow?.meta;
|
|
66934
67116
|
const wasRegistered = existingRow?.registered ?? false;
|
|
@@ -66940,6 +67122,10 @@ var require_device_manager_addon = __commonJS({
|
|
|
66940
67122
|
deviceType: type,
|
|
66941
67123
|
features: featuresArr
|
|
66942
67124
|
});
|
|
67125
|
+
const priorLocation = existingMeta?.location ?? null;
|
|
67126
|
+
const resolvedParentId = parentDeviceId ?? null;
|
|
67127
|
+
const parentChanged = existingMeta !== void 0 && (existingMeta.parentDeviceId ?? null) !== resolvedParentId;
|
|
67128
|
+
const inherited = priorLocation === null && resolvedParentId !== null && (isFirst || parentChanged) ? await resolveInheritedLocation(pctx.metaStore.rows, resolvedParentId) : null;
|
|
66943
67129
|
await pctx.metaStore.rows.upsertRegistration({
|
|
66944
67130
|
deviceId: id,
|
|
66945
67131
|
addonId,
|
|
@@ -66947,21 +67133,69 @@ var require_device_manager_addon = __commonJS({
|
|
|
66947
67133
|
type,
|
|
66948
67134
|
name: resolvedName,
|
|
66949
67135
|
userNamed: wasUserNamed,
|
|
66950
|
-
location:
|
|
67136
|
+
location: priorLocation ?? inherited,
|
|
66951
67137
|
disabled: existingMeta?.disabled ?? false,
|
|
66952
|
-
parentDeviceId:
|
|
67138
|
+
parentDeviceId: resolvedParentId,
|
|
66953
67139
|
registered: true,
|
|
66954
67140
|
features: featuresArr,
|
|
66955
67141
|
exportFingerprint: fingerprint
|
|
66956
67142
|
});
|
|
67143
|
+
const descendantsFilled = [];
|
|
67144
|
+
const descendantsFailed = [];
|
|
67145
|
+
if (inherited !== null) for (const descendant of await collectDescendants(pctx.metaStore, id)) {
|
|
67146
|
+
if (descendant.location !== null) continue;
|
|
67147
|
+
try {
|
|
67148
|
+
await pctx.metaStore.rows.patch(descendant.id, { location: inherited });
|
|
67149
|
+
descendantsFilled.push(descendant.id);
|
|
67150
|
+
} catch (err) {
|
|
67151
|
+
descendantsFailed.push({
|
|
67152
|
+
id: descendant.id,
|
|
67153
|
+
error: err
|
|
67154
|
+
});
|
|
67155
|
+
}
|
|
67156
|
+
}
|
|
66957
67157
|
return {
|
|
66958
67158
|
isFirstRegistration: isFirst,
|
|
66959
67159
|
exportFingerprint: fingerprint,
|
|
66960
|
-
fingerprintChanged: existingMeta?.exportFingerprint !== fingerprint
|
|
67160
|
+
fingerprintChanged: existingMeta?.exportFingerprint !== fingerprint,
|
|
67161
|
+
inheritedLocation: inherited,
|
|
67162
|
+
inheritedDescendantIds: descendantsFilled,
|
|
67163
|
+
inheritFailed: descendantsFailed
|
|
66961
67164
|
};
|
|
66962
67165
|
});
|
|
66963
67166
|
if (Object.keys(config).length > 0) await pctx.settings.writeDeviceStore(id, config);
|
|
66964
67167
|
pctx.metaStore.idToAddonId.set(id, addonId);
|
|
67168
|
+
if (inheritedLocation !== null) {
|
|
67169
|
+
for (const changedId of [id, ...inheritedDescendantIds]) pctx.host.ctx.eventBus.emit({
|
|
67170
|
+
id: (0, node_crypto.randomUUID)(),
|
|
67171
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
67172
|
+
source: {
|
|
67173
|
+
type: "device",
|
|
67174
|
+
id: changedId
|
|
67175
|
+
},
|
|
67176
|
+
category: require_dist10.EventCategory.DeviceMetaChanged,
|
|
67177
|
+
data: {
|
|
67178
|
+
deviceId: changedId,
|
|
67179
|
+
field: "location",
|
|
67180
|
+
value: inheritedLocation
|
|
67181
|
+
}
|
|
67182
|
+
});
|
|
67183
|
+
pctx.host.ctx.logger.info("registerDevice: inherited located-ancestor location", {
|
|
67184
|
+
tags: { deviceId: id },
|
|
67185
|
+
meta: {
|
|
67186
|
+
location: inheritedLocation,
|
|
67187
|
+
descendantsFilled: inheritedDescendantIds.length
|
|
67188
|
+
}
|
|
67189
|
+
});
|
|
67190
|
+
if (inheritFailed.length > 0) pctx.host.ctx.logger.error("registerDevice: inherited-location fill partially failed \u2014 some descendants NOT aligned", {
|
|
67191
|
+
tags: { deviceId: id },
|
|
67192
|
+
meta: {
|
|
67193
|
+
location: inheritedLocation,
|
|
67194
|
+
failedIds: inheritFailed.map((f) => f.id),
|
|
67195
|
+
errors: inheritFailed.map((f) => f.error instanceof Error ? f.error.message : String(f.error))
|
|
67196
|
+
}
|
|
67197
|
+
});
|
|
67198
|
+
}
|
|
66965
67199
|
if (isFirstRegistration) pctx.host.ctx.eventBus.emit({
|
|
66966
67200
|
id: (0, node_crypto.randomUUID)(),
|
|
66967
67201
|
timestamp: /* @__PURE__ */ new Date(),
|
|
@@ -69144,7 +69378,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
69144
69378
|
const stateMirror = this.stateMirrorImpl;
|
|
69145
69379
|
const resolvePersistedById = metaStore.resolvePersistedById;
|
|
69146
69380
|
const idToAddonId = metaStore.idToAddonId;
|
|
69147
|
-
|
|
69381
|
+
const bootRows = await deviceRows.listAll();
|
|
69382
|
+
for (const row of bootRows) idToAddonId.set(row.meta.id, row.meta.addonId);
|
|
69148
69383
|
const stampIntegrationId$1 = (deviceId, integrationId) => stampIntegrationId(metaStore, this.ctx, deviceId, integrationId);
|
|
69149
69384
|
const pctx = {
|
|
69150
69385
|
host: this.providerHost,
|
|
@@ -69159,6 +69394,11 @@ var require_device_manager_addon = __commonJS({
|
|
|
69159
69394
|
return provider;
|
|
69160
69395
|
}
|
|
69161
69396
|
};
|
|
69397
|
+
try {
|
|
69398
|
+
await runLocationBackfillAtBoot(pctx, bootRows);
|
|
69399
|
+
} catch (err) {
|
|
69400
|
+
this.ctx.logger.warn("location backfill failed \u2014 fleet boots without it", { meta: { error: require_dist10.errMsg(err) } });
|
|
69401
|
+
}
|
|
69162
69402
|
const provider = {
|
|
69163
69403
|
resolveDeviceOwnerSync: (deviceId) => resolveDeviceOwnerSync(pctx, deviceId),
|
|
69164
69404
|
resolveNativeCapOwnerSync: (capName, deviceId) => resolveNativeCapOwnerSync(pctx, capName, deviceId),
|
|
@@ -69394,7 +69634,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
69394
69634
|
[Symbol.toStringTag]: { value: "Module" }
|
|
69395
69635
|
});
|
|
69396
69636
|
require_chunk_Cek0wNdY();
|
|
69397
|
-
var require_dist10 =
|
|
69637
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
69398
69638
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
69399
69639
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
69400
69640
|
var HubForwarderDestination = class {
|
|
@@ -69531,7 +69771,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
69531
69771
|
"use strict";
|
|
69532
69772
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
69533
69773
|
require_chunk_Cek0wNdY();
|
|
69534
|
-
var require_dist10 =
|
|
69774
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
69535
69775
|
var NO_DEVICES = "liveness:no-devices";
|
|
69536
69776
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
69537
69777
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -69721,7 +69961,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
69721
69961
|
[Symbol.toStringTag]: { value: "Module" }
|
|
69722
69962
|
});
|
|
69723
69963
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
69724
|
-
var require_dist10 =
|
|
69964
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
69725
69965
|
var node_crypto = __require("crypto");
|
|
69726
69966
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
69727
69967
|
var crypto$1 = __require("crypto");
|
|
@@ -77534,7 +77774,7 @@ var require_loki_logging = __commonJS({
|
|
|
77534
77774
|
[Symbol.toStringTag]: { value: "Module" }
|
|
77535
77775
|
});
|
|
77536
77776
|
require_chunk_Cek0wNdY();
|
|
77537
|
-
var require_dist10 =
|
|
77777
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
77538
77778
|
function sanitizeLabelName(raw) {
|
|
77539
77779
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
77540
77780
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -78099,7 +78339,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
78099
78339
|
[Symbol.toStringTag]: { value: "Module" }
|
|
78100
78340
|
});
|
|
78101
78341
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
78102
|
-
var require_dist10 =
|
|
78342
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
78103
78343
|
var node_fs_promises = __require("fs/promises");
|
|
78104
78344
|
var node_child_process = __require("child_process");
|
|
78105
78345
|
var node_util = __require("util");
|
|
@@ -80683,7 +80923,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
80683
80923
|
[Symbol.toStringTag]: { value: "Module" }
|
|
80684
80924
|
});
|
|
80685
80925
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
80686
|
-
var require_dist10 =
|
|
80926
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
80687
80927
|
var node_crypto = __require("crypto");
|
|
80688
80928
|
var node_fs_promises = __require("fs/promises");
|
|
80689
80929
|
var node_path = __require("path");
|
|
@@ -81799,8 +82039,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
81799
82039
|
[Symbol.toStringTag]: { value: "Module" }
|
|
81800
82040
|
});
|
|
81801
82041
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
81802
|
-
var require_dist10 =
|
|
81803
|
-
var require_retired_settings_keys =
|
|
82042
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
82043
|
+
var require_retired_settings_keys = require_retired_settings_keys_BgUS9Rr3();
|
|
81804
82044
|
var node_crypto = __require("crypto");
|
|
81805
82045
|
var node_fs = __require("fs");
|
|
81806
82046
|
var node_module = __require("module");
|
|
@@ -84290,7 +84530,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
84290
84530
|
[Symbol.toStringTag]: { value: "Module" }
|
|
84291
84531
|
});
|
|
84292
84532
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
84293
|
-
var require_dist10 =
|
|
84533
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
84294
84534
|
var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
|
|
84295
84535
|
var zod = require_zod();
|
|
84296
84536
|
var node_crypto = __require("crypto");
|
|
@@ -87241,7 +87481,7 @@ var require_system_config_addon = __commonJS({
|
|
|
87241
87481
|
[Symbol.toStringTag]: { value: "Module" }
|
|
87242
87482
|
});
|
|
87243
87483
|
require_chunk_Cek0wNdY();
|
|
87244
|
-
var require_dist10 =
|
|
87484
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
87245
87485
|
var SECTION_TITLES = {
|
|
87246
87486
|
server: "Server",
|
|
87247
87487
|
auth: "Authentication"
|
|
@@ -105302,7 +105542,7 @@ var require_winston_logging = __commonJS({
|
|
|
105302
105542
|
[Symbol.toStringTag]: { value: "Module" }
|
|
105303
105543
|
});
|
|
105304
105544
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
105305
|
-
var require_dist10 =
|
|
105545
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
105306
105546
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
105307
105547
|
var node_path = __require("path");
|
|
105308
105548
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -117804,12 +118044,12 @@ var require_dist2 = __commonJS({
|
|
|
117804
118044
|
}
|
|
117805
118045
|
});
|
|
117806
118046
|
|
|
117807
|
-
// ../system/dist/manifest-system-deps-
|
|
117808
|
-
var
|
|
117809
|
-
"../system/dist/manifest-system-deps-
|
|
118047
|
+
// ../system/dist/manifest-system-deps-DMWd5Ygf.js
|
|
118048
|
+
var require_manifest_system_deps_DMWd5Ygf = __commonJS({
|
|
118049
|
+
"../system/dist/manifest-system-deps-DMWd5Ygf.js"(exports) {
|
|
117810
118050
|
"use strict";
|
|
117811
118051
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
117812
|
-
|
|
118052
|
+
require_dist_DE3OH_FG();
|
|
117813
118053
|
require_hub_cap_forward_DmHNjbB0();
|
|
117814
118054
|
var node_crypto = __require("crypto");
|
|
117815
118055
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
@@ -129876,7 +130116,7 @@ var require_dist3 = __commonJS({
|
|
|
129876
130116
|
"use strict";
|
|
129877
130117
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
129878
130118
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
129879
|
-
var require_dist10 =
|
|
130119
|
+
var require_dist10 = require_dist_DE3OH_FG();
|
|
129880
130120
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
129881
130121
|
require_alerts();
|
|
129882
130122
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
@@ -129903,7 +130143,7 @@ var require_dist3 = __commonJS({
|
|
|
129903
130143
|
var require_builtins_winston_logging_index = require_winston_logging();
|
|
129904
130144
|
var require_file_data_plane = require_file_data_plane_DO8KbxCe();
|
|
129905
130145
|
var require_tls$1 = require_tls_BxQlomxd();
|
|
129906
|
-
var require_manifest_system_deps =
|
|
130146
|
+
var require_manifest_system_deps = require_manifest_system_deps_DMWd5Ygf();
|
|
129907
130147
|
var require_resource_monitor = require_resource_monitor_CdnzxBLP();
|
|
129908
130148
|
var require_custom_action_registry = require_custom_action_registry_jY0NOZK8();
|
|
129909
130149
|
var zod = require_zod();
|
|
@@ -238597,9 +238837,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
238597
238837
|
"leak-sensor",
|
|
238598
238838
|
"vibration-sensor",
|
|
238599
238839
|
"tamper-sensor",
|
|
238600
|
-
"sound-sensor"
|
|
238601
|
-
"binary-sensor",
|
|
238602
|
-
"binary-helper"
|
|
238840
|
+
"sound-sensor"
|
|
238603
238841
|
];
|
|
238604
238842
|
function roleRank(role) {
|
|
238605
238843
|
if (role === void 0) return CONTAINER_CHILD_ROLE_PRIORITY.length;
|