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