@camstack/addon-google-services 0.2.14 → 0.2.16

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.
@@ -5551,7 +5551,7 @@ var ZodIssueCode = {
5551
5551
  var ZodFirstPartyTypeKind;
5552
5552
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5553
5553
  //#endregion
5554
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5554
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5555
5555
  /**
5556
5556
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5557
5557
  * window to float samples (D455).
@@ -17410,7 +17410,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17410
17410
  kind: literal("node"),
17411
17411
  nodeId: string().min(1)
17412
17412
  })]);
17413
+ /**
17414
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17415
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17416
+ * meaning); a rollup keeps the time spent in each state (`states`).
17417
+ */
17413
17418
  var DeviceHistoryKindSchema = _enum([
17419
+ "gauge",
17420
+ "counter",
17421
+ "boolean",
17422
+ "enum"
17423
+ ]);
17424
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17425
+ var DeviceHistoryProducerKindSchema = _enum([
17414
17426
  "gauge",
17415
17427
  "counter",
17416
17428
  "boolean"
@@ -17447,7 +17459,13 @@ var SeriesInfoSchema = object({
17447
17459
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17448
17460
  unit: string().nullable(),
17449
17461
  displayName: string(),
17450
- source: _enum(["cap", "addon"]),
17462
+ source: _enum([
17463
+ "cap",
17464
+ "addon",
17465
+ "derived"
17466
+ ]),
17467
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17468
+ values: array(string()).readonly().nullable(),
17451
17469
  firstTs: number(),
17452
17470
  lastTs: number()
17453
17471
  });
@@ -17461,17 +17479,31 @@ var QueryPointSchema = object({
17461
17479
  twMean: number().nullable(),
17462
17480
  min: number(),
17463
17481
  max: number(),
17464
- /** `null` is unknown, never zero (D393). */
17465
- last: number().nullable()
17482
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17483
+ last: number().nullable(),
17484
+ /**
17485
+ * The increase over the point: a `counter`'s growth since the previous point
17486
+ * or bucket (a drop is a reset, counted from zero), and for
17487
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17488
+ * every other kind, and when it cannot be known.
17489
+ */
17490
+ delta: number().nullable(),
17491
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17492
+ state: string().nullable(),
17493
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17494
+ states: record(string(), number()).nullable()
17466
17495
  });
17467
17496
  var QuerySeriesSchema = object({
17468
17497
  scope: string(),
17469
17498
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17470
17499
  before: object({
17471
17500
  t: number(),
17472
- value: number().nullable()
17501
+ value: number().nullable(),
17502
+ state: string().nullable()
17473
17503
  }).nullable(),
17474
- points: array(QueryPointSchema).readonly()
17504
+ points: array(QueryPointSchema).readonly(),
17505
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17506
+ derivedFrom: string().nullable()
17475
17507
  });
17476
17508
  /** The window part of a query, shared by the device and node forms. */
17477
17509
  var QueryWindowShape = {
@@ -17487,6 +17519,23 @@ var QueryResultSchema = object({
17487
17519
  series: array(QuerySeriesSchema).readonly(),
17488
17520
  truncated: boolean()
17489
17521
  });
17522
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17523
+ var QueryManyItemSchema = union([object({
17524
+ deviceId: number().int(),
17525
+ key: string(),
17526
+ scope: string().optional()
17527
+ }), object({
17528
+ forNodeId: string().min(1),
17529
+ key: string(),
17530
+ scope: string().optional()
17531
+ })]);
17532
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17533
+ ok: literal(true),
17534
+ result: QueryResultSchema
17535
+ }), object({
17536
+ ok: literal(false),
17537
+ error: string()
17538
+ })]);
17490
17539
  var TierStatusSchema = object({
17491
17540
  tier: DeviceHistoryResolutionSchema,
17492
17541
  /** `null` until the first background count answered. */
@@ -17542,16 +17591,22 @@ var DeviceHistoryStatusSchema = object({
17542
17591
  lastRefreshAt: number().nullable()
17543
17592
  })
17544
17593
  });
17545
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17594
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17546
17595
  deviceId: number().int(),
17547
17596
  ...QueryWindowShape
17548
17597
  }), QueryResultSchema), method(object({
17549
- nodeId: string().min(1),
17598
+ forNodeId: string().min(1),
17550
17599
  ...QueryWindowShape
17551
17600
  }), QueryResultSchema, { auth: "admin" }), method(object({
17601
+ items: array(QueryManyItemSchema).min(1).max(24),
17602
+ from: QueryWindowShape.from,
17603
+ to: QueryWindowShape.to,
17604
+ resolution: QueryWindowShape.resolution,
17605
+ maxPoints: QueryWindowShape.maxPoints
17606
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17552
17607
  name: string().regex(/^[a-z0-9-]+$/),
17553
17608
  subjectKind: _enum(["device", "node"]),
17554
- kind: DeviceHistoryKindSchema,
17609
+ kind: DeviceHistoryProducerKindSchema,
17555
17610
  unit: string().optional(),
17556
17611
  displayName: string().min(1),
17557
17612
  ingest: _enum(["points", "buckets"])
@@ -40568,14 +40623,106 @@ var LogEntrySchema = object({
40568
40623
  meta: record(string(), unknown()).optional(),
40569
40624
  tags: record(string(), string()).optional()
40570
40625
  });
40571
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40572
- scope: array(string()).optional(),
40626
+ /**
40627
+ * A history READ against one destination (D898).
40628
+ *
40629
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40630
+ * browser applied after the limit is what made a rare device's lines
40631
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40632
+ * minted (opaque to everyone else): a file position for the rotated files, a
40633
+ * nanosecond timestamp for Loki.
40634
+ *
40635
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40636
+ * store answers `done: false` with the cursor it reached and the bytes it
40637
+ * scanned, and the caller decides whether to go on. That is what makes a long
40638
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40639
+ * flight, and not asking for the next slice ends the scan.
40640
+ */
40641
+ var LogReadQuerySchema = object({
40642
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40643
+ requestId: string().min(1).max(64).optional(),
40644
+ /** The device the line is about (`tags.deviceId`, numeric). */
40645
+ deviceId: number().int().optional(),
40646
+ /**
40647
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40648
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40649
+ */
40650
+ fromAddonId: string().min(1).max(200).optional(),
40651
+ /**
40652
+ * The emitting node: matches the agent that emitted the line, the node
40653
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40654
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40655
+ * name as "which node's provider".
40656
+ */
40657
+ fromNodeId: string().min(1).max(200).optional(),
40658
+ /** Any other tag, exact match (AND). */
40659
+ tags: record(string(), union([string(), number()])).optional(),
40660
+ /** Severity FLOOR: this level and above. */
40573
40661
  level: LogLevelSchema.optional(),
40574
- since: date().optional(),
40575
- until: date().optional(),
40576
- limit: number().optional(),
40577
- tags: record(string(), string()).optional()
40578
- }), array(LogEntrySchema).readonly());
40662
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40663
+ text: string().min(1).max(200).optional(),
40664
+ /** Epoch ms, inclusive. */
40665
+ since: number().optional(),
40666
+ /** Epoch ms, inclusive. */
40667
+ until: number().optional(),
40668
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40669
+ before: string().min(1).max(1024).optional(),
40670
+ /** Newer than this cursor (exclusive). */
40671
+ after: string().min(1).max(1024).optional(),
40672
+ limit: number().int().min(1).max(1e3).optional(),
40673
+ /** Wall-clock bound of this slice. The provider caps it. */
40674
+ budgetMs: number().int().min(50).max(1e4).optional()
40675
+ });
40676
+ var LogReadResultSchema = object({
40677
+ /** Newest first. */
40678
+ entries: array(object({
40679
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40680
+ id: string().optional(),
40681
+ /** Epoch ms. */
40682
+ timestamp: number(),
40683
+ level: LogLevelSchema,
40684
+ scope: string().optional(),
40685
+ message: string(),
40686
+ tags: record(string(), union([string(), number()])).optional(),
40687
+ meta: record(string(), unknown()).optional()
40688
+ })),
40689
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40690
+ nextBefore: string().nullable(),
40691
+ /** Pass as `after` to read what arrived since; null when unknown. */
40692
+ nextAfter: string().nullable(),
40693
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40694
+ scannedBytes: number().int().nonnegative(),
40695
+ /**
40696
+ * True when the scan in this direction reached the end of the store.
40697
+ * False with fewer than `limit` entries means the budget ran out first —
40698
+ * call again with `nextBefore` to go on.
40699
+ */
40700
+ done: boolean(),
40701
+ /** True when `cancelRead` ended this slice early. */
40702
+ cancelled: boolean().optional()
40703
+ });
40704
+ var LogReadCapabilitiesSchema = object({
40705
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40706
+ readable: boolean(),
40707
+ /** Why not, when `readable` is false — rendered next to the source. */
40708
+ reason: string().nullable(),
40709
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40710
+ filters: object({
40711
+ deviceId: boolean(),
40712
+ addonId: boolean(),
40713
+ nodeId: boolean(),
40714
+ tags: boolean(),
40715
+ level: boolean(),
40716
+ text: boolean(),
40717
+ timeRange: boolean()
40718
+ }),
40719
+ /** How far back the store reaches, when the provider knows (days). */
40720
+ retentionDays: number().nullable()
40721
+ });
40722
+ 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() }), {
40723
+ kind: "mutation",
40724
+ auth: "admin"
40725
+ });
40579
40726
  /**
40580
40727
  * `login-method` — collection cap through which auth addons contribute
40581
40728
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -43131,6 +43278,33 @@ var NcRuleTargetSchema = object({
43131
43278
  params: record(string(), unknown()).optional()
43132
43279
  });
43133
43280
  /**
43281
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43282
+ *
43283
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43284
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43285
+ * to the zone that fired the rule) and renders it once at send time:
43286
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43287
+ * colour and every OTHER track visible at that instant outlined thin, each
43288
+ * labelled with class and confidence ("dog 87%").
43289
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43290
+ * - `clean` — the whole scene with nothing drawn on it.
43291
+ * - `none` — no picture.
43292
+ *
43293
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43294
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43295
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43296
+ * ship a crop on one event and a boxed scene on the next depending on which
43297
+ * stored kind had landed.
43298
+ */
43299
+ var NcMediaImageSchema = _enum([
43300
+ "scene-boxes",
43301
+ "crop",
43302
+ "clean",
43303
+ "none"
43304
+ ]);
43305
+ /**
43306
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43307
+ *
43134
43308
  * Media attachment policy (P1 still-image subset).
43135
43309
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43136
43310
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43144,6 +43318,8 @@ var NcRuleTargetSchema = object({
43144
43318
  * - `none` — no attachment.
43145
43319
  */
43146
43320
  /**
43321
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43322
+ *
43147
43323
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43148
43324
  * conflate it with the selection strategy and betray the request: asking for
43149
43325
  * the clean scene frame on an object-event owner used to start at
@@ -43172,16 +43348,29 @@ var NcMediaFrameSchema = _enum([
43172
43348
  */
43173
43349
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43174
43350
  var NcMediaPolicySchema = object({
43351
+ /**
43352
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43353
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43354
+ * triple below, at load and at every write, and the store keeps only this.
43355
+ */
43356
+ image: NcMediaImageSchema.optional(),
43357
+ /**
43358
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43359
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43360
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43361
+ * Replaces `zoneCrop`.
43362
+ */
43363
+ showTriggerZone: boolean().optional(),
43364
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43175
43365
  attach: _enum([
43176
43366
  "best",
43177
43367
  "best-matching",
43178
43368
  "keyFrame",
43179
43369
  "none"
43180
- ]).default("best"),
43181
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43370
+ ]).optional(),
43371
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43182
43372
  frame: NcMediaFrameSchema.optional(),
43183
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43184
- * "show me the ZONE", not the whole scene or the subject crop. */
43373
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43185
43374
  zoneCrop: boolean().optional(),
43186
43375
  /**
43187
43376
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43353,7 +43542,9 @@ var NcRuleInputSchema = object({
43353
43542
  * targets.
43354
43543
  */
43355
43544
  targetUsers: array(string()).optional(),
43356
- media: NcMediaPolicySchema.default({ attach: "best" }),
43545
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43546
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43547
+ media: NcMediaPolicySchema.default({}),
43357
43548
  throttle: NcThrottleSchema.default({
43358
43549
  cooldownSec: 60,
43359
43550
  scope: "rule-device"
@@ -44290,13 +44481,37 @@ var NcAlarmModeOpeningsSchema = object({
44290
44481
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44291
44482
  unknown: array(number().int())
44292
44483
  });
44484
+ /**
44485
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44486
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44487
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44488
+ * never looks fully armed (D62: off must never look like broken).
44489
+ */
44490
+ var NcAlarmInputBypassViewSchema = object({
44491
+ ruleId: string(),
44492
+ /** The rule's current name (its frozen name when the rule is gone). */
44493
+ ruleName: string(),
44494
+ /** The input: the sensor of the match, else its camera. */
44495
+ deviceId: number().int(),
44496
+ /** The input's current name. */
44497
+ name: string(),
44498
+ /** When it was bypassed (ms epoch). */
44499
+ since: number(),
44500
+ /** Triggers from this input dropped since. */
44501
+ dropped: number().int().min(0)
44502
+ });
44293
44503
  var NcAlarmLiveSchema = object({
44294
44504
  state: AlarmStateSchema,
44295
44505
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44296
44506
  targetMode: AlarmArmModeSchema.nullable(),
44297
44507
  availableModes: array(AlarmArmModeSchema),
44298
44508
  openings: array(NcAlarmModeOpeningsSchema),
44299
- exclusions: array(NcAlarmExclusionViewSchema)
44509
+ exclusions: array(NcAlarmExclusionViewSchema),
44510
+ /**
44511
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44512
+ * Defaulted so an older hub answer still parses (as "none known").
44513
+ */
44514
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44300
44515
  });
44301
44516
  var NcAlarmConfigSchema = object({
44302
44517
  /**
@@ -58216,9 +58431,24 @@ var NpuInfoSchema = object({
58216
58431
  name: string().optional(),
58217
58432
  generation: _enum(["xdna1", "xdna2"]).optional()
58218
58433
  });
58434
+ var CoralBusSchema = _enum(["usb", "pci"]);
58219
58435
  var CoralInfoSchema = object({
58220
58436
  type: literal("coral-edgetpu"),
58221
- bus: string().optional()
58437
+ /** Legacy single-bus report (older nodes) — read via `coralUsableUnits`. */
58438
+ bus: string().optional(),
58439
+ /** Legacy USB unit count (older nodes) — read via `coralUsableUnits`. */
58440
+ count: number().int().nonnegative().optional(),
58441
+ /** Usable units per bus — each one is its own `edgetpu:<bus>[:N]` device. */
58442
+ units: array(object({
58443
+ bus: CoralBusSchema,
58444
+ count: number().int().nonnegative()
58445
+ })).readonly().optional(),
58446
+ /** Present-but-unusable units, each with its typed reason (never "absent"). */
58447
+ unavailable: array(object({
58448
+ bus: CoralBusSchema,
58449
+ count: number().int().nonnegative(),
58450
+ reason: _enum(["driver-missing", "device-not-accessible"])
58451
+ })).readonly().optional()
58222
58452
  });
58223
58453
  var HardwareInfoSchema = object({
58224
58454
  platform: HardwarePlatformSchema,
@@ -65958,7 +66188,19 @@ Object.freeze({
65958
66188
  addonId: null,
65959
66189
  access: "view"
65960
66190
  },
65961
- "logDestination.query": {
66191
+ "logDestination.cancelRead": {
66192
+ capName: "log-destination",
66193
+ capScope: "system",
66194
+ addonId: null,
66195
+ access: "create"
66196
+ },
66197
+ "logDestination.describeRead": {
66198
+ capName: "log-destination",
66199
+ capScope: "system",
66200
+ addonId: null,
66201
+ access: "view"
66202
+ },
66203
+ "logDestination.read": {
65962
66204
  capName: "log-destination",
65963
66205
  capScope: "system",
65964
66206
  addonId: null,
@@ -71965,6 +72207,11 @@ Object.freeze({
71965
72207
  form: "single",
71966
72208
  optional: false
71967
72209
  }],
72210
+ "logDestination.read": [{
72211
+ name: "deviceId",
72212
+ form: "single",
72213
+ optional: true
72214
+ }],
71968
72215
  "mediaPlayer.getStatus": [{
71969
72216
  name: "deviceId",
71970
72217
  form: "single",
@@ -5547,7 +5547,7 @@ var ZodIssueCode = {
5547
5547
  var ZodFirstPartyTypeKind;
5548
5548
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5549
5549
  //#endregion
5550
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5550
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5551
5551
  /**
5552
5552
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5553
5553
  * window to float samples (D455).
@@ -17406,7 +17406,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17406
17406
  kind: literal("node"),
17407
17407
  nodeId: string().min(1)
17408
17408
  })]);
17409
+ /**
17410
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17411
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17412
+ * meaning); a rollup keeps the time spent in each state (`states`).
17413
+ */
17409
17414
  var DeviceHistoryKindSchema = _enum([
17415
+ "gauge",
17416
+ "counter",
17417
+ "boolean",
17418
+ "enum"
17419
+ ]);
17420
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17421
+ var DeviceHistoryProducerKindSchema = _enum([
17410
17422
  "gauge",
17411
17423
  "counter",
17412
17424
  "boolean"
@@ -17443,7 +17455,13 @@ var SeriesInfoSchema = object({
17443
17455
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17444
17456
  unit: string().nullable(),
17445
17457
  displayName: string(),
17446
- source: _enum(["cap", "addon"]),
17458
+ source: _enum([
17459
+ "cap",
17460
+ "addon",
17461
+ "derived"
17462
+ ]),
17463
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17464
+ values: array(string()).readonly().nullable(),
17447
17465
  firstTs: number(),
17448
17466
  lastTs: number()
17449
17467
  });
@@ -17457,17 +17475,31 @@ var QueryPointSchema = object({
17457
17475
  twMean: number().nullable(),
17458
17476
  min: number(),
17459
17477
  max: number(),
17460
- /** `null` is unknown, never zero (D393). */
17461
- last: number().nullable()
17478
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17479
+ last: number().nullable(),
17480
+ /**
17481
+ * The increase over the point: a `counter`'s growth since the previous point
17482
+ * or bucket (a drop is a reset, counted from zero), and for
17483
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17484
+ * every other kind, and when it cannot be known.
17485
+ */
17486
+ delta: number().nullable(),
17487
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17488
+ state: string().nullable(),
17489
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17490
+ states: record(string(), number()).nullable()
17462
17491
  });
17463
17492
  var QuerySeriesSchema = object({
17464
17493
  scope: string(),
17465
17494
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17466
17495
  before: object({
17467
17496
  t: number(),
17468
- value: number().nullable()
17497
+ value: number().nullable(),
17498
+ state: string().nullable()
17469
17499
  }).nullable(),
17470
- points: array(QueryPointSchema).readonly()
17500
+ points: array(QueryPointSchema).readonly(),
17501
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17502
+ derivedFrom: string().nullable()
17471
17503
  });
17472
17504
  /** The window part of a query, shared by the device and node forms. */
17473
17505
  var QueryWindowShape = {
@@ -17483,6 +17515,23 @@ var QueryResultSchema = object({
17483
17515
  series: array(QuerySeriesSchema).readonly(),
17484
17516
  truncated: boolean()
17485
17517
  });
17518
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17519
+ var QueryManyItemSchema = union([object({
17520
+ deviceId: number().int(),
17521
+ key: string(),
17522
+ scope: string().optional()
17523
+ }), object({
17524
+ forNodeId: string().min(1),
17525
+ key: string(),
17526
+ scope: string().optional()
17527
+ })]);
17528
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17529
+ ok: literal(true),
17530
+ result: QueryResultSchema
17531
+ }), object({
17532
+ ok: literal(false),
17533
+ error: string()
17534
+ })]);
17486
17535
  var TierStatusSchema = object({
17487
17536
  tier: DeviceHistoryResolutionSchema,
17488
17537
  /** `null` until the first background count answered. */
@@ -17538,16 +17587,22 @@ var DeviceHistoryStatusSchema = object({
17538
17587
  lastRefreshAt: number().nullable()
17539
17588
  })
17540
17589
  });
17541
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17590
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17542
17591
  deviceId: number().int(),
17543
17592
  ...QueryWindowShape
17544
17593
  }), QueryResultSchema), method(object({
17545
- nodeId: string().min(1),
17594
+ forNodeId: string().min(1),
17546
17595
  ...QueryWindowShape
17547
17596
  }), QueryResultSchema, { auth: "admin" }), method(object({
17597
+ items: array(QueryManyItemSchema).min(1).max(24),
17598
+ from: QueryWindowShape.from,
17599
+ to: QueryWindowShape.to,
17600
+ resolution: QueryWindowShape.resolution,
17601
+ maxPoints: QueryWindowShape.maxPoints
17602
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17548
17603
  name: string().regex(/^[a-z0-9-]+$/),
17549
17604
  subjectKind: _enum(["device", "node"]),
17550
- kind: DeviceHistoryKindSchema,
17605
+ kind: DeviceHistoryProducerKindSchema,
17551
17606
  unit: string().optional(),
17552
17607
  displayName: string().min(1),
17553
17608
  ingest: _enum(["points", "buckets"])
@@ -40564,14 +40619,106 @@ var LogEntrySchema = object({
40564
40619
  meta: record(string(), unknown()).optional(),
40565
40620
  tags: record(string(), string()).optional()
40566
40621
  });
40567
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40568
- scope: array(string()).optional(),
40622
+ /**
40623
+ * A history READ against one destination (D898).
40624
+ *
40625
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40626
+ * browser applied after the limit is what made a rare device's lines
40627
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40628
+ * minted (opaque to everyone else): a file position for the rotated files, a
40629
+ * nanosecond timestamp for Loki.
40630
+ *
40631
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40632
+ * store answers `done: false` with the cursor it reached and the bytes it
40633
+ * scanned, and the caller decides whether to go on. That is what makes a long
40634
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40635
+ * flight, and not asking for the next slice ends the scan.
40636
+ */
40637
+ var LogReadQuerySchema = object({
40638
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40639
+ requestId: string().min(1).max(64).optional(),
40640
+ /** The device the line is about (`tags.deviceId`, numeric). */
40641
+ deviceId: number().int().optional(),
40642
+ /**
40643
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40644
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40645
+ */
40646
+ fromAddonId: string().min(1).max(200).optional(),
40647
+ /**
40648
+ * The emitting node: matches the agent that emitted the line, the node
40649
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40650
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40651
+ * name as "which node's provider".
40652
+ */
40653
+ fromNodeId: string().min(1).max(200).optional(),
40654
+ /** Any other tag, exact match (AND). */
40655
+ tags: record(string(), union([string(), number()])).optional(),
40656
+ /** Severity FLOOR: this level and above. */
40569
40657
  level: LogLevelSchema.optional(),
40570
- since: date().optional(),
40571
- until: date().optional(),
40572
- limit: number().optional(),
40573
- tags: record(string(), string()).optional()
40574
- }), array(LogEntrySchema).readonly());
40658
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40659
+ text: string().min(1).max(200).optional(),
40660
+ /** Epoch ms, inclusive. */
40661
+ since: number().optional(),
40662
+ /** Epoch ms, inclusive. */
40663
+ until: number().optional(),
40664
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40665
+ before: string().min(1).max(1024).optional(),
40666
+ /** Newer than this cursor (exclusive). */
40667
+ after: string().min(1).max(1024).optional(),
40668
+ limit: number().int().min(1).max(1e3).optional(),
40669
+ /** Wall-clock bound of this slice. The provider caps it. */
40670
+ budgetMs: number().int().min(50).max(1e4).optional()
40671
+ });
40672
+ var LogReadResultSchema = object({
40673
+ /** Newest first. */
40674
+ entries: array(object({
40675
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40676
+ id: string().optional(),
40677
+ /** Epoch ms. */
40678
+ timestamp: number(),
40679
+ level: LogLevelSchema,
40680
+ scope: string().optional(),
40681
+ message: string(),
40682
+ tags: record(string(), union([string(), number()])).optional(),
40683
+ meta: record(string(), unknown()).optional()
40684
+ })),
40685
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40686
+ nextBefore: string().nullable(),
40687
+ /** Pass as `after` to read what arrived since; null when unknown. */
40688
+ nextAfter: string().nullable(),
40689
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40690
+ scannedBytes: number().int().nonnegative(),
40691
+ /**
40692
+ * True when the scan in this direction reached the end of the store.
40693
+ * False with fewer than `limit` entries means the budget ran out first —
40694
+ * call again with `nextBefore` to go on.
40695
+ */
40696
+ done: boolean(),
40697
+ /** True when `cancelRead` ended this slice early. */
40698
+ cancelled: boolean().optional()
40699
+ });
40700
+ var LogReadCapabilitiesSchema = object({
40701
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40702
+ readable: boolean(),
40703
+ /** Why not, when `readable` is false — rendered next to the source. */
40704
+ reason: string().nullable(),
40705
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40706
+ filters: object({
40707
+ deviceId: boolean(),
40708
+ addonId: boolean(),
40709
+ nodeId: boolean(),
40710
+ tags: boolean(),
40711
+ level: boolean(),
40712
+ text: boolean(),
40713
+ timeRange: boolean()
40714
+ }),
40715
+ /** How far back the store reaches, when the provider knows (days). */
40716
+ retentionDays: number().nullable()
40717
+ });
40718
+ 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() }), {
40719
+ kind: "mutation",
40720
+ auth: "admin"
40721
+ });
40575
40722
  /**
40576
40723
  * `login-method` — collection cap through which auth addons contribute
40577
40724
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -43127,6 +43274,33 @@ var NcRuleTargetSchema = object({
43127
43274
  params: record(string(), unknown()).optional()
43128
43275
  });
43129
43276
  /**
43277
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43278
+ *
43279
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43280
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43281
+ * to the zone that fired the rule) and renders it once at send time:
43282
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43283
+ * colour and every OTHER track visible at that instant outlined thin, each
43284
+ * labelled with class and confidence ("dog 87%").
43285
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43286
+ * - `clean` — the whole scene with nothing drawn on it.
43287
+ * - `none` — no picture.
43288
+ *
43289
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43290
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43291
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43292
+ * ship a crop on one event and a boxed scene on the next depending on which
43293
+ * stored kind had landed.
43294
+ */
43295
+ var NcMediaImageSchema = _enum([
43296
+ "scene-boxes",
43297
+ "crop",
43298
+ "clean",
43299
+ "none"
43300
+ ]);
43301
+ /**
43302
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43303
+ *
43130
43304
  * Media attachment policy (P1 still-image subset).
43131
43305
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43132
43306
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43140,6 +43314,8 @@ var NcRuleTargetSchema = object({
43140
43314
  * - `none` — no attachment.
43141
43315
  */
43142
43316
  /**
43317
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43318
+ *
43143
43319
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43144
43320
  * conflate it with the selection strategy and betray the request: asking for
43145
43321
  * the clean scene frame on an object-event owner used to start at
@@ -43168,16 +43344,29 @@ var NcMediaFrameSchema = _enum([
43168
43344
  */
43169
43345
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43170
43346
  var NcMediaPolicySchema = object({
43347
+ /**
43348
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43349
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43350
+ * triple below, at load and at every write, and the store keeps only this.
43351
+ */
43352
+ image: NcMediaImageSchema.optional(),
43353
+ /**
43354
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43355
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43356
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43357
+ * Replaces `zoneCrop`.
43358
+ */
43359
+ showTriggerZone: boolean().optional(),
43360
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43171
43361
  attach: _enum([
43172
43362
  "best",
43173
43363
  "best-matching",
43174
43364
  "keyFrame",
43175
43365
  "none"
43176
- ]).default("best"),
43177
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43366
+ ]).optional(),
43367
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43178
43368
  frame: NcMediaFrameSchema.optional(),
43179
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43180
- * "show me the ZONE", not the whole scene or the subject crop. */
43369
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43181
43370
  zoneCrop: boolean().optional(),
43182
43371
  /**
43183
43372
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43349,7 +43538,9 @@ var NcRuleInputSchema = object({
43349
43538
  * targets.
43350
43539
  */
43351
43540
  targetUsers: array(string()).optional(),
43352
- media: NcMediaPolicySchema.default({ attach: "best" }),
43541
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43542
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43543
+ media: NcMediaPolicySchema.default({}),
43353
43544
  throttle: NcThrottleSchema.default({
43354
43545
  cooldownSec: 60,
43355
43546
  scope: "rule-device"
@@ -44286,13 +44477,37 @@ var NcAlarmModeOpeningsSchema = object({
44286
44477
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44287
44478
  unknown: array(number().int())
44288
44479
  });
44480
+ /**
44481
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44482
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44483
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44484
+ * never looks fully armed (D62: off must never look like broken).
44485
+ */
44486
+ var NcAlarmInputBypassViewSchema = object({
44487
+ ruleId: string(),
44488
+ /** The rule's current name (its frozen name when the rule is gone). */
44489
+ ruleName: string(),
44490
+ /** The input: the sensor of the match, else its camera. */
44491
+ deviceId: number().int(),
44492
+ /** The input's current name. */
44493
+ name: string(),
44494
+ /** When it was bypassed (ms epoch). */
44495
+ since: number(),
44496
+ /** Triggers from this input dropped since. */
44497
+ dropped: number().int().min(0)
44498
+ });
44289
44499
  var NcAlarmLiveSchema = object({
44290
44500
  state: AlarmStateSchema,
44291
44501
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44292
44502
  targetMode: AlarmArmModeSchema.nullable(),
44293
44503
  availableModes: array(AlarmArmModeSchema),
44294
44504
  openings: array(NcAlarmModeOpeningsSchema),
44295
- exclusions: array(NcAlarmExclusionViewSchema)
44505
+ exclusions: array(NcAlarmExclusionViewSchema),
44506
+ /**
44507
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44508
+ * Defaulted so an older hub answer still parses (as "none known").
44509
+ */
44510
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44296
44511
  });
44297
44512
  var NcAlarmConfigSchema = object({
44298
44513
  /**
@@ -58212,9 +58427,24 @@ var NpuInfoSchema = object({
58212
58427
  name: string().optional(),
58213
58428
  generation: _enum(["xdna1", "xdna2"]).optional()
58214
58429
  });
58430
+ var CoralBusSchema = _enum(["usb", "pci"]);
58215
58431
  var CoralInfoSchema = object({
58216
58432
  type: literal("coral-edgetpu"),
58217
- bus: string().optional()
58433
+ /** Legacy single-bus report (older nodes) — read via `coralUsableUnits`. */
58434
+ bus: string().optional(),
58435
+ /** Legacy USB unit count (older nodes) — read via `coralUsableUnits`. */
58436
+ count: number().int().nonnegative().optional(),
58437
+ /** Usable units per bus — each one is its own `edgetpu:<bus>[:N]` device. */
58438
+ units: array(object({
58439
+ bus: CoralBusSchema,
58440
+ count: number().int().nonnegative()
58441
+ })).readonly().optional(),
58442
+ /** Present-but-unusable units, each with its typed reason (never "absent"). */
58443
+ unavailable: array(object({
58444
+ bus: CoralBusSchema,
58445
+ count: number().int().nonnegative(),
58446
+ reason: _enum(["driver-missing", "device-not-accessible"])
58447
+ })).readonly().optional()
58218
58448
  });
58219
58449
  var HardwareInfoSchema = object({
58220
58450
  platform: HardwarePlatformSchema,
@@ -65954,7 +66184,19 @@ Object.freeze({
65954
66184
  addonId: null,
65955
66185
  access: "view"
65956
66186
  },
65957
- "logDestination.query": {
66187
+ "logDestination.cancelRead": {
66188
+ capName: "log-destination",
66189
+ capScope: "system",
66190
+ addonId: null,
66191
+ access: "create"
66192
+ },
66193
+ "logDestination.describeRead": {
66194
+ capName: "log-destination",
66195
+ capScope: "system",
66196
+ addonId: null,
66197
+ access: "view"
66198
+ },
66199
+ "logDestination.read": {
65958
66200
  capName: "log-destination",
65959
66201
  capScope: "system",
65960
66202
  addonId: null,
@@ -71961,6 +72203,11 @@ Object.freeze({
71961
72203
  form: "single",
71962
72204
  optional: false
71963
72205
  }],
72206
+ "logDestination.read": [{
72207
+ name: "deviceId",
72208
+ form: "single",
72209
+ optional: true
72210
+ }],
71964
72211
  "mediaPlayer.getStatus": [{
71965
72212
  name: "deviceId",
71966
72213
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-google-services",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "Google Services — Google brokers (OAuth2): Calendar as calendar-source, Gmail send as smtp-provider.",
5
5
  "keywords": [
6
6
  "camstack",