camstack 1.2.119 → 1.2.121

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.
@@ -19618,6 +19618,9 @@ var QueryFilterSchema = external_exports.object({
19618
19618
  whereBetween: external_exports.record(external_exports.string(), external_exports.tuple([external_exports.unknown(), external_exports.unknown()])).optional(),
19619
19619
  /** NULL-safe exclusion: matches rows whose field is NULL OR != the value. */
19620
19620
  whereNot: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
19621
+ /** NULL-safe exclusion of a SET — `whereNot` for more than one value. An
19622
+ * empty list excludes nothing. See `QueryFilter.whereNotIn`. */
19623
+ whereNotIn: external_exports.record(external_exports.string(), external_exports.array(external_exports.unknown())).optional(),
19621
19624
  orderBy: external_exports.object({
19622
19625
  field: external_exports.string(),
19623
19626
  direction: external_exports.enum(["asc", "desc"])
@@ -19629,7 +19632,8 @@ var MutationFilterSchema = external_exports.object({
19629
19632
  where: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
19630
19633
  whereIn: external_exports.record(external_exports.string(), external_exports.array(external_exports.unknown())).optional(),
19631
19634
  whereBetween: external_exports.record(external_exports.string(), external_exports.tuple([external_exports.unknown(), external_exports.unknown()])).optional(),
19632
- whereNot: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
19635
+ whereNot: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
19636
+ whereNotIn: external_exports.record(external_exports.string(), external_exports.array(external_exports.unknown())).optional()
19633
19637
  });
19634
19638
  var AggregateFieldSchema = external_exports.object({
19635
19639
  /** Result key. */
@@ -26801,7 +26805,9 @@ var RecentTracksQueryInput = external_exports.object({
26801
26805
  * whose class list is unreadable are kept, and the client's rule stays the
26802
26806
  * exact one.
26803
26807
  */
26804
- classes: external_exports.array(external_exports.string()).optional()
26808
+ classes: external_exports.array(external_exports.string()).optional(),
26809
+ /** See {@link ExcludeSourcesDoc}. */
26810
+ excludeSources: external_exports.array(TrackSourceSchema).optional()
26805
26811
  });
26806
26812
  var SummarySchema = external_exports.object({
26807
26813
  id: external_exports.string(),
@@ -27147,7 +27153,9 @@ var pipelineAnalyticsCapability = {
27147
27153
  * selected is an operator who has not narrowed anything, and an empty
27148
27154
  * timeline would read as a camera that saw nothing.
27149
27155
  */
27150
- classes: external_exports.array(external_exports.string()).optional()
27156
+ classes: external_exports.array(external_exports.string()).optional(),
27157
+ /** See {@link ExcludeSourcesDoc}. */
27158
+ excludeSources: external_exports.array(TrackSourceSchema).optional()
27151
27159
  }), external_exports.array(TrackSchema).readonly()),
27152
27160
  /**
27153
27161
  * Batched cluster-wide track listing — ONE call for the events page /
@@ -36982,8 +36990,27 @@ var PrivacyMaskRegionSchema = external_exports.object({
36982
36990
  });
36983
36991
  var PrivacyMaskStatusSchema = external_exports.object({
36984
36992
  enabled: external_exports.boolean(),
36985
- /** Active zones (normalized 0..1). Length ≤ maxRegions. */
36986
- regions: external_exports.array(PrivacyMaskRegionSchema),
36993
+ /**
36994
+ * Active zones (normalized 0..1). Length ≤ maxRegions.
36995
+ *
36996
+ * `null` means "no answer" — the provider has never reached this camera
36997
+ * (a cold `runtimeState` slice, a battery camera asleep) or the read
36998
+ * failed. A consumer must render it as UNKNOWN and never as "this camera
36999
+ * has no zones": those two look identical to an operator right up to the
37000
+ * moment one of them is acted on, and acting on them differs completely.
37001
+ * The switch group turned an unanswered read into *"nothing is set up for
37002
+ * it to act on"* — an instruction to go and draw a zone that already
37003
+ * exists — and this editor seeded an EMPTY canvas from it, one Save away
37004
+ * from deleting the mask it could not read.
37005
+ *
37006
+ * Empty-and-answered is `[]` and stays a real answer: this camera genuinely
37007
+ * has no zones. The distinction is the same one {@link
37008
+ * PrivacyMaskStatusSchema.shape.audioEnabled} already draws for the
37009
+ * microphone, on the very same payload — both planes come from ONE refresh,
37010
+ * so it was never coherent for one of them to be able to say "unknown"
37011
+ * while the other could not.
37012
+ */
37013
+ regions: external_exports.array(PrivacyMaskRegionSchema).nullable(),
36987
37014
  /**
36988
37015
  * Is the camera capturing sound right now? Read from the camera, never from
36989
37016
  * a server-side mirror.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-TTXLCMS6.js";
4
+ } from "./chunk-F56HD6CH.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -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-ZPBN2VWD.js");
41
+ await import("./launcher-2BTQJ5AA.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-ZPBN2VWD.js");
86
+ await import("./launcher-2BTQJ5AA.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-BDIQXDHH.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-X5IKQOKL.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-TTXLCMS6.js";
8
+ } from "./chunk-F56HD6CH.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-BD7M9-5N.js
23637
- var require_dist_BD7M9_5N = __commonJS({
23638
- "../system/dist/dist-BD7M9-5N.js"(exports) {
23636
+ // ../system/dist/dist-kUlalZ6-.js
23637
+ var require_dist_kUlalZ6 = __commonJS({
23638
+ "../system/dist/dist-kUlalZ6-.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -30361,6 +30361,9 @@ var require_dist_BD7M9_5N = __commonJS({
30361
30361
  whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
30362
30362
  /** NULL-safe exclusion: matches rows whose field is NULL OR != the value. */
30363
30363
  whereNot: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
30364
+ /** NULL-safe exclusion of a SET — `whereNot` for more than one value. An
30365
+ * empty list excludes nothing. See `QueryFilter.whereNotIn`. */
30366
+ whereNotIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
30364
30367
  orderBy: zod.z.object({
30365
30368
  field: zod.z.string(),
30366
30369
  direction: zod.z.enum(["asc", "desc"])
@@ -30372,7 +30375,8 @@ var require_dist_BD7M9_5N = __commonJS({
30372
30375
  where: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
30373
30376
  whereIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
30374
30377
  whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
30375
- whereNot: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
30378
+ whereNot: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
30379
+ whereNotIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional()
30376
30380
  });
30377
30381
  var AggregateFieldSchema = zod.z.object({
30378
30382
  /** Result key. */
@@ -37570,7 +37574,9 @@ var require_dist_BD7M9_5N = __commonJS({
37570
37574
  * whose class list is unreadable are kept, and the client's rule stays the
37571
37575
  * exact one.
37572
37576
  */
37573
- classes: zod.z.array(zod.z.string()).optional()
37577
+ classes: zod.z.array(zod.z.string()).optional(),
37578
+ /** See {@link ExcludeSourcesDoc}. */
37579
+ excludeSources: zod.z.array(TrackSourceSchema).optional()
37574
37580
  });
37575
37581
  var SummarySchema = zod.z.object({
37576
37582
  id: zod.z.string(),
@@ -37916,7 +37922,9 @@ var require_dist_BD7M9_5N = __commonJS({
37916
37922
  * selected is an operator who has not narrowed anything, and an empty
37917
37923
  * timeline would read as a camera that saw nothing.
37918
37924
  */
37919
- classes: zod.z.array(zod.z.string()).optional()
37925
+ classes: zod.z.array(zod.z.string()).optional(),
37926
+ /** See {@link ExcludeSourcesDoc}. */
37927
+ excludeSources: zod.z.array(TrackSourceSchema).optional()
37920
37928
  }), zod.z.array(TrackSchema).readonly()),
37921
37929
  /**
37922
37930
  * Batched cluster-wide track listing — ONE call for the events page /
@@ -47597,8 +47605,27 @@ var require_dist_BD7M9_5N = __commonJS({
47597
47605
  });
47598
47606
  var PrivacyMaskStatusSchema = zod.z.object({
47599
47607
  enabled: zod.z.boolean(),
47600
- /** Active zones (normalized 0..1). Length ≤ maxRegions. */
47601
- regions: zod.z.array(PrivacyMaskRegionSchema),
47608
+ /**
47609
+ * Active zones (normalized 0..1). Length ≤ maxRegions.
47610
+ *
47611
+ * `null` means "no answer" — the provider has never reached this camera
47612
+ * (a cold `runtimeState` slice, a battery camera asleep) or the read
47613
+ * failed. A consumer must render it as UNKNOWN and never as "this camera
47614
+ * has no zones": those two look identical to an operator right up to the
47615
+ * moment one of them is acted on, and acting on them differs completely.
47616
+ * The switch group turned an unanswered read into *"nothing is set up for
47617
+ * it to act on"* — an instruction to go and draw a zone that already
47618
+ * exists — and this editor seeded an EMPTY canvas from it, one Save away
47619
+ * from deleting the mask it could not read.
47620
+ *
47621
+ * Empty-and-answered is `[]` and stays a real answer: this camera genuinely
47622
+ * has no zones. The distinction is the same one {@link
47623
+ * PrivacyMaskStatusSchema.shape.audioEnabled} already draws for the
47624
+ * microphone, on the very same payload — both planes come from ONE refresh,
47625
+ * so it was never coherent for one of them to be able to say "unknown"
47626
+ * while the other could not.
47627
+ */
47628
+ regions: zod.z.array(PrivacyMaskRegionSchema).nullable(),
47602
47629
  /**
47603
47630
  * Is the camera capturing sound right now? Read from the camera, never from
47604
47631
  * a server-side mirror.
@@ -60931,7 +60958,7 @@ var require_alerts_addon = __commonJS({
60931
60958
  [Symbol.toStringTag]: { value: "Module" }
60932
60959
  });
60933
60960
  require_chunk_Cek0wNdY();
60934
- var require_dist10 = require_dist_BD7M9_5N();
60961
+ var require_dist10 = require_dist_kUlalZ6();
60935
60962
  function selectExpired(alerts, cutoffMs) {
60936
60963
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
60937
60964
  }
@@ -61750,7 +61777,7 @@ var require_console_logging = __commonJS({
61750
61777
  [Symbol.toStringTag]: { value: "Module" }
61751
61778
  });
61752
61779
  require_chunk_Cek0wNdY();
61753
- var require_dist10 = require_dist_BD7M9_5N();
61780
+ var require_dist10 = require_dist_kUlalZ6();
61754
61781
  var require_formatter = require_formatter_DqAKDlvN();
61755
61782
  var LEVEL_RANK = {
61756
61783
  debug: 0,
@@ -61844,7 +61871,7 @@ var require_core_blocks_addon = __commonJS({
61844
61871
  "use strict";
61845
61872
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
61846
61873
  var require_chunk = require_chunk_Cek0wNdY();
61847
- var require_dist10 = require_dist_BD7M9_5N();
61874
+ var require_dist10 = require_dist_kUlalZ6();
61848
61875
  var node_crypto = __require("crypto");
61849
61876
  var node_fs_promises = __require("fs/promises");
61850
61877
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -62741,11 +62768,11 @@ var require_core_blocks = __commonJS({
62741
62768
  }
62742
62769
  });
62743
62770
 
62744
- // ../system/dist/retired-settings-keys-h7YxHNjB.js
62745
- var require_retired_settings_keys_h7YxHNjB = __commonJS({
62746
- "../system/dist/retired-settings-keys-h7YxHNjB.js"(exports) {
62771
+ // ../system/dist/retired-settings-keys-D61YnSKJ.js
62772
+ var require_retired_settings_keys_D61YnSKJ = __commonJS({
62773
+ "../system/dist/retired-settings-keys-D61YnSKJ.js"(exports) {
62747
62774
  "use strict";
62748
- var require_dist10 = require_dist_BD7M9_5N();
62775
+ var require_dist10 = require_dist_kUlalZ6();
62749
62776
  function settingsStoreIsAuthoritativeHere(env) {
62750
62777
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
62751
62778
  return raw === "" || raw === "hub";
@@ -64980,8 +65007,8 @@ var require_device_manager_addon = __commonJS({
64980
65007
  [Symbol.toStringTag]: { value: "Module" }
64981
65008
  });
64982
65009
  require_chunk_Cek0wNdY();
64983
- var require_dist10 = require_dist_BD7M9_5N();
64984
- var require_retired_settings_keys = require_retired_settings_keys_h7YxHNjB();
65010
+ var require_dist10 = require_dist_kUlalZ6();
65011
+ var require_retired_settings_keys = require_retired_settings_keys_D61YnSKJ();
64985
65012
  var node_crypto = __require("crypto");
64986
65013
  var _camstack_types_node = require_node();
64987
65014
  var JOB_HISTORY = 20;
@@ -70606,7 +70633,7 @@ var require_hub_forwarder = __commonJS({
70606
70633
  [Symbol.toStringTag]: { value: "Module" }
70607
70634
  });
70608
70635
  require_chunk_Cek0wNdY();
70609
- var require_dist10 = require_dist_BD7M9_5N();
70636
+ var require_dist10 = require_dist_kUlalZ6();
70610
70637
  var require_formatter = require_formatter_DqAKDlvN();
70611
70638
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
70612
70639
  var HubForwarderDestination = class {
@@ -70743,7 +70770,7 @@ var require_liveness_monitor_addon = __commonJS({
70743
70770
  "use strict";
70744
70771
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
70745
70772
  require_chunk_Cek0wNdY();
70746
- var require_dist10 = require_dist_BD7M9_5N();
70773
+ var require_dist10 = require_dist_kUlalZ6();
70747
70774
  var NO_DEVICES = "liveness:no-devices";
70748
70775
  var ALL_OFFLINE = "liveness:all-devices-offline";
70749
70776
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -70939,7 +70966,7 @@ var require_local_auth_addon = __commonJS({
70939
70966
  [Symbol.toStringTag]: { value: "Module" }
70940
70967
  });
70941
70968
  var require_chunk = require_chunk_Cek0wNdY();
70942
- var require_dist10 = require_dist_BD7M9_5N();
70969
+ var require_dist10 = require_dist_kUlalZ6();
70943
70970
  var node_crypto = __require("crypto");
70944
70971
  node_crypto = require_chunk.__toESM(node_crypto);
70945
70972
  var crypto$1 = __require("crypto");
@@ -78752,7 +78779,7 @@ var require_loki_logging = __commonJS({
78752
78779
  [Symbol.toStringTag]: { value: "Module" }
78753
78780
  });
78754
78781
  require_chunk_Cek0wNdY();
78755
- var require_dist10 = require_dist_BD7M9_5N();
78782
+ var require_dist10 = require_dist_kUlalZ6();
78756
78783
  function sanitizeLabelName(raw) {
78757
78784
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
78758
78785
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -79317,7 +79344,7 @@ var require_native_metrics_addon = __commonJS({
79317
79344
  [Symbol.toStringTag]: { value: "Module" }
79318
79345
  });
79319
79346
  var require_chunk = require_chunk_Cek0wNdY();
79320
- var require_dist10 = require_dist_BD7M9_5N();
79347
+ var require_dist10 = require_dist_kUlalZ6();
79321
79348
  var node_fs_promises = __require("fs/promises");
79322
79349
  var node_child_process = __require("child_process");
79323
79350
  var node_util = __require("util");
@@ -81901,7 +81928,7 @@ var require_filesystem_storage_addon = __commonJS({
81901
81928
  [Symbol.toStringTag]: { value: "Module" }
81902
81929
  });
81903
81930
  var require_chunk = require_chunk_Cek0wNdY();
81904
- var require_dist10 = require_dist_BD7M9_5N();
81931
+ var require_dist10 = require_dist_kUlalZ6();
81905
81932
  var node_crypto = __require("crypto");
81906
81933
  var node_fs_promises = __require("fs/promises");
81907
81934
  var node_path = __require("path");
@@ -83017,8 +83044,8 @@ var require_sqlite_settings_addon = __commonJS({
83017
83044
  [Symbol.toStringTag]: { value: "Module" }
83018
83045
  });
83019
83046
  var require_chunk = require_chunk_Cek0wNdY();
83020
- var require_dist10 = require_dist_BD7M9_5N();
83021
- var require_retired_settings_keys = require_retired_settings_keys_h7YxHNjB();
83047
+ var require_dist10 = require_dist_kUlalZ6();
83048
+ var require_retired_settings_keys = require_retired_settings_keys_D61YnSKJ();
83022
83049
  var node_crypto = __require("crypto");
83023
83050
  var node_fs = __require("fs");
83024
83051
  var node_module = __require("module");
@@ -83435,6 +83462,20 @@ var require_sqlite_settings_addon = __commonJS({
83435
83462
  clauses.push(`(${expr} IS NULL OR ${expr} != ?)`);
83436
83463
  params.push(serialize2(value));
83437
83464
  }
83465
+ for (const [field, values] of Object.entries(filter?.whereNotIn ?? {})) {
83466
+ const expr = resolve(field);
83467
+ if (expr === null) continue;
83468
+ if (values.length === 0) continue;
83469
+ const hasNull = values.some((v) => v === null);
83470
+ const rest = values.filter((v) => v !== null);
83471
+ if (rest.length === 0) {
83472
+ clauses.push(`${expr} IS NOT NULL`);
83473
+ continue;
83474
+ }
83475
+ const placeholders = rest.map(() => "?").join(", ");
83476
+ clauses.push(hasNull ? `(${expr} IS NOT NULL AND ${expr} NOT IN (${placeholders}))` : `(${expr} IS NULL OR ${expr} NOT IN (${placeholders}))`);
83477
+ for (const v of rest) params.push(serialize2(v));
83478
+ }
83438
83479
  if (clauses.length === 0 && mode === "mutate") throw new UnsafeFilterError("filter compiled to no predicate \u2014 that would affect every row in the collection; use the explicit clear operation if that is the intent");
83439
83480
  return {
83440
83481
  whereSql: clauses.length > 0 ? ` WHERE ${clauses.join(" AND ")}` : "",
@@ -85508,7 +85549,7 @@ var require_storage_orchestrator_addon = __commonJS({
85508
85549
  [Symbol.toStringTag]: { value: "Module" }
85509
85550
  });
85510
85551
  var require_chunk = require_chunk_Cek0wNdY();
85511
- var require_dist10 = require_dist_BD7M9_5N();
85552
+ var require_dist10 = require_dist_kUlalZ6();
85512
85553
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
85513
85554
  var zod = require_zod();
85514
85555
  var node_crypto = __require("crypto");
@@ -89064,7 +89105,7 @@ var require_system_config_addon = __commonJS({
89064
89105
  [Symbol.toStringTag]: { value: "Module" }
89065
89106
  });
89066
89107
  require_chunk_Cek0wNdY();
89067
- var require_dist10 = require_dist_BD7M9_5N();
89108
+ var require_dist10 = require_dist_kUlalZ6();
89068
89109
  var SECTION_TITLES = {
89069
89110
  server: "Server",
89070
89111
  auth: "Authentication"
@@ -107125,7 +107166,7 @@ var require_winston_logging = __commonJS({
107125
107166
  [Symbol.toStringTag]: { value: "Module" }
107126
107167
  });
107127
107168
  var require_chunk = require_chunk_Cek0wNdY();
107128
- var require_dist10 = require_dist_BD7M9_5N();
107169
+ var require_dist10 = require_dist_kUlalZ6();
107129
107170
  var require_formatter = require_formatter_DqAKDlvN();
107130
107171
  var node_path = __require("path");
107131
107172
  node_path = require_chunk.__toESM(node_path);
@@ -131735,7 +131776,7 @@ var require_dist3 = __commonJS({
131735
131776
  "use strict";
131736
131777
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
131737
131778
  var require_chunk = require_chunk_Cek0wNdY();
131738
- var require_dist10 = require_dist_BD7M9_5N();
131779
+ var require_dist10 = require_dist_kUlalZ6();
131739
131780
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
131740
131781
  require_alerts();
131741
131782
  var require_formatter = require_formatter_DqAKDlvN();
@@ -219420,6 +219461,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
219420
219461
  whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
219421
219462
  /** NULL-safe exclusion: matches rows whose field is NULL OR != the value. */
219422
219463
  whereNot: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
219464
+ /** NULL-safe exclusion of a SET — `whereNot` for more than one value. An
219465
+ * empty list excludes nothing. See `QueryFilter.whereNotIn`. */
219466
+ whereNotIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
219423
219467
  orderBy: zod.z.object({
219424
219468
  field: zod.z.string(),
219425
219469
  direction: zod.z.enum(["asc", "desc"])
@@ -219431,7 +219475,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
219431
219475
  where: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
219432
219476
  whereIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
219433
219477
  whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
219434
- whereNot: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
219478
+ whereNot: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
219479
+ whereNotIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional()
219435
219480
  });
219436
219481
  var AggregateFieldSchema = zod.z.object({
219437
219482
  /** Result key. */
@@ -227527,7 +227572,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
227527
227572
  * whose class list is unreadable are kept, and the client's rule stays the
227528
227573
  * exact one.
227529
227574
  */
227530
- classes: zod.z.array(zod.z.string()).optional()
227575
+ classes: zod.z.array(zod.z.string()).optional(),
227576
+ /** See {@link ExcludeSourcesDoc}. */
227577
+ excludeSources: zod.z.array(TrackSourceSchema).optional()
227531
227578
  });
227532
227579
  var SummarySchema = zod.z.object({
227533
227580
  id: zod.z.string(),
@@ -227876,7 +227923,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
227876
227923
  * selected is an operator who has not narrowed anything, and an empty
227877
227924
  * timeline would read as a camera that saw nothing.
227878
227925
  */
227879
- classes: zod.z.array(zod.z.string()).optional()
227926
+ classes: zod.z.array(zod.z.string()).optional(),
227927
+ /** See {@link ExcludeSourcesDoc}. */
227928
+ excludeSources: zod.z.array(TrackSourceSchema).optional()
227880
227929
  }), zod.z.array(TrackSchema).readonly()),
227881
227930
  /**
227882
227931
  * Batched cluster-wide track listing — ONE call for the events page /
@@ -237872,8 +237921,27 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
237872
237921
  });
237873
237922
  var PrivacyMaskStatusSchema = zod.z.object({
237874
237923
  enabled: zod.z.boolean(),
237875
- /** Active zones (normalized 0..1). Length ≤ maxRegions. */
237876
- regions: zod.z.array(PrivacyMaskRegionSchema),
237924
+ /**
237925
+ * Active zones (normalized 0..1). Length ≤ maxRegions.
237926
+ *
237927
+ * `null` means "no answer" — the provider has never reached this camera
237928
+ * (a cold `runtimeState` slice, a battery camera asleep) or the read
237929
+ * failed. A consumer must render it as UNKNOWN and never as "this camera
237930
+ * has no zones": those two look identical to an operator right up to the
237931
+ * moment one of them is acted on, and acting on them differs completely.
237932
+ * The switch group turned an unanswered read into *"nothing is set up for
237933
+ * it to act on"* — an instruction to go and draw a zone that already
237934
+ * exists — and this editor seeded an EMPTY canvas from it, one Save away
237935
+ * from deleting the mask it could not read.
237936
+ *
237937
+ * Empty-and-answered is `[]` and stays a real answer: this camera genuinely
237938
+ * has no zones. The distinction is the same one {@link
237939
+ * PrivacyMaskStatusSchema.shape.audioEnabled} already draws for the
237940
+ * microphone, on the very same payload — both planes come from ONE refresh,
237941
+ * so it was never coherent for one of them to be able to say "unknown"
237942
+ * while the other could not.
237943
+ */
237944
+ regions: zod.z.array(PrivacyMaskRegionSchema).nullable(),
237877
237945
  /**
237878
237946
  * Is the camera capturing sound right now? Read from the camera, never from
237879
237947
  * a server-side mirror.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.119",
3
+ "version": "1.2.121",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",