@camstack/addon-model-studio 1.1.260 → 1.1.262

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 (27) hide show
  1. package/dist/{MaskShapeCanvas-DBaZffFb.mjs → MaskShapeCanvas-CrWutXSb.mjs} +2330 -2329
  2. package/dist/MotionZonesSettings-DtoUJxd6.mjs +309 -0
  3. package/dist/PrivacyMaskSettings-Bd5lL0CO.mjs +368 -0
  4. package/dist/SceneMonitorEditor-BG0CBUrr.mjs +846 -0
  5. package/dist/_stub.js +9125 -7988
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CkwkW2EP.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CmpS6H8K.mjs} +4 -4
  7. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DlW3IlLM.mjs +26 -0
  8. package/dist/{_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-CHL8loOl.mjs → _virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DMBKVIH7.mjs} +1 -1
  9. package/dist/addon-model-studio.css +1 -1
  10. package/dist/{hostInit-Dj9XbnRR.mjs → hostInit-Cuk6X8GJ.mjs} +3 -3
  11. package/dist/model-studio.addon.js +204 -7
  12. package/dist/model-studio.addon.mjs +204 -7
  13. package/dist/player-overlays-DXeDukPC.mjs +44 -0
  14. package/dist/remoteEntry.js +1 -1
  15. package/dist/{responsive-CZQqiIpv.mjs → responsive-D9Bo78lO.mjs} +35 -35
  16. package/dist/scene-monitor-copy-CQr7egaT.mjs +227 -0
  17. package/dist/{square-ScGuLQH_.mjs → square-d__poSpa.mjs} +1 -1
  18. package/dist/{trash-2-CQxFRUtz.mjs → trash-2-C0XdoZQu.mjs} +1 -1
  19. package/dist/ui-text-BqZa5BNK.mjs +34 -0
  20. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-BbU0PjTG.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CS43EGzM.mjs} +1 -1
  21. package/package.json +1 -1
  22. package/dist/MotionZonesSettings-B1K0x6en.mjs +0 -310
  23. package/dist/PrivacyMaskSettings-DUSo9V9v.mjs +0 -377
  24. package/dist/SceneMonitorEditor-BIaR23TE.mjs +0 -831
  25. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CPL5HlJL.mjs +0 -26
  26. package/dist/player-overlays-CeSyVA4A.mjs +0 -44
  27. package/dist/scene-monitor-copy-B6BfcEdC.mjs +0 -187
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.372",
39
+ version: "1.2.374",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -45,7 +45,7 @@ async function r() {
45
45
  }
46
46
  },
47
47
  "@camstack/sdk": {
48
- version: "1.2.131",
48
+ version: "1.2.132",
49
49
  scope: "default",
50
50
  shareConfig: {
51
51
  singleton: !0,
@@ -81,7 +81,7 @@ async function r() {
81
81
  }
82
82
  },
83
83
  "@camstack/ui-library": {
84
- version: "1.2.290",
84
+ version: "1.2.292",
85
85
  scope: "default",
86
86
  shareConfig: {
87
87
  singleton: !0,
@@ -5782,7 +5782,7 @@ var ZodIssueCode = {
5782
5782
  var ZodFirstPartyTypeKind;
5783
5783
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5784
5784
  //#endregion
5785
- //#region ../types/dist/sleep-DAX0-2v9.mjs
5785
+ //#region ../types/dist/sleep-DRqxtc0C.mjs
5786
5786
  /**
5787
5787
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5788
5788
  * window to float samples (D455).
@@ -8631,8 +8631,12 @@ method(object({ deviceId: number() }), array(StreamSourceEntrySchema)), method(o
8631
8631
  kind: "mutation",
8632
8632
  auth: "admin"
8633
8633
  }), method(object({ deviceId: number() }), unknown().nullable()), method(object({ deviceId: number() }), RawStateResultSchema.nullable(), { auth: "protected" });
8634
+ object({
8635
+ code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
8636
+ params: record(string(), union([string(), number()])).optional()
8637
+ });
8634
8638
  //#endregion
8635
- //#region ../types/dist/err-msg-DX6i_MY4.mjs
8639
+ //#region ../types/dist/err-msg-DLerKiVO.mjs
8636
8640
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
8637
8641
  DeviceType["Camera"] = "camera";
8638
8642
  DeviceType["Hub"] = "hub";
@@ -8882,6 +8886,22 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
8882
8886
  DeviceRole["Nightvision"] = "nightvision";
8883
8887
  DeviceRole["PrivacyMask"] = "privacy-mask";
8884
8888
  DeviceRole["Doorbell"] = "doorbell";
8889
+ /** Interior blind / shade / roller blind. HA `device_class: blind|shade`. */
8890
+ DeviceRole["CoverBlind"] = "cover-blind";
8891
+ /** Exterior roller shutter. HA `device_class: shutter`; Homematic BROLL. */
8892
+ DeviceRole["CoverShutter"] = "cover-shutter";
8893
+ /** Exterior awning. HA `device_class: awning`. */
8894
+ DeviceRole["CoverAwning"] = "cover-awning";
8895
+ /** Curtain / drape. HA `device_class: curtain`. */
8896
+ DeviceRole["CoverCurtain"] = "cover-curtain";
8897
+ /** Garage door. HA `device_class: garage`. A security actuator: exports gate it. */
8898
+ DeviceRole["CoverGarage"] = "cover-garage";
8899
+ /** Gate. HA `device_class: gate`. A security actuator: exports gate it. */
8900
+ DeviceRole["CoverGate"] = "cover-gate";
8901
+ /** Door. HA `device_class: door`. A security actuator: exports gate it. */
8902
+ DeviceRole["CoverDoor"] = "cover-door";
8903
+ /** Window. HA `device_class: window`. */
8904
+ DeviceRole["CoverWindow"] = "cover-window";
8885
8905
  /** Virtual HA toggle (input_boolean.*) — distinguishable from a
8886
8906
  * real Switch device for UI rendering / export adapters. */
8887
8907
  DeviceRole["BinaryHelper"] = "binary-helper";
@@ -8952,7 +8972,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
8952
8972
  return DeviceRole;
8953
8973
  }({});
8954
8974
  //#endregion
8955
- //#region ../types/dist/composition-C-WpVYTX.mjs
8975
+ //#region ../types/dist/composition-EQ9Ok0Ee.mjs
8956
8976
  /**
8957
8977
  * The ffmpeg build every CamStack node downloads, per platform and arch.
8958
8978
  *
@@ -12768,6 +12788,8 @@ var ConvertResultSchema = object({
12768
12788
  artifacts: array(ConvertArtifactSchema).readonly()
12769
12789
  });
12770
12790
  _enum(["new-session", "step-up"]);
12791
+ /** The languages the hub's app landing pages are written in (D858). */
12792
+ var AppPageLangSchema = _enum(["en", "it"]);
12771
12793
  /** How a native app starts one login method (D858), as `auth.listLoginMethods` reports it. */
12772
12794
  var AppLoginPathSchema = discriminatedUnion("kind", [object({ kind: literal("native") }), object({
12773
12795
  kind: literal("browser"),
@@ -13281,7 +13303,9 @@ var ConfigTabDeclarationSchema = object({
13281
13303
  var ConfigSectionWithValuesSchema = object({
13282
13304
  id: string(),
13283
13305
  title: string(),
13306
+ titleKey: string().optional(),
13284
13307
  description: string().optional(),
13308
+ descriptionKey: string().optional(),
13285
13309
  style: _enum(["card", "accordion"]).optional(),
13286
13310
  defaultCollapsed: boolean().optional(),
13287
13311
  columns: union([
@@ -16535,6 +16559,9 @@ method(object({
16535
16559
  }), method(object({ refs: RefListSchema }), KeychainResolveResultSchema, { auth: "admin" }), method(object({ refs: RefListSchema }), object({ deleted: number().int() }), {
16536
16560
  kind: "mutation",
16537
16561
  auth: "admin"
16562
+ }), method(object({ deviceId: number().int() }), object({ refs: array(string()).readonly() }), {
16563
+ kind: "mutation",
16564
+ auth: "admin"
16538
16565
  }), method(object({}), array(KeychainSecretMetaSchema).readonly(), { auth: "admin" }), method(object({}), KeychainStateSchema, { auth: "admin" });
16539
16566
  /**
16540
16567
  * device-history — the ONE mechanism for numeric history (D850).
@@ -37938,6 +37965,38 @@ var DeviceRegisterPayloadSchema = object({
37938
37965
  * omits it and the keyword backstop applies. */
37939
37966
  secretConfigPaths: array(string()).optional()
37940
37967
  });
37968
+ /** One deleted device, kept by device-manager so an addon that missed the
37969
+ * deletion can still learn of it (D865). Written by the delete path ONLY. */
37970
+ var DeviceTombstoneSchema = object({
37971
+ deviceId: number().int().positive(),
37972
+ /** Epoch ms the device was deleted. */
37973
+ deletedAt: number(),
37974
+ /** The addon that owned the device when it was deleted. */
37975
+ providerAddonId: string()
37976
+ });
37977
+ /** Data held for one device that device-manager no longer knows. */
37978
+ var OrphanDeviceDataSchema = object({
37979
+ deviceId: number().int().positive(),
37980
+ /** Rows/files per store (`<addonId>:<store>`). */
37981
+ stores: record(string(), number().int().nonnegative())
37982
+ });
37983
+ var CleanupDeletedDevicesResultSchema = object({
37984
+ /**
37985
+ * `skipped` — the absence check could not be trusted (a device-list read
37986
+ * failed or the two reads disagreed); nothing was listed or deleted.
37987
+ * `dry-run` — `devices` is what a confirmed run would delete.
37988
+ * `cleaned` — `devices` is what was deleted.
37989
+ */
37990
+ status: _enum([
37991
+ "skipped",
37992
+ "dry-run",
37993
+ "cleaned"
37994
+ ]),
37995
+ reason: string().nullable(),
37996
+ devices: array(OrphanDeviceDataSchema),
37997
+ /** Implementers that could not be asked (their stores are not in `devices`). */
37998
+ unreachable: array(string())
37999
+ });
37941
38000
  var DeviceRemovePayloadSchema = object({ deviceId: number() });
37942
38001
  var DevicePersistConfigPayloadSchema = object({
37943
38002
  deviceId: number(),
@@ -38176,6 +38235,9 @@ method(object({
38176
38235
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
38177
38236
  kind: "mutation",
38178
38237
  auth: "admin"
38238
+ }), method(object({ sinceMs: number() }), array(DeviceTombstoneSchema).readonly(), { auth: "admin" }), method(object({ confirm: boolean() }), CleanupDeletedDevicesResultSchema, {
38239
+ kind: "mutation",
38240
+ auth: "admin"
38179
38241
  }), method(object({ integrationId: string() }), object({ removed: number() }), {
38180
38242
  kind: "mutation",
38181
38243
  auth: "admin"
@@ -38638,6 +38700,72 @@ method(object({
38638
38700
  auth: "admin"
38639
38701
  });
38640
38702
  /**
38703
+ * `device-removal-hook` — the reliable way an addon learns a device was DELETED,
38704
+ * so it can delete what it keeps for that device (D865).
38705
+ *
38706
+ * ## Why an event was not enough
38707
+ *
38708
+ * `DeviceUnregistered` is telemetry and may be dropped (D8, D11). An addon that
38709
+ * hung its per-device clean-up on it left durable garbage whenever the event was
38710
+ * lost, the addon was down, or it was restarting at that moment — footage,
38711
+ * analytics rows and settings of device 4483 outlived the device. Loss of this
38712
+ * signal corrupts durable state, so it travels by RPC with a recorded fact
38713
+ * behind it (D8: "if loss would corrupt durable state, use RPC plus a reconcile").
38714
+ *
38715
+ * ## The three pieces
38716
+ *
38717
+ * 1. device-manager records a TOMBSTONE per deleted device
38718
+ * (`deviceManager.listDeletedSince`). The tombstone is written by the delete
38719
+ * path only — a device that is unregistered, offline or whose provider is
38720
+ * restarting is NOT deleted and gets none.
38721
+ * 2. After a delete, device-manager calls `onDeviceRemoved` on EVERY provider of
38722
+ * this collection, one by one, with bounded retries, logged.
38723
+ * 3. An implementer that was down asks `deviceManager.listDeletedSince` at start
38724
+ * (and periodically) and runs its own `onDeviceRemoved` for each tombstone it
38725
+ * may have missed. Reconcile is driven by tombstones, never by "the device is
38726
+ * not in the current list": a failed or partial list read must not destroy data.
38727
+ *
38728
+ * ## Contract for an implementer
38729
+ *
38730
+ * - **Idempotent.** It is called again by a retry, by a reconcile and by the
38731
+ * admin cleanup of data that predates tombstones. A device with nothing left
38732
+ * answers zero counts.
38733
+ * - **One key per store** in `counts`, deleted rows/files per store, so the log
38734
+ * line and the admin dry run can say where the data was.
38735
+ * - **Training datasets are NOT device data** and are never deleted by a hook.
38736
+ * - **Per-device SETTINGS are not hooked.** Configuration lives in the standard
38737
+ * per-device store (`ctx.settings.*DeviceStore`), which device-manager clears
38738
+ * for every addon centrally at delete time. This hook is for device DATA
38739
+ * that is not settings: footage, event media, analytics rows, history.
38740
+ * - A provider that cannot tell is allowed to throw; the caller retries it.
38741
+ *
38742
+ * `listDeviceData` is the read side of the admin "Clean data of deleted devices"
38743
+ * action: which device ids this addon holds data for, and how much per store. It
38744
+ * never deletes. device-manager decides which of those ids are absent from the
38745
+ * fleet, from TWO consistent reads of the device list (D49).
38746
+ */
38747
+ /** What a hook is told about the deletion. */
38748
+ var DeviceRemovedInputSchema = object({
38749
+ deviceId: number().int().positive(),
38750
+ /** Epoch ms the device was deleted (the tombstone's `deletedAt`). */
38751
+ deletedAt: number(),
38752
+ /** The addon that owned the device, as device-manager last knew it. */
38753
+ providerAddonId: string()
38754
+ });
38755
+ /** Rows/files/refs deleted, per store this implementer owns. */
38756
+ var DeviceRemovedResultSchema = object({ counts: record(string(), number().int().nonnegative()) });
38757
+ /** One (store, device) pair an implementer holds data for. */
38758
+ var DeviceDataEntrySchema = object({
38759
+ store: string(),
38760
+ deviceId: number().int().positive(),
38761
+ /** Rows (or files) held for the device in the store. */
38762
+ count: number().int().nonnegative()
38763
+ });
38764
+ method(DeviceRemovedInputSchema, DeviceRemovedResultSchema, {
38765
+ kind: "mutation",
38766
+ auth: "admin"
38767
+ }), method(_void(), array(DeviceDataEntrySchema).readonly(), { auth: "admin" });
38768
+ /**
38641
38769
  * `failure-contribution` — the capability an addon reports its OWN losses
38642
38770
  * through, per camera, with the denominator attached. It stores nothing.
38643
38771
  *
@@ -50204,7 +50332,9 @@ var SsoBridgeClaimsSchema = object({
50204
50332
  codeChallenge: string(),
50205
50333
  state: string(),
50206
50334
  purpose: _enum(["new-session", "step-up"]),
50207
- redirect: string()
50335
+ redirect: string(),
50336
+ /** The page language the app asked for (D858); the confirm page speaks it. */
50337
+ lang: _enum(["en", "it"]).optional()
50208
50338
  }).optional()
50209
50339
  });
50210
50340
  method(object({
@@ -59568,6 +59698,21 @@ DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
59568
59698
  on: boolean(),
59569
59699
  lastChangedAt: number()
59570
59700
  });
59701
+ /** C0 controls, DEL and the C1 range: none of them belongs in a name. */
59702
+ function hasControlCharacter(value) {
59703
+ for (const char of value) {
59704
+ const code = char.codePointAt(0) ?? 0;
59705
+ if (code <= 31 || code >= 127 && code <= 159) return true;
59706
+ }
59707
+ return false;
59708
+ }
59709
+ string().transform((value) => value.trim()).pipe(string().min(1, "The server name cannot be empty").max(48, `The server name is at most 48 characters`).refine((value) => !hasControlCharacter(value), { message: "The server name cannot contain control characters" }));
59710
+ /** What every reader gets: the name to show, and whether the hub chose it itself. */
59711
+ var ServerNameInfoSchema = object({
59712
+ name: string(),
59713
+ /** `true` when nobody named the hub: `name` is the machine hostname. */
59714
+ isDefault: boolean()
59715
+ });
59571
59716
  /**
59572
59717
  * system — system-scoped singleton capability exposing hub-level
59573
59718
  * health, feature flags, network interface enumeration, and the
@@ -59597,6 +59742,12 @@ var FeatureManifestSchema = object({
59597
59742
  backup: boolean(),
59598
59743
  repl: boolean()
59599
59744
  });
59745
+ /**
59746
+ * `system.info`: the feature flags plus the hub's human name (D861). The name is
59747
+ * `{ name, isDefault }` — `isDefault: true` means nobody named the hub and `name`
59748
+ * is the machine hostname.
59749
+ */
59750
+ var SystemInfoSchema = FeatureManifestSchema.extend({ serverName: ServerNameInfoSchema });
59600
59751
  var HealthStatusSchema = object({
59601
59752
  status: literal("ok"),
59602
59753
  uptime: number()
@@ -60069,7 +60220,7 @@ var LoggingSettingsStateSchema = object({
60069
60220
  opsLogRetentionDays: number().int().min(0),
60070
60221
  persisted: boolean()
60071
60222
  });
60072
- method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
60223
+ method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
60073
60224
  kind: "mutation",
60074
60225
  auth: "admin"
60075
60226
  }), method(_void(), _void(), {
@@ -63218,6 +63369,12 @@ Object.freeze({
63218
63369
  addonId: null,
63219
63370
  access: "create"
63220
63371
  },
63372
+ "deviceManager.cleanupDeletedDevicesData": {
63373
+ capName: "device-manager",
63374
+ capScope: "system",
63375
+ addonId: null,
63376
+ access: "create"
63377
+ },
63221
63378
  "deviceManager.createDevice": {
63222
63379
  capName: "device-manager",
63223
63380
  capScope: "system",
@@ -63398,6 +63555,12 @@ Object.freeze({
63398
63555
  addonId: null,
63399
63556
  access: "view"
63400
63557
  },
63558
+ "deviceManager.listDeletedSince": {
63559
+ capName: "device-manager",
63560
+ capScope: "system",
63561
+ addonId: null,
63562
+ access: "view"
63563
+ },
63401
63564
  "deviceManager.listDeviceIdsByCaps": {
63402
63565
  capName: "device-manager",
63403
63566
  capScope: "system",
@@ -63806,6 +63969,18 @@ Object.freeze({
63806
63969
  addonId: null,
63807
63970
  access: "create"
63808
63971
  },
63972
+ "deviceRemovalHook.listDeviceData": {
63973
+ capName: "device-removal-hook",
63974
+ capScope: "system",
63975
+ addonId: null,
63976
+ access: "view"
63977
+ },
63978
+ "deviceRemovalHook.onDeviceRemoved": {
63979
+ capName: "device-removal-hook",
63980
+ capScope: "system",
63981
+ addonId: null,
63982
+ access: "create"
63983
+ },
63809
63984
  "deviceState.claimFields": {
63810
63985
  capName: "device-state",
63811
63986
  capScope: "system",
@@ -64238,6 +64413,12 @@ Object.freeze({
64238
64413
  addonId: null,
64239
64414
  access: "delete"
64240
64415
  },
64416
+ "keychain.deleteDeviceScope": {
64417
+ capName: "keychain",
64418
+ capScope: "system",
64419
+ addonId: null,
64420
+ access: "delete"
64421
+ },
64241
64422
  "keychain.getState": {
64242
64423
  capName: "keychain",
64243
64424
  capScope: "system",
@@ -70250,6 +70431,11 @@ Object.freeze({
70250
70431
  form: "single",
70251
70432
  optional: false
70252
70433
  }],
70434
+ "deviceRemovalHook.onDeviceRemoved": [{
70435
+ name: "deviceId",
70436
+ form: "single",
70437
+ optional: false
70438
+ }],
70253
70439
  "deviceState.claimFields": [{
70254
70440
  name: "deviceId",
70255
70441
  form: "single",
@@ -70439,6 +70625,11 @@ Object.freeze({
70439
70625
  form: "single",
70440
70626
  optional: false
70441
70627
  }],
70628
+ "keychain.deleteDeviceScope": [{
70629
+ name: "deviceId",
70630
+ form: "single",
70631
+ optional: false
70632
+ }],
70442
70633
  "lawnMowerControl.dock": [{
70443
70634
  name: "deviceId",
70444
70635
  form: "single",
@@ -72787,6 +72978,8 @@ new Set([
72787
72978
  "audio-tools",
72788
72979
  "audio-silence"
72789
72980
  ]);
72981
+ AppPageLangSchema.options;
72982
+ record(string().min(1), string());
72790
72983
  /**
72791
72984
  * TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
72792
72985
  *
@@ -73337,11 +73530,15 @@ function parseDisplayName(raw) {
73337
73530
  if (name.length === 0) return { kind: "reset" };
73338
73531
  if (CONTROL_CHARS.test(name)) return {
73339
73532
  kind: "invalid",
73340
- reason: "The name contains control characters."
73533
+ reason: "The name contains control characters.",
73534
+ code: "control",
73535
+ length: name.length
73341
73536
  };
73342
73537
  if (name.length > 80) return {
73343
73538
  kind: "invalid",
73344
- reason: `The name is ${name.length} characters long; the limit is 80.`
73539
+ reason: `The name is ${name.length} characters long; the limit is 80.`,
73540
+ code: "too-long",
73541
+ length: name.length
73345
73542
  };
73346
73543
  return {
73347
73544
  kind: "set",