@camstack/types 1.2.254 → 1.2.256

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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Does a rule BELONG TO THE ALARM — and, with D640's chosen edge, can it then
3
+ * still fire at all?
4
+ *
5
+ * `ruleBelongsToAlarm` is D630's predicate: such a rule fires on an opening's
6
+ * OPENING edge only (the engine refuses a closing edge, `rule-engine.ts`). It
7
+ * lived in the engine alone; it is hoisted here because an EDITOR needs the
8
+ * same answer to warn about a rule that asks for the other edge — an alarm rule
9
+ * over contacts set to "only when it clears" passes every save check and never
10
+ * fires, and the operator was never told. One predicate, so the engine and the
11
+ * warning cannot disagree about which rules are the alarm.
12
+ *
13
+ * Structural inputs (conditions + the enabled `onTrigger` sequences), so the
14
+ * admin's form state and the engine's rule both answer without a cast.
15
+ */
16
+ import type { NcConditions, NcRuleActionSequence } from '../capabilities/notification-rules.cap.js';
17
+ /**
18
+ * The sensor-event kinds that are OPENINGS to the alarm — the keys of the
19
+ * engine's opening table (`alarm-openings.ts`, which is checked against this
20
+ * list with `satisfies`). Only these carry an opening edge the alarm refuses.
21
+ */
22
+ export declare const NC_ALARM_OPENING_EVENT_KINDS: readonly ["contact", "cover", "lock"];
23
+ export type NcAlarmOpeningEventKind = (typeof NC_ALARM_OPENING_EVENT_KINDS)[number];
24
+ /** What the alarm-membership question reads off a rule. */
25
+ export interface NcAlarmMembershipSubject {
26
+ readonly conditions: Pick<NcConditions, 'deviceState' | 'sensorKinds' | 'sensorTransition'>;
27
+ readonly onTrigger?: readonly NcRuleActionSequence[];
28
+ }
29
+ /**
30
+ * A rule belongs to the alarm when its `deviceState` gate names ANY device's
31
+ * `armed_*` word, or an ENABLED `onTrigger` sequence pulls the alarm panel's
32
+ * trigger (D630).
33
+ */
34
+ export declare function ruleBelongsToAlarm(rule: NcAlarmMembershipSubject): boolean;
35
+ /**
36
+ * An alarm rule over openings only, asking for the CLEAR: the alarm edge
37
+ * refuses every closing, and the chosen edge refuses every opening, so nothing
38
+ * is left (D640 × D630). Not refused on save — alarm membership is derived and
39
+ * can change with an action edit — but every editor must SAY it.
40
+ */
41
+ export declare function sensorTransitionNeverFires(rule: NcAlarmMembershipSubject): boolean;
42
+ /** The warning an editor shows for {@link sensorTransitionNeverFires}. */
43
+ export declare const NC_SENSOR_TRANSITION_NEVER_FIRES_WARNING = "This rule belongs to the alarm, and an alarm rule fires only when an opening OPENS. Set to \u201Conly when it clears\u201D, it can never fire.";
@@ -61,17 +61,34 @@
61
61
  * (`packages/addon-benchmark/vite.config.ts`) and therefore read whatever the
62
62
  * host loaded; nothing in this file is consumed that way. See
63
63
  * `docs/design/2026-08-19-viewer-notification-rule-parity.md` §3 and Phase 3.
64
+ *
65
+ * THREE SYSTEM KINDS, AND ONE THAT IS ONLY READ (D637)
66
+ * ────────────────────────────────────────────────────
67
+ * A `system-event` rule used to be ONE kind for every infrastructure event. It
68
+ * is now one kind per family (`device-events`, `system`, `alarm`), DERIVED from
69
+ * the event kinds the rule names (`system-event-families.ts`), exactly as sound
70
+ * and occupancy are derived from their condition. A stored rule whose kinds span
71
+ * families — or name a legacy kind, or none — derives `mixed`: it keeps firing,
72
+ * it is listed and deletable, and it is never edited.
64
73
  */
65
74
  import { type NcAudioCondition, type NcConditions, type NcDelivery, type NcOccupancyCondition } from '../capabilities/notification-rules.cap.js';
75
+ import { type NcSystemEventFamily } from './system-event-families.js';
66
76
  /**
67
77
  * The kind of rule an operator is authoring.
68
78
  *
69
79
  * Coarser than `delivery` in one direction and finer in another, deliberately:
70
80
  * `immediate` / `track-end` / `package-event` are ONE kind here (their
71
81
  * differences are already the catalog's `appliesTo` job), while `device-event`
72
- * and `immediate` each split in two on their discriminating condition.
82
+ * and `immediate` each split in two on their discriminating condition, and
83
+ * `system-event` splits by the FAMILY of the event kinds it names (D637).
73
84
  */
74
- export type NcRuleKind = 'detection' | 'sensor' | 'occupancy' | 'sound' | 'system';
85
+ export type NcRuleKind = 'detection' | 'sensor' | 'occupancy' | 'sound' | NcSystemEventFamily | 'mixed';
86
+ /** Every kind a `system-event` rule can derive — the three families and `mixed`. */
87
+ export declare const NC_SYSTEM_RULE_KINDS: readonly ["device-events", "system", "alarm", "mixed"];
88
+ /** Is this a kind a `system-event` rule derives (any family, or `mixed`)? */
89
+ export declare function isSystemRuleKind(kind: NcRuleKind | undefined): boolean;
90
+ /** The family a kind authors, or undefined (a camera kind, or `mixed`). */
91
+ export declare function systemFamilyOfKind(kind: NcRuleKind): NcSystemEventFamily | undefined;
75
92
  export interface NcRuleKindSpec {
76
93
  readonly kind: NcRuleKind;
77
94
  /** What the conditions section is CALLED for this kind (English fallback). */
@@ -81,6 +98,13 @@ export interface NcRuleKindSpec {
81
98
  * excluded — burying it would hide the whole feature (which is how an
82
99
  * operator with a working audio engine reported there was no way to create an
83
100
  * audio rule).
101
+ *
102
+ * NOT UNIQUE PER KIND. A GROUP of kinds may share one discriminator: the three
103
+ * system families and `mixed` all ride `systemEvent` (D637), and which of them
104
+ * a rule is comes from the event kinds, not from the condition's presence. A
105
+ * consumer that maps a discriminator back to ONE kind (a `Map` keyed on it)
106
+ * keeps the last spec and silently misroutes the others — ask
107
+ * {@link kindsForDiscriminator} for the whole group.
84
108
  */
85
109
  readonly discriminator?: keyof NcConditions;
86
110
  /**
@@ -89,6 +113,12 @@ export interface NcRuleKindSpec {
89
113
  * save is about to drop one.
90
114
  */
91
115
  readonly excluded: Readonly<Record<string, string>>;
116
+ /**
117
+ * false = readable and deletable, never edited. Only `mixed`: a rule that
118
+ * predates D637 and spans families. It keeps firing; the operator recreates
119
+ * it one rule per family.
120
+ */
121
+ readonly editable: boolean;
92
122
  /**
93
123
  * Can a notification of this kind carry a picture AT ALL?
94
124
  *
@@ -96,9 +126,9 @@ export interface NcRuleKindSpec {
96
126
  * ladder resolves media by OWNER, and only a subject that freezes one has any
97
127
  * (`triggerCanCarryStill` in the addon's `test-event.ts` is the same list).
98
128
  *
99
- * Only `system` is left. An infrastructure event is about no camera at all —
100
- * there is nothing to photograph, so every media control on it is a knob that
101
- * does nothing. A SOUND rule was here until 2026-08-15 and was right to be:
129
+ * Only the system-event kinds are left. An infrastructure event is about no
130
+ * camera at all — there is nothing to photograph, so every media control on it
131
+ * is a knob that does nothing. A SOUND rule was here until 2026-08-15 and was right to be:
102
132
  * its subject is a sampling window that owns no frame. It now photographs the
103
133
  * camera at the match instead (`still-shelf.ts`), which is a picture nothing
104
134
  * else could give it.
@@ -124,6 +154,12 @@ export interface NcRuleKindSpec {
124
154
  export declare const NC_RULE_KIND_SPECS: readonly NcRuleKindSpec[];
125
155
  /** The spec for a kind. Total by construction — every member has an entry. */
126
156
  export declare function ruleKindSpec(kind: NcRuleKind): NcRuleKindSpec;
157
+ /**
158
+ * Every kind a discriminator makes — one kind for `audio` and `occupancy`, the
159
+ * whole system group for `systemEvent`. Empty for a condition that makes no
160
+ * kind. See {@link NcRuleKindSpec.discriminator}.
161
+ */
162
+ export declare function kindsForDiscriminator(discriminator: keyof NcConditions): readonly NcRuleKind[];
127
163
  /** The delivery a system rule rides — named once, compared everywhere. */
128
164
  export declare const NC_SYSTEM_DELIVERY = "system-event";
129
165
  /**
@@ -171,9 +207,18 @@ export interface NcRuleSectionSubject {
171
207
  * the order below is the engine's own: `evaluateRule` checks the system branch
172
208
  * first, then the occupancy and audio gates. Takes a plain `delivery` string so
173
209
  * a trigger this build does not know still classifies (as `detection`, which is
174
- * the read-only path's own fallback).
210
+ * the read-only path's own fallback). A system rule classifies by the FAMILY of
211
+ * its event kinds (D637) — see {@link systemRuleKindOf}.
175
212
  */
176
213
  export declare function ruleKindOf(rule: NcRuleSectionSubject): NcRuleKind;
214
+ /**
215
+ * A system rule's kind: its one family, or `mixed` (D637).
216
+ *
217
+ * Takes the UNTYPED condition for the same reason {@link NcRuleConditionsSubject}
218
+ * is structural. `mixed` covers kinds across families, a legacy or unknown kind,
219
+ * and no kinds at all — it fails toward read-only, never toward editable.
220
+ */
221
+ export declare function systemRuleKindOf(condition: unknown): NcSystemEventFamily | 'mixed';
177
222
  /**
178
223
  * The shape {@link conditionVisibleForKind} reads off a catalog descriptor.
179
224
  *
@@ -226,10 +271,14 @@ export declare function droppedConditionsForKind(conditions: NcAuthoredCondition
226
271
  *
227
272
  * `all` is kept and is the DEFAULT: a section that hides rules is how an
228
273
  * operator concludes a rule was deleted. Which sections a given SURFACE offers
229
- * for authoring is that surface's decision — the viewer omits `system` from its
230
- * create flow and still renders system rules under `all`.
274
+ * for authoring is that surface's decision — the viewer omits the system-event
275
+ * sections from its create flow and still renders system rules under `all`.
276
+ *
277
+ * D637 split the one `system` section into the three families, plus `mixed`:
278
+ * the stored system rules that span families. `mixed` is a real, owning section
279
+ * (a rule must be listed somewhere) that nothing can CREATE into.
231
280
  */
232
- export type NcRuleSectionKey = 'all' | 'detection' | 'audio' | 'occupancy' | 'system';
281
+ export type NcRuleSectionKey = 'all' | 'detection' | 'audio' | 'occupancy' | 'device-events' | 'system' | 'alarm' | 'mixed';
233
282
  export interface NcRuleSection {
234
283
  readonly key: NcRuleSectionKey;
235
284
  /** English fallback; the viewer maps `key` onto an i18n key. */
@@ -240,6 +289,8 @@ export interface NcRuleSection {
240
289
  readonly newRuleLabel: string;
241
290
  /** What the section says when it holds nothing yet. */
242
291
  readonly emptyHint: string;
292
+ /** Can a rule be CREATED from this section? false only for `mixed` (D637). */
293
+ readonly creatable: boolean;
243
294
  }
244
295
  export declare const NC_RULE_SECTIONS: readonly NcRuleSection[];
245
296
  /** The section for a key, or `undefined` — the lookup behind every label. */
@@ -254,8 +305,9 @@ export declare function isOccupancyRule(subject: NcRuleSectionSubject): boolean;
254
305
  * Does a rule belong in this section?
255
306
  *
256
307
  * `all` always matches — a section that hides a rule is how an operator
257
- * concludes it was deleted. The other four PARTITION the list: sound and
258
- * occupancy are claimed by their condition, system by its trigger, and
308
+ * concludes it was deleted. The others PARTITION the list: sound and
309
+ * occupancy are claimed by their condition, a system-event rule by its trigger
310
+ * and then by the family of its event kinds (or `mixed`, D637), and
259
311
  * everything left over — including a trigger this build has never heard of —
260
312
  * counts as a detection rule so it stays visible somewhere.
261
313
  *
@@ -271,8 +323,9 @@ export type NcRuleOwningSectionKey = Exclude<NcRuleSectionKey, 'all'>;
271
323
  /**
272
324
  * Which section OWNS this rule — the counter behind a section strip.
273
325
  *
274
- * Derived from {@link ruleMatchesSection} rather than restated, so the strip's
275
- * counts and the strip's contents can never disagree.
326
+ * The same order as {@link ruleMatchesSection} — trigger first, then the
327
+ * discriminating condition — and the section spec asserts the two agree on
328
+ * every subject, so the strip's counts and its contents cannot disagree.
276
329
  */
277
330
  export declare function ruleSectionOf(subject: NcRuleSectionSubject): NcRuleOwningSectionKey;
278
331
  /**
@@ -310,6 +363,10 @@ export declare const NC_AUDIO_SEED: NcAudioCondition;
310
363
  * on a trigger they must pick first. That is exactly the gap reported on
311
364
  * 2026-08-13 ("non vedo un modo per creare le nuove rules audio e occupancy")
312
365
  * for two features whose engines had already shipped.
366
+ *
367
+ * A system seed carries its event kinds for the same reason: the kind is derived
368
+ * from them (D637), so an empty seed would open a `mixed` rule. `mixed` itself
369
+ * falls to the default and is never offered — its section is not `creatable`.
313
370
  */
314
371
  export interface NcRuleSeed extends NcRuleSectionSubject {
315
372
  readonly delivery: NcDelivery;
@@ -349,7 +406,7 @@ export interface NcRuleEditorSection {
349
406
  *
350
407
  * Two rules, both of them about a control that would decide nothing:
351
408
  *
352
- * - a `system-event` rule has no device scope — `conditions.devices` is not
409
+ * - a system-event rule (any family) has no device scope — `conditions.devices` is not
353
410
  * evaluated for it and the input builder refuses to write it — so the
354
411
  * Cameras section is DROPPED rather than shown and ignored;
355
412
  * - a sound or occupancy rule is NAMED on its conditions section. Neither has
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Nodes and packages as a PICKER lists them (D637). One projection shared by the
3
+ * admin UI and the viewer, so the system family's two pickers group and label
4
+ * the same way. The shape is structurally the pickers' `PickerItem<string>`.
5
+ */
6
+ import type { NodeDirectoryEntry } from '../capabilities/nodes.cap.js';
7
+ export interface NcScopePickerItem {
8
+ readonly id: string;
9
+ readonly name: string;
10
+ readonly type?: string;
11
+ readonly location?: string | null;
12
+ readonly detail?: string;
13
+ }
14
+ export declare function nodePickerItems(nodes: readonly NodeDirectoryEntry[]): readonly NcScopePickerItem[];
15
+ /**
16
+ * The server's own package name: `server-update-available` / `server-updated`
17
+ * carry it, and `addons.listPackages` does not list it.
18
+ */
19
+ export declare const NC_SERVER_PACKAGE_NAME = "@camstack/server";
20
+ /**
21
+ * Every package name an update EVENT carries as `packageName`, one per
22
+ * producer. The package picker offers each of them whether or not
23
+ * `addons.listPackages` lists it, because a rule scoped to a name no event
24
+ * carries can never fire (and one an event carries must be pickable).
25
+ *
26
+ * - `@camstack/server` — `server-update-available` / `server-updated`: the hub
27
+ * root package (`HUB_ROOT_SPEC.packageName`, `@camstack/node-root`).
28
+ * - `@camstack/system` — `server-update-available` from the framework check,
29
+ * which checks `[SYSTEM_PACKAGE]` only (`AddonPackageService.listFrameworkPackages`).
30
+ * `@camstack/types` / `@camstack/sdk` are framework packages for upload
31
+ * routing but are never announced, so they are NOT here.
32
+ * - `camstack-wrapper` — `wrapper-update-available` (`WRAPPER_PACKAGE_NAME`,
33
+ * `wrapper-update-checker.ts`).
34
+ *
35
+ * Types cannot import those producers; the backend spec
36
+ * `core/updates/__tests__/update-event-package-names.spec.ts` pins each literal
37
+ * to its producer constant. This is a picker list, never a routing list.
38
+ */
39
+ export declare const NC_UPDATE_EVENT_PACKAGE_NAMES: readonly ["@camstack/server", "@camstack/system", "camstack-wrapper"];
40
+ export interface NcInstalledPackageLike {
41
+ readonly name: string;
42
+ readonly version: string;
43
+ }
44
+ /**
45
+ * Every update-event package first (always offered: an event carries it), in
46
+ * `NC_UPDATE_EVENT_PACKAGE_NAMES` order, then the installed addons sorted by
47
+ * name. An installed version is the second line.
48
+ */
49
+ export declare function packagePickerItems(packages: readonly NcInstalledPackageLike[]): readonly NcScopePickerItem[];
@@ -0,0 +1,45 @@
1
+ /**
2
+ * WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
3
+ * persists (D640 "a sensor rule fires on the raise, the clear, or both").
4
+ *
5
+ * A device-event rule over a flood sensor notified on BOTH edges: water
6
+ * detected, and back to dry. `NcConditions.sensorTransition` lets the rule
7
+ * name one edge; this file answers, for one `SensorEvent`, which edge it is.
8
+ *
9
+ * NOT A SECOND TABLE. The "which boolean of this cap counts as HIGH" question
10
+ * already has one answer, `SOURCE_CAP_ACTIVE_FIELD`
11
+ * (`catalogs/sensor-active-state.ts`, the doorbell's and the recorder's edge
12
+ * table), and a sensor event names its kind, not its cap. So the table here is
13
+ * DERIVED: event kind → cap (`EVENT_KIND_BY_CAP`) → that cap's active field.
14
+ * Only kinds whose taxonomy category is `sensor` take part — a switch has an
15
+ * `on` boolean too, but "it triggers / it clears" is not a sentence about a
16
+ * light, and offering it there would be a knob with a misleading label.
17
+ * `presence` is a WORD (`home` / `not_home` / a zone), not a boolean, and is
18
+ * absent from the source table, so it is absent here.
19
+ *
20
+ * `undefined` = never guessed: a kind with no raise (a doorbell press, a
21
+ * button, a cover), or a slice whose field is missing or not a boolean. The
22
+ * engine then does NOT filter — a flood alert must not go silent because one
23
+ * read came back unreadable (the same stance as the alarm's `sensorEdgeOf`).
24
+ *
25
+ * Pure, RN-safe: the viewer imports the support rule from here.
26
+ */
27
+ /** Event kind → the boolean field of its cap slice that means "raised". */
28
+ export declare const NC_SENSOR_RAISED_FIELD_BY_KIND: Readonly<Record<string, string>>;
29
+ /** The sensor kinds `sensorTransition` means something for. */
30
+ export declare const NC_SENSOR_TRANSITION_KINDS: readonly string[];
31
+ /**
32
+ * true = the sensor is raised (water, smoke, open, tampered…), false = it
33
+ * cleared, undefined = this kind has no raise or the slice cannot say.
34
+ */
35
+ export declare function sensorRaisedOf(kind: string, value: Readonly<Record<string, unknown>> | null): boolean | undefined;
36
+ /**
37
+ * THE SUPPORT RULE, shared by both editors: "Notify when" is offered only when
38
+ * the rule names at least one sensor kind and EVERY kind it names has a raise.
39
+ * A mixed rule (flood + doorbell) would hear "only when it clears" as "never
40
+ * for the doorbell" in the operator's head while the engine lets the doorbell
41
+ * through — so the choice is not offered, and an editor prunes it on save.
42
+ */
43
+ export declare function sensorTransitionOffered(sensorKinds: readonly string[] | undefined): boolean;
44
+ /** What an editor tells the operator when it is about to prune the choice. */
45
+ export declare const NC_SENSOR_TRANSITION_UNSUPPORTED_REASON = "Only a sensor that raises and clears (water, smoke, gas, CO, vibration, tamper, motion, contact) can fire on one edge. Pick only such sensor kinds, or the rule fires on every change.";
@@ -0,0 +1,76 @@
1
+ /**
2
+ * WHICH FAMILY every system-event kind belongs to, and which narrowing filters
3
+ * each family may carry: one table, read by the hub validator, by `ruleKindOf`
4
+ * and by both rule editors (D637).
5
+ *
6
+ * A system rule used to be one editor for thirty-one kinds and five filters.
7
+ * "Eventi di sistema" carried battery kinds under a liveness `deviceTypes` filter
8
+ * and went silent for two weeks (D636). The three families are three questions:
9
+ * about devices, about the installation, and about the alarm panel. A rule
10
+ * answers one of them. The engine never needed to know, and it still does not:
11
+ * a mixed stored rule keeps firing. Only AUTHORING is strict.
12
+ *
13
+ * The legacy `camera-*` tail has no family (`null`). It is parsed, never produced,
14
+ * never offered.
15
+ */
16
+ import { type NcSystemEventCondition, type NcSystemEventKind } from '../capabilities/notification-rules.cap.js';
17
+ import { type NcSystemEventFilterKey } from './system-event-filters.js';
18
+ export declare const NC_SYSTEM_EVENT_FAMILIES: readonly ["device-events", "system", "alarm"];
19
+ export type NcSystemEventFamily = (typeof NC_SYSTEM_EVENT_FAMILIES)[number];
20
+ export declare function isSystemEventFamily(value: string): value is NcSystemEventFamily;
21
+ /** Total over the enum: a kind added to the cap without a family fails tsc here. */
22
+ export declare const NC_SYSTEM_EVENT_FAMILY: Readonly<Record<NcSystemEventKind, NcSystemEventFamily | null>>;
23
+ /** A condition field that can narrow or exclude a system subject. */
24
+ export type NcSystemEventConditionFilterKey = NcSystemEventFilterKey | 'excludeDeviceIds';
25
+ export declare const NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS: readonly NcSystemEventConditionFilterKey[];
26
+ /**
27
+ * The filters a family may carry. The four base filters are the union of
28
+ * `systemEventFilterApplies` over the family's kinds (the spec pins that
29
+ * equality). `excludeDeviceIds` is a device-events filter only: an alarm is
30
+ * narrowed to the camera that triggered it and excludes nothing.
31
+ */
32
+ export declare const NC_SYSTEM_EVENT_FAMILY_FILTERS: Readonly<Record<NcSystemEventFamily, readonly NcSystemEventConditionFilterKey[]>>;
33
+ /** A themed set of kinds as both editors list them. `label` is an English fallback. */
34
+ export interface NcSystemEventKindGroupSpec {
35
+ readonly id: string;
36
+ readonly family: NcSystemEventFamily;
37
+ readonly label: string;
38
+ readonly kinds: readonly NcSystemEventKind[];
39
+ }
40
+ export declare const NC_SYSTEM_EVENT_KIND_GROUP_SPECS: readonly NcSystemEventKindGroupSpec[];
41
+ export declare function systemEventKindsOfFamily(family: NcSystemEventFamily): readonly NcSystemEventKind[];
42
+ /** The kind names on an UNTYPED condition, or `undefined` when it has none. */
43
+ export declare function systemEventKindNamesOf(condition: unknown): readonly string[] | undefined;
44
+ export type NcSystemEventFamilyVerdict = {
45
+ readonly kind: 'family';
46
+ readonly family: NcSystemEventFamily;
47
+ } | {
48
+ readonly kind: 'mixed';
49
+ };
50
+ /**
51
+ * One family, or `mixed`. Mixed covers kinds that span families, a legacy kind,
52
+ * a kind this build does not know (it fails toward read-only and never toward
53
+ * editable), and an empty selection (nothing to decide on).
54
+ */
55
+ export declare function systemEventFamilyOf(kindNames: readonly string[]): NcSystemEventFamilyVerdict;
56
+ export type NcSystemEventFamilyProblem = {
57
+ readonly code: 'no-kinds';
58
+ } | {
59
+ readonly code: 'legacy-kind';
60
+ readonly kind: NcSystemEventKind;
61
+ } | {
62
+ readonly code: 'mixed-families';
63
+ readonly families: readonly NcSystemEventFamily[];
64
+ } | {
65
+ readonly code: 'filter-outside-family';
66
+ readonly filter: NcSystemEventConditionFilterKey;
67
+ readonly family: NcSystemEventFamily;
68
+ };
69
+ /**
70
+ * Why the hub refuses this condition on a new or updated rule. Empty = accepted.
71
+ * Families are reported in `NC_SYSTEM_EVENT_FAMILIES` order, and filters in
72
+ * `NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS` order, so a refusal reads the same
73
+ * every time.
74
+ */
75
+ export declare function systemEventFamilyProblems(condition: NcSystemEventCondition | undefined): readonly NcSystemEventFamilyProblem[];
76
+ export declare function describeSystemEventFamilyProblem(problem: NcSystemEventFamilyProblem): string;
@@ -8,10 +8,31 @@
8
8
  * `addon-post-analysis` run each producer and compare its keys with this list,
9
9
  * so the two cannot drift silently again.
10
10
  */
11
- import { NcRuleKindSchema, NcTemplateFamilySchema, NcTemplateFieldSchema, NcTemplateVarContextSchema, NcTemplateVarDescriptorSchema, NcTemplateVarGroupSchema, type NcTemplateVarContext, type NcTemplateVarDescriptor } from '../capabilities/notification-rules.cap.js';
11
+ import { NcRuleKindSchema, NcTemplateFamilySchema, NcTemplateFieldSchema, NcTemplateVarContextSchema, NcTemplateVarDescriptorSchema, NcTemplateVarGroupSchema, type NcTemplateVarContext, type NcTemplateVarDescriptor, type NcTemplateVarKind } from '../capabilities/notification-rules.cap.js';
12
+ import { type NcRuleKind } from './rule-kinds.js';
12
13
  export { NcRuleKindSchema, NcTemplateFamilySchema, NcTemplateFieldSchema, NcTemplateVarContextSchema, NcTemplateVarDescriptorSchema, NcTemplateVarGroupSchema, };
13
14
  export type { NcTemplateFamily, NcTemplateField, NcTemplateVarContext, NcTemplateVarDescriptor, NcTemplateVarGroup, } from '../capabilities/notification-rules.cap.js';
14
15
  export declare const NC_TEMPLATE_VARS: readonly NcTemplateVarDescriptor[];
16
+ /**
17
+ * Does a descriptor declared for `declared` kinds have a value for a rule of
18
+ * `kind`?
19
+ *
20
+ * `system` on the WIRE stands for every system rule kind (D637): the served
21
+ * catalog keeps the five pre-D637 tokens so installed viewers still parse it
22
+ * (`NcTemplateVarKindSchema`), and the family split lives here, in the match.
23
+ * Exported so the admin's local interpreter of the served catalog asks the
24
+ * same question instead of restating it.
25
+ */
26
+ export declare function templateVarKindApplies(declared: readonly NcTemplateVarKind[] | undefined, kind: NcRuleKind | undefined): boolean;
27
+ /**
28
+ * Is a descriptor that names `systemEventKinds` on the event-kind axis of a
29
+ * system rule? Read only for a system rule kind; any other kind ignores it.
30
+ *
31
+ * Event kinds chosen: the descriptor must speak about one of them. None chosen
32
+ * yet: a FAMILY kind watches its own family's event kinds (a device-events rule
33
+ * is never offered the alarm's `{{mode}}`), and `mixed` watches all of them.
34
+ */
35
+ export declare function templateVarSystemEventApplies(d: NcTemplateVarDescriptor, ctx: NcTemplateVarContext): boolean;
15
36
  /**
16
37
  * The variables that have a value in `ctx`, in catalog order. Pure.
17
38
  *
@@ -3752,6 +3752,7 @@ function createDeviceProxy(api, binding, opts) {
3752
3752
  getTemplateCatalog: (input) => dispatch("notification-rules", "notificationRules", "getTemplateCatalog", "query", input),
3753
3753
  previewTemplate: (input) => dispatch("notification-rules", "notificationRules", "previewTemplate", "mutation", input),
3754
3754
  getHistory: (input) => dispatch("notification-rules", "notificationRules", "getHistory", "query", input),
3755
+ getRuleLastRuns: (input) => dispatch("notification-rules", "notificationRules", "getRuleLastRuns", "query", input),
3755
3756
  resolveArtifactUrl: (input) => dispatch("notification-rules", "notificationRules", "resolveArtifactUrl", "query", input),
3756
3757
  listSnoozes: (input) => dispatch("notification-rules", "notificationRules", "listSnoozes", "query", input),
3757
3758
  createSnooze: (input) => dispatch("notification-rules", "notificationRules", "createSnooze", "mutation", input),
@@ -3752,6 +3752,7 @@ function createDeviceProxy(api, binding, opts) {
3752
3752
  getTemplateCatalog: (input) => dispatch("notification-rules", "notificationRules", "getTemplateCatalog", "query", input),
3753
3753
  previewTemplate: (input) => dispatch("notification-rules", "notificationRules", "previewTemplate", "mutation", input),
3754
3754
  getHistory: (input) => dispatch("notification-rules", "notificationRules", "getHistory", "query", input),
3755
+ getRuleLastRuns: (input) => dispatch("notification-rules", "notificationRules", "getRuleLastRuns", "query", input),
3755
3756
  resolveArtifactUrl: (input) => dispatch("notification-rules", "notificationRules", "resolveArtifactUrl", "query", input),
3756
3757
  listSnoozes: (input) => dispatch("notification-rules", "notificationRules", "listSnoozes", "query", input),
3757
3758
  createSnooze: (input) => dispatch("notification-rules", "notificationRules", "createSnooze", "mutation", input),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.254",
3
+ "version": "1.2.256",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",