@camstack/types 1.2.15 → 1.2.17

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 (60) hide show
  1. package/dist/addon.d.ts +1 -0
  2. package/dist/addon.js +265 -1
  3. package/dist/addon.mjs +264 -2
  4. package/dist/capabilities/addons.cap.d.ts +7 -7
  5. package/dist/capabilities/backup.cap.d.ts +73 -1
  6. package/dist/capabilities/broker.cap.d.ts +8 -8
  7. package/dist/capabilities/camera-streams.cap.d.ts +5 -5
  8. package/dist/capabilities/climate-control.cap.d.ts +8 -8
  9. package/dist/capabilities/day-night.cap.d.ts +8 -8
  10. package/dist/capabilities/decoder.cap.d.ts +2 -2
  11. package/dist/capabilities/device-manager.cap.d.ts +2 -2
  12. package/dist/capabilities/face-gallery.cap.d.ts +1 -1
  13. package/dist/capabilities/image-settings.cap.d.ts +16 -16
  14. package/dist/capabilities/index.d.ts +1 -1
  15. package/dist/capabilities/intercom.cap.d.ts +6 -6
  16. package/dist/capabilities/lawn-mower-control.cap.d.ts +4 -4
  17. package/dist/capabilities/llm-runtime.cap.d.ts +3 -3
  18. package/dist/capabilities/llm.cap.d.ts +4 -4
  19. package/dist/capabilities/local-network.cap.d.ts +38 -0
  20. package/dist/capabilities/media-player.cap.d.ts +9 -9
  21. package/dist/capabilities/metrics-provider.cap.d.ts +2 -2
  22. package/dist/capabilities/mqtt-broker.cap.d.ts +3 -3
  23. package/dist/capabilities/notification-output.cap.d.ts +4 -0
  24. package/dist/capabilities/notification-rules.cap.d.ts +236 -18
  25. package/dist/capabilities/pipeline-analytics.cap.d.ts +64 -27
  26. package/dist/capabilities/pipeline-executor.cap.d.ts +2 -2
  27. package/dist/capabilities/pipeline-orchestrator.cap.d.ts +15 -15
  28. package/dist/capabilities/pipeline-runner.cap.d.ts +2 -2
  29. package/dist/capabilities/recording-export.cap.d.ts +7 -7
  30. package/dist/capabilities/recording.cap.d.ts +102 -129
  31. package/dist/capabilities/schemas/orchestrator-metrics.d.ts +2 -2
  32. package/dist/capabilities/schemas/streaming-shared.d.ts +4 -4
  33. package/dist/capabilities/storage-provider.cap.d.ts +44 -0
  34. package/dist/capabilities/storage.cap.d.ts +17 -0
  35. package/dist/capabilities/stream-broker.cap.d.ts +58 -12
  36. package/dist/capabilities/webrtc-session.cap.d.ts +6 -6
  37. package/dist/generated/addon-api.d.ts +5365 -30879
  38. package/dist/generated/cap-input-defaults.d.ts +29 -0
  39. package/dist/generated/device-proxy.d.ts +2 -2
  40. package/dist/generated/method-access-map.d.ts +1 -1
  41. package/dist/generated/system-proxy.d.ts +3 -3
  42. package/dist/index.d.ts +2 -1
  43. package/dist/index.js +693 -139
  44. package/dist/index.mjs +684 -136
  45. package/dist/interfaces/addon.d.ts +9 -0
  46. package/dist/interfaces/ops-log.d.ts +2 -0
  47. package/dist/interfaces/recording-config.d.ts +33 -91
  48. package/dist/interfaces/relocate.d.ts +55 -0
  49. package/dist/interfaces/storage-location-declaration.d.ts +1 -0
  50. package/dist/interfaces/storage-location.d.ts +4 -0
  51. package/dist/interfaces/stream-broker.d.ts +1 -1
  52. package/dist/lifecycle/job.d.ts +6 -6
  53. package/dist/node.js +1 -0
  54. package/dist/node.mjs +1 -0
  55. package/dist/notification/condition-taxonomy.d.ts +61 -0
  56. package/dist/notification/format-transcode.d.ts +12 -1
  57. package/dist/{sleep-C3ceNSsf.mjs → sleep-Ct4Is70g.mjs} +6 -0
  58. package/dist/{sleep-DRg9F6JJ.js → sleep-yfPaamGa.js} +6 -0
  59. package/package.json +1 -1
  60. package/dist/interfaces/recording-config-migrate.d.ts +0 -12
@@ -326,6 +326,15 @@ export interface IKernelServices {
326
326
  readonly capName: string;
327
327
  readonly deviceId: number;
328
328
  }>;
329
+ /**
330
+ * Node-routed capability proxy (hub-side builtins only): every method call
331
+ * on the returned object forwards to `capName`'s provider ON `nodeId` via
332
+ * the cluster transport — the same routing the generated cap routers use
333
+ * for `{nodeId}` inputs. Null when the capability is not reachable on that
334
+ * node. Lets a hub builtin (e.g. storage-orchestrator) execute work WHERE
335
+ * the data lives instead of assuming its own filesystem.
336
+ */
337
+ readonly resolveNodeCapability?: (capName: string, nodeId: string) => Record<string, (params: unknown) => Promise<unknown>> | null;
329
338
  }
330
339
  /**
331
340
  * Canonical hwaccel backend names. Accepted by both the `ffmpeg` CLI
@@ -22,6 +22,7 @@ export declare const OpsLogOpSchema: z.ZodEnum<{
22
22
  "manual-delete": "manual-delete";
23
23
  rescan: "rescan";
24
24
  "retention-run": "retention-run";
25
+ relocate: "relocate";
25
26
  }>;
26
27
  export type OpsLogOp = z.infer<typeof OpsLogOpSchema>;
27
28
  /** Why the operation ran. */
@@ -45,6 +46,7 @@ export declare const OpsLogEntrySchema: z.ZodObject<{
45
46
  "manual-delete": "manual-delete";
46
47
  rescan: "rescan";
47
48
  "retention-run": "retention-run";
49
+ relocate: "relocate";
48
50
  }>;
49
51
  reason: z.ZodEnum<{
50
52
  manual: "manual";
@@ -26,31 +26,15 @@ export type EventPadMs = typeof EVENT_PAD_MS;
26
26
  */
27
27
  export declare const RecordingWeekdaySchema: z.ZodNumber;
28
28
  export type RecordingWeekday = z.infer<typeof RecordingWeekdaySchema>;
29
- export declare const RecordingScheduleSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
30
- kind: z.ZodLiteral<"always">;
31
- }, z.core.$strip>, z.ZodObject<{
32
- kind: z.ZodLiteral<"timeOfDay">;
33
- start: z.ZodString;
34
- end: z.ZodString;
35
- days: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
36
- }, z.core.$strip>], "kind">;
37
- export type RecordingSchedule = z.infer<typeof RecordingScheduleSchema>;
38
- export declare const RecordingModeSchema: z.ZodEnum<{
39
- onMotion: "onMotion";
40
- continuous: "continuous";
41
- onAudioThreshold: "onAudioThreshold";
42
- }>;
43
- export type RecordingMode = z.infer<typeof RecordingModeSchema>;
44
29
  /**
45
- * First-class, authoritative per-camera storage mode — the explicit choice the
46
- * UI reads directly (never inferred from `rules`):
47
- * - `off` — not recording.
48
- * - `events` — record only around triggers (motion / audio threshold),
49
- * with pre/post-buffer.
50
- * - `continuous` — record 24/7 within the schedule.
30
+ * DERIVED per-camera storage summary — the single field cheap consumers read
31
+ * (the viewer's status dot, the camera list) instead of walking `bands`:
32
+ * - `off` — no band covers the camera (or it is disabled).
33
+ * - `events` — every band records around triggers only.
34
+ * - `continuous` — at least one band records continuously.
51
35
  *
52
- * `mode` compiles one-way to the internal `rules[]` consumed by the policy
53
- * engine (see `compileRules`); `rules[]` is never authored directly anymore.
36
+ * NEVER authored: the recorder stamps it from the authoritative `bands` on
37
+ * every save (`activeModeForConfig`). Writing it has no effect.
54
38
  */
55
39
  export declare const RecordingStorageModeSchema: z.ZodEnum<{
56
40
  events: "events";
@@ -58,7 +42,7 @@ export declare const RecordingStorageModeSchema: z.ZodEnum<{
58
42
  continuous: "continuous";
59
43
  }>;
60
44
  export type RecordingStorageMode = z.infer<typeof RecordingStorageModeSchema>;
61
- /** Which detectors trigger an `events`-mode recording. */
45
+ /** Which detectors trigger an `events`-mode band. */
62
46
  export declare const RecordingTriggersSchema: z.ZodObject<{
63
47
  motion: z.ZodOptional<z.ZodBoolean>;
64
48
  audioThresholdDbfs: z.ZodOptional<z.ZodNumber>;
@@ -110,26 +94,6 @@ export declare const RecordingBandSchema: z.ZodObject<{
110
94
  postBufferSec: z.ZodOptional<z.ZodNumber>;
111
95
  }, z.core.$strip>;
112
96
  export type RecordingBand = z.infer<typeof RecordingBandSchema>;
113
- export declare const RecordingRuleSchema: z.ZodObject<{
114
- schedule: z.ZodDiscriminatedUnion<[z.ZodObject<{
115
- kind: z.ZodLiteral<"always">;
116
- }, z.core.$strip>, z.ZodObject<{
117
- kind: z.ZodLiteral<"timeOfDay">;
118
- start: z.ZodString;
119
- end: z.ZodString;
120
- days: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
121
- }, z.core.$strip>], "kind">;
122
- mode: z.ZodEnum<{
123
- onMotion: "onMotion";
124
- continuous: "continuous";
125
- onAudioThreshold: "onAudioThreshold";
126
- }>;
127
- preBufferSec: z.ZodDefault<z.ZodNumber>;
128
- postBufferSec: z.ZodDefault<z.ZodNumber>;
129
- resetTimeoutOnNewEvent: z.ZodDefault<z.ZodBoolean>;
130
- thresholdDbfs: z.ZodOptional<z.ZodNumber>;
131
- }, z.core.$strip>;
132
- export type RecordingRule = z.infer<typeof RecordingRuleSchema>;
133
97
  /**
134
98
  * Per-device retention overrides. Every field is optional; an unset or `0`
135
99
  * value inherits the node-wide recorder default. Only footage-lifetime limits
@@ -193,10 +157,14 @@ export declare function resolveScrubThumbnailGeometry(preset: ScrubThumbnailPres
193
157
  /**
194
158
  * The full per-camera recording intent — the wire shape of a RecordingTarget.
195
159
  *
196
- * `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
197
- * are its mode-specific parameters. `rules` is a DEPRECATED authoring input kept
198
- * only for transition + migration (`migrateRulesToMode`); the policy engine
199
- * consumes the compiled output of `compileRules(config)`, never `rules` directly.
160
+ * `bands` is the ONLY authored recording intent: what to record, when, and on
161
+ * which trigger. `mode` is a derived summary the recorder stamps on save; every
162
+ * other field is a storage knob (profiles, segment length, retention, scrub).
163
+ *
164
+ * STRICT on purpose: the legacy authoring surface (`schedule`/`schedules`/
165
+ * `triggers`/`preBufferSec`/`postBufferSec`/`rules`) was retired 2026-07-30.
166
+ * A stale caller must fail loudly — silently stripping its legacy intent would
167
+ * persist a band-less config, i.e. silently stop recording the camera.
200
168
  */
201
169
  export declare const RecordingConfigSchema: z.ZodObject<{
202
170
  enabled: z.ZodBoolean;
@@ -211,48 +179,7 @@ export declare const RecordingConfigSchema: z.ZodObject<{
211
179
  low: "low";
212
180
  }>>>;
213
181
  segmentSeconds: z.ZodOptional<z.ZodNumber>;
214
- schedules: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
215
- kind: z.ZodLiteral<"always">;
216
- }, z.core.$strip>, z.ZodObject<{
217
- kind: z.ZodLiteral<"timeOfDay">;
218
- start: z.ZodString;
219
- end: z.ZodString;
220
- days: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
221
- }, z.core.$strip>], "kind">>>;
222
- schedule: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
223
- kind: z.ZodLiteral<"always">;
224
- }, z.core.$strip>, z.ZodObject<{
225
- kind: z.ZodLiteral<"timeOfDay">;
226
- start: z.ZodString;
227
- end: z.ZodString;
228
- days: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
229
- }, z.core.$strip>], "kind">>;
230
- triggers: z.ZodOptional<z.ZodObject<{
231
- motion: z.ZodOptional<z.ZodBoolean>;
232
- audioThresholdDbfs: z.ZodOptional<z.ZodNumber>;
233
- }, z.core.$strip>>;
234
- preBufferSec: z.ZodOptional<z.ZodNumber>;
235
- postBufferSec: z.ZodOptional<z.ZodNumber>;
236
- rules: z.ZodOptional<z.ZodArray<z.ZodObject<{
237
- schedule: z.ZodDiscriminatedUnion<[z.ZodObject<{
238
- kind: z.ZodLiteral<"always">;
239
- }, z.core.$strip>, z.ZodObject<{
240
- kind: z.ZodLiteral<"timeOfDay">;
241
- start: z.ZodString;
242
- end: z.ZodString;
243
- days: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
244
- }, z.core.$strip>], "kind">;
245
- mode: z.ZodEnum<{
246
- onMotion: "onMotion";
247
- continuous: "continuous";
248
- onAudioThreshold: "onAudioThreshold";
249
- }>;
250
- preBufferSec: z.ZodDefault<z.ZodNumber>;
251
- postBufferSec: z.ZodDefault<z.ZodNumber>;
252
- resetTimeoutOnNewEvent: z.ZodDefault<z.ZodBoolean>;
253
- thresholdDbfs: z.ZodOptional<z.ZodNumber>;
254
- }, z.core.$strip>>>;
255
- bands: z.ZodOptional<z.ZodArray<z.ZodObject<{
182
+ bands: z.ZodDefault<z.ZodArray<z.ZodObject<{
256
183
  days: z.ZodArray<z.ZodNumber>;
257
184
  start: z.ZodString;
258
185
  end: z.ZodString;
@@ -278,5 +205,20 @@ export declare const RecordingConfigSchema: z.ZodObject<{
278
205
  max: "max";
279
206
  minimal: "minimal";
280
207
  }>>;
281
- }, z.core.$strip>;
208
+ stripsEnabled: z.ZodOptional<z.ZodBoolean>;
209
+ }, z.core.$strict>;
282
210
  export type RecordingConfig = z.infer<typeof RecordingConfigSchema>;
211
+ /** The bands + enabled flag a mode is derived from — all {@link deriveRecordingMode} reads. */
212
+ export type RecordingModeSource = Pick<RecordingConfig, 'enabled' | 'bands'>;
213
+ /**
214
+ * Derive the {@link RecordingStorageModeSchema} summary from the authoritative
215
+ * bands: `continuous` when any band records continuously, `events` when a band
216
+ * exists at all, else `off`. Pure.
217
+ *
218
+ * THE one definition: the recorder stamps `config.mode` with it on save and
219
+ * reports it as the cap's `activeMode`, and the settings UI reads it back to
220
+ * decide which authoring tab a config opens in. Two copies would drift, and the
221
+ * symptom (a status dot disagreeing with what is being recorded) is exactly the
222
+ * bug this field was added to fix.
223
+ */
224
+ export declare function deriveRecordingMode(config: RecordingModeSource): RecordingStorageMode;
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Entity-relocation job state (storage entity-routing spec, Phase 4).
4
+ *
5
+ * One shape shared by the recorder's `relocateFootage` (segments + strips) and
6
+ * pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
7
+ * page renders both movers with one component. Jobs are in-RAM (a restart
8
+ * forgets them — re-running is safe by construction: copy-if-absent, delete
9
+ * after verify) and each completed/failed run also lands one durable ops-log
10
+ * row on the owning addon's surface.
11
+ */
12
+ export declare const RelocateJobStateSchema: z.ZodEnum<{
13
+ running: "running";
14
+ done: "done";
15
+ failed: "failed";
16
+ cancelled: "cancelled";
17
+ }>;
18
+ export type RelocateJobState = z.infer<typeof RelocateJobStateSchema>;
19
+ export declare const RelocateJobSchema: z.ZodObject<{
20
+ jobId: z.ZodString;
21
+ state: z.ZodEnum<{
22
+ running: "running";
23
+ done: "done";
24
+ failed: "failed";
25
+ cancelled: "cancelled";
26
+ }>;
27
+ fromLocationId: z.ZodString;
28
+ toLocationId: z.ZodString;
29
+ deviceId: z.ZodNullable<z.ZodNumber>;
30
+ entities: z.ZodArray<z.ZodString>;
31
+ filesMoved: z.ZodNumber;
32
+ bytesMoved: z.ZodNumber;
33
+ filesTotal: z.ZodNullable<z.ZodNumber>;
34
+ startedAt: z.ZodNumber;
35
+ finishedAt: z.ZodNullable<z.ZodNumber>;
36
+ error: z.ZodNullable<z.ZodString>;
37
+ }, z.core.$strip>;
38
+ export type RelocateJob = z.infer<typeof RelocateJobSchema>;
39
+ export declare const RelocateFootageInputSchema: z.ZodObject<{
40
+ deviceId: z.ZodOptional<z.ZodNumber>;
41
+ fromLocationId: z.ZodString;
42
+ toLocationId: z.ZodString;
43
+ entities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
44
+ segments: "segments";
45
+ strips: "strips";
46
+ }>>>;
47
+ throttleMbps: z.ZodOptional<z.ZodNumber>;
48
+ }, z.core.$strip>;
49
+ export type RelocateFootageInput = z.infer<typeof RelocateFootageInputSchema>;
50
+ export declare const RelocateMediaInputSchema: z.ZodObject<{
51
+ deviceId: z.ZodOptional<z.ZodNumber>;
52
+ toLocationId: z.ZodString;
53
+ throttleMbps: z.ZodOptional<z.ZodNumber>;
54
+ }, z.core.$strip>;
55
+ export type RelocateMediaInput = z.infer<typeof RelocateMediaInputSchema>;
@@ -30,6 +30,7 @@ export declare const StorageLocationDeclarationSchema: z.ZodObject<{
30
30
  defaultsTo: z.ZodOptional<z.ZodString>;
31
31
  defaultRoot: z.ZodOptional<z.ZodEnum<{
32
32
  data: "data";
33
+ backup: "backup";
33
34
  media: "media";
34
35
  }>>;
35
36
  }, z.core.$strip>;
@@ -48,6 +48,10 @@ export declare const StorageLocationSchema: z.ZodObject<{
48
48
  nodeId: z.ZodOptional<z.ZodString>;
49
49
  isDefault: z.ZodDefault<z.ZodBoolean>;
50
50
  isSystem: z.ZodDefault<z.ZodBoolean>;
51
+ capacity: z.ZodOptional<z.ZodNullable<z.ZodObject<{
52
+ totalBytes: z.ZodNumber;
53
+ availableBytes: z.ZodNumber;
54
+ }, z.core.$strip>>>;
51
55
  createdAt: z.ZodNumber;
52
56
  updatedAt: z.ZodNumber;
53
57
  }, z.core.$strip>;
@@ -28,8 +28,8 @@ export declare const DecoderSessionConfigSchema: z.ZodObject<{
28
28
  deviceId: z.ZodOptional<z.ZodNumber>;
29
29
  tag: z.ZodOptional<z.ZodString>;
30
30
  frameSink: z.ZodDefault<z.ZodEnum<{
31
- callback: "callback";
32
31
  shm: "shm";
32
+ callback: "callback";
33
33
  }>>;
34
34
  debug: z.ZodOptional<z.ZodBoolean>;
35
35
  }, z.core.$strip>;
@@ -7,7 +7,6 @@ export declare const jobKindSchema: z.ZodEnum<{
7
7
  }>;
8
8
  export type JobKind = z.infer<typeof jobKindSchema>;
9
9
  export declare const taskPhaseSchema: z.ZodEnum<{
10
- failed: "failed";
11
10
  queued: "queued";
12
11
  fetching: "fetching";
13
12
  staged: "staged";
@@ -16,6 +15,7 @@ export declare const taskPhaseSchema: z.ZodEnum<{
16
15
  restarting: "restarting";
17
16
  applied: "applied";
18
17
  done: "done";
18
+ failed: "failed";
19
19
  skipped: "skipped";
20
20
  }>;
21
21
  export type TaskPhase = z.infer<typeof taskPhaseSchema>;
@@ -29,7 +29,6 @@ export declare const taskLogEntrySchema: z.ZodObject<{
29
29
  nodeId: z.ZodString;
30
30
  packageName: z.ZodString;
31
31
  phase: z.ZodEnum<{
32
- failed: "failed";
33
32
  queued: "queued";
34
33
  fetching: "fetching";
35
34
  staged: "staged";
@@ -38,6 +37,7 @@ export declare const taskLogEntrySchema: z.ZodObject<{
38
37
  restarting: "restarting";
39
38
  applied: "applied";
40
39
  done: "done";
40
+ failed: "failed";
41
41
  skipped: "skipped";
42
42
  }>;
43
43
  message: z.ZodString;
@@ -54,7 +54,6 @@ export declare const lifecycleTaskSchema: z.ZodObject<{
54
54
  addon: "addon";
55
55
  }>;
56
56
  phase: z.ZodEnum<{
57
- failed: "failed";
58
57
  queued: "queued";
59
58
  fetching: "fetching";
60
59
  staged: "staged";
@@ -63,6 +62,7 @@ export declare const lifecycleTaskSchema: z.ZodObject<{
63
62
  restarting: "restarting";
64
63
  applied: "applied";
65
64
  done: "done";
65
+ failed: "failed";
66
66
  skipped: "skipped";
67
67
  }>;
68
68
  stagedPath: z.ZodNullable<z.ZodString>;
@@ -72,7 +72,6 @@ export declare const lifecycleTaskSchema: z.ZodObject<{
72
72
  nodeId: z.ZodString;
73
73
  packageName: z.ZodString;
74
74
  phase: z.ZodEnum<{
75
- failed: "failed";
76
75
  queued: "queued";
77
76
  fetching: "fetching";
78
77
  staged: "staged";
@@ -81,6 +80,7 @@ export declare const lifecycleTaskSchema: z.ZodObject<{
81
80
  restarting: "restarting";
82
81
  applied: "applied";
83
82
  done: "done";
83
+ failed: "failed";
84
84
  skipped: "skipped";
85
85
  }>;
86
86
  message: z.ZodString;
@@ -130,7 +130,6 @@ export declare const lifecycleJobSchema: z.ZodObject<{
130
130
  addon: "addon";
131
131
  }>;
132
132
  phase: z.ZodEnum<{
133
- failed: "failed";
134
133
  queued: "queued";
135
134
  fetching: "fetching";
136
135
  staged: "staged";
@@ -139,6 +138,7 @@ export declare const lifecycleJobSchema: z.ZodObject<{
139
138
  restarting: "restarting";
140
139
  applied: "applied";
141
140
  done: "done";
141
+ failed: "failed";
142
142
  skipped: "skipped";
143
143
  }>;
144
144
  stagedPath: z.ZodNullable<z.ZodString>;
@@ -148,7 +148,6 @@ export declare const lifecycleJobSchema: z.ZodObject<{
148
148
  nodeId: z.ZodString;
149
149
  packageName: z.ZodString;
150
150
  phase: z.ZodEnum<{
151
- failed: "failed";
152
151
  queued: "queued";
153
152
  fetching: "fetching";
154
153
  staged: "staged";
@@ -157,6 +156,7 @@ export declare const lifecycleJobSchema: z.ZodObject<{
157
156
  restarting: "restarting";
158
157
  applied: "applied";
159
158
  done: "done";
159
+ failed: "failed";
160
160
  skipped: "skipped";
161
161
  }>;
162
162
  message: z.ZodString;
package/dist/node.js CHANGED
@@ -517,6 +517,7 @@ var FilesystemStorageProvider = class {
517
517
  this.locationPaths.set(loc, node_path.isAbsolute(subdir) ? subdir : node_path.join(this.rootPath, subdir));
518
518
  }
519
519
  }
520
+ for (const [loc, override] of Object.entries(overrides ?? {})) if (typeof override === "string" && !this.locationPaths.has(loc)) this.locationPaths.set(loc, node_path.resolve(override));
520
521
  }
521
522
  async resolve({ location, relativePath }) {
522
523
  const base = this.locationPaths.get(location) ?? node_path.join(this.rootPath, location);
package/dist/node.mjs CHANGED
@@ -494,6 +494,7 @@ var FilesystemStorageProvider = class {
494
494
  this.locationPaths.set(loc, path.isAbsolute(subdir) ? subdir : path.join(this.rootPath, subdir));
495
495
  }
496
496
  }
497
+ for (const [loc, override] of Object.entries(overrides ?? {})) if (typeof override === "string" && !this.locationPaths.has(loc)) this.locationPaths.set(loc, path.resolve(override));
497
498
  }
498
499
  async resolve({ location, relativePath }) {
499
500
  const base = this.locationPaths.get(location) ?? path.join(this.rootPath, location);
@@ -0,0 +1,61 @@
1
+ /**
2
+ * condition-taxonomy — pure mapping from a notification-rule condition id to a
3
+ * grouped picker model, driven by the server's `NcTaxonomy` (video classes +
4
+ * audio kinds + sensor/control labels).
5
+ *
6
+ * WHY IT LIVES HERE
7
+ * ─────────────────
8
+ * It was written in the viewer and is the correct model — macro→sub grouping,
9
+ * translated headers with an English fallback, free text kept as a deliberate
10
+ * escape hatch. The admin UI had none of it and rendered every list condition
11
+ * as a free-text tag input, so an operator had to TYPE `person` / `vehicle`
12
+ * from memory and type a zone's *id* rather than pick its name, and a typo
13
+ * produced a rule that silently never matched.
14
+ *
15
+ * Copying it into the admin UI would leave two implementations of "which
16
+ * vocabulary backs which condition" free to drift. It is UI-framework-free by
17
+ * construction, so it is hoisted here — beside `degrade-engine.ts`, the
18
+ * existing precedent for pure notification logic in this package — and both
19
+ * surfaces consume it.
20
+ *
21
+ * A condition with no fixed vocabulary (identities, plates, raw event tokens,
22
+ * admin zone ids) returns `null` and keeps its free-text input. Conditions WITH
23
+ * a vocabulary keep free text too, as an escape hatch for values the taxonomy
24
+ * does not know.
25
+ */
26
+ import type { NcTaxonomy } from '../catalogs/nc-taxonomy.js';
27
+ /** One selectable option inside a picker group. */
28
+ export interface TaxonomyOption {
29
+ readonly value: string;
30
+ readonly label: string;
31
+ }
32
+ /** A labelled group of options (rendered under a translated header). */
33
+ export interface TaxonomyGroup {
34
+ /** i18n sub-key under `v2.nc.rules.editor.taxonomy.` */
35
+ readonly key: string;
36
+ /** English fallback header when the i18n key is missing. */
37
+ readonly fallbackLabel: string;
38
+ readonly options: readonly TaxonomyOption[];
39
+ }
40
+ /** The picker model for one condition, or `null` when it stays free-text. */
41
+ export interface TaxonomyPicker {
42
+ readonly groups: readonly TaxonomyGroup[];
43
+ }
44
+ /**
45
+ * Build the grouped picker model for a condition id, or `null` when the
46
+ * condition has no fixed vocabulary (→ free-text tag input).
47
+ */
48
+ export declare function pickerForCondition(conditionId: string, taxonomy: NcTaxonomy | undefined): TaxonomyPicker | null;
49
+ /** All option values across a picker's groups (for custom-value detection). */
50
+ export declare function knownValues(picker: TaxonomyPicker): ReadonlySet<string>;
51
+ /**
52
+ * The condition ids shown in the ALWAYS-VISIBLE area of a rule editor. Every
53
+ * other catalog descriptor is advanced and lives behind an expander.
54
+ *
55
+ * Shared for the same reason as the picker model: two surfaces disagreeing
56
+ * about what counts as "basic" is a worse outcome than either choice.
57
+ */
58
+ export declare const NC_BASE_CONDITION_KEYS: readonly ["devices", "classes"];
59
+ export type NcBaseConditionKey = (typeof NC_BASE_CONDITION_KEYS)[number];
60
+ /** True when a condition key belongs to the BASE surface. */
61
+ export declare function isBaseConditionKey(key: string): boolean;
@@ -13,7 +13,18 @@ export declare function htmlToText(html: string): string;
13
13
  export declare function textToHtml(text: string): string;
14
14
  /** Markdown → HTML-lite (bold/italic/code/links; used e.g. for Pushover). */
15
15
  export declare function markdownToHtmlLite(md: string): string;
16
- /** Pick the best target format the kind supports for a given source format. */
16
+ /**
17
+ * Pick the best target format the kind supports for a given source format.
18
+ *
19
+ * TOLERANT of a source outside the union. `NotificationSchema.format` carries
20
+ * `.default('text')`, but that default only runs where the schema is PARSED —
21
+ * the tRPC router. A cap call arriving from another addon (`ctx.api`) skips
22
+ * that parse, so `format` reaches here `undefined`, and the bare
23
+ * `DEGRADE_ORDER[source]` threw `is not iterable`. That broke the one promise
24
+ * the degrade path makes ("never throws — degradation is reported, never
25
+ * surfaced as an error") and dead-lettered every Notification-Center delivery
26
+ * for a day (2026-07-30). An unknown source degrades like `text`.
27
+ */
17
28
  export declare function resolveFormat(source: NotificationFormat, supported: readonly NotificationFormat[]): NotificationFormat;
18
29
  /** Transcode a body between formats. */
19
30
  export declare function transcodeBody(body: string, from: NotificationFormat, to: NotificationFormat): string;
@@ -3019,6 +3019,9 @@ function createDeviceProxy(api, binding, opts) {
3019
3019
  getEventStoreFootprint: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventStoreFootprint", "query", input),
3020
3020
  pruneEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEvents", "mutation", input),
3021
3021
  deleteDeviceEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteDeviceEvents", "mutation", input),
3022
+ relocateMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "relocateMedia", "mutation", input),
3023
+ getMediaRelocateStatus: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getMediaRelocateStatus", "query", input),
3024
+ cancelMediaRelocate: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "cancelMediaRelocate", "mutation", input),
3022
3025
  listOpsLog: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listOpsLog", "query", input),
3023
3026
  getEventMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventMedia", "query", input),
3024
3027
  getTrackMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrackMedia", "query", input),
@@ -3269,6 +3272,8 @@ function createDeviceProxy(api, binding, opts) {
3269
3272
  rescanStorage: (input) => dispatchSystem("recording", "rescanStorage", "mutation", input),
3270
3273
  pruneFootage: (input) => dispatchSystem("recording", "pruneFootage", "mutation", input),
3271
3274
  deleteFootprint: (input) => dispatchSystem("recording", "deleteFootprint", "mutation", input),
3275
+ renderGif: (input) => dispatchSystem("recording", "renderGif", "mutation", input),
3276
+ renderClip: (input) => dispatchSystem("recording", "renderClip", "mutation", input),
3272
3277
  getStatus: (input) => dispatchSystem("recording", "getStatus", "query", input),
3273
3278
  getDeviceSettingsContribution: (input) => dispatchSystem("recording", "getDeviceSettingsContribution", "query", input),
3274
3279
  getDeviceLiveContribution: (input) => dispatchSystem("recording", "getDeviceLiveContribution", "query", input),
@@ -3283,6 +3288,7 @@ function createDeviceProxy(api, binding, opts) {
3283
3288
  retractCameraStream: (input) => dispatchSystem("streamBroker", "retractCameraStream", "mutation", input),
3284
3289
  assignProfile: (input) => dispatchSystem("streamBroker", "assignProfile", "mutation", input),
3285
3290
  unassignProfile: (input) => dispatchSystem("streamBroker", "unassignProfile", "mutation", input),
3291
+ renderPreBufferClip: (input) => dispatchSystem("streamBroker", "renderPreBufferClip", "mutation", input),
3286
3292
  restartProfile: (input) => dispatchSystem("streamBroker", "restartProfile", "mutation", input),
3287
3293
  getDeviceSettingsContribution: (input) => dispatchSystem("streamBroker", "getDeviceSettingsContribution", "query", input),
3288
3294
  getDeviceLiveContribution: (input) => dispatchSystem("streamBroker", "getDeviceLiveContribution", "query", input),
@@ -3019,6 +3019,9 @@ function createDeviceProxy(api, binding, opts) {
3019
3019
  getEventStoreFootprint: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventStoreFootprint", "query", input),
3020
3020
  pruneEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEvents", "mutation", input),
3021
3021
  deleteDeviceEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteDeviceEvents", "mutation", input),
3022
+ relocateMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "relocateMedia", "mutation", input),
3023
+ getMediaRelocateStatus: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getMediaRelocateStatus", "query", input),
3024
+ cancelMediaRelocate: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "cancelMediaRelocate", "mutation", input),
3022
3025
  listOpsLog: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listOpsLog", "query", input),
3023
3026
  getEventMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventMedia", "query", input),
3024
3027
  getTrackMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrackMedia", "query", input),
@@ -3269,6 +3272,8 @@ function createDeviceProxy(api, binding, opts) {
3269
3272
  rescanStorage: (input) => dispatchSystem("recording", "rescanStorage", "mutation", input),
3270
3273
  pruneFootage: (input) => dispatchSystem("recording", "pruneFootage", "mutation", input),
3271
3274
  deleteFootprint: (input) => dispatchSystem("recording", "deleteFootprint", "mutation", input),
3275
+ renderGif: (input) => dispatchSystem("recording", "renderGif", "mutation", input),
3276
+ renderClip: (input) => dispatchSystem("recording", "renderClip", "mutation", input),
3272
3277
  getStatus: (input) => dispatchSystem("recording", "getStatus", "query", input),
3273
3278
  getDeviceSettingsContribution: (input) => dispatchSystem("recording", "getDeviceSettingsContribution", "query", input),
3274
3279
  getDeviceLiveContribution: (input) => dispatchSystem("recording", "getDeviceLiveContribution", "query", input),
@@ -3283,6 +3288,7 @@ function createDeviceProxy(api, binding, opts) {
3283
3288
  retractCameraStream: (input) => dispatchSystem("streamBroker", "retractCameraStream", "mutation", input),
3284
3289
  assignProfile: (input) => dispatchSystem("streamBroker", "assignProfile", "mutation", input),
3285
3290
  unassignProfile: (input) => dispatchSystem("streamBroker", "unassignProfile", "mutation", input),
3291
+ renderPreBufferClip: (input) => dispatchSystem("streamBroker", "renderPreBufferClip", "mutation", input),
3286
3292
  restartProfile: (input) => dispatchSystem("streamBroker", "restartProfile", "mutation", input),
3287
3293
  getDeviceSettingsContribution: (input) => dispatchSystem("streamBroker", "getDeviceSettingsContribution", "query", input),
3288
3294
  getDeviceLiveContribution: (input) => dispatchSystem("streamBroker", "getDeviceLiveContribution", "query", input),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.15",
3
+ "version": "1.2.17",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",
@@ -1,12 +0,0 @@
1
- import type { RecordingConfig, RecordingBand } from './recording-config.js';
2
- /**
3
- * One-way migration from the legacy recording-config shape to the authoritative
4
- * mode-per-band model. Pure (no clock access).
5
- *
6
- * - If `config.bands` is present, it is authoritative and returned as-is.
7
- * - Otherwise the result is derived from the legacy fields: a disabled config or
8
- * `mode: 'off'` yields no bands; every legacy schedule maps to one band whose
9
- * mode is `continuous` when `config.mode === 'continuous'`, else `events`
10
- * (carrying `triggers`/`preBufferSec`/`postBufferSec`).
11
- */
12
- export declare function migrateConfigToBands(config: RecordingConfig): RecordingBand[];