@camstack/addon-model-studio 1.1.191 → 1.1.193

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.
Files changed (19) hide show
  1. package/dist/{MotionZonesSettings-BPTwSN9l.mjs → MotionZonesSettings-DttTm07s.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-BUeTedM4.mjs → PrivacyMaskSettings-Dh8hmteV.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-WRXqYE4X.mjs → SceneMonitorEditor-DwS357pX.mjs} +3 -3
  4. package/dist/_stub.js +12 -12
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DajnZUDj.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-9EZ9ti_a.mjs} +3 -3
  6. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BRYjyL8x.mjs +26 -0
  7. package/dist/addon-model-studio.css +1 -1
  8. package/dist/{hostInit-BSJgrQAJ.mjs → hostInit-BtfdDN9c.mjs} +2 -2
  9. package/dist/model-studio.addon.js +238 -40
  10. package/dist/model-studio.addon.mjs +238 -40
  11. package/dist/{player-overlays-BcG6COgL.mjs → player-overlays-BpOKgNmV.mjs} +1 -1
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-CYpgwv3g.mjs → responsive-Csmgluoo.mjs} +1 -1
  14. package/dist/{scene-monitor-copy-DvrdS2az.mjs → scene-monitor-copy-YW0guW_V.mjs} +1 -1
  15. package/dist/{square-BRARfL3C.mjs → square-BZmzImQ3.mjs} +1 -1
  16. package/dist/{trash-2-DLomxTVm.mjs → trash-2-DUI8dvQz.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DFLwncq5.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DT6YTat_.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-VZy4YTrJ.mjs +0 -26
@@ -20519,14 +20519,52 @@ var NcAlarmNonBlockingEditSchema = object({
20519
20519
  nonBlocking: boolean()
20520
20520
  });
20521
20521
  /**
20522
+ * Controllable openings: opt IN to blocking (default is do not block). Contacts
20523
+ * keep using {@link NcAlarmNonBlockingEditSchema}.
20524
+ */
20525
+ var NcAlarmBlockingEditSchema = object({
20526
+ mode: AlarmArmModeSchema,
20527
+ deviceId: number().int().positive(),
20528
+ /** true = on the list (blocks when open); false = off the list (default). */
20529
+ blocking: boolean()
20530
+ });
20531
+ /**
20532
+ * Controllable openings: opt OUT of secure-on-arm (default is secure ON —
20533
+ * close / lock / turn off when this mode arms).
20534
+ */
20535
+ var NcAlarmSecureOnArmEditSchema = object({
20536
+ mode: AlarmArmModeSchema,
20537
+ deviceId: number().int().positive(),
20538
+ /** true = secure on arm (default); false = do not actuate on arm. */
20539
+ secureOnArm: boolean()
20540
+ });
20541
+ /**
20542
+ * One arm mode's device-id list (non-blocking, blocking, or secure-on-arm-off).
20543
+ */
20544
+ var NcAlarmModeDeviceListSchema = object({
20545
+ mode: AlarmArmModeSchema,
20546
+ deviceIds: array(number().int()).max(200)
20547
+ });
20548
+ /**
20549
+ * One arm mode's non-blocking list: devices that may be open when that mode
20550
+ * arms, without the arm being refused.
20551
+ */
20552
+ var NcAlarmNonBlockingSchema = NcAlarmModeDeviceListSchema;
20553
+ /** Controllable devices that DO block when open (opt-in; default empty). */
20554
+ var NcAlarmBlockingSchema = NcAlarmModeDeviceListSchema;
20555
+ /**
20556
+ * Controllable devices that do NOT secure on arm (opt-out; default empty =
20557
+ * every controllable secures).
20558
+ */
20559
+ var NcAlarmSecureOnArmOffSchema = NcAlarmModeDeviceListSchema;
20560
+ /**
20522
20561
  * The per-mode lists, at most one per mode. Two lists for one mode have no
20523
20562
  * meaning a reader could agree on (union? the last one?), so they are refused
20524
20563
  * at the boundary rather than interpreted.
20525
20564
  */
20526
- var NcAlarmNonBlockingListSchema = array(object({
20527
- mode: AlarmArmModeSchema,
20528
- deviceIds: array(number().int()).max(200)
20529
- })).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
20565
+ var NcAlarmNonBlockingListSchema = array(NcAlarmNonBlockingSchema).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
20566
+ var NcAlarmBlockingListSchema = array(NcAlarmBlockingSchema).max(8).refine(uniqueModes, { message: "blocking: at most one list per arm mode" });
20567
+ var NcAlarmSecureOnArmOffListSchema = array(NcAlarmSecureOnArmOffSchema).max(8).refine(uniqueModes, { message: "secureOnArmOff: at most one list per arm mode" });
20530
20568
  /**
20531
20569
  * The three durations — global, and per mode since D697 — the panel's state
20532
20570
  * machine runs on, who hears about its transitions, and which openings each mode tolerates.
@@ -20569,9 +20607,23 @@ var NcAlarmSettingsSchema = object({
20569
20607
  * arm (a window left ajar for the cat under `home`, say). At most one entry
20570
20608
  * per mode is meaningful. Defaulted to `[]` so a blob stored before D630
20571
20609
  * parses as "every opening blocks" — the behaviour it was written under.
20610
+ * Contacts use this list; controllable openings use {@link blocking} instead
20611
+ * (default: do not block).
20572
20612
  */
20573
20613
  nonBlocking: NcAlarmNonBlockingListSchema.default([]),
20574
20614
  /**
20615
+ * Per arm mode, controllable openings that DO refuse the arm when open.
20616
+ * Default `[]` = none block (secure-on-arm closes them instead). Absent on a
20617
+ * blob older than this field — read as empty.
20618
+ */
20619
+ blocking: NcAlarmBlockingListSchema.default([]),
20620
+ /**
20621
+ * Per arm mode, controllable openings that must NOT be actuated on arm.
20622
+ * Default `[]` = every controllable secures (close / lock / off). Absent on
20623
+ * an older blob — read as empty (secure ON).
20624
+ */
20625
+ secureOnArmOff: NcAlarmSecureOnArmOffListSchema.default([]),
20626
+ /**
20575
20627
  * Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
20576
20628
  * without a field, uses the global value above — so `[]`, the default, is exactly the
20577
20629
  * behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
@@ -20581,7 +20633,7 @@ var NcAlarmSettingsSchema = object({
20581
20633
  /**
20582
20634
  * Every field optional — a tab edits one control at a time.
20583
20635
  *
20584
- * `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
20636
+ * List fields and `modeDelays` are re-declared WITHOUT their defaults:
20585
20637
  * `.partial()` does not remove an inner `.default()`, so a patch that never
20586
20638
  * named the field would parse to `[]` and wipe every mode's list on an
20587
20639
  * unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
@@ -20589,11 +20641,15 @@ var NcAlarmSettingsSchema = object({
20589
20641
  */
20590
20642
  var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
20591
20643
  nonBlocking: NcAlarmNonBlockingListSchema,
20644
+ blocking: NcAlarmBlockingListSchema,
20645
+ secureOnArmOff: NcAlarmSecureOnArmOffListSchema,
20592
20646
  /** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
20593
20647
  modeDelays: NcAlarmModeDelaysEditListSchema,
20594
20648
  /** ONE membership change; the panel applies it to the list it holds at its turn. */
20595
- nonBlockingEdit: NcAlarmNonBlockingEditSchema
20596
- }).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
20649
+ nonBlockingEdit: NcAlarmNonBlockingEditSchema,
20650
+ blockingEdit: NcAlarmBlockingEditSchema,
20651
+ secureOnArmEdit: NcAlarmSecureOnArmEditSchema
20652
+ }).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" }).refine((p) => p.blocking === void 0 || p.blockingEdit === void 0, { message: "blocking and blockingEdit are exclusive — send the whole lists or one edit" }).refine((p) => p.secureOnArmOff === void 0 || p.secureOnArmEdit === void 0, { message: "secureOnArmOff and secureOnArmEdit are exclusive — send the whole lists or one edit" });
20597
20653
  /**
20598
20654
  * What one arm mode actually arms, DERIVED from the enabled rules gated on it.
20599
20655
  * Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
@@ -20708,7 +20764,13 @@ var NcAlarmSensorStateSchema = object({
20708
20764
  /** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
20709
20765
  unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
20710
20766
  /** The device manager's liveness as the centre mirrors it; null = not known. */
20711
- online: boolean().nullable()
20767
+ online: boolean().nullable(),
20768
+ /**
20769
+ * True when the opening is a cover / lock / switch — the table shows the
20770
+ * Secure-on-arm switch and uses the controllable defaults. False for contacts
20771
+ * and for non-openings. Defaulted so an older hub answer still parses.
20772
+ */
20773
+ controllable: boolean().default(false)
20712
20774
  });
20713
20775
  var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
20714
20776
  var NcAlarmSensorsSchema = object({
@@ -28763,6 +28825,65 @@ DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _v
28763
28825
  auth: "protected"
28764
28826
  });
28765
28827
  /**
28828
+ * `calendar-source` — collection cap exposing per-provider calendars and
28829
+ * their events. Every addon that contributes calendars (Home Assistant,
28830
+ * a future Google Calendar addon, …) registers a provider here. The hub
28831
+ * singleton `calendars` walks the collection and merges the answers.
28832
+ *
28833
+ * Mirrors `addon-pages-source`: the public listing is a different shape
28834
+ * (source-stamped ids) and lives on the aggregator.
28835
+ */
28836
+ var CalendarSourceKindSchema = _enum(["ha", "addon"]);
28837
+ var CalendarInfoSchema = object({
28838
+ /** Provider-local id (e.g. HA `calendar.family`). The aggregator prefixes. */
28839
+ id: string().min(1),
28840
+ name: string().min(1),
28841
+ source: CalendarSourceKindSchema,
28842
+ enabled: boolean()
28843
+ });
28844
+ var CalendarEventSchema = object({
28845
+ id: string().min(1),
28846
+ calendarId: string().min(1),
28847
+ title: string(),
28848
+ startMs: number().int(),
28849
+ endMs: number().int(),
28850
+ allDay: boolean().optional(),
28851
+ description: string().optional(),
28852
+ location: string().optional()
28853
+ });
28854
+ var CalendarListEventsInputSchema = object({
28855
+ calendarIds: array(string().min(1)).max(64).optional(),
28856
+ startMs: number().int(),
28857
+ endMs: number().int()
28858
+ });
28859
+ method(_void(), array(CalendarInfoSchema).readonly(), { auth: "admin" }), method(CalendarListEventsInputSchema, array(CalendarEventSchema).readonly(), { auth: "admin" });
28860
+ /**
28861
+ * `calendars` — system-scoped singleton. Public surface admin-ui and the
28862
+ * notification-center calendar-events producer consume.
28863
+ *
28864
+ * Walks every `calendar-source` provider, stamps each calendar with a
28865
+ * cluster-stable id (`<sourceAddonId>:<localId>`) and the providing
28866
+ * addon's id, and fans `listEvents` out the same way. Home Assistant
28867
+ * import is a built-in refresh of the HA source rather than a second
28868
+ * registry — `importFromHomeAssistant` asks that source to re-discover.
28869
+ */
28870
+ var CalendarEntrySchema = CalendarInfoSchema.extend({
28871
+ /** Cluster-stable id: `<providerAddonId>:<localId>`. */
28872
+ id: string().min(1),
28873
+ /** The addon that registered the calendar-source provider. */
28874
+ providerAddonId: string().min(1).optional()
28875
+ });
28876
+ var CalendarImportResultSchema = object({
28877
+ imported: number().int().nonnegative(),
28878
+ /** Absent when no HA calendar-source provider was reachable. */
28879
+ providerAddonId: string().min(1).optional(),
28880
+ error: string().optional()
28881
+ });
28882
+ method(_void(), array(CalendarEntrySchema).readonly(), { auth: "admin" }), method(CalendarListEventsInputSchema, array(CalendarEventSchema).readonly(), { auth: "admin" }), method(_void(), CalendarImportResultSchema, {
28883
+ auth: "admin",
28884
+ kind: "mutation"
28885
+ });
28886
+ /**
28766
28887
  * camera-credentials — device-scoped cap exposing the camera's network
28767
28888
  * + auth surface in a vendor-neutral shape.
28768
28889
  *
@@ -32013,38 +32134,52 @@ DeviceType.Camera, method(object({
32013
32134
  deviceId: number(),
32014
32135
  status: OsdStatusSchema
32015
32136
  });
32137
+ _enum([
32138
+ "value",
32139
+ "unit",
32140
+ "full"
32141
+ ]);
32142
+ _enum([
32143
+ "value+unit",
32144
+ "value",
32145
+ "unit"
32146
+ ]);
32147
+ /**
32148
+ * How the operator reached the leaf device. `deviceId` is ALWAYS the
32149
+ * OSD-supported leaf that is read; `containerId` is set when the pick
32150
+ * went through a container (gateway) first.
32151
+ */
32152
+ var OsdTemplatePickSchema = object({
32153
+ containerId: number().int().optional(),
32154
+ deviceId: number().int()
32155
+ });
32156
+ /**
32157
+ * One named binding inside a multi-device template: device path + unit
32158
+ * selection + precision. The parser expands `{alias}`, `{alias.value}`,
32159
+ * `{alias.unit}`, or `{alias.full}` from the same binding — there is no
32160
+ * per-binding format lock.
32161
+ */
32162
+ var OsdTemplateBindingSchema = object({
32163
+ /** Token stem in the parser, e.g. `t` → `{t}` / `{t.value}`. Unique within the template. */
32164
+ alias: string().min(1).max(32).regex(/^[A-Za-z][A-Za-z0-9_-]*$/, "alias must start with a letter"),
32165
+ pick: OsdTemplatePickSchema,
32166
+ capName: string().min(1).max(64),
32167
+ valuePath: string().min(1).max(64),
32168
+ /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
32169
+ displayUnit: string().max(16).optional(),
32170
+ maxDecimals: number().int().min(0).max(4).default(1)
32171
+ });
32016
32172
  /**
32017
- * `osd-manager` — the ORCHESTRATOR over the device-scope `osd` cap.
32018
- *
32019
- * The `osd` cap is the firmware contract: it probes a camera's overlay
32020
- * SLOTS and writes literal text into one. It has no idea WHERE that text
32021
- * comes from, and it must not — a driver that grew a "show the temperature
32022
- * here" feature would grow it once per vendor.
32023
- *
32024
- * This cap owns the other half: a per-(camera, slot) BINDING that says
32025
- * which value feeds the slot, how it is formatted, and under which
32026
- * conditions it is shown at all. One addon renders every binding on every
32027
- * camera, so a new source costs zero driver code.
32028
- *
32029
- * Three deliberate choices, each with a rejected alternative:
32030
- *
32031
- * 1. A source is `(capName, valuePath)` over the kernel's device
32032
- * runtime-state mirror — NOT a closed enum of source kinds. Every
32033
- * cap-keyed slice a device publishes is bindable the day the cap
32034
- * ships. The rejected alternative (one enum member per source, with
32035
- * a resolver branch each) is what makes "add the humidity too" a
32036
- * code change.
32037
- * 2. The display gate reuses `NcConditionsSchema` verbatim — the
32038
- * notification centre's condition vocabulary — rather than a parallel
32039
- * model. An operator who has learned one condition editor has learned
32040
- * both.
32041
- * 3. Because the renderer's facts are device STATE and not a detection
32042
- * record, only a SUBSET of that vocabulary can be answered here.
32043
- * `setSlotBinding` REJECTS the rest at write time (see
32044
- * `getConditionSupport`). It does not accept-then-fail-closed: a
32045
- * condition that can never be true renders a permanently blank
32046
- * overlay, and a blank overlay looks exactly like a broken camera.
32173
+ * A named template: bindings (alias → leaf field) + a parser that
32174
+ * references `{alias}` / `{alias.value}` / `{alias.unit}` / `{alias.full}`.
32047
32175
  */
32176
+ var OsdNamedTemplateSchema = object({
32177
+ id: string().min(1).max(64),
32178
+ name: string().min(1).max(64),
32179
+ bindings: array(OsdTemplateBindingSchema).max(32).default([]),
32180
+ /** Parser with alias placeholders, e.g. `{t.value} {t.unit} / {h}`. */
32181
+ parser: string().max(256).default("")
32182
+ });
32048
32183
  /** Where a slot's value comes from. */
32049
32184
  var OsdSourceSchema = discriminatedUnion("kind", [
32050
32185
  object({
@@ -32063,11 +32198,17 @@ var OsdSourceSchema = discriminatedUnion("kind", [
32063
32198
  deviceId: number().int().optional(),
32064
32199
  capName: string().min(1).max(64),
32065
32200
  /** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
32066
- valuePath: string().min(1).max(64)
32201
+ valuePath: string().min(1).max(64),
32202
+ /** Convert TO this unit at render. Absent = no conversion. */
32203
+ displayUnit: string().max(16).optional()
32067
32204
  }),
32068
32205
  object({
32069
32206
  kind: literal("latest-recognition"),
32070
32207
  recognition: _enum(["person", "plate"])
32208
+ }),
32209
+ object({
32210
+ kind: literal("template"),
32211
+ templateId: string().min(1).max(64)
32071
32212
  })
32072
32213
  ]);
32073
32214
  var OsdSlotBindingSchema = object({
@@ -32083,7 +32224,10 @@ var OsdSlotBindingSchema = object({
32083
32224
  * documented workaround for firmwares that reject `.` in overlay text.
32084
32225
  */
32085
32226
  maxDecimals: number().int().min(0).max(4).default(1),
32086
- /** Appended via `${unit}`. The state mirror does not carry units. */
32227
+ /**
32228
+ * Appended via `${unit}` when no unit conversion produces a label.
32229
+ * Prefer `source.displayUnit` for converted device-state values.
32230
+ */
32087
32231
  unitLabel: string().max(8).optional(),
32088
32232
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
32089
32233
  valueMap: record(string(), string()).optional(),
@@ -32192,6 +32336,12 @@ method(object({ deviceId: number().int() }), object({
32192
32336
  }), method(object({ deviceId: number().int() }), object({ results: array(OsdRenderResultSchema) }), {
32193
32337
  kind: "mutation",
32194
32338
  auth: "admin"
32339
+ }), method(object({}), object({ templates: array(OsdNamedTemplateSchema) }), { auth: "admin" }), method(object({ template: OsdNamedTemplateSchema }), object({ template: OsdNamedTemplateSchema }), {
32340
+ kind: "mutation",
32341
+ auth: "admin"
32342
+ }), method(object({ templateId: string().min(1).max(64) }), object({ success: literal(true) }), {
32343
+ kind: "mutation",
32344
+ auth: "admin"
32195
32345
  });
32196
32346
  /**
32197
32347
  * Feeder connectivity / power status — mirrors the HA petkit device-status
@@ -38430,6 +38580,36 @@ Object.freeze({
38430
38580
  addonId: null,
38431
38581
  access: "create"
38432
38582
  },
38583
+ "calendars.importFromHomeAssistant": {
38584
+ capName: "calendars",
38585
+ capScope: "system",
38586
+ addonId: null,
38587
+ access: "create"
38588
+ },
38589
+ "calendars.listCalendars": {
38590
+ capName: "calendars",
38591
+ capScope: "system",
38592
+ addonId: null,
38593
+ access: "view"
38594
+ },
38595
+ "calendars.listEvents": {
38596
+ capName: "calendars",
38597
+ capScope: "system",
38598
+ addonId: null,
38599
+ access: "view"
38600
+ },
38601
+ "calendarSource.listCalendars": {
38602
+ capName: "calendar-source",
38603
+ capScope: "system",
38604
+ addonId: null,
38605
+ access: "view"
38606
+ },
38607
+ "calendarSource.listEvents": {
38608
+ capName: "calendar-source",
38609
+ capScope: "system",
38610
+ addonId: null,
38611
+ access: "view"
38612
+ },
38433
38613
  "cameraCredentials.getCredentials": {
38434
38614
  capName: "camera-credentials",
38435
38615
  capScope: "device",
@@ -41424,6 +41604,12 @@ Object.freeze({
41424
41604
  addonId: null,
41425
41605
  access: "create"
41426
41606
  },
41607
+ "osdManager.deleteTemplate": {
41608
+ capName: "osd-manager",
41609
+ capScope: "system",
41610
+ addonId: null,
41611
+ access: "delete"
41612
+ },
41427
41613
  "osdManager.getConditionSupport": {
41428
41614
  capName: "osd-manager",
41429
41615
  capScope: "system",
@@ -41442,6 +41628,12 @@ Object.freeze({
41442
41628
  addonId: null,
41443
41629
  access: "view"
41444
41630
  },
41631
+ "osdManager.listTemplates": {
41632
+ capName: "osd-manager",
41633
+ capScope: "system",
41634
+ addonId: null,
41635
+ access: "view"
41636
+ },
41445
41637
  "osdManager.previewSlot": {
41446
41638
  capName: "osd-manager",
41447
41639
  capScope: "system",
@@ -41460,6 +41652,12 @@ Object.freeze({
41460
41652
  addonId: null,
41461
41653
  access: "create"
41462
41654
  },
41655
+ "osdManager.upsertTemplate": {
41656
+ capName: "osd-manager",
41657
+ capScope: "system",
41658
+ addonId: null,
41659
+ access: "create"
41660
+ },
41463
41661
  "petFeeder.callPet": {
41464
41662
  capName: "pet-feeder",
41465
41663
  capScope: "device",