@camstack/addon-pipeline-orchestrator 1.2.603 → 1.2.605

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 (17) hide show
  1. package/assets/viewer/.viewer-current-files.json +2 -2
  2. package/assets/viewer/.viewer-version +1 -1
  3. package/assets/viewer/_expo/static/js/web/{__common-9186121cdd8e84b37963670cd7556b7e.js → __common-9209f030f5701da0e2e0d599fceea2f3.js} +9 -9
  4. package/assets/viewer/_expo/static/js/web/{index-5ea107bdcc99730e8fa2e5ef6ddb4a89.js → index-e0ee1e84f97c3608e8d3f41b36e5cf8e.js} +2 -2
  5. package/assets/viewer/index.html +1 -1
  6. package/dist/_stub.js +2 -2
  7. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-Bg5karC8.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-CX6Mz1A2.mjs} +3 -3
  8. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Wjbq284_.mjs +26 -0
  9. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DOO3_jHl.mjs +26 -0
  10. package/dist/{hostInit-BvlQyOZn.mjs → hostInit-BPiBtFhh.mjs} +3 -3
  11. package/dist/index.js +480 -240
  12. package/dist/index.mjs +480 -240
  13. package/dist/remoteEntry.js +1 -1
  14. package/package.json +1 -1
  15. package/assets/viewer/_expo/static/js/web/cameras-b1835891e5675d9822c90116cac3b30c.js +0 -21
  16. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BLLm0SDo.mjs +0 -26
  17. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DaLsVu7q.mjs +0 -26
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ node_fs = __toESM(node_fs);
30
30
  let node_path = require("node:path");
31
31
  node_path = __toESM(node_path);
32
32
  let node_url = require("node:url");
33
- //#region ../types/dist/event-category-BvOFi6PY.mjs
33
+ //#region ../types/dist/event-category-DOl51-Ij.mjs
34
34
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
35
35
  EventCategory["SystemBoot"] = "system.boot";
36
36
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -109,9 +109,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
109
109
  /**
110
110
  * The node's one-shot runner boot check (D877): planned runners against the
111
111
  * process service, `degraded` when any is failed, refused or missing. The
112
- * alert centre turns it into one alert and a direct critical push.
112
+ * alert centre turns it into one critical alert.
113
113
  */
114
114
  EventCategory["SystemRunnerCheck"] = "system.runner-check";
115
+ /**
116
+ * An alert EPISODE opened or closed, emitted by the alert centre for alerts
117
+ * of severity `critical` or `error` (`AlertEpisodePayload`). The alert
118
+ * centre sends no notification of its own: Notification Center turns this
119
+ * into the `alert-critical` / `alert-error` / `alert-critical-resolved`
120
+ * system-event kinds, and reconciles from the alerts store because a bus
121
+ * event may be dropped (D8, D11).
122
+ */
123
+ EventCategory["AlertEpisode"] = "alert.episode";
115
124
  EventCategory["AddonError"] = "addon.error";
116
125
  EventCategory["AddonPageReady"] = "addon.page-ready";
117
126
  EventCategory["AddonWidgetReady"] = "addon.widget-ready";
@@ -5569,7 +5578,7 @@ var ZodIssueCode = {
5569
5578
  var ZodFirstPartyTypeKind;
5570
5579
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5571
5580
  //#endregion
5572
- //#region ../types/dist/sleep-BegKjwUu.mjs
5581
+ //#region ../types/dist/sleep-BxjU_fJM.mjs
5573
5582
  /**
5574
5583
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5575
5584
  * window to float samples (D455).
@@ -7967,6 +7976,12 @@ function normalizeAddonInitResult(result) {
7967
7976
  if (Array.isArray(result)) return { providers: result };
7968
7977
  return result;
7969
7978
  }
7979
+ /**
7980
+ * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7981
+ * and validates them (`share-token.service.ts` builds its enum from this
7982
+ * list); a data plane names the kinds it ACCEPTS in `share`.
7983
+ */
7984
+ var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7970
7985
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
7971
7986
  var PeerBytesTicketSchema = object({
7972
7987
  /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
@@ -13816,6 +13831,229 @@ var ConvertResultSchema = object({
13816
13831
  files: array(string()).readonly()
13817
13832
  })).readonly()
13818
13833
  });
13834
+ /**
13835
+ * Zod schemas for persisted record types.
13836
+ *
13837
+ * These schemas serve as the single source of truth for types that are
13838
+ * stored in the settings-store backend and retrieved via tRPC. They
13839
+ * replace the manual TypeScript interfaces with schema-derived types,
13840
+ * enabling runtime validation when reading from the backend.
13841
+ *
13842
+ * Convention: each schema is named `<Type>Schema`, the inferred TS type
13843
+ * keeps the original name for backward compatibility.
13844
+ */
13845
+ /**
13846
+ * Auth model (v2 — 2026-05-12 caps-only):
13847
+ *
13848
+ * Two principals:
13849
+ * - `isAdmin: true` — full bypass. Admin scope set is ignored.
13850
+ * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
13851
+ *
13852
+ * No role enum. There used to be `viewer / agent / scoped` and earlier
13853
+ * `super_admin` — collapsed onto the single boolean because every
13854
+ * non-admin caller is governed by the same scope-check rules; the
13855
+ * distinction was only ever used to route role-specific procedures
13856
+ * which we no longer have. CLI / webhook integrations are `cst_*` tokens
13857
+ * with `isAdmin: false` + an explicit scope list.
13858
+ */
13859
+ /** Per-method access flavour. Materialised on every cap method via codegen. */
13860
+ var MethodAccessSchema = _enum([
13861
+ "view",
13862
+ "create",
13863
+ "delete"
13864
+ ]);
13865
+ /**
13866
+ * A single scope grant. Three forms — checked in matcher with OR
13867
+ * semantics; the first match decides whether the call passes:
13868
+ *
13869
+ * - `category` — broadest. `target: 'device' | 'system'` selects every
13870
+ * cap with the matching `scope` declaration. New caps inherit grants
13871
+ * automatically — adding a device cap to the codebase makes it
13872
+ * reachable to every user with `category:device [...]` without a
13873
+ * re-grant. Use this for "family viewer" / "operator" tiers.
13874
+ *
13875
+ * - `addon` — every cap that ships inside a given addon id. Niche;
13876
+ * useful when an integration needs to interact with one specific
13877
+ * addon's surface regardless of how many caps it exports.
13878
+ *
13879
+ * - `capability` — the most precise form. Single cap name. Use for
13880
+ * integration tokens where you want to grant `addons.installPackage`
13881
+ * and nothing else.
13882
+ *
13883
+ * `access` is REQUIRED with min 1 element. `admin` bypass is the
13884
+ * "give me everything" escape; there is no wildcard scope.
13885
+ */
13886
+ var AllowedProviderSchema = union([literal("*"), array(string())]);
13887
+ var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
13888
+ var CapScopeSchema = _enum(["device", "system"]);
13889
+ /**
13890
+ * DeviceSelector (scope model v3 — 2026-08-12).
13891
+ *
13892
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
13893
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
13894
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
13895
+ * AFTER the grant was minted — no re-grant, no re-login.
13896
+ *
13897
+ * - `all` — every device in the deployment. The broad viewer/operator
13898
+ * lever without a `category` grant (a `category` grant also covers device
13899
+ * caps that carry no deviceId; `all` is specifically the device set).
13900
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
13901
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
13902
+ * is NOT covered until the grant is edited.
13903
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
13904
+ * DYNAMIC. A device that changes type, or a new device of the type,
13905
+ * re-resolves on the next request.
13906
+ * - `locations` — every device whose operator-assigned `location` label is
13907
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
13908
+ * null/unset location matches NO `locations` selector.
13909
+ */
13910
+ var DeviceSelectorSchema = discriminatedUnion("kind", [
13911
+ object({ kind: literal("all") }),
13912
+ object({
13913
+ kind: literal("ids"),
13914
+ ids: array(number().int()).min(1)
13915
+ }),
13916
+ object({
13917
+ kind: literal("types"),
13918
+ types: array(_enum(DeviceType)).min(1)
13919
+ }),
13920
+ object({
13921
+ kind: literal("locations"),
13922
+ locations: array(string().min(1)).min(1)
13923
+ })
13924
+ ]);
13925
+ var DeviceTokenScopeSchema = object({
13926
+ type: literal("device"),
13927
+ /** The device SET this grant covers — resolved against the live fleet. */
13928
+ selector: DeviceSelectorSchema,
13929
+ access: array(MethodAccessSchema).min(1),
13930
+ /**
13931
+ * Whether a grant on a PARENT device transparently covers its accessory
13932
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
13933
+ * Direction is parent → children ONLY.
13934
+ *
13935
+ * Absent → the matcher DERIVES it from the access flavour: `view`
13936
+ * inherits (a camera viewer sees the camera's accessories), `create` /
13937
+ * `delete` do NOT (actuating/removing a child is an explicit act the
13938
+ * operator must grant on the child, not inherit from the parent). Set it
13939
+ * explicitly to override that default per grant.
13940
+ */
13941
+ includeLinked: boolean().optional()
13942
+ });
13943
+ /**
13944
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
13945
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
13946
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
13947
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
13948
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
13949
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
13950
+ * migration cannot reach a JWT already in a client's hands; parse-time
13951
+ * migration covers both without a flag day. No cast — the raw object is read
13952
+ * through `Reflect.get` (its static type is `unknown`).
13953
+ */
13954
+ function migrateLegacyTokenScope(raw) {
13955
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
13956
+ if (Reflect.get(raw, "type") !== "device") return raw;
13957
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
13958
+ const targets = Reflect.get(raw, "targets");
13959
+ if (!Array.isArray(targets)) return raw;
13960
+ return {
13961
+ type: "device",
13962
+ selector: {
13963
+ kind: "ids",
13964
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
13965
+ },
13966
+ access: Reflect.get(raw, "access")
13967
+ };
13968
+ }
13969
+ var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
13970
+ object({
13971
+ type: literal("category"),
13972
+ target: CapScopeSchema,
13973
+ access: array(MethodAccessSchema).min(1)
13974
+ }),
13975
+ object({
13976
+ type: literal("capability"),
13977
+ target: string(),
13978
+ access: array(MethodAccessSchema).min(1)
13979
+ }),
13980
+ object({
13981
+ type: literal("addon"),
13982
+ target: string(),
13983
+ access: array(MethodAccessSchema).min(1)
13984
+ }),
13985
+ DeviceTokenScopeSchema
13986
+ ]));
13987
+ object({
13988
+ id: string(),
13989
+ username: string(),
13990
+ passwordHash: string(),
13991
+ /**
13992
+ * Admin bypass. When true, the middleware skips the scope-access
13993
+ * check entirely. There is no other axis of privilege; the legacy
13994
+ * role enum collapsed onto this boolean in v2.
13995
+ */
13996
+ isAdmin: boolean().default(false),
13997
+ allowedProviders: AllowedProviderSchema,
13998
+ allowedDevices: AllowedDevicesSchema,
13999
+ /**
14000
+ * Scopes granted to this user. Admins bypass; their `scopes` is
14001
+ * ignored. Non-admins without scopes are locked out of every
14002
+ * protected call.
14003
+ */
14004
+ scopes: array(TokenScopeSchema).default([]),
14005
+ createdAt: number(),
14006
+ updatedAt: number()
14007
+ });
14008
+ object({
14009
+ id: string(),
14010
+ label: string(),
14011
+ isAdmin: boolean().default(false),
14012
+ allowedProviders: AllowedProviderSchema,
14013
+ allowedDevices: AllowedDevicesSchema,
14014
+ tokenHash: string(),
14015
+ tokenPrefix: string(),
14016
+ createdAt: number(),
14017
+ lastUsedAt: number().optional()
14018
+ });
14019
+ object({
14020
+ id: string(),
14021
+ userId: string(),
14022
+ name: string(),
14023
+ tokenHash: string(),
14024
+ tokenPrefix: string(),
14025
+ scopes: array(TokenScopeSchema),
14026
+ expiresAt: number().nullish(),
14027
+ lastUsedAt: number().nullish(),
14028
+ createdAt: number()
14029
+ });
14030
+ /** What a share-view grant lets its holder see. */
14031
+ var ShareViewGrantSchema = object({
14032
+ kind: _enum(SHARE_VIEW_KINDS),
14033
+ deviceIds: array(number().int().nonnegative()).min(1).max(64),
14034
+ /** Talk-back, opt-in at mint time; absent means off. */
14035
+ talk: boolean().optional()
14036
+ });
14037
+ var ShareViewScopeSchema = object({
14038
+ type: literal("share-view"),
14039
+ grant: ShareViewGrantSchema
14040
+ });
14041
+ var AddonRoutesScopeSchema = object({
14042
+ type: literal("addon-routes"),
14043
+ access: array(MethodAccessSchema).min(1)
14044
+ });
14045
+ var CredentialScopeSchema = union([
14046
+ literal("*"),
14047
+ ShareViewScopeSchema,
14048
+ AddonRoutesScopeSchema,
14049
+ TokenScopeSchema
14050
+ ]);
14051
+ object({
14052
+ kind: literal("credential"),
14053
+ sub: string().min(1),
14054
+ jti: string().min(16),
14055
+ scopes: array(CredentialScopeSchema).min(1)
14056
+ });
13819
14057
  _enum(["new-session", "step-up"]);
13820
14058
  /** The languages the hub's app landing pages are written in (D858). */
13821
14059
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -14551,7 +14789,14 @@ var AlertSeveritySchema = _enum([
14551
14789
  ]);
14552
14790
  var AlertActionSchema = object({
14553
14791
  label: string(),
14554
- href: string().optional()
14792
+ href: string().optional(),
14793
+ /**
14794
+ * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
14795
+ * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
14796
+ * start) — the browser must leave the SPA with a full navigation, because
14797
+ * the SPA has no such route and would bounce to the home page.
14798
+ */
14799
+ navigation: _enum(["app", "server"]).optional()
14555
14800
  });
14556
14801
  var AlertStatusSchema = _enum([
14557
14802
  "active",
@@ -42965,6 +43210,9 @@ var NcSystemEventKindSchema = _enum([
42965
43210
  "server-updated",
42966
43211
  "export-completed",
42967
43212
  "backup-completed",
43213
+ "alert-critical",
43214
+ "alert-error",
43215
+ "alert-critical-resolved",
42968
43216
  "camera-online",
42969
43217
  "camera-offline",
42970
43218
  "camera-disabled",
@@ -45000,202 +45248,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
45000
45248
  auth: "admin"
45001
45249
  }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
45002
45250
  /**
45003
- * Zod schemas for persisted record types.
45004
- *
45005
- * These schemas serve as the single source of truth for types that are
45006
- * stored in the settings-store backend and retrieved via tRPC. They
45007
- * replace the manual TypeScript interfaces with schema-derived types,
45008
- * enabling runtime validation when reading from the backend.
45009
- *
45010
- * Convention: each schema is named `<Type>Schema`, the inferred TS type
45011
- * keeps the original name for backward compatibility.
45012
- */
45013
- /**
45014
- * Auth model (v2 — 2026-05-12 caps-only):
45015
- *
45016
- * Two principals:
45017
- * - `isAdmin: true` — full bypass. Admin scope set is ignored.
45018
- * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
45019
- *
45020
- * No role enum. There used to be `viewer / agent / scoped` and earlier
45021
- * `super_admin` — collapsed onto the single boolean because every
45022
- * non-admin caller is governed by the same scope-check rules; the
45023
- * distinction was only ever used to route role-specific procedures
45024
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
45025
- * with `isAdmin: false` + an explicit scope list.
45026
- */
45027
- /** Per-method access flavour. Materialised on every cap method via codegen. */
45028
- var MethodAccessSchema = _enum([
45029
- "view",
45030
- "create",
45031
- "delete"
45032
- ]);
45033
- /**
45034
- * A single scope grant. Three forms — checked in matcher with OR
45035
- * semantics; the first match decides whether the call passes:
45036
- *
45037
- * - `category` — broadest. `target: 'device' | 'system'` selects every
45038
- * cap with the matching `scope` declaration. New caps inherit grants
45039
- * automatically — adding a device cap to the codebase makes it
45040
- * reachable to every user with `category:device [...]` without a
45041
- * re-grant. Use this for "family viewer" / "operator" tiers.
45042
- *
45043
- * - `addon` — every cap that ships inside a given addon id. Niche;
45044
- * useful when an integration needs to interact with one specific
45045
- * addon's surface regardless of how many caps it exports.
45046
- *
45047
- * - `capability` — the most precise form. Single cap name. Use for
45048
- * integration tokens where you want to grant `addons.installPackage`
45049
- * and nothing else.
45050
- *
45051
- * `access` is REQUIRED with min 1 element. `admin` bypass is the
45052
- * "give me everything" escape; there is no wildcard scope.
45053
- */
45054
- var AllowedProviderSchema = union([literal("*"), array(string())]);
45055
- var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
45056
- var CapScopeSchema = _enum(["device", "system"]);
45057
- /**
45058
- * DeviceSelector (scope model v3 — 2026-08-12).
45059
- *
45060
- * A `device` grant no longer carries a frozen list of deviceIds. It carries
45061
- * a SELECTOR the matcher resolves against the live fleet, so the grant can be
45062
- * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
45063
- * AFTER the grant was minted — no re-grant, no re-login.
45064
- *
45065
- * - `all` — every device in the deployment. The broad viewer/operator
45066
- * lever without a `category` grant (a `category` grant also covers device
45067
- * caps that carry no deviceId; `all` is specifically the device set).
45068
- * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
45069
- * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
45070
- * is NOT covered until the grant is edited.
45071
- * - `types` — every device of a `DeviceType` (e.g. every `camera`).
45072
- * DYNAMIC. A device that changes type, or a new device of the type,
45073
- * re-resolves on the next request.
45074
- * - `locations` — every device whose operator-assigned `location` label is
45075
- * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
45076
- * null/unset location matches NO `locations` selector.
45077
- */
45078
- var DeviceSelectorSchema = discriminatedUnion("kind", [
45079
- object({ kind: literal("all") }),
45080
- object({
45081
- kind: literal("ids"),
45082
- ids: array(number().int()).min(1)
45083
- }),
45084
- object({
45085
- kind: literal("types"),
45086
- types: array(_enum(DeviceType)).min(1)
45087
- }),
45088
- object({
45089
- kind: literal("locations"),
45090
- locations: array(string().min(1)).min(1)
45091
- })
45092
- ]);
45093
- var DeviceTokenScopeSchema = object({
45094
- type: literal("device"),
45095
- /** The device SET this grant covers — resolved against the live fleet. */
45096
- selector: DeviceSelectorSchema,
45097
- access: array(MethodAccessSchema).min(1),
45098
- /**
45099
- * Whether a grant on a PARENT device transparently covers its accessory
45100
- * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
45101
- * Direction is parent → children ONLY.
45102
- *
45103
- * Absent → the matcher DERIVES it from the access flavour: `view`
45104
- * inherits (a camera viewer sees the camera's accessories), `create` /
45105
- * `delete` do NOT (actuating/removing a child is an explicit act the
45106
- * operator must grant on the child, not inherit from the parent). Set it
45107
- * explicitly to override that default per grant.
45108
- */
45109
- includeLinked: boolean().optional()
45110
- });
45111
- /**
45112
- * v2 → v3 lazy migration. A pre-v3 `device` grant carried
45113
- * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
45114
- * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
45115
- * EVERY parse path — stored records AND the JWT-carried scope arrays
45116
- * normalised at the request boundary ({@link normalizeTokenScopes} in
45117
- * `device-selector.ts`). Chosen over a one-time DB migration because a
45118
- * migration cannot reach a JWT already in a client's hands; parse-time
45119
- * migration covers both without a flag day. No cast — the raw object is read
45120
- * through `Reflect.get` (its static type is `unknown`).
45121
- */
45122
- function migrateLegacyTokenScope(raw) {
45123
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
45124
- if (Reflect.get(raw, "type") !== "device") return raw;
45125
- if (Reflect.get(raw, "selector") !== void 0) return raw;
45126
- const targets = Reflect.get(raw, "targets");
45127
- if (!Array.isArray(targets)) return raw;
45128
- return {
45129
- type: "device",
45130
- selector: {
45131
- kind: "ids",
45132
- ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
45133
- },
45134
- access: Reflect.get(raw, "access")
45135
- };
45136
- }
45137
- var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
45138
- object({
45139
- type: literal("category"),
45140
- target: CapScopeSchema,
45141
- access: array(MethodAccessSchema).min(1)
45142
- }),
45143
- object({
45144
- type: literal("capability"),
45145
- target: string(),
45146
- access: array(MethodAccessSchema).min(1)
45147
- }),
45148
- object({
45149
- type: literal("addon"),
45150
- target: string(),
45151
- access: array(MethodAccessSchema).min(1)
45152
- }),
45153
- DeviceTokenScopeSchema
45154
- ]));
45155
- object({
45156
- id: string(),
45157
- username: string(),
45158
- passwordHash: string(),
45159
- /**
45160
- * Admin bypass. When true, the middleware skips the scope-access
45161
- * check entirely. There is no other axis of privilege; the legacy
45162
- * role enum collapsed onto this boolean in v2.
45163
- */
45164
- isAdmin: boolean().default(false),
45165
- allowedProviders: AllowedProviderSchema,
45166
- allowedDevices: AllowedDevicesSchema,
45167
- /**
45168
- * Scopes granted to this user. Admins bypass; their `scopes` is
45169
- * ignored. Non-admins without scopes are locked out of every
45170
- * protected call.
45171
- */
45172
- scopes: array(TokenScopeSchema).default([]),
45173
- createdAt: number(),
45174
- updatedAt: number()
45175
- });
45176
- object({
45177
- id: string(),
45178
- label: string(),
45179
- isAdmin: boolean().default(false),
45180
- allowedProviders: AllowedProviderSchema,
45181
- allowedDevices: AllowedDevicesSchema,
45182
- tokenHash: string(),
45183
- tokenPrefix: string(),
45184
- createdAt: number(),
45185
- lastUsedAt: number().optional()
45186
- });
45187
- object({
45188
- id: string(),
45189
- userId: string(),
45190
- name: string(),
45191
- tokenHash: string(),
45192
- tokenPrefix: string(),
45193
- scopes: array(TokenScopeSchema),
45194
- expiresAt: number().nullish(),
45195
- lastUsedAt: number().nullish(),
45196
- createdAt: number()
45197
- });
45198
- /**
45199
45251
  * `oauth-integration` — a collection cap by which an addon declares
45200
45252
  * itself a linkable OAuth client of the hub's core `/oauth2/*` server.
45201
45253
  * Each provider returns a static descriptor; the core enumerates them
@@ -52947,7 +52999,10 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
52947
52999
  }), method(object({ jobId: string().optional() }), StorageMigrationJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
52948
53000
  kind: "mutation",
52949
53001
  auth: "admin"
52950
- }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
53002
+ }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({ locationIds: array(string()).readonly() }), object({
53003
+ clear: boolean(),
53004
+ repointLocationId: string().optional()
53005
+ }), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
52951
53006
  kind: "mutation",
52952
53007
  auth: "admin"
52953
53008
  }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
@@ -56382,6 +56437,11 @@ object({
56382
56437
  *
56383
56438
  * `kind: 'poll'` — cloud REST APIs typically have no push channel; the
56384
56439
  * provider refreshes the slice on an interval and eagerly after commands.
56440
+ *
56441
+ * UNKNOWN IS NOT OFF. Every field the appliance reports separately is
56442
+ * nullable: `null` means "not known right now" (the appliance has not said,
56443
+ * the link is down, or the description does not carry it) and is never
56444
+ * rendered or exported as `false` / `0`. `availability` says why.
56385
56445
  */
56386
56446
  var DishwasherStateSchema = _enum([
56387
56447
  "idle",
@@ -56391,112 +56451,227 @@ var DishwasherStateSchema = _enum([
56391
56451
  "error",
56392
56452
  "unavailable"
56393
56453
  ]);
56454
+ /**
56455
+ * The appliance's own operation state, uncollapsed. `state` above is the coarse
56456
+ * view for compact surfaces; this is what the appliance said.
56457
+ */
56458
+ var DishwasherOperationStateSchema = _enum([
56459
+ "Inactive",
56460
+ "Ready",
56461
+ "DelayedStart",
56462
+ "Run",
56463
+ "Pause",
56464
+ "ActionRequired",
56465
+ "Finished",
56466
+ "Error",
56467
+ "Aborting"
56468
+ ]);
56469
+ /**
56470
+ * Why fields may be `null`:
56471
+ * - `available` — the link is up and the description is loaded;
56472
+ * - `offline` — the local link is down (values are unknown, not last-known);
56473
+ * - `description-missing` — the link is up but the appliance's description could not
56474
+ * be loaded, so its values cannot be decoded.
56475
+ */
56476
+ var DishwasherAvailabilitySchema = _enum([
56477
+ "available",
56478
+ "offline",
56479
+ "description-missing"
56480
+ ]);
56394
56481
  var DishwasherConsumableLevelSchema = _enum([
56395
56482
  "ok",
56396
56483
  "low",
56397
56484
  "empty"
56398
56485
  ]);
56399
56486
  object({
56487
+ availability: DishwasherAvailabilitySchema,
56488
+ /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
56400
56489
  state: DishwasherStateSchema,
56401
- /** Active program id/name, or null when none selected / unknown. */
56490
+ /** The appliance's operation state as reported; null when not known. */
56491
+ operationState: DishwasherOperationStateSchema.nullable(),
56492
+ /** Feature key of the ACTIVE (running) program, or null when none runs / not known. */
56402
56493
  program: string().nullable(),
56403
- /** Program tokens the hardware accepts — drives the UI selector. */
56494
+ /** Feature key of the SELECTED program (what Start would run), or null when none / not known. */
56495
+ selectedProgram: string().nullable(),
56496
+ /** Feature keys of the programs the appliance currently offers — drives the UI selector. */
56404
56497
  availablePrograms: array(string()),
56405
- /** Minutes remaining on the active cycle, or null when not running. */
56406
- remainingMinutes: number().int().nonnegative().nullable(),
56498
+ /** Seconds remaining on the active cycle, or null when not running / not known. */
56499
+ remainingSeconds: number().int().nonnegative().nullable(),
56500
+ /** Seconds the delayed start is set to (time until the cycle starts), or null. */
56501
+ delayedStartSeconds: number().int().nonnegative().nullable(),
56407
56502
  /** Cycle completion 0..100, or null when not applicable. */
56408
56503
  progressPercent: number().min(0).max(100).nullable(),
56409
- /** True when the door is reported open. */
56410
- doorOpen: boolean(),
56411
- /** True when remote start is allowed (door closed, power on, etc.). */
56412
- remoteStartAllowed: boolean(),
56413
- /** Main power / switched-on state. */
56414
- powerOn: boolean(),
56504
+ /** True when the door is reported open; null when the door state is not known. */
56505
+ doorOpen: boolean().nullable(),
56506
+ /** True when the door is latched (locked) during a cycle; null when not reported. */
56507
+ doorLocked: boolean().nullable(),
56508
+ /** True when remote start is allowed (door closed, power on, etc.); null when not known. */
56509
+ remoteStartAllowed: boolean().nullable(),
56510
+ /** True when the appliance accepts remote control now; null when not known. */
56511
+ remoteControlActive: boolean().nullable(),
56512
+ /** True while somebody operates the appliance at its panel; null when not reported. */
56513
+ localControlActive: boolean().nullable(),
56514
+ /** Main power / switched-on state; null when not known. */
56515
+ powerOn: boolean().nullable(),
56516
+ /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
56517
+ powerState: string().nullable(),
56415
56518
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
56416
56519
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
56417
- halfLoad: boolean(),
56418
- hygienePlus: boolean(),
56520
+ /** Option states: null when the appliance does not expose the option or has not said. */
56521
+ halfLoad: boolean().nullable(),
56522
+ hygienePlus: boolean().nullable(),
56419
56523
  /** Extra dry option when the appliance exposes it. */
56420
- extraDry: boolean(),
56524
+ extraDry: boolean().nullable(),
56421
56525
  /** Intensive zone (lower basket) when the appliance exposes it. */
56422
- intensiveZone: boolean(),
56526
+ intensiveZone: boolean().nullable(),
56423
56527
  /** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
56424
- varioSpeedPlus: boolean(),
56425
- /** Child lock (controls disabled on the appliance). */
56426
- childLock: boolean(),
56528
+ varioSpeedPlus: boolean().nullable(),
56529
+ /** Child lock (controls disabled on the appliance); null when not known. */
56530
+ childLock: boolean().nullable(),
56531
+ /** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
56532
+ activeEvents: array(string()),
56533
+ /** Numeric error code when the appliance reports one; null otherwise. */
56427
56534
  errorCode: number().nullable(),
56535
+ /** Name of the raised alert-level event while the appliance is in error; null otherwise. */
56428
56536
  errorLabel: string().nullable(),
56537
+ /** Ms epoch of the last value received from the appliance; 0 = never. */
56429
56538
  lastFetchedAt: number()
56430
56539
  });
56431
- DeviceType.Dishwasher, method(object({ deviceId: number().int().nonnegative() }), _void(), {
56540
+ var DeviceIdSchema = number().int().nonnegative();
56541
+ /** A value a program option or setting can take. */
56542
+ var DishwasherValueSchema = union([
56543
+ boolean(),
56544
+ string(),
56545
+ number()
56546
+ ]);
56547
+ var DishwasherAccessSchema = _enum([
56548
+ "none",
56549
+ "read",
56550
+ "readWrite",
56551
+ "writeOnly",
56552
+ "readStatic"
56553
+ ]);
56554
+ /**
56555
+ * One option or setting the appliance declares, with the constraints its description
56556
+ * gives. A `readWrite` descriptor that is `available` is what `setOption` accepts.
56557
+ */
56558
+ var DishwasherOptionDescriptorSchema = object({
56559
+ /** Feature key (`Dishcare.Dishwasher.Option.ExtraDry`). */
56560
+ key: string(),
56561
+ /** Last segment of the key, for display. */
56562
+ name: string(),
56563
+ type: _enum([
56564
+ "boolean",
56565
+ "number",
56566
+ "enum",
56567
+ "string"
56568
+ ]),
56569
+ access: DishwasherAccessSchema,
56570
+ /** The appliance reports this entity as currently available. */
56571
+ available: boolean(),
56572
+ /** Unit the description declares for a number; null when it declares none. */
56573
+ unit: string().nullable(),
56574
+ min: number().nullable(),
56575
+ max: number().nullable(),
56576
+ step: number().nullable(),
56577
+ /** Allowed members of an enum; null for other types. */
56578
+ enumValues: array(string()).nullable(),
56579
+ defaultValue: DishwasherValueSchema.nullable()
56580
+ });
56581
+ var DishwasherProgramSchema = object({
56582
+ /** Feature key (`Dishcare.Dishwasher.Program.Eco50`) — what `setProgram` / `start` take. */
56583
+ key: string(),
56584
+ name: string(),
56585
+ /** The appliance currently offers this program. */
56586
+ available: boolean(),
56587
+ /** The options this program lists, with the program-level access / availability / default. */
56588
+ options: array(DishwasherOptionDescriptorSchema)
56589
+ });
56590
+ var DishwasherOptionsSchema = object({
56591
+ availability: DishwasherAvailabilitySchema,
56592
+ /** What the appliance can be told to do, from the commands its description declares. */
56593
+ supportsStart: boolean(),
56594
+ supportsPause: boolean(),
56595
+ supportsResume: boolean(),
56596
+ supportsStop: boolean(),
56597
+ supportsPower: boolean(),
56598
+ /** Every program the description lists, with its options. */
56599
+ programs: array(DishwasherProgramSchema),
56600
+ /** Every option and setting entity the description lists (programs reference these by key). */
56601
+ options: array(DishwasherOptionDescriptorSchema)
56602
+ });
56603
+ DeviceType.Dishwasher, method(object({
56604
+ deviceId: DeviceIdSchema,
56605
+ program: string().min(1).optional(),
56606
+ options: record(string(), DishwasherValueSchema).optional()
56607
+ }), _void(), {
56432
56608
  kind: "mutation",
56433
56609
  auth: "protected"
56434
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
56610
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
56435
56611
  kind: "mutation",
56436
56612
  auth: "protected"
56437
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
56613
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
56614
+ kind: "mutation",
56615
+ auth: "protected"
56616
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
56438
56617
  kind: "mutation",
56439
56618
  auth: "protected"
56440
56619
  }), method(object({
56441
- deviceId: number().int().nonnegative(),
56620
+ deviceId: DeviceIdSchema,
56442
56621
  program: string().min(1)
56443
56622
  }), _void(), {
56444
56623
  kind: "mutation",
56445
56624
  auth: "protected"
56446
56625
  }), method(object({
56447
- deviceId: number().int().nonnegative(),
56626
+ deviceId: DeviceIdSchema,
56448
56627
  on: boolean()
56449
56628
  }), _void(), {
56450
56629
  kind: "mutation",
56451
56630
  auth: "protected"
56452
56631
  }), method(object({
56453
- deviceId: number().int().nonnegative(),
56632
+ deviceId: DeviceIdSchema,
56454
56633
  on: boolean()
56455
56634
  }), _void(), {
56456
56635
  kind: "mutation",
56457
56636
  auth: "protected"
56458
56637
  }), method(object({
56459
- deviceId: number().int().nonnegative(),
56638
+ deviceId: DeviceIdSchema,
56460
56639
  on: boolean()
56461
56640
  }), _void(), {
56462
56641
  kind: "mutation",
56463
56642
  auth: "protected"
56464
56643
  }), method(object({
56465
- deviceId: number().int().nonnegative(),
56644
+ deviceId: DeviceIdSchema,
56466
56645
  on: boolean()
56467
56646
  }), _void(), {
56468
56647
  kind: "mutation",
56469
56648
  auth: "protected"
56470
56649
  }), method(object({
56471
- deviceId: number().int().nonnegative(),
56650
+ deviceId: DeviceIdSchema,
56472
56651
  on: boolean()
56473
56652
  }), _void(), {
56474
56653
  kind: "mutation",
56475
56654
  auth: "protected"
56476
56655
  }), method(object({
56477
- deviceId: number().int().nonnegative(),
56656
+ deviceId: DeviceIdSchema,
56478
56657
  on: boolean()
56479
56658
  }), _void(), {
56480
56659
  kind: "mutation",
56481
56660
  auth: "protected"
56482
56661
  }), method(object({
56483
- deviceId: number().int().nonnegative(),
56662
+ deviceId: DeviceIdSchema,
56484
56663
  on: boolean()
56485
56664
  }), _void(), {
56486
56665
  kind: "mutation",
56487
56666
  auth: "protected"
56488
56667
  }), method(object({
56489
- deviceId: number().int().nonnegative(),
56668
+ deviceId: DeviceIdSchema,
56490
56669
  key: string().min(1),
56491
- value: union([
56492
- boolean(),
56493
- string(),
56494
- number()
56495
- ])
56670
+ value: DishwasherValueSchema
56496
56671
  }), _void(), {
56497
56672
  kind: "mutation",
56498
56673
  auth: "protected"
56499
- });
56674
+ }), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
56500
56675
  object({
56501
56676
  /** Ms epoch of the last press. null = never observed since this provider started. */
56502
56677
  lastPressedAt: number().nullable(),
@@ -66675,6 +66850,12 @@ Object.freeze({
66675
66850
  addonId: null,
66676
66851
  access: "view"
66677
66852
  },
66853
+ "dishwasher.getOptions": {
66854
+ capName: "dishwasher",
66855
+ capScope: "device",
66856
+ addonId: null,
66857
+ access: "view"
66858
+ },
66678
66859
  "dishwasher.getStatus": {
66679
66860
  capName: "dishwasher",
66680
66861
  capScope: "device",
@@ -66687,6 +66868,12 @@ Object.freeze({
66687
66868
  addonId: null,
66688
66869
  access: "create"
66689
66870
  },
66871
+ "dishwasher.resume": {
66872
+ capName: "dishwasher",
66873
+ capScope: "device",
66874
+ addonId: null,
66875
+ access: "create"
66876
+ },
66690
66877
  "dishwasher.setChildLock": {
66691
66878
  capName: "dishwasher",
66692
66879
  capScope: "device",
@@ -71187,6 +71374,12 @@ Object.freeze({
71187
71374
  addonId: null,
71188
71375
  access: "view"
71189
71376
  },
71377
+ "storageMigration.moverClearance": {
71378
+ capName: "storage-migration",
71379
+ capScope: "system",
71380
+ addonId: null,
71381
+ access: "view"
71382
+ },
71190
71383
  "storageMigration.movers": {
71191
71384
  capName: "storage-migration",
71192
71385
  capScope: "system",
@@ -73408,6 +73601,11 @@ Object.freeze({
73408
73601
  form: "single",
73409
73602
  optional: false
73410
73603
  }],
73604
+ "dishwasher.getOptions": [{
73605
+ name: "deviceId",
73606
+ form: "single",
73607
+ optional: false
73608
+ }],
73411
73609
  "dishwasher.getStatus": [{
73412
73610
  name: "deviceId",
73413
73611
  form: "single",
@@ -73418,6 +73616,11 @@ Object.freeze({
73418
73616
  form: "single",
73419
73617
  optional: false
73420
73618
  }],
73619
+ "dishwasher.resume": [{
73620
+ name: "deviceId",
73621
+ form: "single",
73622
+ optional: false
73623
+ }],
73421
73624
  "dishwasher.setChildLock": [{
73422
73625
  name: "deviceId",
73423
73626
  form: "single",
@@ -75601,6 +75804,9 @@ new Map(Object.entries({
75601
75804
  "wrapper-update-available": "system",
75602
75805
  "backup-completed": "system",
75603
75806
  "export-completed": "system",
75807
+ "alert-critical": "system",
75808
+ "alert-error": "system",
75809
+ "alert-critical-resolved": "system",
75604
75810
  "storage-location-low": "system",
75605
75811
  "storage-location-critical": "system",
75606
75812
  "storage-location-ok": "system",
@@ -75725,6 +75931,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
75725
75931
  "storage-location-ok"
75726
75932
  ]
75727
75933
  },
75934
+ {
75935
+ id: "alerts",
75936
+ family: "system",
75937
+ label: "Alerts",
75938
+ kinds: [
75939
+ "alert-critical",
75940
+ "alert-error",
75941
+ "alert-critical-resolved"
75942
+ ]
75943
+ },
75728
75944
  {
75729
75945
  id: "alarm",
75730
75946
  family: "alarm",
@@ -75769,6 +75985,21 @@ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.ent
75769
75985
  return [[descriptor.kind, field]];
75770
75986
  })));
75771
75987
  Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
75988
+ object({
75989
+ phase: _enum(["raised", "resolved"]),
75990
+ episodeId: string().min(1),
75991
+ alertId: string().min(1),
75992
+ severity: AlertSeveritySchema,
75993
+ category: string(),
75994
+ title: string(),
75995
+ message: string(),
75996
+ sourceType: string().optional(),
75997
+ sourceId: string().optional(),
75998
+ nodeId: string().optional(),
75999
+ /** The alert's own action link (where the operator acts on it), when it has one. */
76000
+ actionUrl: string().optional(),
76001
+ at: number()
76002
+ });
75772
76003
  var RULE_BODY_ONLY = ["body"];
75773
76004
  var RULE_TEXT = ["title", "body"];
75774
76005
  var BATTERY = ["device-battery-low", "device-battery-normal"];
@@ -75778,6 +76009,11 @@ var TANK = [
75778
76009
  "device-tank-full",
75779
76010
  "device-tank-normal"
75780
76011
  ];
76012
+ var ALERT_EPISODE = [
76013
+ "alert-critical",
76014
+ "alert-error",
76015
+ "alert-critical-resolved"
76016
+ ];
75781
76017
  var UPDATES = [
75782
76018
  "addon-update-available",
75783
76019
  "server-update-available",
@@ -75970,14 +76206,14 @@ var STATE_SUMMARY_VARS = [
75970
76206
  ([...RULE_TEXT], [...CONSUMABLE]),
75971
76207
  ([...RULE_TEXT], [...TANK]),
75972
76208
  [...RULE_TEXT],
75973
- ([...RULE_TEXT], [...UPDATES]),
75974
- ([...RULE_TEXT], [...UPDATES]),
75975
- [...RULE_TEXT],
76209
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
76210
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
75976
76211
  [...RULE_TEXT],
75977
76212
  [...RULE_TEXT],
75978
76213
  [...RULE_TEXT],
75979
76214
  [...RULE_TEXT],
75980
76215
  [...RULE_TEXT],
76216
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
75981
76217
  [...RULE_TEXT],
75982
76218
  [...RULE_TEXT],
75983
76219
  [...RULE_TEXT],
@@ -75995,7 +76231,11 @@ var STATE_SUMMARY_VARS = [
75995
76231
  [...RULE_TEXT],
75996
76232
  [...RULE_TEXT],
75997
76233
  [...RULE_TEXT],
75998
- [...RULE_TEXT],
76234
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
76235
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
76236
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
76237
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
76238
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
75999
76239
  [...RULE_TEXT],
76000
76240
  [...RULE_TEXT],
76001
76241
  [...RULE_TEXT],