@camstack/addon-mqtt-broker 1.2.130 → 1.2.131

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.
@@ -5594,7 +5594,7 @@ var ZodIssueCode = {
5594
5594
  var ZodFirstPartyTypeKind;
5595
5595
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5596
5596
  //#endregion
5597
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5597
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5598
5598
  /**
5599
5599
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5600
5600
  * window to float samples (D455).
@@ -17312,7 +17312,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17312
17312
  kind: literal("node"),
17313
17313
  nodeId: string().min(1)
17314
17314
  })]);
17315
+ /**
17316
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17317
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17318
+ * meaning); a rollup keeps the time spent in each state (`states`).
17319
+ */
17315
17320
  var DeviceHistoryKindSchema = _enum([
17321
+ "gauge",
17322
+ "counter",
17323
+ "boolean",
17324
+ "enum"
17325
+ ]);
17326
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17327
+ var DeviceHistoryProducerKindSchema = _enum([
17316
17328
  "gauge",
17317
17329
  "counter",
17318
17330
  "boolean"
@@ -17349,7 +17361,13 @@ var SeriesInfoSchema = object({
17349
17361
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17350
17362
  unit: string().nullable(),
17351
17363
  displayName: string(),
17352
- source: _enum(["cap", "addon"]),
17364
+ source: _enum([
17365
+ "cap",
17366
+ "addon",
17367
+ "derived"
17368
+ ]),
17369
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17370
+ values: array(string()).readonly().nullable(),
17353
17371
  firstTs: number(),
17354
17372
  lastTs: number()
17355
17373
  });
@@ -17363,17 +17381,31 @@ var QueryPointSchema = object({
17363
17381
  twMean: number().nullable(),
17364
17382
  min: number(),
17365
17383
  max: number(),
17366
- /** `null` is unknown, never zero (D393). */
17367
- last: number().nullable()
17384
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17385
+ last: number().nullable(),
17386
+ /**
17387
+ * The increase over the point: a `counter`'s growth since the previous point
17388
+ * or bucket (a drop is a reset, counted from zero), and for
17389
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17390
+ * every other kind, and when it cannot be known.
17391
+ */
17392
+ delta: number().nullable(),
17393
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17394
+ state: string().nullable(),
17395
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17396
+ states: record(string(), number()).nullable()
17368
17397
  });
17369
17398
  var QuerySeriesSchema = object({
17370
17399
  scope: string(),
17371
17400
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17372
17401
  before: object({
17373
17402
  t: number(),
17374
- value: number().nullable()
17403
+ value: number().nullable(),
17404
+ state: string().nullable()
17375
17405
  }).nullable(),
17376
- points: array(QueryPointSchema).readonly()
17406
+ points: array(QueryPointSchema).readonly(),
17407
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17408
+ derivedFrom: string().nullable()
17377
17409
  });
17378
17410
  /** The window part of a query, shared by the device and node forms. */
17379
17411
  var QueryWindowShape = {
@@ -17389,6 +17421,23 @@ var QueryResultSchema = object({
17389
17421
  series: array(QuerySeriesSchema).readonly(),
17390
17422
  truncated: boolean()
17391
17423
  });
17424
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17425
+ var QueryManyItemSchema = union([object({
17426
+ deviceId: number().int(),
17427
+ key: string(),
17428
+ scope: string().optional()
17429
+ }), object({
17430
+ forNodeId: string().min(1),
17431
+ key: string(),
17432
+ scope: string().optional()
17433
+ })]);
17434
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17435
+ ok: literal(true),
17436
+ result: QueryResultSchema
17437
+ }), object({
17438
+ ok: literal(false),
17439
+ error: string()
17440
+ })]);
17392
17441
  var TierStatusSchema = object({
17393
17442
  tier: DeviceHistoryResolutionSchema,
17394
17443
  /** `null` until the first background count answered. */
@@ -17444,16 +17493,22 @@ var DeviceHistoryStatusSchema = object({
17444
17493
  lastRefreshAt: number().nullable()
17445
17494
  })
17446
17495
  });
17447
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17496
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17448
17497
  deviceId: number().int(),
17449
17498
  ...QueryWindowShape
17450
17499
  }), QueryResultSchema), method(object({
17451
- nodeId: string().min(1),
17500
+ forNodeId: string().min(1),
17452
17501
  ...QueryWindowShape
17453
17502
  }), QueryResultSchema, { auth: "admin" }), method(object({
17503
+ items: array(QueryManyItemSchema).min(1).max(24),
17504
+ from: QueryWindowShape.from,
17505
+ to: QueryWindowShape.to,
17506
+ resolution: QueryWindowShape.resolution,
17507
+ maxPoints: QueryWindowShape.maxPoints
17508
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17454
17509
  name: string().regex(/^[a-z0-9-]+$/),
17455
17510
  subjectKind: _enum(["device", "node"]),
17456
- kind: DeviceHistoryKindSchema,
17511
+ kind: DeviceHistoryProducerKindSchema,
17457
17512
  unit: string().optional(),
17458
17513
  displayName: string().min(1),
17459
17514
  ingest: _enum(["points", "buckets"])
@@ -40470,14 +40525,106 @@ var LogEntrySchema = object({
40470
40525
  meta: record(string(), unknown()).optional(),
40471
40526
  tags: record(string(), string()).optional()
40472
40527
  });
40473
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40474
- scope: array(string()).optional(),
40528
+ /**
40529
+ * A history READ against one destination (D898).
40530
+ *
40531
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40532
+ * browser applied after the limit is what made a rare device's lines
40533
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40534
+ * minted (opaque to everyone else): a file position for the rotated files, a
40535
+ * nanosecond timestamp for Loki.
40536
+ *
40537
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40538
+ * store answers `done: false` with the cursor it reached and the bytes it
40539
+ * scanned, and the caller decides whether to go on. That is what makes a long
40540
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40541
+ * flight, and not asking for the next slice ends the scan.
40542
+ */
40543
+ var LogReadQuerySchema = object({
40544
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40545
+ requestId: string().min(1).max(64).optional(),
40546
+ /** The device the line is about (`tags.deviceId`, numeric). */
40547
+ deviceId: number().int().optional(),
40548
+ /**
40549
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40550
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40551
+ */
40552
+ fromAddonId: string().min(1).max(200).optional(),
40553
+ /**
40554
+ * The emitting node: matches the agent that emitted the line, the node
40555
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40556
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40557
+ * name as "which node's provider".
40558
+ */
40559
+ fromNodeId: string().min(1).max(200).optional(),
40560
+ /** Any other tag, exact match (AND). */
40561
+ tags: record(string(), union([string(), number()])).optional(),
40562
+ /** Severity FLOOR: this level and above. */
40475
40563
  level: LogLevelSchema.optional(),
40476
- since: date().optional(),
40477
- until: date().optional(),
40478
- limit: number().optional(),
40479
- tags: record(string(), string()).optional()
40480
- }), array(LogEntrySchema).readonly());
40564
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40565
+ text: string().min(1).max(200).optional(),
40566
+ /** Epoch ms, inclusive. */
40567
+ since: number().optional(),
40568
+ /** Epoch ms, inclusive. */
40569
+ until: number().optional(),
40570
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40571
+ before: string().min(1).max(1024).optional(),
40572
+ /** Newer than this cursor (exclusive). */
40573
+ after: string().min(1).max(1024).optional(),
40574
+ limit: number().int().min(1).max(1e3).optional(),
40575
+ /** Wall-clock bound of this slice. The provider caps it. */
40576
+ budgetMs: number().int().min(50).max(1e4).optional()
40577
+ });
40578
+ var LogReadResultSchema = object({
40579
+ /** Newest first. */
40580
+ entries: array(object({
40581
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40582
+ id: string().optional(),
40583
+ /** Epoch ms. */
40584
+ timestamp: number(),
40585
+ level: LogLevelSchema,
40586
+ scope: string().optional(),
40587
+ message: string(),
40588
+ tags: record(string(), union([string(), number()])).optional(),
40589
+ meta: record(string(), unknown()).optional()
40590
+ })),
40591
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40592
+ nextBefore: string().nullable(),
40593
+ /** Pass as `after` to read what arrived since; null when unknown. */
40594
+ nextAfter: string().nullable(),
40595
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40596
+ scannedBytes: number().int().nonnegative(),
40597
+ /**
40598
+ * True when the scan in this direction reached the end of the store.
40599
+ * False with fewer than `limit` entries means the budget ran out first —
40600
+ * call again with `nextBefore` to go on.
40601
+ */
40602
+ done: boolean(),
40603
+ /** True when `cancelRead` ended this slice early. */
40604
+ cancelled: boolean().optional()
40605
+ });
40606
+ var LogReadCapabilitiesSchema = object({
40607
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40608
+ readable: boolean(),
40609
+ /** Why not, when `readable` is false — rendered next to the source. */
40610
+ reason: string().nullable(),
40611
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40612
+ filters: object({
40613
+ deviceId: boolean(),
40614
+ addonId: boolean(),
40615
+ nodeId: boolean(),
40616
+ tags: boolean(),
40617
+ level: boolean(),
40618
+ text: boolean(),
40619
+ timeRange: boolean()
40620
+ }),
40621
+ /** How far back the store reaches, when the provider knows (days). */
40622
+ retentionDays: number().nullable()
40623
+ });
40624
+ method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string().min(1).max(64) }), object({ cancelled: boolean() }), {
40625
+ kind: "mutation",
40626
+ auth: "admin"
40627
+ });
40481
40628
  /**
40482
40629
  * `login-method` — collection cap through which auth addons contribute
40483
40630
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -43052,6 +43199,33 @@ var NcRuleTargetSchema = object({
43052
43199
  params: record(string(), unknown()).optional()
43053
43200
  });
43054
43201
  /**
43202
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43203
+ *
43204
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43205
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43206
+ * to the zone that fired the rule) and renders it once at send time:
43207
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43208
+ * colour and every OTHER track visible at that instant outlined thin, each
43209
+ * labelled with class and confidence ("dog 87%").
43210
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43211
+ * - `clean` — the whole scene with nothing drawn on it.
43212
+ * - `none` — no picture.
43213
+ *
43214
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43215
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43216
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43217
+ * ship a crop on one event and a boxed scene on the next depending on which
43218
+ * stored kind had landed.
43219
+ */
43220
+ var NcMediaImageSchema = _enum([
43221
+ "scene-boxes",
43222
+ "crop",
43223
+ "clean",
43224
+ "none"
43225
+ ]);
43226
+ /**
43227
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43228
+ *
43055
43229
  * Media attachment policy (P1 still-image subset).
43056
43230
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43057
43231
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43065,6 +43239,8 @@ var NcRuleTargetSchema = object({
43065
43239
  * - `none` — no attachment.
43066
43240
  */
43067
43241
  /**
43242
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43243
+ *
43068
43244
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43069
43245
  * conflate it with the selection strategy and betray the request: asking for
43070
43246
  * the clean scene frame on an object-event owner used to start at
@@ -43093,16 +43269,29 @@ var NcMediaFrameSchema = _enum([
43093
43269
  */
43094
43270
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43095
43271
  var NcMediaPolicySchema = object({
43272
+ /**
43273
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43274
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43275
+ * triple below, at load and at every write, and the store keeps only this.
43276
+ */
43277
+ image: NcMediaImageSchema.optional(),
43278
+ /**
43279
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43280
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43281
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43282
+ * Replaces `zoneCrop`.
43283
+ */
43284
+ showTriggerZone: boolean().optional(),
43285
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43096
43286
  attach: _enum([
43097
43287
  "best",
43098
43288
  "best-matching",
43099
43289
  "keyFrame",
43100
43290
  "none"
43101
- ]).default("best"),
43102
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43291
+ ]).optional(),
43292
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43103
43293
  frame: NcMediaFrameSchema.optional(),
43104
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43105
- * "show me the ZONE", not the whole scene or the subject crop. */
43294
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43106
43295
  zoneCrop: boolean().optional(),
43107
43296
  /**
43108
43297
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43274,7 +43463,9 @@ var NcRuleInputSchema = object({
43274
43463
  * targets.
43275
43464
  */
43276
43465
  targetUsers: array(string()).optional(),
43277
- media: NcMediaPolicySchema.default({ attach: "best" }),
43466
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43467
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43468
+ media: NcMediaPolicySchema.default({}),
43278
43469
  throttle: NcThrottleSchema.default({
43279
43470
  cooldownSec: 60,
43280
43471
  scope: "rule-device"
@@ -44211,13 +44402,37 @@ var NcAlarmModeOpeningsSchema = object({
44211
44402
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44212
44403
  unknown: array(number().int())
44213
44404
  });
44405
+ /**
44406
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44407
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44408
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44409
+ * never looks fully armed (D62: off must never look like broken).
44410
+ */
44411
+ var NcAlarmInputBypassViewSchema = object({
44412
+ ruleId: string(),
44413
+ /** The rule's current name (its frozen name when the rule is gone). */
44414
+ ruleName: string(),
44415
+ /** The input: the sensor of the match, else its camera. */
44416
+ deviceId: number().int(),
44417
+ /** The input's current name. */
44418
+ name: string(),
44419
+ /** When it was bypassed (ms epoch). */
44420
+ since: number(),
44421
+ /** Triggers from this input dropped since. */
44422
+ dropped: number().int().min(0)
44423
+ });
44214
44424
  var NcAlarmLiveSchema = object({
44215
44425
  state: AlarmStateSchema,
44216
44426
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44217
44427
  targetMode: AlarmArmModeSchema.nullable(),
44218
44428
  availableModes: array(AlarmArmModeSchema),
44219
44429
  openings: array(NcAlarmModeOpeningsSchema),
44220
- exclusions: array(NcAlarmExclusionViewSchema)
44430
+ exclusions: array(NcAlarmExclusionViewSchema),
44431
+ /**
44432
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44433
+ * Defaulted so an older hub answer still parses (as "none known").
44434
+ */
44435
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44221
44436
  });
44222
44437
  var NcAlarmConfigSchema = object({
44223
44438
  /**
@@ -65856,7 +66071,19 @@ Object.freeze({
65856
66071
  addonId: null,
65857
66072
  access: "view"
65858
66073
  },
65859
- "logDestination.query": {
66074
+ "logDestination.cancelRead": {
66075
+ capName: "log-destination",
66076
+ capScope: "system",
66077
+ addonId: null,
66078
+ access: "create"
66079
+ },
66080
+ "logDestination.describeRead": {
66081
+ capName: "log-destination",
66082
+ capScope: "system",
66083
+ addonId: null,
66084
+ access: "view"
66085
+ },
66086
+ "logDestination.read": {
65860
66087
  capName: "log-destination",
65861
66088
  capScope: "system",
65862
66089
  addonId: null,
@@ -71863,6 +72090,11 @@ Object.freeze({
71863
72090
  form: "single",
71864
72091
  optional: false
71865
72092
  }],
72093
+ "logDestination.read": [{
72094
+ name: "deviceId",
72095
+ form: "single",
72096
+ optional: true
72097
+ }],
71866
72098
  "mediaPlayer.getStatus": [{
71867
72099
  name: "deviceId",
71868
72100
  form: "single",
@@ -5587,7 +5587,7 @@ var ZodIssueCode = {
5587
5587
  var ZodFirstPartyTypeKind;
5588
5588
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5589
5589
  //#endregion
5590
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5590
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5591
5591
  /**
5592
5592
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5593
5593
  * window to float samples (D455).
@@ -17305,7 +17305,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17305
17305
  kind: literal("node"),
17306
17306
  nodeId: string().min(1)
17307
17307
  })]);
17308
+ /**
17309
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17310
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17311
+ * meaning); a rollup keeps the time spent in each state (`states`).
17312
+ */
17308
17313
  var DeviceHistoryKindSchema = _enum([
17314
+ "gauge",
17315
+ "counter",
17316
+ "boolean",
17317
+ "enum"
17318
+ ]);
17319
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17320
+ var DeviceHistoryProducerKindSchema = _enum([
17309
17321
  "gauge",
17310
17322
  "counter",
17311
17323
  "boolean"
@@ -17342,7 +17354,13 @@ var SeriesInfoSchema = object({
17342
17354
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17343
17355
  unit: string().nullable(),
17344
17356
  displayName: string(),
17345
- source: _enum(["cap", "addon"]),
17357
+ source: _enum([
17358
+ "cap",
17359
+ "addon",
17360
+ "derived"
17361
+ ]),
17362
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17363
+ values: array(string()).readonly().nullable(),
17346
17364
  firstTs: number(),
17347
17365
  lastTs: number()
17348
17366
  });
@@ -17356,17 +17374,31 @@ var QueryPointSchema = object({
17356
17374
  twMean: number().nullable(),
17357
17375
  min: number(),
17358
17376
  max: number(),
17359
- /** `null` is unknown, never zero (D393). */
17360
- last: number().nullable()
17377
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17378
+ last: number().nullable(),
17379
+ /**
17380
+ * The increase over the point: a `counter`'s growth since the previous point
17381
+ * or bucket (a drop is a reset, counted from zero), and for
17382
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17383
+ * every other kind, and when it cannot be known.
17384
+ */
17385
+ delta: number().nullable(),
17386
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17387
+ state: string().nullable(),
17388
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17389
+ states: record(string(), number()).nullable()
17361
17390
  });
17362
17391
  var QuerySeriesSchema = object({
17363
17392
  scope: string(),
17364
17393
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17365
17394
  before: object({
17366
17395
  t: number(),
17367
- value: number().nullable()
17396
+ value: number().nullable(),
17397
+ state: string().nullable()
17368
17398
  }).nullable(),
17369
- points: array(QueryPointSchema).readonly()
17399
+ points: array(QueryPointSchema).readonly(),
17400
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17401
+ derivedFrom: string().nullable()
17370
17402
  });
17371
17403
  /** The window part of a query, shared by the device and node forms. */
17372
17404
  var QueryWindowShape = {
@@ -17382,6 +17414,23 @@ var QueryResultSchema = object({
17382
17414
  series: array(QuerySeriesSchema).readonly(),
17383
17415
  truncated: boolean()
17384
17416
  });
17417
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17418
+ var QueryManyItemSchema = union([object({
17419
+ deviceId: number().int(),
17420
+ key: string(),
17421
+ scope: string().optional()
17422
+ }), object({
17423
+ forNodeId: string().min(1),
17424
+ key: string(),
17425
+ scope: string().optional()
17426
+ })]);
17427
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17428
+ ok: literal(true),
17429
+ result: QueryResultSchema
17430
+ }), object({
17431
+ ok: literal(false),
17432
+ error: string()
17433
+ })]);
17385
17434
  var TierStatusSchema = object({
17386
17435
  tier: DeviceHistoryResolutionSchema,
17387
17436
  /** `null` until the first background count answered. */
@@ -17437,16 +17486,22 @@ var DeviceHistoryStatusSchema = object({
17437
17486
  lastRefreshAt: number().nullable()
17438
17487
  })
17439
17488
  });
17440
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17489
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17441
17490
  deviceId: number().int(),
17442
17491
  ...QueryWindowShape
17443
17492
  }), QueryResultSchema), method(object({
17444
- nodeId: string().min(1),
17493
+ forNodeId: string().min(1),
17445
17494
  ...QueryWindowShape
17446
17495
  }), QueryResultSchema, { auth: "admin" }), method(object({
17496
+ items: array(QueryManyItemSchema).min(1).max(24),
17497
+ from: QueryWindowShape.from,
17498
+ to: QueryWindowShape.to,
17499
+ resolution: QueryWindowShape.resolution,
17500
+ maxPoints: QueryWindowShape.maxPoints
17501
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17447
17502
  name: string().regex(/^[a-z0-9-]+$/),
17448
17503
  subjectKind: _enum(["device", "node"]),
17449
- kind: DeviceHistoryKindSchema,
17504
+ kind: DeviceHistoryProducerKindSchema,
17450
17505
  unit: string().optional(),
17451
17506
  displayName: string().min(1),
17452
17507
  ingest: _enum(["points", "buckets"])
@@ -40463,14 +40518,106 @@ var LogEntrySchema = object({
40463
40518
  meta: record(string(), unknown()).optional(),
40464
40519
  tags: record(string(), string()).optional()
40465
40520
  });
40466
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40467
- scope: array(string()).optional(),
40521
+ /**
40522
+ * A history READ against one destination (D898).
40523
+ *
40524
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40525
+ * browser applied after the limit is what made a rare device's lines
40526
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40527
+ * minted (opaque to everyone else): a file position for the rotated files, a
40528
+ * nanosecond timestamp for Loki.
40529
+ *
40530
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40531
+ * store answers `done: false` with the cursor it reached and the bytes it
40532
+ * scanned, and the caller decides whether to go on. That is what makes a long
40533
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40534
+ * flight, and not asking for the next slice ends the scan.
40535
+ */
40536
+ var LogReadQuerySchema = object({
40537
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40538
+ requestId: string().min(1).max(64).optional(),
40539
+ /** The device the line is about (`tags.deviceId`, numeric). */
40540
+ deviceId: number().int().optional(),
40541
+ /**
40542
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40543
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40544
+ */
40545
+ fromAddonId: string().min(1).max(200).optional(),
40546
+ /**
40547
+ * The emitting node: matches the agent that emitted the line, the node
40548
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40549
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40550
+ * name as "which node's provider".
40551
+ */
40552
+ fromNodeId: string().min(1).max(200).optional(),
40553
+ /** Any other tag, exact match (AND). */
40554
+ tags: record(string(), union([string(), number()])).optional(),
40555
+ /** Severity FLOOR: this level and above. */
40468
40556
  level: LogLevelSchema.optional(),
40469
- since: date().optional(),
40470
- until: date().optional(),
40471
- limit: number().optional(),
40472
- tags: record(string(), string()).optional()
40473
- }), array(LogEntrySchema).readonly());
40557
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40558
+ text: string().min(1).max(200).optional(),
40559
+ /** Epoch ms, inclusive. */
40560
+ since: number().optional(),
40561
+ /** Epoch ms, inclusive. */
40562
+ until: number().optional(),
40563
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40564
+ before: string().min(1).max(1024).optional(),
40565
+ /** Newer than this cursor (exclusive). */
40566
+ after: string().min(1).max(1024).optional(),
40567
+ limit: number().int().min(1).max(1e3).optional(),
40568
+ /** Wall-clock bound of this slice. The provider caps it. */
40569
+ budgetMs: number().int().min(50).max(1e4).optional()
40570
+ });
40571
+ var LogReadResultSchema = object({
40572
+ /** Newest first. */
40573
+ entries: array(object({
40574
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40575
+ id: string().optional(),
40576
+ /** Epoch ms. */
40577
+ timestamp: number(),
40578
+ level: LogLevelSchema,
40579
+ scope: string().optional(),
40580
+ message: string(),
40581
+ tags: record(string(), union([string(), number()])).optional(),
40582
+ meta: record(string(), unknown()).optional()
40583
+ })),
40584
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40585
+ nextBefore: string().nullable(),
40586
+ /** Pass as `after` to read what arrived since; null when unknown. */
40587
+ nextAfter: string().nullable(),
40588
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40589
+ scannedBytes: number().int().nonnegative(),
40590
+ /**
40591
+ * True when the scan in this direction reached the end of the store.
40592
+ * False with fewer than `limit` entries means the budget ran out first —
40593
+ * call again with `nextBefore` to go on.
40594
+ */
40595
+ done: boolean(),
40596
+ /** True when `cancelRead` ended this slice early. */
40597
+ cancelled: boolean().optional()
40598
+ });
40599
+ var LogReadCapabilitiesSchema = object({
40600
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40601
+ readable: boolean(),
40602
+ /** Why not, when `readable` is false — rendered next to the source. */
40603
+ reason: string().nullable(),
40604
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40605
+ filters: object({
40606
+ deviceId: boolean(),
40607
+ addonId: boolean(),
40608
+ nodeId: boolean(),
40609
+ tags: boolean(),
40610
+ level: boolean(),
40611
+ text: boolean(),
40612
+ timeRange: boolean()
40613
+ }),
40614
+ /** How far back the store reaches, when the provider knows (days). */
40615
+ retentionDays: number().nullable()
40616
+ });
40617
+ method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string().min(1).max(64) }), object({ cancelled: boolean() }), {
40618
+ kind: "mutation",
40619
+ auth: "admin"
40620
+ });
40474
40621
  /**
40475
40622
  * `login-method` — collection cap through which auth addons contribute
40476
40623
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -43045,6 +43192,33 @@ var NcRuleTargetSchema = object({
43045
43192
  params: record(string(), unknown()).optional()
43046
43193
  });
43047
43194
  /**
43195
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43196
+ *
43197
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43198
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43199
+ * to the zone that fired the rule) and renders it once at send time:
43200
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43201
+ * colour and every OTHER track visible at that instant outlined thin, each
43202
+ * labelled with class and confidence ("dog 87%").
43203
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43204
+ * - `clean` — the whole scene with nothing drawn on it.
43205
+ * - `none` — no picture.
43206
+ *
43207
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43208
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43209
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43210
+ * ship a crop on one event and a boxed scene on the next depending on which
43211
+ * stored kind had landed.
43212
+ */
43213
+ var NcMediaImageSchema = _enum([
43214
+ "scene-boxes",
43215
+ "crop",
43216
+ "clean",
43217
+ "none"
43218
+ ]);
43219
+ /**
43220
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43221
+ *
43048
43222
  * Media attachment policy (P1 still-image subset).
43049
43223
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43050
43224
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43058,6 +43232,8 @@ var NcRuleTargetSchema = object({
43058
43232
  * - `none` — no attachment.
43059
43233
  */
43060
43234
  /**
43235
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43236
+ *
43061
43237
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43062
43238
  * conflate it with the selection strategy and betray the request: asking for
43063
43239
  * the clean scene frame on an object-event owner used to start at
@@ -43086,16 +43262,29 @@ var NcMediaFrameSchema = _enum([
43086
43262
  */
43087
43263
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43088
43264
  var NcMediaPolicySchema = object({
43265
+ /**
43266
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43267
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43268
+ * triple below, at load and at every write, and the store keeps only this.
43269
+ */
43270
+ image: NcMediaImageSchema.optional(),
43271
+ /**
43272
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43273
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43274
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43275
+ * Replaces `zoneCrop`.
43276
+ */
43277
+ showTriggerZone: boolean().optional(),
43278
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43089
43279
  attach: _enum([
43090
43280
  "best",
43091
43281
  "best-matching",
43092
43282
  "keyFrame",
43093
43283
  "none"
43094
- ]).default("best"),
43095
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43284
+ ]).optional(),
43285
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43096
43286
  frame: NcMediaFrameSchema.optional(),
43097
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43098
- * "show me the ZONE", not the whole scene or the subject crop. */
43287
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43099
43288
  zoneCrop: boolean().optional(),
43100
43289
  /**
43101
43290
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43267,7 +43456,9 @@ var NcRuleInputSchema = object({
43267
43456
  * targets.
43268
43457
  */
43269
43458
  targetUsers: array(string()).optional(),
43270
- media: NcMediaPolicySchema.default({ attach: "best" }),
43459
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43460
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43461
+ media: NcMediaPolicySchema.default({}),
43271
43462
  throttle: NcThrottleSchema.default({
43272
43463
  cooldownSec: 60,
43273
43464
  scope: "rule-device"
@@ -44204,13 +44395,37 @@ var NcAlarmModeOpeningsSchema = object({
44204
44395
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44205
44396
  unknown: array(number().int())
44206
44397
  });
44398
+ /**
44399
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44400
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44401
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44402
+ * never looks fully armed (D62: off must never look like broken).
44403
+ */
44404
+ var NcAlarmInputBypassViewSchema = object({
44405
+ ruleId: string(),
44406
+ /** The rule's current name (its frozen name when the rule is gone). */
44407
+ ruleName: string(),
44408
+ /** The input: the sensor of the match, else its camera. */
44409
+ deviceId: number().int(),
44410
+ /** The input's current name. */
44411
+ name: string(),
44412
+ /** When it was bypassed (ms epoch). */
44413
+ since: number(),
44414
+ /** Triggers from this input dropped since. */
44415
+ dropped: number().int().min(0)
44416
+ });
44207
44417
  var NcAlarmLiveSchema = object({
44208
44418
  state: AlarmStateSchema,
44209
44419
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44210
44420
  targetMode: AlarmArmModeSchema.nullable(),
44211
44421
  availableModes: array(AlarmArmModeSchema),
44212
44422
  openings: array(NcAlarmModeOpeningsSchema),
44213
- exclusions: array(NcAlarmExclusionViewSchema)
44423
+ exclusions: array(NcAlarmExclusionViewSchema),
44424
+ /**
44425
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44426
+ * Defaulted so an older hub answer still parses (as "none known").
44427
+ */
44428
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44214
44429
  });
44215
44430
  var NcAlarmConfigSchema = object({
44216
44431
  /**
@@ -65849,7 +66064,19 @@ Object.freeze({
65849
66064
  addonId: null,
65850
66065
  access: "view"
65851
66066
  },
65852
- "logDestination.query": {
66067
+ "logDestination.cancelRead": {
66068
+ capName: "log-destination",
66069
+ capScope: "system",
66070
+ addonId: null,
66071
+ access: "create"
66072
+ },
66073
+ "logDestination.describeRead": {
66074
+ capName: "log-destination",
66075
+ capScope: "system",
66076
+ addonId: null,
66077
+ access: "view"
66078
+ },
66079
+ "logDestination.read": {
65853
66080
  capName: "log-destination",
65854
66081
  capScope: "system",
65855
66082
  addonId: null,
@@ -71856,6 +72083,11 @@ Object.freeze({
71856
72083
  form: "single",
71857
72084
  optional: false
71858
72085
  }],
72086
+ "logDestination.read": [{
72087
+ name: "deviceId",
72088
+ form: "single",
72089
+ optional: true
72090
+ }],
71859
72091
  "mediaPlayer.getStatus": [{
71860
72092
  name: "deviceId",
71861
72093
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-mqtt-broker",
3
- "version": "1.2.130",
3
+ "version": "1.2.131",
4
4
  "description": "MQTT broker registry addon for CamStack — manages external broker entries + an optional embedded aedes broker. Consumers spin up their own `mqtt.js` clients via the `mqtt-broker` cap.",
5
5
  "keywords": [
6
6
  "camstack",