@camstack/system 1.2.241 → 1.2.243
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/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.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/adoption-job-engine.d.ts +28 -7
- package/dist/builtins/device-manager/device-manager.addon.d.ts +11 -0
- package/dist/builtins/device-manager/device-manager.addon.js +147 -15
- package/dist/builtins/device-manager/device-manager.addon.mjs +147 -15
- package/dist/builtins/device-manager/device-meta-actions.d.ts +32 -0
- package/dist/builtins/device-manager/device-meta-types.d.ts +17 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- 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-BjSYm1hH.mjs → dist-B4htkDVv.mjs} +104 -3
- package/dist/{dist-C6JIhqS6.js → dist-D6kqBW1G.js} +115 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{retired-settings-keys-C53Y2Q1C.js → retired-settings-keys-BPIyHR4_.js} +1 -1
- package/dist/{retired-settings-keys-MpSfaPEY.mjs → retired-settings-keys-C9w4b4TV.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-
|
|
1
|
+
import { C as STREAM_PROFILE_META, Et as parseStreamParamsFormPatch, J as deviceStatusCapability, K as deviceManagerCapability, Pt as runtimeStatePolicyFor, Q as enumerateSchemaFields, R as buildStreamParamsConfigSchema, Sn as EventCategory, Xt as BaseAddon, Yt as errMsg, Z as enumerateItemArrayFields, a as CAMERA_SWITCH_ORDER, an as WELL_KNOWN_TAB_MAP, en as DeviceFeature, f as DeviceStatusSchema, gt as locationIconKey, h as LocationIconIdSchema, jt as resolveContainerPrimaryChild, mn as isDeviceConfigCap, nn as DeviceType, o as CAP_NAMES_WITH_STATUS, q as deviceStateCapability, t as ALL_CAPABILITY_DEFINITIONS, tn as DeviceRole, wt as normalizeUnit, xn as sleep$1 } from "../../dist-B4htkDVv.mjs";
|
|
2
|
+
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-C9w4b4TV.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
5
5
|
//#region src/builtins/device-manager/adoption-job-engine.ts
|
|
@@ -223,13 +223,15 @@ var AdoptionJobEngine = class {
|
|
|
223
223
|
const startedAt = this.now();
|
|
224
224
|
try {
|
|
225
225
|
const per = input.perCandidate?.[childNativeId];
|
|
226
|
-
const
|
|
226
|
+
const adoptCandidate = async () => await provider.adopt({
|
|
227
227
|
integrationId: input.integrationId,
|
|
228
228
|
childNativeIds: [childNativeId],
|
|
229
229
|
...input.filter !== void 0 ? { filter: input.filter } : {},
|
|
230
230
|
...input.importLocations !== void 0 ? { importLocations: input.importLocations } : {},
|
|
231
231
|
...per !== void 0 ? { perCandidate: { [childNativeId]: per } } : {}
|
|
232
|
-
})
|
|
232
|
+
});
|
|
233
|
+
const fence = this.deps.removalFence;
|
|
234
|
+
const entry = (fence === void 0 ? await adoptCandidate() : await fence.runUnfenced(adoptCandidate)).adopted[0];
|
|
233
235
|
if (!entry) {
|
|
234
236
|
job.results.push({
|
|
235
237
|
childNativeId,
|
|
@@ -3921,7 +3923,8 @@ async function runLocationBackfillAtBoot(pctx, bootRows) {
|
|
|
3921
3923
|
* setLocation, setType, setIntegrationId, setLinkDeviceId,
|
|
3922
3924
|
* setPrimaryChildEntityId, setChildLayout, setRole, setDisplay,
|
|
3923
3925
|
* applyInitialMeta, setMetadata, setDisabled), and the location registry
|
|
3924
|
-
* (listLocations, addLocation, removeLocation)
|
|
3926
|
+
* (listLocations, addLocation, removeLocation, renameLocation) with its icon
|
|
3927
|
+
* map (listLocationIcons, setLocationIcon).
|
|
3925
3928
|
*
|
|
3926
3929
|
* EXACT ordering and side effects preserved — notably registerDevice's
|
|
3927
3930
|
* name-precedence reconcile + field-preservation spreads, the
|
|
@@ -4973,6 +4976,83 @@ async function addLocation(pctx, input) {
|
|
|
4973
4976
|
});
|
|
4974
4977
|
}
|
|
4975
4978
|
/**
|
|
4979
|
+
* Every location that carries an icon, as `(locationKey, icon)` pairs.
|
|
4980
|
+
*
|
|
4981
|
+
* ADDITIVE beside `listLocations`, which still answers `string[]` — the
|
|
4982
|
+
* autocomplete, the HA adoption import and the recorder all read a list of
|
|
4983
|
+
* LABELS and a shape change there would break every one of them. A surface
|
|
4984
|
+
* that wants icons asks for them and joins on `locationIconKey`.
|
|
4985
|
+
*
|
|
4986
|
+
* Returns only what was actually stored. A location with no assignment is
|
|
4987
|
+
* ABSENT, never `map-pin`: the fallback belongs to the renderer
|
|
4988
|
+
* (`resolveLocationIcon`), and folding it in here would make "the operator
|
|
4989
|
+
* picked the pin" indistinguishable from "the operator picked nothing" —
|
|
4990
|
+
* which is the difference an icon picker has to draw.
|
|
4991
|
+
*/
|
|
4992
|
+
async function listLocationIcons(pctx) {
|
|
4993
|
+
const icons = (await pctx.metaStore.readStore()).locationIcons ?? {};
|
|
4994
|
+
return Object.entries(icons).map(([locationKey, icon]) => ({
|
|
4995
|
+
locationKey,
|
|
4996
|
+
icon
|
|
4997
|
+
})).toSorted((a, b) => a.locationKey.localeCompare(b.locationKey));
|
|
4998
|
+
}
|
|
4999
|
+
/**
|
|
5000
|
+
* Set (or clear) the icon of a location label.
|
|
5001
|
+
*
|
|
5002
|
+
* Keyed on `locationIconKey` — trimmed + lower-cased, the equality the
|
|
5003
|
+
* registry matches on everywhere — so a case-only rename keeps the icon and
|
|
5004
|
+
* two spellings of one room can never carry two different icons.
|
|
5005
|
+
*
|
|
5006
|
+
* The label need NOT be registered: `setLocation` accepts a free-form string
|
|
5007
|
+
* and `listLocations` folds in whatever devices carry, so requiring
|
|
5008
|
+
* registration here would leave exactly the ad-hoc rooms unable to have an
|
|
5009
|
+
* icon. An empty label throws — there is no room to name.
|
|
5010
|
+
*
|
|
5011
|
+
* Same read-modify-write and same lock as `addLocation`: the map is one key of
|
|
5012
|
+
* the addon store, and `writeAddonStore` re-inserts the whole key range, so an
|
|
5013
|
+
* unordered write carries a stale copy of every other key.
|
|
5014
|
+
*/
|
|
5015
|
+
async function setLocationIcon(pctx, input) {
|
|
5016
|
+
const trimmed = input.location.trim();
|
|
5017
|
+
if (trimmed.length === 0) throw new Error("[device-manager] setLocationIcon: location must be non-empty");
|
|
5018
|
+
const key = locationIconKey(trimmed);
|
|
5019
|
+
await pctx.bindingsDeps.withAddonStoreWriteLock(async () => {
|
|
5020
|
+
const icons = (await pctx.metaStore.readStore()).locationIcons ?? {};
|
|
5021
|
+
if (input.icon === null) {
|
|
5022
|
+
if (!(key in icons)) return;
|
|
5023
|
+
const { [key]: _cleared, ...kept } = icons;
|
|
5024
|
+
await pctx.settings.writeAddonStore({ locationIcons: kept });
|
|
5025
|
+
return;
|
|
5026
|
+
}
|
|
5027
|
+
if (icons[key] === input.icon) return;
|
|
5028
|
+
await pctx.settings.writeAddonStore({ locationIcons: {
|
|
5029
|
+
...icons,
|
|
5030
|
+
[key]: input.icon
|
|
5031
|
+
} });
|
|
5032
|
+
});
|
|
5033
|
+
}
|
|
5034
|
+
/**
|
|
5035
|
+
* Move a location's icon from one key to another, for `renameLocation`.
|
|
5036
|
+
*
|
|
5037
|
+
* Returns `null` when NOTHING changes, so the caller can leave the key out of
|
|
5038
|
+
* its `writeAddonStore` patch instead of re-writing an identical map.
|
|
5039
|
+
*
|
|
5040
|
+
* A rename onto a room that already has an icon is a MERGE, and the surviving
|
|
5041
|
+
* room keeps its own: the operator renaming "Sala" into "Salone" is moving
|
|
5042
|
+
* devices into Salone, not restyling it. The source key is dropped either way.
|
|
5043
|
+
* Pure — builds a new record, mutates nothing.
|
|
5044
|
+
*/
|
|
5045
|
+
function renameLocationIcon(icons, fromKey, toKey) {
|
|
5046
|
+
const moved = icons[fromKey];
|
|
5047
|
+
if (moved === void 0) return null;
|
|
5048
|
+
if (fromKey === toKey) return null;
|
|
5049
|
+
const { [fromKey]: _dropped, ...rest } = icons;
|
|
5050
|
+
return toKey in rest ? rest : {
|
|
5051
|
+
...rest,
|
|
5052
|
+
[toKey]: moved
|
|
5053
|
+
};
|
|
5054
|
+
}
|
|
5055
|
+
/**
|
|
4976
5056
|
* Remove a label from the curated registry. Match is
|
|
4977
5057
|
* case-insensitive. Devices that still reference this label keep
|
|
4978
5058
|
* their `meta.location` value (the registry is a suggestion
|
|
@@ -5003,13 +5083,19 @@ async function renameLocation(pctx, input) {
|
|
|
5003
5083
|
const fromKey = from.toLowerCase();
|
|
5004
5084
|
const toKey = to.toLowerCase();
|
|
5005
5085
|
await pctx.bindingsDeps.withAddonStoreWriteLock(async () => {
|
|
5006
|
-
const
|
|
5007
|
-
|
|
5086
|
+
const store = await pctx.metaStore.readStore();
|
|
5087
|
+
const current = store.locations ?? [];
|
|
5088
|
+
const registered = current.some((l) => l.trim().toLowerCase() === fromKey);
|
|
5089
|
+
const movedIcons = renameLocationIcon(store.locationIcons ?? {}, fromKey, toKey);
|
|
5090
|
+
if (!registered && movedIcons === null) return;
|
|
5008
5091
|
const kept = current.filter((l) => {
|
|
5009
5092
|
const key = l.trim().toLowerCase();
|
|
5010
5093
|
return key !== fromKey && key !== toKey;
|
|
5011
5094
|
});
|
|
5012
|
-
await pctx.settings.writeAddonStore({
|
|
5095
|
+
await pctx.settings.writeAddonStore({
|
|
5096
|
+
...registered ? { locations: [...kept, to] } : {},
|
|
5097
|
+
...movedIcons !== null ? { locationIcons: movedIcons } : {}
|
|
5098
|
+
});
|
|
5013
5099
|
});
|
|
5014
5100
|
const moved = await pctx.metaStore.withMetaWriteLock(async () => {
|
|
5015
5101
|
const out = [];
|
|
@@ -5047,10 +5133,19 @@ async function removeLocation(pctx, input) {
|
|
|
5047
5133
|
const trimmed = input.name.trim();
|
|
5048
5134
|
if (trimmed.length === 0) return;
|
|
5049
5135
|
await pctx.bindingsDeps.withAddonStoreWriteLock(async () => {
|
|
5050
|
-
const
|
|
5051
|
-
const
|
|
5052
|
-
|
|
5053
|
-
|
|
5136
|
+
const store = await pctx.metaStore.readStore();
|
|
5137
|
+
const current = store.locations ?? [];
|
|
5138
|
+
const key = locationIconKey(trimmed);
|
|
5139
|
+
const remaining = current.filter((l) => l.toLowerCase() !== key);
|
|
5140
|
+
const droppedLabel = remaining.length !== current.length;
|
|
5141
|
+
const icons = store.locationIcons ?? {};
|
|
5142
|
+
const droppedIcon = key in icons;
|
|
5143
|
+
if (!droppedLabel && !droppedIcon) return;
|
|
5144
|
+
const { [key]: _removedIcon, ...keptIcons } = icons;
|
|
5145
|
+
await pctx.settings.writeAddonStore({
|
|
5146
|
+
...droppedLabel ? { locations: remaining } : {},
|
|
5147
|
+
...droppedIcon ? { locationIcons: keptIcons } : {}
|
|
5148
|
+
});
|
|
5054
5149
|
});
|
|
5055
5150
|
if (input.cascade !== true) return;
|
|
5056
5151
|
const cleared = await pctx.metaStore.withMetaWriteLock(async () => {
|
|
@@ -5152,12 +5247,35 @@ function decodeAddonStore(raw) {
|
|
|
5152
5247
|
const nextDeviceId = raw["nextDeviceId"];
|
|
5153
5248
|
const locations = raw["locations"];
|
|
5154
5249
|
const roleDisplayDefaults = raw["roleDisplayDefaults"];
|
|
5250
|
+
const locationIcons = decodeLocationIcons(raw["locationIcons"]);
|
|
5155
5251
|
return {
|
|
5156
5252
|
...typeof nextDeviceId === "number" && Number.isFinite(nextDeviceId) ? { nextDeviceId } : {},
|
|
5157
5253
|
...Array.isArray(locations) ? { locations: locations.filter((l) => typeof l === "string") } : {},
|
|
5158
|
-
...isRoleDisplayDefaults(roleDisplayDefaults) ? { roleDisplayDefaults } : {}
|
|
5254
|
+
...isRoleDisplayDefaults(roleDisplayDefaults) ? { roleDisplayDefaults } : {},
|
|
5255
|
+
...locationIcons !== null ? { locationIcons } : {}
|
|
5159
5256
|
};
|
|
5160
5257
|
}
|
|
5258
|
+
/**
|
|
5259
|
+
* Decode the `locationIcons` map, dropping every entry whose value is not a
|
|
5260
|
+
* member of the closed vocabulary.
|
|
5261
|
+
*
|
|
5262
|
+
* Dropping, not passing through: the icon's whole point is that both surfaces
|
|
5263
|
+
* can draw it, and an id from a hand-edit or a newer hub is exactly the value
|
|
5264
|
+
* that draws nothing. Absent reads as "no icon chosen", which every renderer
|
|
5265
|
+
* already degrades to the fallback pin. Returns `null` when the key itself is
|
|
5266
|
+
* absent or of the wrong shape, so the field stays OMITTED rather than being
|
|
5267
|
+
* written back as an empty object.
|
|
5268
|
+
*/
|
|
5269
|
+
function decodeLocationIcons(raw) {
|
|
5270
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
5271
|
+
const out = {};
|
|
5272
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
5273
|
+
const parsed = LocationIconIdSchema.safeParse(value);
|
|
5274
|
+
if (!parsed.success) continue;
|
|
5275
|
+
out[key] = parsed.data;
|
|
5276
|
+
}
|
|
5277
|
+
return out;
|
|
5278
|
+
}
|
|
5161
5279
|
function isRoleDisplayDefaults(value) {
|
|
5162
5280
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5163
5281
|
}
|
|
@@ -6744,6 +6862,17 @@ var DeviceManagerAddon = class extends BaseAddon {
|
|
|
6744
6862
|
remoteNativeCaps = /* @__PURE__ */ new Map();
|
|
6745
6863
|
/** Background adoption jobs — lazily constructed (needs `ctx.logger`). */
|
|
6746
6864
|
adoptionJobEngine = null;
|
|
6865
|
+
/**
|
|
6866
|
+
* ONE removal fence for this process, shared by the provider context and the
|
|
6867
|
+
* adoption-job engine.
|
|
6868
|
+
*
|
|
6869
|
+
* It used to be constructed inline into the context, so the job engine had
|
|
6870
|
+
* no way to reach it and an operator re-adopting hardware they had just
|
|
6871
|
+
* deleted was refused for the whole 5-minute TTL — their own action, denied.
|
|
6872
|
+
* Two fences would be worse than one: the engine would suspend a fence that
|
|
6873
|
+
* `allocateDeviceId` never consults.
|
|
6874
|
+
*/
|
|
6875
|
+
removalFence = createRemovalFence();
|
|
6747
6876
|
/** The runtime-state mirror, asserted present (constructed in onInitialize). */
|
|
6748
6877
|
get stateMirror() {
|
|
6749
6878
|
if (!this.stateMirrorImpl) throw new Error("DeviceManagerAddon: state mirror accessed before onInitialize");
|
|
@@ -6781,7 +6910,8 @@ var DeviceManagerAddon = class extends BaseAddon {
|
|
|
6781
6910
|
get adoptionJobsImpl() {
|
|
6782
6911
|
if (!this.adoptionJobEngine) this.adoptionJobEngine = new AdoptionJobEngine({
|
|
6783
6912
|
resolveProvider: async (addonId) => this.requireDeviceAdoptionProvider(addonId),
|
|
6784
|
-
logger: this.ctx.logger
|
|
6913
|
+
logger: this.ctx.logger,
|
|
6914
|
+
removalFence: this.removalFence
|
|
6785
6915
|
});
|
|
6786
6916
|
return this.adoptionJobEngine;
|
|
6787
6917
|
}
|
|
@@ -6932,7 +7062,7 @@ var DeviceManagerAddon = class extends BaseAddon {
|
|
|
6932
7062
|
registry,
|
|
6933
7063
|
bindingsDeps: this.bindingsDeps,
|
|
6934
7064
|
migrationGuard: createMigrationGuard(),
|
|
6935
|
-
removalFence:
|
|
7065
|
+
removalFence: this.removalFence,
|
|
6936
7066
|
requireDeviceOps,
|
|
6937
7067
|
stampIntegrationId: stampIntegrationId$1,
|
|
6938
7068
|
get provider() {
|
|
@@ -6978,6 +7108,8 @@ var DeviceManagerAddon = class extends BaseAddon {
|
|
|
6978
7108
|
addLocation: (input) => addLocation(pctx, input),
|
|
6979
7109
|
removeLocation: (input) => removeLocation(pctx, input),
|
|
6980
7110
|
renameLocation: (input) => renameLocation(pctx, input),
|
|
7111
|
+
listLocationIcons: () => listLocationIcons(pctx),
|
|
7112
|
+
setLocationIcon: (input) => setLocationIcon(pctx, input),
|
|
6981
7113
|
listPersistedByAddon: (input) => listPersistedByAddon(pctx, input),
|
|
6982
7114
|
listAll: (input) => listAll(pctx, input),
|
|
6983
7115
|
getDevice: (input) => getDevice(pctx, input),
|
|
@@ -212,6 +212,38 @@ export declare function listLocations(pctx: ProviderContext): ReturnType<IDevice
|
|
|
212
212
|
* meaningful label.
|
|
213
213
|
*/
|
|
214
214
|
export declare function addLocation(pctx: ProviderContext, input: Parameters<IDeviceManagerProvider['addLocation']>[0]): ReturnType<IDeviceManagerProvider['addLocation']>;
|
|
215
|
+
/**
|
|
216
|
+
* Every location that carries an icon, as `(locationKey, icon)` pairs.
|
|
217
|
+
*
|
|
218
|
+
* ADDITIVE beside `listLocations`, which still answers `string[]` — the
|
|
219
|
+
* autocomplete, the HA adoption import and the recorder all read a list of
|
|
220
|
+
* LABELS and a shape change there would break every one of them. A surface
|
|
221
|
+
* that wants icons asks for them and joins on `locationIconKey`.
|
|
222
|
+
*
|
|
223
|
+
* Returns only what was actually stored. A location with no assignment is
|
|
224
|
+
* ABSENT, never `map-pin`: the fallback belongs to the renderer
|
|
225
|
+
* (`resolveLocationIcon`), and folding it in here would make "the operator
|
|
226
|
+
* picked the pin" indistinguishable from "the operator picked nothing" —
|
|
227
|
+
* which is the difference an icon picker has to draw.
|
|
228
|
+
*/
|
|
229
|
+
export declare function listLocationIcons(pctx: ProviderContext): ReturnType<IDeviceManagerProvider['listLocationIcons']>;
|
|
230
|
+
/**
|
|
231
|
+
* Set (or clear) the icon of a location label.
|
|
232
|
+
*
|
|
233
|
+
* Keyed on `locationIconKey` — trimmed + lower-cased, the equality the
|
|
234
|
+
* registry matches on everywhere — so a case-only rename keeps the icon and
|
|
235
|
+
* two spellings of one room can never carry two different icons.
|
|
236
|
+
*
|
|
237
|
+
* The label need NOT be registered: `setLocation` accepts a free-form string
|
|
238
|
+
* and `listLocations` folds in whatever devices carry, so requiring
|
|
239
|
+
* registration here would leave exactly the ad-hoc rooms unable to have an
|
|
240
|
+
* icon. An empty label throws — there is no room to name.
|
|
241
|
+
*
|
|
242
|
+
* Same read-modify-write and same lock as `addLocation`: the map is one key of
|
|
243
|
+
* the addon store, and `writeAddonStore` re-inserts the whole key range, so an
|
|
244
|
+
* unordered write carries a stale copy of every other key.
|
|
245
|
+
*/
|
|
246
|
+
export declare function setLocationIcon(pctx: ProviderContext, input: Parameters<IDeviceManagerProvider['setLocationIcon']>[0]): ReturnType<IDeviceManagerProvider['setLocationIcon']>;
|
|
215
247
|
/**
|
|
216
248
|
* Remove a label from the curated registry. Match is
|
|
217
249
|
* case-insensitive. Devices that still reference this label keep
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChildLayout, DeviceDisplayOverride, RoleDisplayDefault } from '@camstack/types';
|
|
1
|
+
import { ChildLayout, DeviceDisplayOverride, LocationIconId, RoleDisplayDefault } from '@camstack/types';
|
|
2
2
|
/**
|
|
3
3
|
* Wire shape matching `z.infer<typeof SettingsSchemaWithValuesSchema>` —
|
|
4
4
|
* duplicated as a plain interface because importing the Zod schema across
|
|
@@ -161,6 +161,22 @@ export interface AddonStore {
|
|
|
161
161
|
* the operator forgot to register a label before assigning it.
|
|
162
162
|
*/
|
|
163
163
|
locations?: readonly string[];
|
|
164
|
+
/**
|
|
165
|
+
* Icon per location, keyed by `locationIconKey(label)` — trimmed and
|
|
166
|
+
* lower-cased, the same equality the registry itself matches on. Lives HERE,
|
|
167
|
+
* beside `locations`, because that is where a location exists at all: a
|
|
168
|
+
* location is a label, not a row, so there is no record to hang an icon on.
|
|
169
|
+
*
|
|
170
|
+
* Keyed on the folded label rather than the operator's casing on purpose. A
|
|
171
|
+
* case-only rename (`cucina` → `Cucina`) is a real edit this repo supports,
|
|
172
|
+
* and a map keyed on the displayed spelling would silently orphan its entry
|
|
173
|
+
* on exactly that edit — the icon would vanish and nothing would say why.
|
|
174
|
+
*
|
|
175
|
+
* A value outside `LOCATION_ICON_IDS` is DROPPED on decode, not trusted: the
|
|
176
|
+
* store is JSON on disk and a renderer handed an unknown id can only draw a
|
|
177
|
+
* hole. Dropping it degrades the location to the fallback pin instead.
|
|
178
|
+
*/
|
|
179
|
+
locationIcons?: Readonly<Record<string, LocationIconId>>;
|
|
164
180
|
/** Operator-authored per-role display defaults (unit/precision/icon), keyed
|
|
165
181
|
* by `DeviceRole` string. Resolution merges these UNDER any per-device
|
|
166
182
|
* `display` override. Written whole-record by `setRoleDisplayDefaults`
|
|
@@ -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-D6kqBW1G.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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as evaluateSensorEdge, I as bareAddonId, Sn as EventCategory, Xt as BaseAddon, Y as doorbellCapability, Yt as errMsg, b as SOURCE_CAPS, ln as createEvent, lt as isSameAddonId, nn as DeviceType, ut as isSourceCap, x as SOURCE_DEVICE_TYPES } from "../../dist-B4htkDVv.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
|
|
@@ -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-D6kqBW1G.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 { Xt as BaseAddon, _t as logDestinationCapability } from "../../dist-B4htkDVv.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-D6kqBW1G.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 { Sn as EventCategory, Xt as BaseAddon, Yt as errMsg, ln as createEvent, y as RecordingStatusSchema } from "../../dist-B4htkDVv.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-D6kqBW1G.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 { Gt as userManagementCapability, P as authProviderCapability, Xt as BaseAddon, k as UserRecordSchema, r as ApiKeyRecordSchema, w as ScopedTokenSchema } from "../../dist-B4htkDVv.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-D6kqBW1G.js");
|
|
4
4
|
const require_tls = require("../../tls-BFs4PzoW.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 { Sn as EventCategory, Xt as BaseAddon, ht as localNetworkCapability } from "../../dist-B4htkDVv.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-2xbgg78V.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-D6kqBW1G.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 { Xt as BaseAddon, _t as logDestinationCapability } from "../../dist-B4htkDVv.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-D6kqBW1G.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 { At as resolveBucketMs, Sn as EventCategory, St as metricsProviderCapability, Xt as BaseAddon, Yt as errMsg, kt as reducePoints, ln as createEvent, rt as foldSnapshotByFunction } from "../../dist-B4htkDVv.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-D6kqBW1G.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 { Dt as platformProbeCapability, Lt as scoreRuntimes, Sn as EventCategory, X as enumerateInferenceDevices, Xt as BaseAddon, Yt as errMsg, dn as emitReadiness } from "../../dist-B4htkDVv.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-D6kqBW1G.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 { Sn as EventCategory, Xt as BaseAddon } from "../../dist-B4htkDVv.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-D6kqBW1G.js");
|
|
7
7
|
const require_snapshot_courtesy = require("../../snapshot-courtesy-oeTWCXPv.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as deriveBatteryPresence, I as bareAddonId, L as batteryCapability, Sn as EventCategory, Wt as streamQualityLabel, Xt as BaseAddon, Yt as errMsg, en as DeviceFeature, hn as nodePin, i as BatteryStatusSchema, nn as DeviceType, zt as snapshotCapability } from "../../dist-B4htkDVv.mjs";
|
|
2
2
|
import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg } from "../../snapshot-courtesy-LoJNgHHZ.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-D6kqBW1G.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 { Ut as storageProviderCapability, Xt as BaseAddon, nt as filesystemBrowseCapability } from "../../dist-B4htkDVv.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-D6kqBW1G.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 { Bt as storageCapability, Ct as modeMayWrite, D as StorageLocationTypeSchema, E as StorageLocationModeSchema, Jt as withLocationMode, Mt as resolveLocationMode, O as StorageMigrationJobSchema, Rt as settingsStoreCapability, Sn as EventCategory, T as StorageCleanupJobSchema, Vt as storageMigrationCapability, Xt as BaseAddon, _ as REDACTED_SECRET, bt as mayReadLocation, et as evictionPolicyOfLocation, gn as parseJsonObject, it as gbToBytes, m as LegacyStorageLocationDefaultSchema, pt as legacyModeOf, st as isLocationEnabled, xt as mayWriteToLocation, z as collectSecretConfigKeys } from "../../dist-B4htkDVv.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-D6kqBW1G.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 { Xt as BaseAddon, Yt as errMsg, pn as hydrateSchema } from "../../dist-B4htkDVv.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-D6kqBW1G.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);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Xt as BaseAddon, _t as logDestinationCapability } from "../../dist-B4htkDVv.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|