@camstack/addon-decoder-nodeav 1.2.124 → 1.2.126

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 (3) hide show
  1. package/dist/index.js +480 -240
  2. package/dist/index.mjs +480 -240
  3. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
- //#region ../types/dist/event-category-BvOFi6PY.mjs
2
+ //#region ../types/dist/event-category-DOl51-Ij.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -78,9 +78,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
78
78
  /**
79
79
  * The node's one-shot runner boot check (D877): planned runners against the
80
80
  * process service, `degraded` when any is failed, refused or missing. The
81
- * alert centre turns it into one alert and a direct critical push.
81
+ * alert centre turns it into one critical alert.
82
82
  */
83
83
  EventCategory["SystemRunnerCheck"] = "system.runner-check";
84
+ /**
85
+ * An alert EPISODE opened or closed, emitted by the alert centre for alerts
86
+ * of severity `critical` or `error` (`AlertEpisodePayload`). The alert
87
+ * centre sends no notification of its own: Notification Center turns this
88
+ * into the `alert-critical` / `alert-error` / `alert-critical-resolved`
89
+ * system-event kinds, and reconciles from the alerts store because a bus
90
+ * event may be dropped (D8, D11).
91
+ */
92
+ EventCategory["AlertEpisode"] = "alert.episode";
84
93
  EventCategory["AddonError"] = "addon.error";
85
94
  EventCategory["AddonPageReady"] = "addon.page-ready";
86
95
  EventCategory["AddonWidgetReady"] = "addon.widget-ready";
@@ -5405,7 +5414,7 @@ var ZodIssueCode = {
5405
5414
  var ZodFirstPartyTypeKind;
5406
5415
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5407
5416
  //#endregion
5408
- //#region ../types/dist/sleep-BegKjwUu.mjs
5417
+ //#region ../types/dist/sleep-BxjU_fJM.mjs
5409
5418
  /**
5410
5419
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5411
5420
  * window to float samples (D455).
@@ -7787,6 +7796,12 @@ function normalizeAddonInitResult(result) {
7787
7796
  if (Array.isArray(result)) return { providers: result };
7788
7797
  return result;
7789
7798
  }
7799
+ /**
7800
+ * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7801
+ * and validates them (`share-token.service.ts` builds its enum from this
7802
+ * list); a data plane names the kinds it ACCEPTS in `share`.
7803
+ */
7804
+ var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7790
7805
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
7791
7806
  var PeerBytesTicketSchema = object({
7792
7807
  /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
@@ -12381,6 +12396,229 @@ var ConvertResultSchema = object({
12381
12396
  files: array(string()).readonly()
12382
12397
  })).readonly()
12383
12398
  });
12399
+ /**
12400
+ * Zod schemas for persisted record types.
12401
+ *
12402
+ * These schemas serve as the single source of truth for types that are
12403
+ * stored in the settings-store backend and retrieved via tRPC. They
12404
+ * replace the manual TypeScript interfaces with schema-derived types,
12405
+ * enabling runtime validation when reading from the backend.
12406
+ *
12407
+ * Convention: each schema is named `<Type>Schema`, the inferred TS type
12408
+ * keeps the original name for backward compatibility.
12409
+ */
12410
+ /**
12411
+ * Auth model (v2 — 2026-05-12 caps-only):
12412
+ *
12413
+ * Two principals:
12414
+ * - `isAdmin: true` — full bypass. Admin scope set is ignored.
12415
+ * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
12416
+ *
12417
+ * No role enum. There used to be `viewer / agent / scoped` and earlier
12418
+ * `super_admin` — collapsed onto the single boolean because every
12419
+ * non-admin caller is governed by the same scope-check rules; the
12420
+ * distinction was only ever used to route role-specific procedures
12421
+ * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12422
+ * with `isAdmin: false` + an explicit scope list.
12423
+ */
12424
+ /** Per-method access flavour. Materialised on every cap method via codegen. */
12425
+ var MethodAccessSchema = _enum([
12426
+ "view",
12427
+ "create",
12428
+ "delete"
12429
+ ]);
12430
+ /**
12431
+ * A single scope grant. Three forms — checked in matcher with OR
12432
+ * semantics; the first match decides whether the call passes:
12433
+ *
12434
+ * - `category` — broadest. `target: 'device' | 'system'` selects every
12435
+ * cap with the matching `scope` declaration. New caps inherit grants
12436
+ * automatically — adding a device cap to the codebase makes it
12437
+ * reachable to every user with `category:device [...]` without a
12438
+ * re-grant. Use this for "family viewer" / "operator" tiers.
12439
+ *
12440
+ * - `addon` — every cap that ships inside a given addon id. Niche;
12441
+ * useful when an integration needs to interact with one specific
12442
+ * addon's surface regardless of how many caps it exports.
12443
+ *
12444
+ * - `capability` — the most precise form. Single cap name. Use for
12445
+ * integration tokens where you want to grant `addons.installPackage`
12446
+ * and nothing else.
12447
+ *
12448
+ * `access` is REQUIRED with min 1 element. `admin` bypass is the
12449
+ * "give me everything" escape; there is no wildcard scope.
12450
+ */
12451
+ var AllowedProviderSchema = union([literal("*"), array(string())]);
12452
+ var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
12453
+ var CapScopeSchema = _enum(["device", "system"]);
12454
+ /**
12455
+ * DeviceSelector (scope model v3 — 2026-08-12).
12456
+ *
12457
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
12458
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
12459
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
12460
+ * AFTER the grant was minted — no re-grant, no re-login.
12461
+ *
12462
+ * - `all` — every device in the deployment. The broad viewer/operator
12463
+ * lever without a `category` grant (a `category` grant also covers device
12464
+ * caps that carry no deviceId; `all` is specifically the device set).
12465
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
12466
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
12467
+ * is NOT covered until the grant is edited.
12468
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
12469
+ * DYNAMIC. A device that changes type, or a new device of the type,
12470
+ * re-resolves on the next request.
12471
+ * - `locations` — every device whose operator-assigned `location` label is
12472
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
12473
+ * null/unset location matches NO `locations` selector.
12474
+ */
12475
+ var DeviceSelectorSchema = discriminatedUnion("kind", [
12476
+ object({ kind: literal("all") }),
12477
+ object({
12478
+ kind: literal("ids"),
12479
+ ids: array(number().int()).min(1)
12480
+ }),
12481
+ object({
12482
+ kind: literal("types"),
12483
+ types: array(_enum(DeviceType)).min(1)
12484
+ }),
12485
+ object({
12486
+ kind: literal("locations"),
12487
+ locations: array(string().min(1)).min(1)
12488
+ })
12489
+ ]);
12490
+ var DeviceTokenScopeSchema = object({
12491
+ type: literal("device"),
12492
+ /** The device SET this grant covers — resolved against the live fleet. */
12493
+ selector: DeviceSelectorSchema,
12494
+ access: array(MethodAccessSchema).min(1),
12495
+ /**
12496
+ * Whether a grant on a PARENT device transparently covers its accessory
12497
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
12498
+ * Direction is parent → children ONLY.
12499
+ *
12500
+ * Absent → the matcher DERIVES it from the access flavour: `view`
12501
+ * inherits (a camera viewer sees the camera's accessories), `create` /
12502
+ * `delete` do NOT (actuating/removing a child is an explicit act the
12503
+ * operator must grant on the child, not inherit from the parent). Set it
12504
+ * explicitly to override that default per grant.
12505
+ */
12506
+ includeLinked: boolean().optional()
12507
+ });
12508
+ /**
12509
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
12510
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
12511
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
12512
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
12513
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
12514
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
12515
+ * migration cannot reach a JWT already in a client's hands; parse-time
12516
+ * migration covers both without a flag day. No cast — the raw object is read
12517
+ * through `Reflect.get` (its static type is `unknown`).
12518
+ */
12519
+ function migrateLegacyTokenScope(raw) {
12520
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
12521
+ if (Reflect.get(raw, "type") !== "device") return raw;
12522
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
12523
+ const targets = Reflect.get(raw, "targets");
12524
+ if (!Array.isArray(targets)) return raw;
12525
+ return {
12526
+ type: "device",
12527
+ selector: {
12528
+ kind: "ids",
12529
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
12530
+ },
12531
+ access: Reflect.get(raw, "access")
12532
+ };
12533
+ }
12534
+ var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
12535
+ object({
12536
+ type: literal("category"),
12537
+ target: CapScopeSchema,
12538
+ access: array(MethodAccessSchema).min(1)
12539
+ }),
12540
+ object({
12541
+ type: literal("capability"),
12542
+ target: string(),
12543
+ access: array(MethodAccessSchema).min(1)
12544
+ }),
12545
+ object({
12546
+ type: literal("addon"),
12547
+ target: string(),
12548
+ access: array(MethodAccessSchema).min(1)
12549
+ }),
12550
+ DeviceTokenScopeSchema
12551
+ ]));
12552
+ object({
12553
+ id: string(),
12554
+ username: string(),
12555
+ passwordHash: string(),
12556
+ /**
12557
+ * Admin bypass. When true, the middleware skips the scope-access
12558
+ * check entirely. There is no other axis of privilege; the legacy
12559
+ * role enum collapsed onto this boolean in v2.
12560
+ */
12561
+ isAdmin: boolean().default(false),
12562
+ allowedProviders: AllowedProviderSchema,
12563
+ allowedDevices: AllowedDevicesSchema,
12564
+ /**
12565
+ * Scopes granted to this user. Admins bypass; their `scopes` is
12566
+ * ignored. Non-admins without scopes are locked out of every
12567
+ * protected call.
12568
+ */
12569
+ scopes: array(TokenScopeSchema).default([]),
12570
+ createdAt: number(),
12571
+ updatedAt: number()
12572
+ });
12573
+ object({
12574
+ id: string(),
12575
+ label: string(),
12576
+ isAdmin: boolean().default(false),
12577
+ allowedProviders: AllowedProviderSchema,
12578
+ allowedDevices: AllowedDevicesSchema,
12579
+ tokenHash: string(),
12580
+ tokenPrefix: string(),
12581
+ createdAt: number(),
12582
+ lastUsedAt: number().optional()
12583
+ });
12584
+ object({
12585
+ id: string(),
12586
+ userId: string(),
12587
+ name: string(),
12588
+ tokenHash: string(),
12589
+ tokenPrefix: string(),
12590
+ scopes: array(TokenScopeSchema),
12591
+ expiresAt: number().nullish(),
12592
+ lastUsedAt: number().nullish(),
12593
+ createdAt: number()
12594
+ });
12595
+ /** What a share-view grant lets its holder see. */
12596
+ var ShareViewGrantSchema = object({
12597
+ kind: _enum(SHARE_VIEW_KINDS),
12598
+ deviceIds: array(number().int().nonnegative()).min(1).max(64),
12599
+ /** Talk-back, opt-in at mint time; absent means off. */
12600
+ talk: boolean().optional()
12601
+ });
12602
+ var ShareViewScopeSchema = object({
12603
+ type: literal("share-view"),
12604
+ grant: ShareViewGrantSchema
12605
+ });
12606
+ var AddonRoutesScopeSchema = object({
12607
+ type: literal("addon-routes"),
12608
+ access: array(MethodAccessSchema).min(1)
12609
+ });
12610
+ var CredentialScopeSchema = union([
12611
+ literal("*"),
12612
+ ShareViewScopeSchema,
12613
+ AddonRoutesScopeSchema,
12614
+ TokenScopeSchema
12615
+ ]);
12616
+ object({
12617
+ kind: literal("credential"),
12618
+ sub: string().min(1),
12619
+ jti: string().min(16),
12620
+ scopes: array(CredentialScopeSchema).min(1)
12621
+ });
12384
12622
  _enum(["new-session", "step-up"]);
12385
12623
  /** The languages the hub's app landing pages are written in (D858). */
12386
12624
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -13097,7 +13335,14 @@ var AlertSeveritySchema = _enum([
13097
13335
  ]);
13098
13336
  var AlertActionSchema = object({
13099
13337
  label: string(),
13100
- href: string().optional()
13338
+ href: string().optional(),
13339
+ /**
13340
+ * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
13341
+ * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
13342
+ * start) — the browser must leave the SPA with a full navigation, because
13343
+ * the SPA has no such route and would bounce to the home page.
13344
+ */
13345
+ navigation: _enum(["app", "server"]).optional()
13101
13346
  });
13102
13347
  var AlertStatusSchema = _enum([
13103
13348
  "active",
@@ -41591,6 +41836,9 @@ var NcSystemEventKindSchema = _enum([
41591
41836
  "server-updated",
41592
41837
  "export-completed",
41593
41838
  "backup-completed",
41839
+ "alert-critical",
41840
+ "alert-error",
41841
+ "alert-critical-resolved",
41594
41842
  "camera-online",
41595
41843
  "camera-offline",
41596
41844
  "camera-disabled",
@@ -43626,202 +43874,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
43626
43874
  auth: "admin"
43627
43875
  }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
43628
43876
  /**
43629
- * Zod schemas for persisted record types.
43630
- *
43631
- * These schemas serve as the single source of truth for types that are
43632
- * stored in the settings-store backend and retrieved via tRPC. They
43633
- * replace the manual TypeScript interfaces with schema-derived types,
43634
- * enabling runtime validation when reading from the backend.
43635
- *
43636
- * Convention: each schema is named `<Type>Schema`, the inferred TS type
43637
- * keeps the original name for backward compatibility.
43638
- */
43639
- /**
43640
- * Auth model (v2 — 2026-05-12 caps-only):
43641
- *
43642
- * Two principals:
43643
- * - `isAdmin: true` — full bypass. Admin scope set is ignored.
43644
- * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
43645
- *
43646
- * No role enum. There used to be `viewer / agent / scoped` and earlier
43647
- * `super_admin` — collapsed onto the single boolean because every
43648
- * non-admin caller is governed by the same scope-check rules; the
43649
- * distinction was only ever used to route role-specific procedures
43650
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
43651
- * with `isAdmin: false` + an explicit scope list.
43652
- */
43653
- /** Per-method access flavour. Materialised on every cap method via codegen. */
43654
- var MethodAccessSchema = _enum([
43655
- "view",
43656
- "create",
43657
- "delete"
43658
- ]);
43659
- /**
43660
- * A single scope grant. Three forms — checked in matcher with OR
43661
- * semantics; the first match decides whether the call passes:
43662
- *
43663
- * - `category` — broadest. `target: 'device' | 'system'` selects every
43664
- * cap with the matching `scope` declaration. New caps inherit grants
43665
- * automatically — adding a device cap to the codebase makes it
43666
- * reachable to every user with `category:device [...]` without a
43667
- * re-grant. Use this for "family viewer" / "operator" tiers.
43668
- *
43669
- * - `addon` — every cap that ships inside a given addon id. Niche;
43670
- * useful when an integration needs to interact with one specific
43671
- * addon's surface regardless of how many caps it exports.
43672
- *
43673
- * - `capability` — the most precise form. Single cap name. Use for
43674
- * integration tokens where you want to grant `addons.installPackage`
43675
- * and nothing else.
43676
- *
43677
- * `access` is REQUIRED with min 1 element. `admin` bypass is the
43678
- * "give me everything" escape; there is no wildcard scope.
43679
- */
43680
- var AllowedProviderSchema = union([literal("*"), array(string())]);
43681
- var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
43682
- var CapScopeSchema = _enum(["device", "system"]);
43683
- /**
43684
- * DeviceSelector (scope model v3 — 2026-08-12).
43685
- *
43686
- * A `device` grant no longer carries a frozen list of deviceIds. It carries
43687
- * a SELECTOR the matcher resolves against the live fleet, so the grant can be
43688
- * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
43689
- * AFTER the grant was minted — no re-grant, no re-login.
43690
- *
43691
- * - `all` — every device in the deployment. The broad viewer/operator
43692
- * lever without a `category` grant (a `category` grant also covers device
43693
- * caps that carry no deviceId; `all` is specifically the device set).
43694
- * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
43695
- * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
43696
- * is NOT covered until the grant is edited.
43697
- * - `types` — every device of a `DeviceType` (e.g. every `camera`).
43698
- * DYNAMIC. A device that changes type, or a new device of the type,
43699
- * re-resolves on the next request.
43700
- * - `locations` — every device whose operator-assigned `location` label is
43701
- * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
43702
- * null/unset location matches NO `locations` selector.
43703
- */
43704
- var DeviceSelectorSchema = discriminatedUnion("kind", [
43705
- object({ kind: literal("all") }),
43706
- object({
43707
- kind: literal("ids"),
43708
- ids: array(number().int()).min(1)
43709
- }),
43710
- object({
43711
- kind: literal("types"),
43712
- types: array(_enum(DeviceType)).min(1)
43713
- }),
43714
- object({
43715
- kind: literal("locations"),
43716
- locations: array(string().min(1)).min(1)
43717
- })
43718
- ]);
43719
- var DeviceTokenScopeSchema = object({
43720
- type: literal("device"),
43721
- /** The device SET this grant covers — resolved against the live fleet. */
43722
- selector: DeviceSelectorSchema,
43723
- access: array(MethodAccessSchema).min(1),
43724
- /**
43725
- * Whether a grant on a PARENT device transparently covers its accessory
43726
- * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
43727
- * Direction is parent → children ONLY.
43728
- *
43729
- * Absent → the matcher DERIVES it from the access flavour: `view`
43730
- * inherits (a camera viewer sees the camera's accessories), `create` /
43731
- * `delete` do NOT (actuating/removing a child is an explicit act the
43732
- * operator must grant on the child, not inherit from the parent). Set it
43733
- * explicitly to override that default per grant.
43734
- */
43735
- includeLinked: boolean().optional()
43736
- });
43737
- /**
43738
- * v2 → v3 lazy migration. A pre-v3 `device` grant carried
43739
- * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
43740
- * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
43741
- * EVERY parse path — stored records AND the JWT-carried scope arrays
43742
- * normalised at the request boundary ({@link normalizeTokenScopes} in
43743
- * `device-selector.ts`). Chosen over a one-time DB migration because a
43744
- * migration cannot reach a JWT already in a client's hands; parse-time
43745
- * migration covers both without a flag day. No cast — the raw object is read
43746
- * through `Reflect.get` (its static type is `unknown`).
43747
- */
43748
- function migrateLegacyTokenScope(raw) {
43749
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
43750
- if (Reflect.get(raw, "type") !== "device") return raw;
43751
- if (Reflect.get(raw, "selector") !== void 0) return raw;
43752
- const targets = Reflect.get(raw, "targets");
43753
- if (!Array.isArray(targets)) return raw;
43754
- return {
43755
- type: "device",
43756
- selector: {
43757
- kind: "ids",
43758
- ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
43759
- },
43760
- access: Reflect.get(raw, "access")
43761
- };
43762
- }
43763
- var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
43764
- object({
43765
- type: literal("category"),
43766
- target: CapScopeSchema,
43767
- access: array(MethodAccessSchema).min(1)
43768
- }),
43769
- object({
43770
- type: literal("capability"),
43771
- target: string(),
43772
- access: array(MethodAccessSchema).min(1)
43773
- }),
43774
- object({
43775
- type: literal("addon"),
43776
- target: string(),
43777
- access: array(MethodAccessSchema).min(1)
43778
- }),
43779
- DeviceTokenScopeSchema
43780
- ]));
43781
- object({
43782
- id: string(),
43783
- username: string(),
43784
- passwordHash: string(),
43785
- /**
43786
- * Admin bypass. When true, the middleware skips the scope-access
43787
- * check entirely. There is no other axis of privilege; the legacy
43788
- * role enum collapsed onto this boolean in v2.
43789
- */
43790
- isAdmin: boolean().default(false),
43791
- allowedProviders: AllowedProviderSchema,
43792
- allowedDevices: AllowedDevicesSchema,
43793
- /**
43794
- * Scopes granted to this user. Admins bypass; their `scopes` is
43795
- * ignored. Non-admins without scopes are locked out of every
43796
- * protected call.
43797
- */
43798
- scopes: array(TokenScopeSchema).default([]),
43799
- createdAt: number(),
43800
- updatedAt: number()
43801
- });
43802
- object({
43803
- id: string(),
43804
- label: string(),
43805
- isAdmin: boolean().default(false),
43806
- allowedProviders: AllowedProviderSchema,
43807
- allowedDevices: AllowedDevicesSchema,
43808
- tokenHash: string(),
43809
- tokenPrefix: string(),
43810
- createdAt: number(),
43811
- lastUsedAt: number().optional()
43812
- });
43813
- object({
43814
- id: string(),
43815
- userId: string(),
43816
- name: string(),
43817
- tokenHash: string(),
43818
- tokenPrefix: string(),
43819
- scopes: array(TokenScopeSchema),
43820
- expiresAt: number().nullish(),
43821
- lastUsedAt: number().nullish(),
43822
- createdAt: number()
43823
- });
43824
- /**
43825
43877
  * `oauth-integration` — a collection cap by which an addon declares
43826
43878
  * itself a linkable OAuth client of the hub's core `/oauth2/*` server.
43827
43879
  * Each provider returns a static descriptor; the core enumerates them
@@ -50623,7 +50675,10 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
50623
50675
  }), method(object({ jobId: string().optional() }), StorageMigrationJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
50624
50676
  kind: "mutation",
50625
50677
  auth: "admin"
50626
- }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
50678
+ }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({ locationIds: array(string()).readonly() }), object({
50679
+ clear: boolean(),
50680
+ repointLocationId: string().optional()
50681
+ }), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
50627
50682
  kind: "mutation",
50628
50683
  auth: "admin"
50629
50684
  }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
@@ -54058,6 +54113,11 @@ object({
54058
54113
  *
54059
54114
  * `kind: 'poll'` — cloud REST APIs typically have no push channel; the
54060
54115
  * provider refreshes the slice on an interval and eagerly after commands.
54116
+ *
54117
+ * UNKNOWN IS NOT OFF. Every field the appliance reports separately is
54118
+ * nullable: `null` means "not known right now" (the appliance has not said,
54119
+ * the link is down, or the description does not carry it) and is never
54120
+ * rendered or exported as `false` / `0`. `availability` says why.
54061
54121
  */
54062
54122
  var DishwasherStateSchema = _enum([
54063
54123
  "idle",
@@ -54067,112 +54127,227 @@ var DishwasherStateSchema = _enum([
54067
54127
  "error",
54068
54128
  "unavailable"
54069
54129
  ]);
54130
+ /**
54131
+ * The appliance's own operation state, uncollapsed. `state` above is the coarse
54132
+ * view for compact surfaces; this is what the appliance said.
54133
+ */
54134
+ var DishwasherOperationStateSchema = _enum([
54135
+ "Inactive",
54136
+ "Ready",
54137
+ "DelayedStart",
54138
+ "Run",
54139
+ "Pause",
54140
+ "ActionRequired",
54141
+ "Finished",
54142
+ "Error",
54143
+ "Aborting"
54144
+ ]);
54145
+ /**
54146
+ * Why fields may be `null`:
54147
+ * - `available` — the link is up and the description is loaded;
54148
+ * - `offline` — the local link is down (values are unknown, not last-known);
54149
+ * - `description-missing` — the link is up but the appliance's description could not
54150
+ * be loaded, so its values cannot be decoded.
54151
+ */
54152
+ var DishwasherAvailabilitySchema = _enum([
54153
+ "available",
54154
+ "offline",
54155
+ "description-missing"
54156
+ ]);
54070
54157
  var DishwasherConsumableLevelSchema = _enum([
54071
54158
  "ok",
54072
54159
  "low",
54073
54160
  "empty"
54074
54161
  ]);
54075
54162
  object({
54163
+ availability: DishwasherAvailabilitySchema,
54164
+ /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
54076
54165
  state: DishwasherStateSchema,
54077
- /** Active program id/name, or null when none selected / unknown. */
54166
+ /** The appliance's operation state as reported; null when not known. */
54167
+ operationState: DishwasherOperationStateSchema.nullable(),
54168
+ /** Feature key of the ACTIVE (running) program, or null when none runs / not known. */
54078
54169
  program: string().nullable(),
54079
- /** Program tokens the hardware accepts — drives the UI selector. */
54170
+ /** Feature key of the SELECTED program (what Start would run), or null when none / not known. */
54171
+ selectedProgram: string().nullable(),
54172
+ /** Feature keys of the programs the appliance currently offers — drives the UI selector. */
54080
54173
  availablePrograms: array(string()),
54081
- /** Minutes remaining on the active cycle, or null when not running. */
54082
- remainingMinutes: number().int().nonnegative().nullable(),
54174
+ /** Seconds remaining on the active cycle, or null when not running / not known. */
54175
+ remainingSeconds: number().int().nonnegative().nullable(),
54176
+ /** Seconds the delayed start is set to (time until the cycle starts), or null. */
54177
+ delayedStartSeconds: number().int().nonnegative().nullable(),
54083
54178
  /** Cycle completion 0..100, or null when not applicable. */
54084
54179
  progressPercent: number().min(0).max(100).nullable(),
54085
- /** True when the door is reported open. */
54086
- doorOpen: boolean(),
54087
- /** True when remote start is allowed (door closed, power on, etc.). */
54088
- remoteStartAllowed: boolean(),
54089
- /** Main power / switched-on state. */
54090
- powerOn: boolean(),
54180
+ /** True when the door is reported open; null when the door state is not known. */
54181
+ doorOpen: boolean().nullable(),
54182
+ /** True when the door is latched (locked) during a cycle; null when not reported. */
54183
+ doorLocked: boolean().nullable(),
54184
+ /** True when remote start is allowed (door closed, power on, etc.); null when not known. */
54185
+ remoteStartAllowed: boolean().nullable(),
54186
+ /** True when the appliance accepts remote control now; null when not known. */
54187
+ remoteControlActive: boolean().nullable(),
54188
+ /** True while somebody operates the appliance at its panel; null when not reported. */
54189
+ localControlActive: boolean().nullable(),
54190
+ /** Main power / switched-on state; null when not known. */
54191
+ powerOn: boolean().nullable(),
54192
+ /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
54193
+ powerState: string().nullable(),
54091
54194
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
54092
54195
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
54093
- halfLoad: boolean(),
54094
- hygienePlus: boolean(),
54196
+ /** Option states: null when the appliance does not expose the option or has not said. */
54197
+ halfLoad: boolean().nullable(),
54198
+ hygienePlus: boolean().nullable(),
54095
54199
  /** Extra dry option when the appliance exposes it. */
54096
- extraDry: boolean(),
54200
+ extraDry: boolean().nullable(),
54097
54201
  /** Intensive zone (lower basket) when the appliance exposes it. */
54098
- intensiveZone: boolean(),
54202
+ intensiveZone: boolean().nullable(),
54099
54203
  /** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
54100
- varioSpeedPlus: boolean(),
54101
- /** Child lock (controls disabled on the appliance). */
54102
- childLock: boolean(),
54204
+ varioSpeedPlus: boolean().nullable(),
54205
+ /** Child lock (controls disabled on the appliance); null when not known. */
54206
+ childLock: boolean().nullable(),
54207
+ /** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
54208
+ activeEvents: array(string()),
54209
+ /** Numeric error code when the appliance reports one; null otherwise. */
54103
54210
  errorCode: number().nullable(),
54211
+ /** Name of the raised alert-level event while the appliance is in error; null otherwise. */
54104
54212
  errorLabel: string().nullable(),
54213
+ /** Ms epoch of the last value received from the appliance; 0 = never. */
54105
54214
  lastFetchedAt: number()
54106
54215
  });
54107
- DeviceType.Dishwasher, method(object({ deviceId: number().int().nonnegative() }), _void(), {
54216
+ var DeviceIdSchema = number().int().nonnegative();
54217
+ /** A value a program option or setting can take. */
54218
+ var DishwasherValueSchema = union([
54219
+ boolean(),
54220
+ string(),
54221
+ number()
54222
+ ]);
54223
+ var DishwasherAccessSchema = _enum([
54224
+ "none",
54225
+ "read",
54226
+ "readWrite",
54227
+ "writeOnly",
54228
+ "readStatic"
54229
+ ]);
54230
+ /**
54231
+ * One option or setting the appliance declares, with the constraints its description
54232
+ * gives. A `readWrite` descriptor that is `available` is what `setOption` accepts.
54233
+ */
54234
+ var DishwasherOptionDescriptorSchema = object({
54235
+ /** Feature key (`Dishcare.Dishwasher.Option.ExtraDry`). */
54236
+ key: string(),
54237
+ /** Last segment of the key, for display. */
54238
+ name: string(),
54239
+ type: _enum([
54240
+ "boolean",
54241
+ "number",
54242
+ "enum",
54243
+ "string"
54244
+ ]),
54245
+ access: DishwasherAccessSchema,
54246
+ /** The appliance reports this entity as currently available. */
54247
+ available: boolean(),
54248
+ /** Unit the description declares for a number; null when it declares none. */
54249
+ unit: string().nullable(),
54250
+ min: number().nullable(),
54251
+ max: number().nullable(),
54252
+ step: number().nullable(),
54253
+ /** Allowed members of an enum; null for other types. */
54254
+ enumValues: array(string()).nullable(),
54255
+ defaultValue: DishwasherValueSchema.nullable()
54256
+ });
54257
+ var DishwasherProgramSchema = object({
54258
+ /** Feature key (`Dishcare.Dishwasher.Program.Eco50`) — what `setProgram` / `start` take. */
54259
+ key: string(),
54260
+ name: string(),
54261
+ /** The appliance currently offers this program. */
54262
+ available: boolean(),
54263
+ /** The options this program lists, with the program-level access / availability / default. */
54264
+ options: array(DishwasherOptionDescriptorSchema)
54265
+ });
54266
+ var DishwasherOptionsSchema = object({
54267
+ availability: DishwasherAvailabilitySchema,
54268
+ /** What the appliance can be told to do, from the commands its description declares. */
54269
+ supportsStart: boolean(),
54270
+ supportsPause: boolean(),
54271
+ supportsResume: boolean(),
54272
+ supportsStop: boolean(),
54273
+ supportsPower: boolean(),
54274
+ /** Every program the description lists, with its options. */
54275
+ programs: array(DishwasherProgramSchema),
54276
+ /** Every option and setting entity the description lists (programs reference these by key). */
54277
+ options: array(DishwasherOptionDescriptorSchema)
54278
+ });
54279
+ DeviceType.Dishwasher, method(object({
54280
+ deviceId: DeviceIdSchema,
54281
+ program: string().min(1).optional(),
54282
+ options: record(string(), DishwasherValueSchema).optional()
54283
+ }), _void(), {
54108
54284
  kind: "mutation",
54109
54285
  auth: "protected"
54110
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54286
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54111
54287
  kind: "mutation",
54112
54288
  auth: "protected"
54113
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54289
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54290
+ kind: "mutation",
54291
+ auth: "protected"
54292
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54114
54293
  kind: "mutation",
54115
54294
  auth: "protected"
54116
54295
  }), method(object({
54117
- deviceId: number().int().nonnegative(),
54296
+ deviceId: DeviceIdSchema,
54118
54297
  program: string().min(1)
54119
54298
  }), _void(), {
54120
54299
  kind: "mutation",
54121
54300
  auth: "protected"
54122
54301
  }), method(object({
54123
- deviceId: number().int().nonnegative(),
54302
+ deviceId: DeviceIdSchema,
54124
54303
  on: boolean()
54125
54304
  }), _void(), {
54126
54305
  kind: "mutation",
54127
54306
  auth: "protected"
54128
54307
  }), method(object({
54129
- deviceId: number().int().nonnegative(),
54308
+ deviceId: DeviceIdSchema,
54130
54309
  on: boolean()
54131
54310
  }), _void(), {
54132
54311
  kind: "mutation",
54133
54312
  auth: "protected"
54134
54313
  }), method(object({
54135
- deviceId: number().int().nonnegative(),
54314
+ deviceId: DeviceIdSchema,
54136
54315
  on: boolean()
54137
54316
  }), _void(), {
54138
54317
  kind: "mutation",
54139
54318
  auth: "protected"
54140
54319
  }), method(object({
54141
- deviceId: number().int().nonnegative(),
54320
+ deviceId: DeviceIdSchema,
54142
54321
  on: boolean()
54143
54322
  }), _void(), {
54144
54323
  kind: "mutation",
54145
54324
  auth: "protected"
54146
54325
  }), method(object({
54147
- deviceId: number().int().nonnegative(),
54326
+ deviceId: DeviceIdSchema,
54148
54327
  on: boolean()
54149
54328
  }), _void(), {
54150
54329
  kind: "mutation",
54151
54330
  auth: "protected"
54152
54331
  }), method(object({
54153
- deviceId: number().int().nonnegative(),
54332
+ deviceId: DeviceIdSchema,
54154
54333
  on: boolean()
54155
54334
  }), _void(), {
54156
54335
  kind: "mutation",
54157
54336
  auth: "protected"
54158
54337
  }), method(object({
54159
- deviceId: number().int().nonnegative(),
54338
+ deviceId: DeviceIdSchema,
54160
54339
  on: boolean()
54161
54340
  }), _void(), {
54162
54341
  kind: "mutation",
54163
54342
  auth: "protected"
54164
54343
  }), method(object({
54165
- deviceId: number().int().nonnegative(),
54344
+ deviceId: DeviceIdSchema,
54166
54345
  key: string().min(1),
54167
- value: union([
54168
- boolean(),
54169
- string(),
54170
- number()
54171
- ])
54346
+ value: DishwasherValueSchema
54172
54347
  }), _void(), {
54173
54348
  kind: "mutation",
54174
54349
  auth: "protected"
54175
- });
54350
+ }), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
54176
54351
  object({
54177
54352
  /** Ms epoch of the last press. null = never observed since this provider started. */
54178
54353
  lastPressedAt: number().nullable(),
@@ -64232,6 +64407,12 @@ Object.freeze({
64232
64407
  addonId: null,
64233
64408
  access: "view"
64234
64409
  },
64410
+ "dishwasher.getOptions": {
64411
+ capName: "dishwasher",
64412
+ capScope: "device",
64413
+ addonId: null,
64414
+ access: "view"
64415
+ },
64235
64416
  "dishwasher.getStatus": {
64236
64417
  capName: "dishwasher",
64237
64418
  capScope: "device",
@@ -64244,6 +64425,12 @@ Object.freeze({
64244
64425
  addonId: null,
64245
64426
  access: "create"
64246
64427
  },
64428
+ "dishwasher.resume": {
64429
+ capName: "dishwasher",
64430
+ capScope: "device",
64431
+ addonId: null,
64432
+ access: "create"
64433
+ },
64247
64434
  "dishwasher.setChildLock": {
64248
64435
  capName: "dishwasher",
64249
64436
  capScope: "device",
@@ -68744,6 +68931,12 @@ Object.freeze({
68744
68931
  addonId: null,
68745
68932
  access: "view"
68746
68933
  },
68934
+ "storageMigration.moverClearance": {
68935
+ capName: "storage-migration",
68936
+ capScope: "system",
68937
+ addonId: null,
68938
+ access: "view"
68939
+ },
68747
68940
  "storageMigration.movers": {
68748
68941
  capName: "storage-migration",
68749
68942
  capScope: "system",
@@ -70937,6 +71130,11 @@ Object.freeze({
70937
71130
  form: "single",
70938
71131
  optional: false
70939
71132
  }],
71133
+ "dishwasher.getOptions": [{
71134
+ name: "deviceId",
71135
+ form: "single",
71136
+ optional: false
71137
+ }],
70940
71138
  "dishwasher.getStatus": [{
70941
71139
  name: "deviceId",
70942
71140
  form: "single",
@@ -70947,6 +71145,11 @@ Object.freeze({
70947
71145
  form: "single",
70948
71146
  optional: false
70949
71147
  }],
71148
+ "dishwasher.resume": [{
71149
+ name: "deviceId",
71150
+ form: "single",
71151
+ optional: false
71152
+ }],
70950
71153
  "dishwasher.setChildLock": [{
70951
71154
  name: "deviceId",
70952
71155
  form: "single",
@@ -73033,6 +73236,9 @@ new Map(Object.entries({
73033
73236
  "wrapper-update-available": "system",
73034
73237
  "backup-completed": "system",
73035
73238
  "export-completed": "system",
73239
+ "alert-critical": "system",
73240
+ "alert-error": "system",
73241
+ "alert-critical-resolved": "system",
73036
73242
  "storage-location-low": "system",
73037
73243
  "storage-location-critical": "system",
73038
73244
  "storage-location-ok": "system",
@@ -73157,6 +73363,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
73157
73363
  "storage-location-ok"
73158
73364
  ]
73159
73365
  },
73366
+ {
73367
+ id: "alerts",
73368
+ family: "system",
73369
+ label: "Alerts",
73370
+ kinds: [
73371
+ "alert-critical",
73372
+ "alert-error",
73373
+ "alert-critical-resolved"
73374
+ ]
73375
+ },
73160
73376
  {
73161
73377
  id: "alarm",
73162
73378
  family: "alarm",
@@ -73201,6 +73417,21 @@ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.ent
73201
73417
  return [[descriptor.kind, field]];
73202
73418
  })));
73203
73419
  Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
73420
+ object({
73421
+ phase: _enum(["raised", "resolved"]),
73422
+ episodeId: string().min(1),
73423
+ alertId: string().min(1),
73424
+ severity: AlertSeveritySchema,
73425
+ category: string(),
73426
+ title: string(),
73427
+ message: string(),
73428
+ sourceType: string().optional(),
73429
+ sourceId: string().optional(),
73430
+ nodeId: string().optional(),
73431
+ /** The alert's own action link (where the operator acts on it), when it has one. */
73432
+ actionUrl: string().optional(),
73433
+ at: number()
73434
+ });
73204
73435
  var RULE_BODY_ONLY = ["body"];
73205
73436
  var RULE_TEXT = ["title", "body"];
73206
73437
  var BATTERY = ["device-battery-low", "device-battery-normal"];
@@ -73210,6 +73441,11 @@ var TANK = [
73210
73441
  "device-tank-full",
73211
73442
  "device-tank-normal"
73212
73443
  ];
73444
+ var ALERT_EPISODE = [
73445
+ "alert-critical",
73446
+ "alert-error",
73447
+ "alert-critical-resolved"
73448
+ ];
73213
73449
  var UPDATES = [
73214
73450
  "addon-update-available",
73215
73451
  "server-update-available",
@@ -73402,14 +73638,14 @@ var STATE_SUMMARY_VARS = [
73402
73638
  ([...RULE_TEXT], [...CONSUMABLE]),
73403
73639
  ([...RULE_TEXT], [...TANK]),
73404
73640
  [...RULE_TEXT],
73405
- ([...RULE_TEXT], [...UPDATES]),
73406
- ([...RULE_TEXT], [...UPDATES]),
73407
- [...RULE_TEXT],
73641
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
73642
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
73408
73643
  [...RULE_TEXT],
73409
73644
  [...RULE_TEXT],
73410
73645
  [...RULE_TEXT],
73411
73646
  [...RULE_TEXT],
73412
73647
  [...RULE_TEXT],
73648
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73413
73649
  [...RULE_TEXT],
73414
73650
  [...RULE_TEXT],
73415
73651
  [...RULE_TEXT],
@@ -73427,7 +73663,11 @@ var STATE_SUMMARY_VARS = [
73427
73663
  [...RULE_TEXT],
73428
73664
  [...RULE_TEXT],
73429
73665
  [...RULE_TEXT],
73430
- [...RULE_TEXT],
73666
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73667
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73668
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73669
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73670
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73431
73671
  [...RULE_TEXT],
73432
73672
  [...RULE_TEXT],
73433
73673
  [...RULE_TEXT],