@camstack/types 1.2.88 → 1.2.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capabilities/recording.cap.d.ts +7 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +378 -3
- package/dist/index.mjs +358 -4
- package/dist/notification/rule-kinds.d.ts +348 -0
- package/package.json +1 -1
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rule-kinds — WHICH KIND OF RULE THIS IS, WHICH FIELDS IT ACTUALLY HAS, AND
|
|
3
|
+
* WHICH LIST SECTION IT LIVES IN. Pure, UI-framework-free, RN-safe.
|
|
4
|
+
*
|
|
5
|
+
* WHY IT LIVES HERE
|
|
6
|
+
* ─────────────────
|
|
7
|
+
* Two editors author the same rules — the admin UI (React DOM, shipped with
|
|
8
|
+
* `camstack deploy`) and the viewer (React Native / Hermes, shipped by EAS OTA)
|
|
9
|
+
* — and the layer they were NOT sharing is this one: not the schema (already
|
|
10
|
+
* shared) and not the widgets (they cannot be), but the model in between.
|
|
11
|
+
* The divergence it caused is on the record: the viewer filtered conditions on
|
|
12
|
+
* the served `appliesTo` alone, so a viewer-authored occupancy rule was still
|
|
13
|
+
* offered `sensorKinds`, `eventTypeTokens` and `source` — the exact "in
|
|
14
|
+
* occupancy alcuni campi non hanno senso" failure the admin UI fixed on
|
|
15
|
+
* 2026-08-14 and the viewer never got. Beside it, the viewer's rule list had no
|
|
16
|
+
* sections and no seeded creates, so the two features that have no delivery of
|
|
17
|
+
* their own (sound, occupancy) were unauthorable from the phone.
|
|
18
|
+
*
|
|
19
|
+
* The CONTENT is what makes a second copy expensive: a dozen exclusions, each
|
|
20
|
+
* traced to a subject field the engine reads and finds absent, each carrying
|
|
21
|
+
* the sentence shown to the operator. Two tables disagreeing about which fields
|
|
22
|
+
* an occupancy rule has is the same failure as two knobs writing a store nobody
|
|
23
|
+
* read.
|
|
24
|
+
*
|
|
25
|
+
* THE MISSING DIMENSION
|
|
26
|
+
* ─────────────────────
|
|
27
|
+
* The editor had exactly ONE dimension of applicability, the rule's `delivery`,
|
|
28
|
+
* which the served catalog answers through `appliesTo`. Two features have no
|
|
29
|
+
* delivery of their own:
|
|
30
|
+
*
|
|
31
|
+
* - an OCCUPANCY rule is a `device-event` rule carrying `conditions.occupancy`
|
|
32
|
+
* - a SOUND rule is an `immediate` rule carrying `conditions.audio`
|
|
33
|
+
*
|
|
34
|
+
* and the engine discriminates them by that CONDITION (`rule-engine.ts`: an
|
|
35
|
+
* occupancy edge fires only for a rule declaring `occupancy`, a confirmed audio
|
|
36
|
+
* window only for one declaring `audio`). So an occupancy rule was offered the
|
|
37
|
+
* whole `device-event` surface — sensor kinds, raw event tokens, a detection
|
|
38
|
+
* source — every one of which the engine FAILS CLOSED on an occupancy subject,
|
|
39
|
+
* because the subject carries no `sensorKind`, no `eventType` and always the
|
|
40
|
+
* `pipeline` source.
|
|
41
|
+
*
|
|
42
|
+
* This module adds that dimension: `delivery` × `kind`. Visibility is the
|
|
43
|
+
* COMPOSITION of the two — `appliesTo` still answers the trigger question (it is
|
|
44
|
+
* the server's answer and stays authoritative), and the kind subtracts what the
|
|
45
|
+
* sub-type cannot use. Every subtraction is declared WITH ITS REASON and the
|
|
46
|
+
* reason is shown to the operator rather than kept in a comment.
|
|
47
|
+
*
|
|
48
|
+
* LABELS ARE ENGLISH FALLBACKS, NOT TRANSLATIONS. The stable thing here is the
|
|
49
|
+
* ID (`kind`, section `key`, editor-section `key`); the admin UI renders these
|
|
50
|
+
* strings verbatim, the viewer maps the ids onto its `v2.nc.rules.*` i18n keys
|
|
51
|
+
* and falls back to them.
|
|
52
|
+
*
|
|
53
|
+
* The admin UI keeps a pinned local copy for now — `@camstack/types` reaches it
|
|
54
|
+
* as a Module-Federation singleton provided by the HOST, so a newly-added export
|
|
55
|
+
* reads `undefined` there until a server closure carrying it is installed. See
|
|
56
|
+
* `docs/design/2026-08-19-viewer-notification-rule-parity.md` §3 and Phase 3.
|
|
57
|
+
*/
|
|
58
|
+
import { type NcAudioCondition, type NcConditions, type NcDelivery, type NcOccupancyCondition } from '../capabilities/notification-rules.cap.js';
|
|
59
|
+
/**
|
|
60
|
+
* The kind of rule an operator is authoring.
|
|
61
|
+
*
|
|
62
|
+
* Coarser than `delivery` in one direction and finer in another, deliberately:
|
|
63
|
+
* `immediate` / `track-end` / `package-event` are ONE kind here (their
|
|
64
|
+
* differences are already the catalog's `appliesTo` job), while `device-event`
|
|
65
|
+
* and `immediate` each split in two on their discriminating condition.
|
|
66
|
+
*/
|
|
67
|
+
export type NcRuleKind = 'detection' | 'sensor' | 'occupancy' | 'sound' | 'system';
|
|
68
|
+
export interface NcRuleKindSpec {
|
|
69
|
+
readonly kind: NcRuleKind;
|
|
70
|
+
/** What the conditions section is CALLED for this kind (English fallback). */
|
|
71
|
+
readonly label: string;
|
|
72
|
+
/**
|
|
73
|
+
* The condition that MAKES a rule this kind. Always visible, and never
|
|
74
|
+
* excluded — burying it would hide the whole feature (which is how an
|
|
75
|
+
* operator with a working audio engine reported there was no way to create an
|
|
76
|
+
* audio rule).
|
|
77
|
+
*/
|
|
78
|
+
readonly discriminator?: keyof NcConditions;
|
|
79
|
+
/**
|
|
80
|
+
* Conditions the catalog offers for this kind's DELIVERY that a rule of this
|
|
81
|
+
* kind cannot use, each with the engine reason — shown to the operator when a
|
|
82
|
+
* save is about to drop one.
|
|
83
|
+
*/
|
|
84
|
+
readonly excluded: Readonly<Record<string, string>>;
|
|
85
|
+
/**
|
|
86
|
+
* Can a notification of this kind carry a picture AT ALL?
|
|
87
|
+
*
|
|
88
|
+
* `false` is not a UI preference, it is the delivery path: the attachment
|
|
89
|
+
* ladder resolves media by OWNER, and only a subject that freezes one has any
|
|
90
|
+
* (`triggerCanCarryStill` in the addon's `test-event.ts` is the same list).
|
|
91
|
+
*
|
|
92
|
+
* Only `system` is left. An infrastructure event is about no camera at all —
|
|
93
|
+
* there is nothing to photograph, so every media control on it is a knob that
|
|
94
|
+
* does nothing. A SOUND rule was here until 2026-08-15 and was right to be:
|
|
95
|
+
* its subject is a sampling window that owns no frame. It now photographs the
|
|
96
|
+
* camera at the match instead (`still-shelf.ts`), which is a picture nothing
|
|
97
|
+
* else could give it.
|
|
98
|
+
*/
|
|
99
|
+
readonly carriesMedia: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Does anything about this kind's subject describe a REGION of the frame?
|
|
102
|
+
*
|
|
103
|
+
* `false` removes the two controls that cut one — the zone crop and the image
|
|
104
|
+
* frame — because neither has an input. A sound was not boxed and carries no
|
|
105
|
+
* zone condition to crop to, so `frame: 'cropped'` resolves nothing and
|
|
106
|
+
* `zoneCrop` has no ids to use. Same argument as `excluded`, applied to the
|
|
107
|
+
* media policy instead of the conditions: a knob that decides nothing is
|
|
108
|
+
* worse than a missing one, because the operator sets it and believes they
|
|
109
|
+
* have asked for something.
|
|
110
|
+
*/
|
|
111
|
+
readonly carriesSubjectCrop: boolean;
|
|
112
|
+
/** One line under the section title — what this kind of rule IS. */
|
|
113
|
+
readonly blurb?: string;
|
|
114
|
+
/** One line above the media controls, when the picture needs explaining. */
|
|
115
|
+
readonly mediaBlurb?: string;
|
|
116
|
+
}
|
|
117
|
+
export declare const NC_RULE_KIND_SPECS: readonly NcRuleKindSpec[];
|
|
118
|
+
/** The spec for a kind. Total by construction — every member has an entry. */
|
|
119
|
+
export declare function ruleKindSpec(kind: NcRuleKind): NcRuleKindSpec;
|
|
120
|
+
/** The delivery a system rule rides — named once, compared everywhere. */
|
|
121
|
+
export declare const NC_SYSTEM_DELIVERY = "system-event";
|
|
122
|
+
/**
|
|
123
|
+
* Is this a SYSTEM rule — one about the installation rather than about anything
|
|
124
|
+
* a camera saw? Takes a plain `string` so a rule carrying a delivery this build
|
|
125
|
+
* has never heard of still gets an answer instead of a type error.
|
|
126
|
+
*/
|
|
127
|
+
export declare function isSystemDelivery(delivery: string): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* The conditions of a rule, as much of them as classification needs.
|
|
130
|
+
*
|
|
131
|
+
* DELIBERATELY STRUCTURAL, and this is load-bearing. The viewer keeps its OWN
|
|
132
|
+
* Zod mirror of the rule schema on purpose (older/newer hub tolerance —
|
|
133
|
+
* `camstack/src/data/notification-center.ts`), so a parameter typed as THIS
|
|
134
|
+
* package's `NcConditions` would be unusable from the surface this module was
|
|
135
|
+
* hoisted for without a cast, and this repo does not take casts. Two optional
|
|
136
|
+
* `unknown`s is the whole question the classifier asks.
|
|
137
|
+
*/
|
|
138
|
+
export interface NcRuleConditionsSubject {
|
|
139
|
+
readonly occupancy?: unknown;
|
|
140
|
+
readonly audio?: unknown;
|
|
141
|
+
}
|
|
142
|
+
/** Every authored condition, keyed by descriptor id — same reasoning as above. */
|
|
143
|
+
export type NcAuthoredConditions = Readonly<Record<string, unknown>>;
|
|
144
|
+
/** What both the kind and the section ask a rule about. */
|
|
145
|
+
export interface NcRuleSectionSubject {
|
|
146
|
+
readonly delivery: string;
|
|
147
|
+
readonly conditions: NcRuleConditionsSubject;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Which kind of rule is this?
|
|
151
|
+
*
|
|
152
|
+
* The CONDITION wins over the delivery wherever the engine says it does, and
|
|
153
|
+
* the order below is the engine's own: `evaluateRule` checks the system branch
|
|
154
|
+
* first, then the occupancy and audio gates. Takes a plain `delivery` string so
|
|
155
|
+
* a trigger this build does not know still classifies (as `detection`, which is
|
|
156
|
+
* the read-only path's own fallback).
|
|
157
|
+
*/
|
|
158
|
+
export declare function ruleKindOf(rule: NcRuleSectionSubject): NcRuleKind;
|
|
159
|
+
/**
|
|
160
|
+
* The shape {@link conditionVisibleForKind} reads off a catalog descriptor.
|
|
161
|
+
*
|
|
162
|
+
* `appliesTo` is `readonly string[]`, not `readonly NcDelivery[]`: the catalog
|
|
163
|
+
* arrives at RUNTIME from a server that may be newer than this build, and each
|
|
164
|
+
* editor parses it through its own mirror. Narrowing the parameter to this
|
|
165
|
+
* package's union would reject the viewer's descriptor for a nominal reason
|
|
166
|
+
* while the value is identical.
|
|
167
|
+
*/
|
|
168
|
+
export interface NcKindVisibilitySubject {
|
|
169
|
+
readonly id: string;
|
|
170
|
+
readonly appliesTo: readonly string[];
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Is this condition visible — and authorable — for a rule of this kind?
|
|
174
|
+
*
|
|
175
|
+
* The COMPOSITION, and the only function that decides it: `appliesTo` is the
|
|
176
|
+
* server's answer about the trigger, the kind's `excluded` map is this build's
|
|
177
|
+
* answer about the sub-type, and the discriminator overrides both (a sound rule
|
|
178
|
+
* must be able to edit its sound even though `audio` is excluded for every
|
|
179
|
+
* OTHER kind that rides `immediate`).
|
|
180
|
+
*/
|
|
181
|
+
export declare function conditionVisibleForKind(descriptor: NcKindVisibilitySubject, delivery: string, kind: NcRuleKind): boolean;
|
|
182
|
+
/** Why a condition is not offered for this kind, or `null` when it IS. */
|
|
183
|
+
export declare function conditionExclusionReason(descriptorId: string, kind: NcRuleKind): string | null;
|
|
184
|
+
/**
|
|
185
|
+
* Conditions the rule CARRIES that this kind cannot use — the save will drop
|
|
186
|
+
* them, and the operator is told which and why BEFORE pressing Save.
|
|
187
|
+
*
|
|
188
|
+
* Dropping is the right action and not a compromise: every entry here is a
|
|
189
|
+
* condition the engine fails closed on for this subject, so the rule is
|
|
190
|
+
* currently enabled, in the list, and permanently silent. Keeping it would keep
|
|
191
|
+
* it silent; dropping it is what makes the rule fire again. Saying nothing
|
|
192
|
+
* about the drop would be the third option, and it is the one this repo has
|
|
193
|
+
* paid for before.
|
|
194
|
+
*/
|
|
195
|
+
export interface NcDroppedCondition {
|
|
196
|
+
readonly conditionId: string;
|
|
197
|
+
readonly reason: string;
|
|
198
|
+
}
|
|
199
|
+
export declare function droppedConditionsForKind(conditions: NcAuthoredConditions, kind: NcRuleKind): readonly NcDroppedCondition[];
|
|
200
|
+
/**
|
|
201
|
+
* The sections a rule LIST is split into.
|
|
202
|
+
*
|
|
203
|
+
* Operator request, 2026-08-13: "vorrei che le system rules fossero in una
|
|
204
|
+
* sezione a parte, più facile da utilizzare, affianco alle detection rules". A
|
|
205
|
+
* system rule and a detection rule share a store and nothing else — different
|
|
206
|
+
* triggers, different conditions, no media, a different question ("is my
|
|
207
|
+
* installation healthy?" vs "what did the camera see?").
|
|
208
|
+
*
|
|
209
|
+
* `all` is kept and is the DEFAULT: a section that hides rules is how an
|
|
210
|
+
* operator concludes a rule was deleted. Which sections a given SURFACE offers
|
|
211
|
+
* for authoring is that surface's decision — the viewer omits `system` from its
|
|
212
|
+
* create flow and still renders system rules under `all`.
|
|
213
|
+
*/
|
|
214
|
+
export type NcRuleSectionKey = 'all' | 'detection' | 'audio' | 'occupancy' | 'system';
|
|
215
|
+
export interface NcRuleSection {
|
|
216
|
+
readonly key: NcRuleSectionKey;
|
|
217
|
+
/** English fallback; the viewer maps `key` onto an i18n key. */
|
|
218
|
+
readonly label: string;
|
|
219
|
+
/** Shown under the section strip — what this section is for. */
|
|
220
|
+
readonly blurb: string;
|
|
221
|
+
/** The create button's words in this section — it authors a DIFFERENT rule. */
|
|
222
|
+
readonly newRuleLabel: string;
|
|
223
|
+
/** What the section says when it holds nothing yet. */
|
|
224
|
+
readonly emptyHint: string;
|
|
225
|
+
}
|
|
226
|
+
export declare const NC_RULE_SECTIONS: readonly NcRuleSection[];
|
|
227
|
+
/** The section for a key, or `undefined` — the lookup behind every label. */
|
|
228
|
+
export declare function ruleSection(key: NcRuleSectionKey): NcRuleSection;
|
|
229
|
+
/** Narrow a raw section string back to a known key (no cast). */
|
|
230
|
+
export declare function parseRuleSection(value: string): NcRuleSectionKey | undefined;
|
|
231
|
+
/** True for a rule whose sound condition makes it a SOUND rule. */
|
|
232
|
+
export declare function isAudioRule(subject: NcRuleSectionSubject): boolean;
|
|
233
|
+
/** True for a rule whose occupancy condition makes it an OCCUPANCY rule. */
|
|
234
|
+
export declare function isOccupancyRule(subject: NcRuleSectionSubject): boolean;
|
|
235
|
+
/**
|
|
236
|
+
* Does a rule belong in this section?
|
|
237
|
+
*
|
|
238
|
+
* `all` always matches — a section that hides a rule is how an operator
|
|
239
|
+
* concludes it was deleted. The other four PARTITION the list: sound and
|
|
240
|
+
* occupancy are claimed by their condition, system by its trigger, and
|
|
241
|
+
* everything left over — including a trigger this build has never heard of —
|
|
242
|
+
* counts as a detection rule so it stays visible somewhere.
|
|
243
|
+
*
|
|
244
|
+
* Keyed on the CONDITION for two of them, because the trigger alone cannot
|
|
245
|
+
* answer: a sound rule is `immediate` and an occupancy rule is `device-event`,
|
|
246
|
+
* and in each case the condition is the discriminator the engine itself uses.
|
|
247
|
+
* A section keyed on delivery would put both back in the pile they are
|
|
248
|
+
* invisible in.
|
|
249
|
+
*/
|
|
250
|
+
export declare function ruleMatchesSection(subject: NcRuleSectionSubject, section: NcRuleSectionKey): boolean;
|
|
251
|
+
/** The ONE real section a rule lives in — `all` holds everything and is not it. */
|
|
252
|
+
export type NcRuleOwningSectionKey = Exclude<NcRuleSectionKey, 'all'>;
|
|
253
|
+
/**
|
|
254
|
+
* Which section OWNS this rule — the counter behind a section strip.
|
|
255
|
+
*
|
|
256
|
+
* Derived from {@link ruleMatchesSection} rather than restated, so the strip's
|
|
257
|
+
* counts and the strip's contents can never disagree.
|
|
258
|
+
*/
|
|
259
|
+
export declare function ruleSectionOf(subject: NcRuleSectionSubject): NcRuleOwningSectionKey;
|
|
260
|
+
/**
|
|
261
|
+
* The occupancy schema's own defaults, in one place.
|
|
262
|
+
*
|
|
263
|
+
* Both the WIDGET (what an untouched sub-field shows) and the CREATION PRESET
|
|
264
|
+
* (what "New occupancy rule" seeds) have to author exactly these numbers, and
|
|
265
|
+
* two copies of a default is how a preset starts writing a rule that does not
|
|
266
|
+
* match what the editor then displays. Mirrors `NcOccupancyConditionSchema`'s
|
|
267
|
+
* `.default(...)` clauses, and the spec asserts the mirror.
|
|
268
|
+
*/
|
|
269
|
+
export declare const NC_OCCUPANCY_DEFAULTS: NcOccupancyCondition;
|
|
270
|
+
/**
|
|
271
|
+
* The seeded sound condition.
|
|
272
|
+
*
|
|
273
|
+
* Carries a level floor rather than the bare defaults: with neither a level nor
|
|
274
|
+
* a label the engine returns false for every window (`matchesAudio`), so a
|
|
275
|
+
* preset without one would hand the operator a rule that can never fire. The
|
|
276
|
+
* offered level is the same one the widget writes, so switching to SOUNDS
|
|
277
|
+
* (label mode — the one that fires on the first labelled frame, D157) is one
|
|
278
|
+
* tap on the mode picker.
|
|
279
|
+
*
|
|
280
|
+
* The seed cannot be a label rule instead: a labels-only condition with no
|
|
281
|
+
* labels chosen yet is fail-closed too, and it would hand the operator the same
|
|
282
|
+
* dead rule from the other side.
|
|
283
|
+
*/
|
|
284
|
+
export declare const NC_AUDIO_SEED: NcAudioCondition;
|
|
285
|
+
/**
|
|
286
|
+
* What a "New rule" started from a section opens on.
|
|
287
|
+
*
|
|
288
|
+
* A trigger alone was enough while every section WAS a trigger. It is not for
|
|
289
|
+
* sound and occupancy: the condition is what makes the rule that kind of rule,
|
|
290
|
+
* so the preset seeds it — otherwise the operator lands on a form identical to
|
|
291
|
+
* a detection rule's and has to know that the feature lives behind an expander
|
|
292
|
+
* on a trigger they must pick first. That is exactly the gap reported on
|
|
293
|
+
* 2026-08-13 ("non vedo un modo per creare le nuove rules audio e occupancy")
|
|
294
|
+
* for two features whose engines had already shipped.
|
|
295
|
+
*/
|
|
296
|
+
export interface NcRuleSeed extends NcRuleSectionSubject {
|
|
297
|
+
readonly delivery: NcDelivery;
|
|
298
|
+
/** Pre-authored conditions — the ones that DEFINE the kind, nothing else. */
|
|
299
|
+
readonly conditions: NcConditions;
|
|
300
|
+
}
|
|
301
|
+
export declare function ruleSeedForSection(section: NcRuleSectionKey): NcRuleSeed;
|
|
302
|
+
/** The trigger a "New rule" in this section should open on. */
|
|
303
|
+
export declare function defaultDeliveryForSection(section: NcRuleSectionKey): NcDelivery;
|
|
304
|
+
/**
|
|
305
|
+
* The rule editor's sections, in the order an operator meets them.
|
|
306
|
+
*
|
|
307
|
+
* Operator request, 2026-08-04 (admin) and 2026-08-18 (viewer): the editor was
|
|
308
|
+
* ONE scrolling form holding every setting a rule has, so authoring a simple
|
|
309
|
+
* rule meant scrolling past everything a simple rule does not need. Ordered by
|
|
310
|
+
* how often a setting is touched — not by how the schema is shaped.
|
|
311
|
+
*
|
|
312
|
+
* The admin renders them as dialog TABS and the viewer as one scroll of
|
|
313
|
+
* headings (a phone scrolls; dialog tabs are a desktop idiom), and the viewer
|
|
314
|
+
* renders a SUBSET — but the ORDER is shared, because two surfaces that put the
|
|
315
|
+
* same five things in two different orders are two features to learn.
|
|
316
|
+
*
|
|
317
|
+
* The `fields` claim map stays per-surface: each editor's form state is its own
|
|
318
|
+
* type, and each side's spec asserts every field of ITS form is claimed exactly
|
|
319
|
+
* once. What is shared is which sections exist, in what order, and which ones a
|
|
320
|
+
* kind shows at all.
|
|
321
|
+
*/
|
|
322
|
+
export type NcRuleEditorSectionKey = 'rule' | 'devices' | 'conditions' | 'notification' | 'actions' | 'advanced';
|
|
323
|
+
export declare const NC_RULE_EDITOR_SECTION_ORDER: readonly NcRuleEditorSectionKey[];
|
|
324
|
+
export interface NcRuleEditorSection {
|
|
325
|
+
readonly key: NcRuleEditorSectionKey;
|
|
326
|
+
/** English fallback; the viewer maps `key` onto an i18n key. */
|
|
327
|
+
readonly label: string;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* The sections a rule of THIS kind actually shows.
|
|
331
|
+
*
|
|
332
|
+
* Two rules, both of them about a control that would decide nothing:
|
|
333
|
+
*
|
|
334
|
+
* - a `system-event` rule has no device scope — `conditions.devices` is not
|
|
335
|
+
* evaluated for it and the input builder refuses to write it — so the
|
|
336
|
+
* Cameras section is DROPPED rather than shown and ignored;
|
|
337
|
+
* - a sound or occupancy rule is NAMED on its conditions section. Neither has
|
|
338
|
+
* a trigger of its own, so that section is the only place either feature
|
|
339
|
+
* exists, and a heading that never mentions sound is exactly why an operator
|
|
340
|
+
* with a working audio engine reported there was no way to create an audio
|
|
341
|
+
* rule.
|
|
342
|
+
*
|
|
343
|
+
* The NOTIFICATION section always survives: priority and the template still
|
|
344
|
+
* matter even for a kind that carries no picture, and dropping the section to
|
|
345
|
+
* hide the media controls would take the template with it. Whether the media
|
|
346
|
+
* half renders is `carriesMedia` / `carriesSubjectCrop`, asked separately.
|
|
347
|
+
*/
|
|
348
|
+
export declare function ruleEditorSectionsForKind(kind: NcRuleKind): readonly NcRuleEditorSection[];
|