@camstack/addon-smtp-nodemailer 1.2.123 → 1.2.125

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.
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
34
  var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
35
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
36
36
  //#endregion
37
- //#region ../types/dist/event-category-BvOFi6PY.mjs
37
+ //#region ../types/dist/event-category-DOl51-Ij.mjs
38
38
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
39
39
  EventCategory["SystemBoot"] = "system.boot";
40
40
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -113,9 +113,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
113
113
  /**
114
114
  * The node's one-shot runner boot check (D877): planned runners against the
115
115
  * process service, `degraded` when any is failed, refused or missing. The
116
- * alert centre turns it into one alert and a direct critical push.
116
+ * alert centre turns it into one critical alert.
117
117
  */
118
118
  EventCategory["SystemRunnerCheck"] = "system.runner-check";
119
+ /**
120
+ * An alert EPISODE opened or closed, emitted by the alert centre for alerts
121
+ * of severity `critical` or `error` (`AlertEpisodePayload`). The alert
122
+ * centre sends no notification of its own: Notification Center turns this
123
+ * into the `alert-critical` / `alert-error` / `alert-critical-resolved`
124
+ * system-event kinds, and reconciles from the alerts store because a bus
125
+ * event may be dropped (D8, D11).
126
+ */
127
+ EventCategory["AlertEpisode"] = "alert.episode";
119
128
  EventCategory["AddonError"] = "addon.error";
120
129
  EventCategory["AddonPageReady"] = "addon.page-ready";
121
130
  EventCategory["AddonWidgetReady"] = "addon.widget-ready";
@@ -5440,7 +5449,7 @@ var ZodIssueCode = {
5440
5449
  var ZodFirstPartyTypeKind;
5441
5450
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5442
5451
  //#endregion
5443
- //#region ../types/dist/sleep-BegKjwUu.mjs
5452
+ //#region ../types/dist/sleep-BxjU_fJM.mjs
5444
5453
  /**
5445
5454
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5446
5455
  * window to float samples (D455).
@@ -7822,6 +7831,12 @@ function normalizeAddonInitResult(result) {
7822
7831
  if (Array.isArray(result)) return { providers: result };
7823
7832
  return result;
7824
7833
  }
7834
+ /**
7835
+ * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7836
+ * and validates them (`share-token.service.ts` builds its enum from this
7837
+ * list); a data plane names the kinds it ACCEPTS in `share`.
7838
+ */
7839
+ var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7825
7840
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
7826
7841
  var PeerBytesTicketSchema = object({
7827
7842
  /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
@@ -12406,6 +12421,229 @@ var ConvertResultSchema = object({
12406
12421
  files: array(string()).readonly()
12407
12422
  })).readonly()
12408
12423
  });
12424
+ /**
12425
+ * Zod schemas for persisted record types.
12426
+ *
12427
+ * These schemas serve as the single source of truth for types that are
12428
+ * stored in the settings-store backend and retrieved via tRPC. They
12429
+ * replace the manual TypeScript interfaces with schema-derived types,
12430
+ * enabling runtime validation when reading from the backend.
12431
+ *
12432
+ * Convention: each schema is named `<Type>Schema`, the inferred TS type
12433
+ * keeps the original name for backward compatibility.
12434
+ */
12435
+ /**
12436
+ * Auth model (v2 — 2026-05-12 caps-only):
12437
+ *
12438
+ * Two principals:
12439
+ * - `isAdmin: true` — full bypass. Admin scope set is ignored.
12440
+ * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
12441
+ *
12442
+ * No role enum. There used to be `viewer / agent / scoped` and earlier
12443
+ * `super_admin` — collapsed onto the single boolean because every
12444
+ * non-admin caller is governed by the same scope-check rules; the
12445
+ * distinction was only ever used to route role-specific procedures
12446
+ * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12447
+ * with `isAdmin: false` + an explicit scope list.
12448
+ */
12449
+ /** Per-method access flavour. Materialised on every cap method via codegen. */
12450
+ var MethodAccessSchema = _enum([
12451
+ "view",
12452
+ "create",
12453
+ "delete"
12454
+ ]);
12455
+ /**
12456
+ * A single scope grant. Three forms — checked in matcher with OR
12457
+ * semantics; the first match decides whether the call passes:
12458
+ *
12459
+ * - `category` — broadest. `target: 'device' | 'system'` selects every
12460
+ * cap with the matching `scope` declaration. New caps inherit grants
12461
+ * automatically — adding a device cap to the codebase makes it
12462
+ * reachable to every user with `category:device [...]` without a
12463
+ * re-grant. Use this for "family viewer" / "operator" tiers.
12464
+ *
12465
+ * - `addon` — every cap that ships inside a given addon id. Niche;
12466
+ * useful when an integration needs to interact with one specific
12467
+ * addon's surface regardless of how many caps it exports.
12468
+ *
12469
+ * - `capability` — the most precise form. Single cap name. Use for
12470
+ * integration tokens where you want to grant `addons.installPackage`
12471
+ * and nothing else.
12472
+ *
12473
+ * `access` is REQUIRED with min 1 element. `admin` bypass is the
12474
+ * "give me everything" escape; there is no wildcard scope.
12475
+ */
12476
+ var AllowedProviderSchema = union([literal("*"), array(string())]);
12477
+ var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
12478
+ var CapScopeSchema = _enum(["device", "system"]);
12479
+ /**
12480
+ * DeviceSelector (scope model v3 — 2026-08-12).
12481
+ *
12482
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
12483
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
12484
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
12485
+ * AFTER the grant was minted — no re-grant, no re-login.
12486
+ *
12487
+ * - `all` — every device in the deployment. The broad viewer/operator
12488
+ * lever without a `category` grant (a `category` grant also covers device
12489
+ * caps that carry no deviceId; `all` is specifically the device set).
12490
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
12491
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
12492
+ * is NOT covered until the grant is edited.
12493
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
12494
+ * DYNAMIC. A device that changes type, or a new device of the type,
12495
+ * re-resolves on the next request.
12496
+ * - `locations` — every device whose operator-assigned `location` label is
12497
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
12498
+ * null/unset location matches NO `locations` selector.
12499
+ */
12500
+ var DeviceSelectorSchema = discriminatedUnion("kind", [
12501
+ object({ kind: literal("all") }),
12502
+ object({
12503
+ kind: literal("ids"),
12504
+ ids: array(number().int()).min(1)
12505
+ }),
12506
+ object({
12507
+ kind: literal("types"),
12508
+ types: array(_enum(DeviceType)).min(1)
12509
+ }),
12510
+ object({
12511
+ kind: literal("locations"),
12512
+ locations: array(string().min(1)).min(1)
12513
+ })
12514
+ ]);
12515
+ var DeviceTokenScopeSchema = object({
12516
+ type: literal("device"),
12517
+ /** The device SET this grant covers — resolved against the live fleet. */
12518
+ selector: DeviceSelectorSchema,
12519
+ access: array(MethodAccessSchema).min(1),
12520
+ /**
12521
+ * Whether a grant on a PARENT device transparently covers its accessory
12522
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
12523
+ * Direction is parent → children ONLY.
12524
+ *
12525
+ * Absent → the matcher DERIVES it from the access flavour: `view`
12526
+ * inherits (a camera viewer sees the camera's accessories), `create` /
12527
+ * `delete` do NOT (actuating/removing a child is an explicit act the
12528
+ * operator must grant on the child, not inherit from the parent). Set it
12529
+ * explicitly to override that default per grant.
12530
+ */
12531
+ includeLinked: boolean().optional()
12532
+ });
12533
+ /**
12534
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
12535
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
12536
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
12537
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
12538
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
12539
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
12540
+ * migration cannot reach a JWT already in a client's hands; parse-time
12541
+ * migration covers both without a flag day. No cast — the raw object is read
12542
+ * through `Reflect.get` (its static type is `unknown`).
12543
+ */
12544
+ function migrateLegacyTokenScope(raw) {
12545
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
12546
+ if (Reflect.get(raw, "type") !== "device") return raw;
12547
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
12548
+ const targets = Reflect.get(raw, "targets");
12549
+ if (!Array.isArray(targets)) return raw;
12550
+ return {
12551
+ type: "device",
12552
+ selector: {
12553
+ kind: "ids",
12554
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
12555
+ },
12556
+ access: Reflect.get(raw, "access")
12557
+ };
12558
+ }
12559
+ var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
12560
+ object({
12561
+ type: literal("category"),
12562
+ target: CapScopeSchema,
12563
+ access: array(MethodAccessSchema).min(1)
12564
+ }),
12565
+ object({
12566
+ type: literal("capability"),
12567
+ target: string(),
12568
+ access: array(MethodAccessSchema).min(1)
12569
+ }),
12570
+ object({
12571
+ type: literal("addon"),
12572
+ target: string(),
12573
+ access: array(MethodAccessSchema).min(1)
12574
+ }),
12575
+ DeviceTokenScopeSchema
12576
+ ]));
12577
+ object({
12578
+ id: string(),
12579
+ username: string(),
12580
+ passwordHash: string(),
12581
+ /**
12582
+ * Admin bypass. When true, the middleware skips the scope-access
12583
+ * check entirely. There is no other axis of privilege; the legacy
12584
+ * role enum collapsed onto this boolean in v2.
12585
+ */
12586
+ isAdmin: boolean().default(false),
12587
+ allowedProviders: AllowedProviderSchema,
12588
+ allowedDevices: AllowedDevicesSchema,
12589
+ /**
12590
+ * Scopes granted to this user. Admins bypass; their `scopes` is
12591
+ * ignored. Non-admins without scopes are locked out of every
12592
+ * protected call.
12593
+ */
12594
+ scopes: array(TokenScopeSchema).default([]),
12595
+ createdAt: number(),
12596
+ updatedAt: number()
12597
+ });
12598
+ object({
12599
+ id: string(),
12600
+ label: string(),
12601
+ isAdmin: boolean().default(false),
12602
+ allowedProviders: AllowedProviderSchema,
12603
+ allowedDevices: AllowedDevicesSchema,
12604
+ tokenHash: string(),
12605
+ tokenPrefix: string(),
12606
+ createdAt: number(),
12607
+ lastUsedAt: number().optional()
12608
+ });
12609
+ object({
12610
+ id: string(),
12611
+ userId: string(),
12612
+ name: string(),
12613
+ tokenHash: string(),
12614
+ tokenPrefix: string(),
12615
+ scopes: array(TokenScopeSchema),
12616
+ expiresAt: number().nullish(),
12617
+ lastUsedAt: number().nullish(),
12618
+ createdAt: number()
12619
+ });
12620
+ /** What a share-view grant lets its holder see. */
12621
+ var ShareViewGrantSchema = object({
12622
+ kind: _enum(SHARE_VIEW_KINDS),
12623
+ deviceIds: array(number().int().nonnegative()).min(1).max(64),
12624
+ /** Talk-back, opt-in at mint time; absent means off. */
12625
+ talk: boolean().optional()
12626
+ });
12627
+ var ShareViewScopeSchema = object({
12628
+ type: literal("share-view"),
12629
+ grant: ShareViewGrantSchema
12630
+ });
12631
+ var AddonRoutesScopeSchema = object({
12632
+ type: literal("addon-routes"),
12633
+ access: array(MethodAccessSchema).min(1)
12634
+ });
12635
+ var CredentialScopeSchema = union([
12636
+ literal("*"),
12637
+ ShareViewScopeSchema,
12638
+ AddonRoutesScopeSchema,
12639
+ TokenScopeSchema
12640
+ ]);
12641
+ object({
12642
+ kind: literal("credential"),
12643
+ sub: string().min(1),
12644
+ jti: string().min(16),
12645
+ scopes: array(CredentialScopeSchema).min(1)
12646
+ });
12409
12647
  _enum(["new-session", "step-up"]);
12410
12648
  /** The languages the hub's app landing pages are written in (D858). */
12411
12649
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -13122,7 +13360,14 @@ var AlertSeveritySchema = _enum([
13122
13360
  ]);
13123
13361
  var AlertActionSchema = object({
13124
13362
  label: string(),
13125
- href: string().optional()
13363
+ href: string().optional(),
13364
+ /**
13365
+ * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
13366
+ * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
13367
+ * start) — the browser must leave the SPA with a full navigation, because
13368
+ * the SPA has no such route and would bounce to the home page.
13369
+ */
13370
+ navigation: _enum(["app", "server"]).optional()
13126
13371
  });
13127
13372
  var AlertStatusSchema = _enum([
13128
13373
  "active",
@@ -41498,6 +41743,9 @@ var NcSystemEventKindSchema = _enum([
41498
41743
  "server-updated",
41499
41744
  "export-completed",
41500
41745
  "backup-completed",
41746
+ "alert-critical",
41747
+ "alert-error",
41748
+ "alert-critical-resolved",
41501
41749
  "camera-online",
41502
41750
  "camera-offline",
41503
41751
  "camera-disabled",
@@ -43533,202 +43781,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
43533
43781
  auth: "admin"
43534
43782
  }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
43535
43783
  /**
43536
- * Zod schemas for persisted record types.
43537
- *
43538
- * These schemas serve as the single source of truth for types that are
43539
- * stored in the settings-store backend and retrieved via tRPC. They
43540
- * replace the manual TypeScript interfaces with schema-derived types,
43541
- * enabling runtime validation when reading from the backend.
43542
- *
43543
- * Convention: each schema is named `<Type>Schema`, the inferred TS type
43544
- * keeps the original name for backward compatibility.
43545
- */
43546
- /**
43547
- * Auth model (v2 — 2026-05-12 caps-only):
43548
- *
43549
- * Two principals:
43550
- * - `isAdmin: true` — full bypass. Admin scope set is ignored.
43551
- * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
43552
- *
43553
- * No role enum. There used to be `viewer / agent / scoped` and earlier
43554
- * `super_admin` — collapsed onto the single boolean because every
43555
- * non-admin caller is governed by the same scope-check rules; the
43556
- * distinction was only ever used to route role-specific procedures
43557
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
43558
- * with `isAdmin: false` + an explicit scope list.
43559
- */
43560
- /** Per-method access flavour. Materialised on every cap method via codegen. */
43561
- var MethodAccessSchema = _enum([
43562
- "view",
43563
- "create",
43564
- "delete"
43565
- ]);
43566
- /**
43567
- * A single scope grant. Three forms — checked in matcher with OR
43568
- * semantics; the first match decides whether the call passes:
43569
- *
43570
- * - `category` — broadest. `target: 'device' | 'system'` selects every
43571
- * cap with the matching `scope` declaration. New caps inherit grants
43572
- * automatically — adding a device cap to the codebase makes it
43573
- * reachable to every user with `category:device [...]` without a
43574
- * re-grant. Use this for "family viewer" / "operator" tiers.
43575
- *
43576
- * - `addon` — every cap that ships inside a given addon id. Niche;
43577
- * useful when an integration needs to interact with one specific
43578
- * addon's surface regardless of how many caps it exports.
43579
- *
43580
- * - `capability` — the most precise form. Single cap name. Use for
43581
- * integration tokens where you want to grant `addons.installPackage`
43582
- * and nothing else.
43583
- *
43584
- * `access` is REQUIRED with min 1 element. `admin` bypass is the
43585
- * "give me everything" escape; there is no wildcard scope.
43586
- */
43587
- var AllowedProviderSchema = union([literal("*"), array(string())]);
43588
- var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
43589
- var CapScopeSchema = _enum(["device", "system"]);
43590
- /**
43591
- * DeviceSelector (scope model v3 — 2026-08-12).
43592
- *
43593
- * A `device` grant no longer carries a frozen list of deviceIds. It carries
43594
- * a SELECTOR the matcher resolves against the live fleet, so the grant can be
43595
- * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
43596
- * AFTER the grant was minted — no re-grant, no re-login.
43597
- *
43598
- * - `all` — every device in the deployment. The broad viewer/operator
43599
- * lever without a `category` grant (a `category` grant also covers device
43600
- * caps that carry no deviceId; `all` is specifically the device set).
43601
- * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
43602
- * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
43603
- * is NOT covered until the grant is edited.
43604
- * - `types` — every device of a `DeviceType` (e.g. every `camera`).
43605
- * DYNAMIC. A device that changes type, or a new device of the type,
43606
- * re-resolves on the next request.
43607
- * - `locations` — every device whose operator-assigned `location` label is
43608
- * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
43609
- * null/unset location matches NO `locations` selector.
43610
- */
43611
- var DeviceSelectorSchema = discriminatedUnion("kind", [
43612
- object({ kind: literal("all") }),
43613
- object({
43614
- kind: literal("ids"),
43615
- ids: array(number().int()).min(1)
43616
- }),
43617
- object({
43618
- kind: literal("types"),
43619
- types: array(_enum(DeviceType)).min(1)
43620
- }),
43621
- object({
43622
- kind: literal("locations"),
43623
- locations: array(string().min(1)).min(1)
43624
- })
43625
- ]);
43626
- var DeviceTokenScopeSchema = object({
43627
- type: literal("device"),
43628
- /** The device SET this grant covers — resolved against the live fleet. */
43629
- selector: DeviceSelectorSchema,
43630
- access: array(MethodAccessSchema).min(1),
43631
- /**
43632
- * Whether a grant on a PARENT device transparently covers its accessory
43633
- * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
43634
- * Direction is parent → children ONLY.
43635
- *
43636
- * Absent → the matcher DERIVES it from the access flavour: `view`
43637
- * inherits (a camera viewer sees the camera's accessories), `create` /
43638
- * `delete` do NOT (actuating/removing a child is an explicit act the
43639
- * operator must grant on the child, not inherit from the parent). Set it
43640
- * explicitly to override that default per grant.
43641
- */
43642
- includeLinked: boolean().optional()
43643
- });
43644
- /**
43645
- * v2 → v3 lazy migration. A pre-v3 `device` grant carried
43646
- * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
43647
- * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
43648
- * EVERY parse path — stored records AND the JWT-carried scope arrays
43649
- * normalised at the request boundary ({@link normalizeTokenScopes} in
43650
- * `device-selector.ts`). Chosen over a one-time DB migration because a
43651
- * migration cannot reach a JWT already in a client's hands; parse-time
43652
- * migration covers both without a flag day. No cast — the raw object is read
43653
- * through `Reflect.get` (its static type is `unknown`).
43654
- */
43655
- function migrateLegacyTokenScope(raw) {
43656
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
43657
- if (Reflect.get(raw, "type") !== "device") return raw;
43658
- if (Reflect.get(raw, "selector") !== void 0) return raw;
43659
- const targets = Reflect.get(raw, "targets");
43660
- if (!Array.isArray(targets)) return raw;
43661
- return {
43662
- type: "device",
43663
- selector: {
43664
- kind: "ids",
43665
- ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
43666
- },
43667
- access: Reflect.get(raw, "access")
43668
- };
43669
- }
43670
- var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
43671
- object({
43672
- type: literal("category"),
43673
- target: CapScopeSchema,
43674
- access: array(MethodAccessSchema).min(1)
43675
- }),
43676
- object({
43677
- type: literal("capability"),
43678
- target: string(),
43679
- access: array(MethodAccessSchema).min(1)
43680
- }),
43681
- object({
43682
- type: literal("addon"),
43683
- target: string(),
43684
- access: array(MethodAccessSchema).min(1)
43685
- }),
43686
- DeviceTokenScopeSchema
43687
- ]));
43688
- object({
43689
- id: string(),
43690
- username: string(),
43691
- passwordHash: string(),
43692
- /**
43693
- * Admin bypass. When true, the middleware skips the scope-access
43694
- * check entirely. There is no other axis of privilege; the legacy
43695
- * role enum collapsed onto this boolean in v2.
43696
- */
43697
- isAdmin: boolean().default(false),
43698
- allowedProviders: AllowedProviderSchema,
43699
- allowedDevices: AllowedDevicesSchema,
43700
- /**
43701
- * Scopes granted to this user. Admins bypass; their `scopes` is
43702
- * ignored. Non-admins without scopes are locked out of every
43703
- * protected call.
43704
- */
43705
- scopes: array(TokenScopeSchema).default([]),
43706
- createdAt: number(),
43707
- updatedAt: number()
43708
- });
43709
- object({
43710
- id: string(),
43711
- label: string(),
43712
- isAdmin: boolean().default(false),
43713
- allowedProviders: AllowedProviderSchema,
43714
- allowedDevices: AllowedDevicesSchema,
43715
- tokenHash: string(),
43716
- tokenPrefix: string(),
43717
- createdAt: number(),
43718
- lastUsedAt: number().optional()
43719
- });
43720
- object({
43721
- id: string(),
43722
- userId: string(),
43723
- name: string(),
43724
- tokenHash: string(),
43725
- tokenPrefix: string(),
43726
- scopes: array(TokenScopeSchema),
43727
- expiresAt: number().nullish(),
43728
- lastUsedAt: number().nullish(),
43729
- createdAt: number()
43730
- });
43731
- /**
43732
43784
  * `oauth-integration` — a collection cap by which an addon declares
43733
43785
  * itself a linkable OAuth client of the hub's core `/oauth2/*` server.
43734
43786
  * Each provider returns a static descriptor; the core enumerates them
@@ -50543,7 +50595,10 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
50543
50595
  }), method(object({ jobId: string().optional() }), StorageMigrationJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
50544
50596
  kind: "mutation",
50545
50597
  auth: "admin"
50546
- }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
50598
+ }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({ locationIds: array(string()).readonly() }), object({
50599
+ clear: boolean(),
50600
+ repointLocationId: string().optional()
50601
+ }), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
50547
50602
  kind: "mutation",
50548
50603
  auth: "admin"
50549
50604
  }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
@@ -53978,6 +54033,11 @@ object({
53978
54033
  *
53979
54034
  * `kind: 'poll'` — cloud REST APIs typically have no push channel; the
53980
54035
  * provider refreshes the slice on an interval and eagerly after commands.
54036
+ *
54037
+ * UNKNOWN IS NOT OFF. Every field the appliance reports separately is
54038
+ * nullable: `null` means "not known right now" (the appliance has not said,
54039
+ * the link is down, or the description does not carry it) and is never
54040
+ * rendered or exported as `false` / `0`. `availability` says why.
53981
54041
  */
53982
54042
  var DishwasherStateSchema = _enum([
53983
54043
  "idle",
@@ -53987,112 +54047,227 @@ var DishwasherStateSchema = _enum([
53987
54047
  "error",
53988
54048
  "unavailable"
53989
54049
  ]);
54050
+ /**
54051
+ * The appliance's own operation state, uncollapsed. `state` above is the coarse
54052
+ * view for compact surfaces; this is what the appliance said.
54053
+ */
54054
+ var DishwasherOperationStateSchema = _enum([
54055
+ "Inactive",
54056
+ "Ready",
54057
+ "DelayedStart",
54058
+ "Run",
54059
+ "Pause",
54060
+ "ActionRequired",
54061
+ "Finished",
54062
+ "Error",
54063
+ "Aborting"
54064
+ ]);
54065
+ /**
54066
+ * Why fields may be `null`:
54067
+ * - `available` — the link is up and the description is loaded;
54068
+ * - `offline` — the local link is down (values are unknown, not last-known);
54069
+ * - `description-missing` — the link is up but the appliance's description could not
54070
+ * be loaded, so its values cannot be decoded.
54071
+ */
54072
+ var DishwasherAvailabilitySchema = _enum([
54073
+ "available",
54074
+ "offline",
54075
+ "description-missing"
54076
+ ]);
53990
54077
  var DishwasherConsumableLevelSchema = _enum([
53991
54078
  "ok",
53992
54079
  "low",
53993
54080
  "empty"
53994
54081
  ]);
53995
54082
  object({
54083
+ availability: DishwasherAvailabilitySchema,
54084
+ /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
53996
54085
  state: DishwasherStateSchema,
53997
- /** Active program id/name, or null when none selected / unknown. */
54086
+ /** The appliance's operation state as reported; null when not known. */
54087
+ operationState: DishwasherOperationStateSchema.nullable(),
54088
+ /** Feature key of the ACTIVE (running) program, or null when none runs / not known. */
53998
54089
  program: string().nullable(),
53999
- /** Program tokens the hardware accepts — drives the UI selector. */
54090
+ /** Feature key of the SELECTED program (what Start would run), or null when none / not known. */
54091
+ selectedProgram: string().nullable(),
54092
+ /** Feature keys of the programs the appliance currently offers — drives the UI selector. */
54000
54093
  availablePrograms: array(string()),
54001
- /** Minutes remaining on the active cycle, or null when not running. */
54002
- remainingMinutes: number().int().nonnegative().nullable(),
54094
+ /** Seconds remaining on the active cycle, or null when not running / not known. */
54095
+ remainingSeconds: number().int().nonnegative().nullable(),
54096
+ /** Seconds the delayed start is set to (time until the cycle starts), or null. */
54097
+ delayedStartSeconds: number().int().nonnegative().nullable(),
54003
54098
  /** Cycle completion 0..100, or null when not applicable. */
54004
54099
  progressPercent: number().min(0).max(100).nullable(),
54005
- /** True when the door is reported open. */
54006
- doorOpen: boolean(),
54007
- /** True when remote start is allowed (door closed, power on, etc.). */
54008
- remoteStartAllowed: boolean(),
54009
- /** Main power / switched-on state. */
54010
- powerOn: boolean(),
54100
+ /** True when the door is reported open; null when the door state is not known. */
54101
+ doorOpen: boolean().nullable(),
54102
+ /** True when the door is latched (locked) during a cycle; null when not reported. */
54103
+ doorLocked: boolean().nullable(),
54104
+ /** True when remote start is allowed (door closed, power on, etc.); null when not known. */
54105
+ remoteStartAllowed: boolean().nullable(),
54106
+ /** True when the appliance accepts remote control now; null when not known. */
54107
+ remoteControlActive: boolean().nullable(),
54108
+ /** True while somebody operates the appliance at its panel; null when not reported. */
54109
+ localControlActive: boolean().nullable(),
54110
+ /** Main power / switched-on state; null when not known. */
54111
+ powerOn: boolean().nullable(),
54112
+ /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
54113
+ powerState: string().nullable(),
54011
54114
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
54012
54115
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
54013
- halfLoad: boolean(),
54014
- hygienePlus: boolean(),
54116
+ /** Option states: null when the appliance does not expose the option or has not said. */
54117
+ halfLoad: boolean().nullable(),
54118
+ hygienePlus: boolean().nullable(),
54015
54119
  /** Extra dry option when the appliance exposes it. */
54016
- extraDry: boolean(),
54120
+ extraDry: boolean().nullable(),
54017
54121
  /** Intensive zone (lower basket) when the appliance exposes it. */
54018
- intensiveZone: boolean(),
54122
+ intensiveZone: boolean().nullable(),
54019
54123
  /** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
54020
- varioSpeedPlus: boolean(),
54021
- /** Child lock (controls disabled on the appliance). */
54022
- childLock: boolean(),
54124
+ varioSpeedPlus: boolean().nullable(),
54125
+ /** Child lock (controls disabled on the appliance); null when not known. */
54126
+ childLock: boolean().nullable(),
54127
+ /** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
54128
+ activeEvents: array(string()),
54129
+ /** Numeric error code when the appliance reports one; null otherwise. */
54023
54130
  errorCode: number().nullable(),
54131
+ /** Name of the raised alert-level event while the appliance is in error; null otherwise. */
54024
54132
  errorLabel: string().nullable(),
54133
+ /** Ms epoch of the last value received from the appliance; 0 = never. */
54025
54134
  lastFetchedAt: number()
54026
54135
  });
54027
- DeviceType.Dishwasher, method(object({ deviceId: number().int().nonnegative() }), _void(), {
54136
+ var DeviceIdSchema = number().int().nonnegative();
54137
+ /** A value a program option or setting can take. */
54138
+ var DishwasherValueSchema = union([
54139
+ boolean(),
54140
+ string(),
54141
+ number()
54142
+ ]);
54143
+ var DishwasherAccessSchema = _enum([
54144
+ "none",
54145
+ "read",
54146
+ "readWrite",
54147
+ "writeOnly",
54148
+ "readStatic"
54149
+ ]);
54150
+ /**
54151
+ * One option or setting the appliance declares, with the constraints its description
54152
+ * gives. A `readWrite` descriptor that is `available` is what `setOption` accepts.
54153
+ */
54154
+ var DishwasherOptionDescriptorSchema = object({
54155
+ /** Feature key (`Dishcare.Dishwasher.Option.ExtraDry`). */
54156
+ key: string(),
54157
+ /** Last segment of the key, for display. */
54158
+ name: string(),
54159
+ type: _enum([
54160
+ "boolean",
54161
+ "number",
54162
+ "enum",
54163
+ "string"
54164
+ ]),
54165
+ access: DishwasherAccessSchema,
54166
+ /** The appliance reports this entity as currently available. */
54167
+ available: boolean(),
54168
+ /** Unit the description declares for a number; null when it declares none. */
54169
+ unit: string().nullable(),
54170
+ min: number().nullable(),
54171
+ max: number().nullable(),
54172
+ step: number().nullable(),
54173
+ /** Allowed members of an enum; null for other types. */
54174
+ enumValues: array(string()).nullable(),
54175
+ defaultValue: DishwasherValueSchema.nullable()
54176
+ });
54177
+ var DishwasherProgramSchema = object({
54178
+ /** Feature key (`Dishcare.Dishwasher.Program.Eco50`) — what `setProgram` / `start` take. */
54179
+ key: string(),
54180
+ name: string(),
54181
+ /** The appliance currently offers this program. */
54182
+ available: boolean(),
54183
+ /** The options this program lists, with the program-level access / availability / default. */
54184
+ options: array(DishwasherOptionDescriptorSchema)
54185
+ });
54186
+ var DishwasherOptionsSchema = object({
54187
+ availability: DishwasherAvailabilitySchema,
54188
+ /** What the appliance can be told to do, from the commands its description declares. */
54189
+ supportsStart: boolean(),
54190
+ supportsPause: boolean(),
54191
+ supportsResume: boolean(),
54192
+ supportsStop: boolean(),
54193
+ supportsPower: boolean(),
54194
+ /** Every program the description lists, with its options. */
54195
+ programs: array(DishwasherProgramSchema),
54196
+ /** Every option and setting entity the description lists (programs reference these by key). */
54197
+ options: array(DishwasherOptionDescriptorSchema)
54198
+ });
54199
+ DeviceType.Dishwasher, method(object({
54200
+ deviceId: DeviceIdSchema,
54201
+ program: string().min(1).optional(),
54202
+ options: record(string(), DishwasherValueSchema).optional()
54203
+ }), _void(), {
54028
54204
  kind: "mutation",
54029
54205
  auth: "protected"
54030
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54206
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54031
54207
  kind: "mutation",
54032
54208
  auth: "protected"
54033
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54209
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54210
+ kind: "mutation",
54211
+ auth: "protected"
54212
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54034
54213
  kind: "mutation",
54035
54214
  auth: "protected"
54036
54215
  }), method(object({
54037
- deviceId: number().int().nonnegative(),
54216
+ deviceId: DeviceIdSchema,
54038
54217
  program: string().min(1)
54039
54218
  }), _void(), {
54040
54219
  kind: "mutation",
54041
54220
  auth: "protected"
54042
54221
  }), method(object({
54043
- deviceId: number().int().nonnegative(),
54222
+ deviceId: DeviceIdSchema,
54044
54223
  on: boolean()
54045
54224
  }), _void(), {
54046
54225
  kind: "mutation",
54047
54226
  auth: "protected"
54048
54227
  }), method(object({
54049
- deviceId: number().int().nonnegative(),
54228
+ deviceId: DeviceIdSchema,
54050
54229
  on: boolean()
54051
54230
  }), _void(), {
54052
54231
  kind: "mutation",
54053
54232
  auth: "protected"
54054
54233
  }), method(object({
54055
- deviceId: number().int().nonnegative(),
54234
+ deviceId: DeviceIdSchema,
54056
54235
  on: boolean()
54057
54236
  }), _void(), {
54058
54237
  kind: "mutation",
54059
54238
  auth: "protected"
54060
54239
  }), method(object({
54061
- deviceId: number().int().nonnegative(),
54240
+ deviceId: DeviceIdSchema,
54062
54241
  on: boolean()
54063
54242
  }), _void(), {
54064
54243
  kind: "mutation",
54065
54244
  auth: "protected"
54066
54245
  }), method(object({
54067
- deviceId: number().int().nonnegative(),
54246
+ deviceId: DeviceIdSchema,
54068
54247
  on: boolean()
54069
54248
  }), _void(), {
54070
54249
  kind: "mutation",
54071
54250
  auth: "protected"
54072
54251
  }), method(object({
54073
- deviceId: number().int().nonnegative(),
54252
+ deviceId: DeviceIdSchema,
54074
54253
  on: boolean()
54075
54254
  }), _void(), {
54076
54255
  kind: "mutation",
54077
54256
  auth: "protected"
54078
54257
  }), method(object({
54079
- deviceId: number().int().nonnegative(),
54258
+ deviceId: DeviceIdSchema,
54080
54259
  on: boolean()
54081
54260
  }), _void(), {
54082
54261
  kind: "mutation",
54083
54262
  auth: "protected"
54084
54263
  }), method(object({
54085
- deviceId: number().int().nonnegative(),
54264
+ deviceId: DeviceIdSchema,
54086
54265
  key: string().min(1),
54087
- value: union([
54088
- boolean(),
54089
- string(),
54090
- number()
54091
- ])
54266
+ value: DishwasherValueSchema
54092
54267
  }), _void(), {
54093
54268
  kind: "mutation",
54094
54269
  auth: "protected"
54095
- });
54270
+ }), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
54096
54271
  object({
54097
54272
  /** Ms epoch of the last press. null = never observed since this provider started. */
54098
54273
  lastPressedAt: number().nullable(),
@@ -64152,6 +64327,12 @@ Object.freeze({
64152
64327
  addonId: null,
64153
64328
  access: "view"
64154
64329
  },
64330
+ "dishwasher.getOptions": {
64331
+ capName: "dishwasher",
64332
+ capScope: "device",
64333
+ addonId: null,
64334
+ access: "view"
64335
+ },
64155
64336
  "dishwasher.getStatus": {
64156
64337
  capName: "dishwasher",
64157
64338
  capScope: "device",
@@ -64164,6 +64345,12 @@ Object.freeze({
64164
64345
  addonId: null,
64165
64346
  access: "create"
64166
64347
  },
64348
+ "dishwasher.resume": {
64349
+ capName: "dishwasher",
64350
+ capScope: "device",
64351
+ addonId: null,
64352
+ access: "create"
64353
+ },
64167
64354
  "dishwasher.setChildLock": {
64168
64355
  capName: "dishwasher",
64169
64356
  capScope: "device",
@@ -68664,6 +68851,12 @@ Object.freeze({
68664
68851
  addonId: null,
68665
68852
  access: "view"
68666
68853
  },
68854
+ "storageMigration.moverClearance": {
68855
+ capName: "storage-migration",
68856
+ capScope: "system",
68857
+ addonId: null,
68858
+ access: "view"
68859
+ },
68667
68860
  "storageMigration.movers": {
68668
68861
  capName: "storage-migration",
68669
68862
  capScope: "system",
@@ -70857,6 +71050,11 @@ Object.freeze({
70857
71050
  form: "single",
70858
71051
  optional: false
70859
71052
  }],
71053
+ "dishwasher.getOptions": [{
71054
+ name: "deviceId",
71055
+ form: "single",
71056
+ optional: false
71057
+ }],
70860
71058
  "dishwasher.getStatus": [{
70861
71059
  name: "deviceId",
70862
71060
  form: "single",
@@ -70867,6 +71065,11 @@ Object.freeze({
70867
71065
  form: "single",
70868
71066
  optional: false
70869
71067
  }],
71068
+ "dishwasher.resume": [{
71069
+ name: "deviceId",
71070
+ form: "single",
71071
+ optional: false
71072
+ }],
70870
71073
  "dishwasher.setChildLock": [{
70871
71074
  name: "deviceId",
70872
71075
  form: "single",
@@ -72953,6 +73156,9 @@ new Map(Object.entries({
72953
73156
  "wrapper-update-available": "system",
72954
73157
  "backup-completed": "system",
72955
73158
  "export-completed": "system",
73159
+ "alert-critical": "system",
73160
+ "alert-error": "system",
73161
+ "alert-critical-resolved": "system",
72956
73162
  "storage-location-low": "system",
72957
73163
  "storage-location-critical": "system",
72958
73164
  "storage-location-ok": "system",
@@ -73077,6 +73283,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
73077
73283
  "storage-location-ok"
73078
73284
  ]
73079
73285
  },
73286
+ {
73287
+ id: "alerts",
73288
+ family: "system",
73289
+ label: "Alerts",
73290
+ kinds: [
73291
+ "alert-critical",
73292
+ "alert-error",
73293
+ "alert-critical-resolved"
73294
+ ]
73295
+ },
73080
73296
  {
73081
73297
  id: "alarm",
73082
73298
  family: "alarm",
@@ -73121,6 +73337,21 @@ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.ent
73121
73337
  return [[descriptor.kind, field]];
73122
73338
  })));
73123
73339
  Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
73340
+ object({
73341
+ phase: _enum(["raised", "resolved"]),
73342
+ episodeId: string().min(1),
73343
+ alertId: string().min(1),
73344
+ severity: AlertSeveritySchema,
73345
+ category: string(),
73346
+ title: string(),
73347
+ message: string(),
73348
+ sourceType: string().optional(),
73349
+ sourceId: string().optional(),
73350
+ nodeId: string().optional(),
73351
+ /** The alert's own action link (where the operator acts on it), when it has one. */
73352
+ actionUrl: string().optional(),
73353
+ at: number()
73354
+ });
73124
73355
  var RULE_BODY_ONLY = ["body"];
73125
73356
  var RULE_TEXT = ["title", "body"];
73126
73357
  var BATTERY = ["device-battery-low", "device-battery-normal"];
@@ -73130,6 +73361,11 @@ var TANK = [
73130
73361
  "device-tank-full",
73131
73362
  "device-tank-normal"
73132
73363
  ];
73364
+ var ALERT_EPISODE = [
73365
+ "alert-critical",
73366
+ "alert-error",
73367
+ "alert-critical-resolved"
73368
+ ];
73133
73369
  var UPDATES = [
73134
73370
  "addon-update-available",
73135
73371
  "server-update-available",
@@ -73322,14 +73558,14 @@ var STATE_SUMMARY_VARS = [
73322
73558
  ([...RULE_TEXT], [...CONSUMABLE]),
73323
73559
  ([...RULE_TEXT], [...TANK]),
73324
73560
  [...RULE_TEXT],
73325
- ([...RULE_TEXT], [...UPDATES]),
73326
- ([...RULE_TEXT], [...UPDATES]),
73327
- [...RULE_TEXT],
73561
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
73562
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
73328
73563
  [...RULE_TEXT],
73329
73564
  [...RULE_TEXT],
73330
73565
  [...RULE_TEXT],
73331
73566
  [...RULE_TEXT],
73332
73567
  [...RULE_TEXT],
73568
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73333
73569
  [...RULE_TEXT],
73334
73570
  [...RULE_TEXT],
73335
73571
  [...RULE_TEXT],
@@ -73347,7 +73583,11 @@ var STATE_SUMMARY_VARS = [
73347
73583
  [...RULE_TEXT],
73348
73584
  [...RULE_TEXT],
73349
73585
  [...RULE_TEXT],
73350
- [...RULE_TEXT],
73586
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73587
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73588
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73589
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73590
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73351
73591
  [...RULE_TEXT],
73352
73592
  [...RULE_TEXT],
73353
73593
  [...RULE_TEXT],