@camstack/types 1.2.384 → 1.2.386

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.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-REHQvLV6.js");
3
- const require_event_category = require("./event-category-Hoe-mqbd.js");
2
+ const require_sleep = require("./sleep-BE7_6UnC.js");
3
+ const require_event_category = require("./event-category-eSqkye-K.js");
4
4
  const require_composition = require("./composition-eoYYVfOp.js");
5
5
  const require_node_color = require("./node-color.js");
6
6
  const require_err_msg = require("./err-msg-BhVbr0NX.js");
@@ -3951,6 +3951,41 @@ var StorageCleanupJobSchema = zod.z.object({
3951
3951
  error: zod.z.string().nullable()
3952
3952
  });
3953
3953
  var StorageCleanupStatusInputSchema = zod.z.object({ jobId: zod.z.string().optional() });
3954
+ /**
3955
+ * Start a mover only when no single-location repoint holds an overlapping
3956
+ * physical root. Asks BEFORE (cheap refusal, no job) and AFTER registering the
3957
+ * job: the repoint announces its claim and then lists movers, so a mover that
3958
+ * registers first is seen by it and one that registers second sees the claim —
3959
+ * neither side can miss the other (2026-10-20: a repoint and a relocate job
3960
+ * moved and deleted the same event media with no lock between them).
3961
+ *
3962
+ * Fail CLOSED: a clearance that cannot be asked refuses the start.
3963
+ */
3964
+ async function startMoverUnderClearance(deps) {
3965
+ const refuse = (detail) => {
3966
+ throw new Error(`mover refused: ${detail}`);
3967
+ };
3968
+ const ask = async () => {
3969
+ try {
3970
+ return await deps.clearance(deps.locationIds);
3971
+ } catch (err) {
3972
+ return refuse(`the storage orchestrator could not be asked (${err instanceof Error ? err.message : String(err)})`);
3973
+ }
3974
+ };
3975
+ const blocked = (answer) => `a re-point of "${answer.repointLocationId ?? "a location"}" holds an overlapping storage root`;
3976
+ const before = await ask();
3977
+ if (!before.clear) return refuse(blocked(before));
3978
+ const jobId = deps.start();
3979
+ const after = await ask().catch((err) => {
3980
+ deps.cancel(jobId);
3981
+ throw err;
3982
+ });
3983
+ if (!after.clear) {
3984
+ deps.cancel(jobId);
3985
+ return refuse(blocked(after));
3986
+ }
3987
+ return jobId;
3988
+ }
3954
3989
  //#endregion
3955
3990
  //#region src/interfaces/server-analysis.ts
3956
3991
  var SUB_DETECTION_TYPES = ["face", "plate"];
@@ -6602,6 +6637,312 @@ function principalMayReachAddon(input) {
6602
6637
  };
6603
6638
  }
6604
6639
  //#endregion
6640
+ //#region src/schemas/auth-records.ts
6641
+ /**
6642
+ * Zod schemas for persisted record types.
6643
+ *
6644
+ * These schemas serve as the single source of truth for types that are
6645
+ * stored in the settings-store backend and retrieved via tRPC. They
6646
+ * replace the manual TypeScript interfaces with schema-derived types,
6647
+ * enabling runtime validation when reading from the backend.
6648
+ *
6649
+ * Convention: each schema is named `<Type>Schema`, the inferred TS type
6650
+ * keeps the original name for backward compatibility.
6651
+ */
6652
+ /**
6653
+ * Auth model (v2 — 2026-05-12 caps-only):
6654
+ *
6655
+ * Two principals:
6656
+ * - `isAdmin: true` — full bypass. Admin scope set is ignored.
6657
+ * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
6658
+ *
6659
+ * No role enum. There used to be `viewer / agent / scoped` and earlier
6660
+ * `super_admin` — collapsed onto the single boolean because every
6661
+ * non-admin caller is governed by the same scope-check rules; the
6662
+ * distinction was only ever used to route role-specific procedures
6663
+ * which we no longer have. CLI / webhook integrations are `cst_*` tokens
6664
+ * with `isAdmin: false` + an explicit scope list.
6665
+ */
6666
+ /** Per-method access flavour. Materialised on every cap method via codegen. */
6667
+ var MethodAccessSchema = zod.z.enum([
6668
+ "view",
6669
+ "create",
6670
+ "delete"
6671
+ ]);
6672
+ /**
6673
+ * A single scope grant. Three forms — checked in matcher with OR
6674
+ * semantics; the first match decides whether the call passes:
6675
+ *
6676
+ * - `category` — broadest. `target: 'device' | 'system'` selects every
6677
+ * cap with the matching `scope` declaration. New caps inherit grants
6678
+ * automatically — adding a device cap to the codebase makes it
6679
+ * reachable to every user with `category:device [...]` without a
6680
+ * re-grant. Use this for "family viewer" / "operator" tiers.
6681
+ *
6682
+ * - `addon` — every cap that ships inside a given addon id. Niche;
6683
+ * useful when an integration needs to interact with one specific
6684
+ * addon's surface regardless of how many caps it exports.
6685
+ *
6686
+ * - `capability` — the most precise form. Single cap name. Use for
6687
+ * integration tokens where you want to grant `addons.installPackage`
6688
+ * and nothing else.
6689
+ *
6690
+ * `access` is REQUIRED with min 1 element. `admin` bypass is the
6691
+ * "give me everything" escape; there is no wildcard scope.
6692
+ */
6693
+ var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
6694
+ var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
6695
+ var CapScopeSchema = zod.z.enum(["device", "system"]);
6696
+ /**
6697
+ * DeviceSelector (scope model v3 — 2026-08-12).
6698
+ *
6699
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
6700
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
6701
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
6702
+ * AFTER the grant was minted — no re-grant, no re-login.
6703
+ *
6704
+ * - `all` — every device in the deployment. The broad viewer/operator
6705
+ * lever without a `category` grant (a `category` grant also covers device
6706
+ * caps that carry no deviceId; `all` is specifically the device set).
6707
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
6708
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
6709
+ * is NOT covered until the grant is edited.
6710
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
6711
+ * DYNAMIC. A device that changes type, or a new device of the type,
6712
+ * re-resolves on the next request.
6713
+ * - `locations` — every device whose operator-assigned `location` label is
6714
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
6715
+ * null/unset location matches NO `locations` selector.
6716
+ */
6717
+ var DeviceSelectorSchema = zod.z.discriminatedUnion("kind", [
6718
+ zod.z.object({ kind: zod.z.literal("all") }),
6719
+ zod.z.object({
6720
+ kind: zod.z.literal("ids"),
6721
+ ids: zod.z.array(zod.z.number().int()).min(1)
6722
+ }),
6723
+ zod.z.object({
6724
+ kind: zod.z.literal("types"),
6725
+ types: zod.z.array(zod.z.enum(require_err_msg.DeviceType)).min(1)
6726
+ }),
6727
+ zod.z.object({
6728
+ kind: zod.z.literal("locations"),
6729
+ locations: zod.z.array(zod.z.string().min(1)).min(1)
6730
+ })
6731
+ ]);
6732
+ var DeviceTokenScopeSchema = zod.z.object({
6733
+ type: zod.z.literal("device"),
6734
+ /** The device SET this grant covers — resolved against the live fleet. */
6735
+ selector: DeviceSelectorSchema,
6736
+ access: zod.z.array(MethodAccessSchema).min(1),
6737
+ /**
6738
+ * Whether a grant on a PARENT device transparently covers its accessory
6739
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
6740
+ * Direction is parent → children ONLY.
6741
+ *
6742
+ * Absent → the matcher DERIVES it from the access flavour: `view`
6743
+ * inherits (a camera viewer sees the camera's accessories), `create` /
6744
+ * `delete` do NOT (actuating/removing a child is an explicit act the
6745
+ * operator must grant on the child, not inherit from the parent). Set it
6746
+ * explicitly to override that default per grant.
6747
+ */
6748
+ includeLinked: zod.z.boolean().optional()
6749
+ });
6750
+ /**
6751
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
6752
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
6753
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
6754
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
6755
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
6756
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
6757
+ * migration cannot reach a JWT already in a client's hands; parse-time
6758
+ * migration covers both without a flag day. No cast — the raw object is read
6759
+ * through `Reflect.get` (its static type is `unknown`).
6760
+ */
6761
+ function migrateLegacyTokenScope(raw) {
6762
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
6763
+ if (Reflect.get(raw, "type") !== "device") return raw;
6764
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
6765
+ const targets = Reflect.get(raw, "targets");
6766
+ if (!Array.isArray(targets)) return raw;
6767
+ return {
6768
+ type: "device",
6769
+ selector: {
6770
+ kind: "ids",
6771
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
6772
+ },
6773
+ access: Reflect.get(raw, "access")
6774
+ };
6775
+ }
6776
+ var TokenScopeSchema = zod.z.preprocess(migrateLegacyTokenScope, zod.z.discriminatedUnion("type", [
6777
+ zod.z.object({
6778
+ type: zod.z.literal("category"),
6779
+ target: CapScopeSchema,
6780
+ access: zod.z.array(MethodAccessSchema).min(1)
6781
+ }),
6782
+ zod.z.object({
6783
+ type: zod.z.literal("capability"),
6784
+ target: zod.z.string(),
6785
+ access: zod.z.array(MethodAccessSchema).min(1)
6786
+ }),
6787
+ zod.z.object({
6788
+ type: zod.z.literal("addon"),
6789
+ target: zod.z.string(),
6790
+ access: zod.z.array(MethodAccessSchema).min(1)
6791
+ }),
6792
+ DeviceTokenScopeSchema
6793
+ ]));
6794
+ var UserRecordSchema = zod.z.object({
6795
+ id: zod.z.string(),
6796
+ username: zod.z.string(),
6797
+ passwordHash: zod.z.string(),
6798
+ /**
6799
+ * Admin bypass. When true, the middleware skips the scope-access
6800
+ * check entirely. There is no other axis of privilege; the legacy
6801
+ * role enum collapsed onto this boolean in v2.
6802
+ */
6803
+ isAdmin: zod.z.boolean().default(false),
6804
+ allowedProviders: AllowedProviderSchema,
6805
+ allowedDevices: AllowedDevicesSchema,
6806
+ /**
6807
+ * Scopes granted to this user. Admins bypass; their `scopes` is
6808
+ * ignored. Non-admins without scopes are locked out of every
6809
+ * protected call.
6810
+ */
6811
+ scopes: zod.z.array(TokenScopeSchema).default([]),
6812
+ createdAt: zod.z.number(),
6813
+ updatedAt: zod.z.number()
6814
+ });
6815
+ var ApiKeyRecordSchema = zod.z.object({
6816
+ id: zod.z.string(),
6817
+ label: zod.z.string(),
6818
+ isAdmin: zod.z.boolean().default(false),
6819
+ allowedProviders: AllowedProviderSchema,
6820
+ allowedDevices: AllowedDevicesSchema,
6821
+ tokenHash: zod.z.string(),
6822
+ tokenPrefix: zod.z.string(),
6823
+ createdAt: zod.z.number(),
6824
+ lastUsedAt: zod.z.number().optional()
6825
+ });
6826
+ var ScopedTokenSchema = zod.z.object({
6827
+ id: zod.z.string(),
6828
+ userId: zod.z.string(),
6829
+ name: zod.z.string(),
6830
+ tokenHash: zod.z.string(),
6831
+ tokenPrefix: zod.z.string(),
6832
+ scopes: zod.z.array(TokenScopeSchema),
6833
+ expiresAt: zod.z.number().nullish(),
6834
+ lastUsedAt: zod.z.number().nullish(),
6835
+ createdAt: zod.z.number()
6836
+ });
6837
+ //#endregion
6838
+ //#region src/auth/credential-scope.ts
6839
+ /**
6840
+ * The ONE permission vocabulary every credential is reduced to (D892).
6841
+ *
6842
+ * A credential — a login session, an account-link token, a legacy `csa_` /
6843
+ * `cst_` / `csv_` token, or the unified token `auth.mintToken` issues — is
6844
+ * verified into a principal whose permissions are a `CredentialScope[]`, and
6845
+ * nothing else. What KIND of credential it was never decides what it may do:
6846
+ *
6847
+ * - `'*'` — everything (the admin bypass). Held by an admin's session, a
6848
+ * legacy admin token, and a unified token minted with it.
6849
+ * - a {@link TokenScope} — the v3 capability grants (`category`,
6850
+ * `capability`, `addon`, `device`) the tRPC matcher has always applied.
6851
+ * - `share-view` — one fail-closed embed perimeter (`grid-view` /
6852
+ * `events-view`) over a few devices. A principal that holds one is
6853
+ * RESTRICTED to it: the matcher honours nothing else it holds.
6854
+ * - `addon-routes` — may reach any addon's own `authenticated` HTTP routes
6855
+ * and data planes (never an `admin` one). A person's session has always
6856
+ * had this; an integration token never had it and must hold
6857
+ * `addon:<id>` instead.
6858
+ *
6859
+ * Pure: no I/O. It lives in `@camstack/types` so the hub, the kernel and any
6860
+ * addon read the same vocabulary.
6861
+ */
6862
+ /** The admin scope: every permission. */
6863
+ var ADMIN_SCOPE = "*";
6864
+ /** At most this many devices in one share-view grant (the share-link bound). */
6865
+ var SHARE_VIEW_MAX_DEVICES = 64;
6866
+ /** What a share-view grant lets its holder see. */
6867
+ var ShareViewGrantSchema = zod.z.object({
6868
+ kind: zod.z.enum(require_sleep.SHARE_VIEW_KINDS),
6869
+ deviceIds: zod.z.array(zod.z.number().int().nonnegative()).min(1).max(64),
6870
+ /** Talk-back, opt-in at mint time; absent means off. */
6871
+ talk: zod.z.boolean().optional()
6872
+ });
6873
+ var ShareViewScopeSchema = zod.z.object({
6874
+ type: zod.z.literal("share-view"),
6875
+ grant: ShareViewGrantSchema
6876
+ });
6877
+ var AddonRoutesScopeSchema = zod.z.object({
6878
+ type: zod.z.literal("addon-routes"),
6879
+ access: zod.z.array(MethodAccessSchema).min(1)
6880
+ });
6881
+ var CredentialScopeSchema = zod.z.union([
6882
+ zod.z.literal("*"),
6883
+ ShareViewScopeSchema,
6884
+ AddonRoutesScopeSchema,
6885
+ TokenScopeSchema
6886
+ ]);
6887
+ /** Every access flavour — what a person's session holds on addon routes. */
6888
+ var ALL_METHOD_ACCESS = [
6889
+ "view",
6890
+ "create",
6891
+ "delete"
6892
+ ];
6893
+ function isTokenScope(scope) {
6894
+ return scope !== "*" && scope.type !== "share-view" && scope.type !== "addon-routes";
6895
+ }
6896
+ /** True iff the scope set holds `'*'`. */
6897
+ function scopesGrantAdmin(scopes) {
6898
+ return scopes.includes("*");
6899
+ }
6900
+ /**
6901
+ * The share-view grant that RESTRICTS this principal, or `null` when it holds
6902
+ * none. Fail closed: a set that mixes a share-view grant with anything else
6903
+ * is still restricted to its FIRST share-view grant, never widened by the rest.
6904
+ */
6905
+ function shareViewGrantOf(scopes) {
6906
+ for (const scope of scopes) if (scope !== "*" && scope.type === "share-view") return scope.grant;
6907
+ return null;
6908
+ }
6909
+ /** The capability grants the tRPC scope matcher reads. */
6910
+ function capabilityScopesOf(scopes) {
6911
+ return scopes.filter(isTokenScope);
6912
+ }
6913
+ /** True iff the set reaches every addon's own routes at `access`. */
6914
+ function scopesAllowAddonRoutes(scopes, access) {
6915
+ return scopes.some((s) => s !== "*" && s.type === "addon-routes" && s.access.includes(access));
6916
+ }
6917
+ /**
6918
+ * Parse a scope array from an untrusted source (a JWT claim, a stored row).
6919
+ * Any element that does not parse makes the WHOLE set unusable — `null` — so
6920
+ * a corrupt grant can never degrade into a partial one.
6921
+ */
6922
+ function parseCredentialScopes(raw) {
6923
+ const parsed = zod.z.array(CredentialScopeSchema).safeParse(raw);
6924
+ return parsed.success ? parsed.data : null;
6925
+ }
6926
+ /**
6927
+ * The `kind` claim of a unified token. It names the TOKEN FAMILY (so every
6928
+ * older gate that classifies a hub JWT refuses it — `classifyBearerPrincipal`
6929
+ * treats any `kind` it does not know as not-a-credential), never what the
6930
+ * token may do: that is its `scopes`, and only its `scopes`.
6931
+ */
6932
+ var CREDENTIAL_TOKEN_KIND = "credential";
6933
+ /**
6934
+ * The claims of a unified token (`auth.mintToken`). It carries no `exp`: its
6935
+ * row (looked up by `jti` on every verify, for revocation) holds the ONE
6936
+ * expiry, so a share link can be extended and a JWT clock can never disagree
6937
+ * with the row.
6938
+ */
6939
+ var CredentialTokenClaimsSchema = zod.z.object({
6940
+ kind: zod.z.literal(CREDENTIAL_TOKEN_KIND),
6941
+ sub: zod.z.string().min(1),
6942
+ jti: zod.z.string().min(16),
6943
+ scopes: zod.z.array(CredentialScopeSchema).min(1)
6944
+ });
6945
+ //#endregion
6605
6946
  //#region src/auth/app-callback.ts
6606
6947
  /**
6607
6948
  * The viewer app's custom-scheme callback — the ONE list of URLs a hub flow
@@ -8285,7 +8626,14 @@ var AlertSeveritySchema = zod.z.enum([
8285
8626
  ]);
8286
8627
  var AlertActionSchema = zod.z.object({
8287
8628
  label: zod.z.string(),
8288
- href: zod.z.string().optional()
8629
+ href: zod.z.string().optional(),
8630
+ /**
8631
+ * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
8632
+ * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
8633
+ * start) — the browser must leave the SPA with a full navigation, because
8634
+ * the SPA has no such route and would bounce to the home page.
8635
+ */
8636
+ navigation: zod.z.enum(["app", "server"]).optional()
8289
8637
  });
8290
8638
  var AlertStatusSchema = zod.z.enum([
8291
8639
  "active",
@@ -42824,6 +43172,9 @@ var NcSystemEventKindSchema = zod.z.enum([
42824
43172
  "server-updated",
42825
43173
  "export-completed",
42826
43174
  "backup-completed",
43175
+ "alert-critical",
43176
+ "alert-error",
43177
+ "alert-critical-resolved",
42827
43178
  "camera-online",
42828
43179
  "camera-offline",
42829
43180
  "camera-disabled",
@@ -44466,6 +44817,18 @@ var NC_CONDITION_CATALOG = [
44466
44817
  value: "backup-completed",
44467
44818
  label: "Backup completed"
44468
44819
  },
44820
+ {
44821
+ value: "alert-critical",
44822
+ label: "Critical alert raised"
44823
+ },
44824
+ {
44825
+ value: "alert-error",
44826
+ label: "Error alert raised"
44827
+ },
44828
+ {
44829
+ value: "alert-critical-resolved",
44830
+ label: "Critical alert resolved"
44831
+ },
44469
44832
  {
44470
44833
  value: "alarm-arm-refused",
44471
44834
  label: "Alarm arm refused"
@@ -45842,204 +46205,6 @@ var notificationRulesCapability = {
45842
46205
  }
45843
46206
  };
45844
46207
  //#endregion
45845
- //#region src/schemas/auth-records.ts
45846
- /**
45847
- * Zod schemas for persisted record types.
45848
- *
45849
- * These schemas serve as the single source of truth for types that are
45850
- * stored in the settings-store backend and retrieved via tRPC. They
45851
- * replace the manual TypeScript interfaces with schema-derived types,
45852
- * enabling runtime validation when reading from the backend.
45853
- *
45854
- * Convention: each schema is named `<Type>Schema`, the inferred TS type
45855
- * keeps the original name for backward compatibility.
45856
- */
45857
- /**
45858
- * Auth model (v2 — 2026-05-12 caps-only):
45859
- *
45860
- * Two principals:
45861
- * - `isAdmin: true` — full bypass. Admin scope set is ignored.
45862
- * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
45863
- *
45864
- * No role enum. There used to be `viewer / agent / scoped` and earlier
45865
- * `super_admin` — collapsed onto the single boolean because every
45866
- * non-admin caller is governed by the same scope-check rules; the
45867
- * distinction was only ever used to route role-specific procedures
45868
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
45869
- * with `isAdmin: false` + an explicit scope list.
45870
- */
45871
- /** Per-method access flavour. Materialised on every cap method via codegen. */
45872
- var MethodAccessSchema = zod.z.enum([
45873
- "view",
45874
- "create",
45875
- "delete"
45876
- ]);
45877
- /**
45878
- * A single scope grant. Three forms — checked in matcher with OR
45879
- * semantics; the first match decides whether the call passes:
45880
- *
45881
- * - `category` — broadest. `target: 'device' | 'system'` selects every
45882
- * cap with the matching `scope` declaration. New caps inherit grants
45883
- * automatically — adding a device cap to the codebase makes it
45884
- * reachable to every user with `category:device [...]` without a
45885
- * re-grant. Use this for "family viewer" / "operator" tiers.
45886
- *
45887
- * - `addon` — every cap that ships inside a given addon id. Niche;
45888
- * useful when an integration needs to interact with one specific
45889
- * addon's surface regardless of how many caps it exports.
45890
- *
45891
- * - `capability` — the most precise form. Single cap name. Use for
45892
- * integration tokens where you want to grant `addons.installPackage`
45893
- * and nothing else.
45894
- *
45895
- * `access` is REQUIRED with min 1 element. `admin` bypass is the
45896
- * "give me everything" escape; there is no wildcard scope.
45897
- */
45898
- var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
45899
- var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
45900
- var CapScopeSchema = zod.z.enum(["device", "system"]);
45901
- /**
45902
- * DeviceSelector (scope model v3 — 2026-08-12).
45903
- *
45904
- * A `device` grant no longer carries a frozen list of deviceIds. It carries
45905
- * a SELECTOR the matcher resolves against the live fleet, so the grant can be
45906
- * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
45907
- * AFTER the grant was minted — no re-grant, no re-login.
45908
- *
45909
- * - `all` — every device in the deployment. The broad viewer/operator
45910
- * lever without a `category` grant (a `category` grant also covers device
45911
- * caps that carry no deviceId; `all` is specifically the device set).
45912
- * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
45913
- * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
45914
- * is NOT covered until the grant is edited.
45915
- * - `types` — every device of a `DeviceType` (e.g. every `camera`).
45916
- * DYNAMIC. A device that changes type, or a new device of the type,
45917
- * re-resolves on the next request.
45918
- * - `locations` — every device whose operator-assigned `location` label is
45919
- * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
45920
- * null/unset location matches NO `locations` selector.
45921
- */
45922
- var DeviceSelectorSchema = zod.z.discriminatedUnion("kind", [
45923
- zod.z.object({ kind: zod.z.literal("all") }),
45924
- zod.z.object({
45925
- kind: zod.z.literal("ids"),
45926
- ids: zod.z.array(zod.z.number().int()).min(1)
45927
- }),
45928
- zod.z.object({
45929
- kind: zod.z.literal("types"),
45930
- types: zod.z.array(zod.z.enum(require_err_msg.DeviceType)).min(1)
45931
- }),
45932
- zod.z.object({
45933
- kind: zod.z.literal("locations"),
45934
- locations: zod.z.array(zod.z.string().min(1)).min(1)
45935
- })
45936
- ]);
45937
- var DeviceTokenScopeSchema = zod.z.object({
45938
- type: zod.z.literal("device"),
45939
- /** The device SET this grant covers — resolved against the live fleet. */
45940
- selector: DeviceSelectorSchema,
45941
- access: zod.z.array(MethodAccessSchema).min(1),
45942
- /**
45943
- * Whether a grant on a PARENT device transparently covers its accessory
45944
- * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
45945
- * Direction is parent → children ONLY.
45946
- *
45947
- * Absent → the matcher DERIVES it from the access flavour: `view`
45948
- * inherits (a camera viewer sees the camera's accessories), `create` /
45949
- * `delete` do NOT (actuating/removing a child is an explicit act the
45950
- * operator must grant on the child, not inherit from the parent). Set it
45951
- * explicitly to override that default per grant.
45952
- */
45953
- includeLinked: zod.z.boolean().optional()
45954
- });
45955
- /**
45956
- * v2 → v3 lazy migration. A pre-v3 `device` grant carried
45957
- * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
45958
- * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
45959
- * EVERY parse path — stored records AND the JWT-carried scope arrays
45960
- * normalised at the request boundary ({@link normalizeTokenScopes} in
45961
- * `device-selector.ts`). Chosen over a one-time DB migration because a
45962
- * migration cannot reach a JWT already in a client's hands; parse-time
45963
- * migration covers both without a flag day. No cast — the raw object is read
45964
- * through `Reflect.get` (its static type is `unknown`).
45965
- */
45966
- function migrateLegacyTokenScope(raw) {
45967
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
45968
- if (Reflect.get(raw, "type") !== "device") return raw;
45969
- if (Reflect.get(raw, "selector") !== void 0) return raw;
45970
- const targets = Reflect.get(raw, "targets");
45971
- if (!Array.isArray(targets)) return raw;
45972
- return {
45973
- type: "device",
45974
- selector: {
45975
- kind: "ids",
45976
- ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
45977
- },
45978
- access: Reflect.get(raw, "access")
45979
- };
45980
- }
45981
- var TokenScopeSchema = zod.z.preprocess(migrateLegacyTokenScope, zod.z.discriminatedUnion("type", [
45982
- zod.z.object({
45983
- type: zod.z.literal("category"),
45984
- target: CapScopeSchema,
45985
- access: zod.z.array(MethodAccessSchema).min(1)
45986
- }),
45987
- zod.z.object({
45988
- type: zod.z.literal("capability"),
45989
- target: zod.z.string(),
45990
- access: zod.z.array(MethodAccessSchema).min(1)
45991
- }),
45992
- zod.z.object({
45993
- type: zod.z.literal("addon"),
45994
- target: zod.z.string(),
45995
- access: zod.z.array(MethodAccessSchema).min(1)
45996
- }),
45997
- DeviceTokenScopeSchema
45998
- ]));
45999
- var UserRecordSchema = zod.z.object({
46000
- id: zod.z.string(),
46001
- username: zod.z.string(),
46002
- passwordHash: zod.z.string(),
46003
- /**
46004
- * Admin bypass. When true, the middleware skips the scope-access
46005
- * check entirely. There is no other axis of privilege; the legacy
46006
- * role enum collapsed onto this boolean in v2.
46007
- */
46008
- isAdmin: zod.z.boolean().default(false),
46009
- allowedProviders: AllowedProviderSchema,
46010
- allowedDevices: AllowedDevicesSchema,
46011
- /**
46012
- * Scopes granted to this user. Admins bypass; their `scopes` is
46013
- * ignored. Non-admins without scopes are locked out of every
46014
- * protected call.
46015
- */
46016
- scopes: zod.z.array(TokenScopeSchema).default([]),
46017
- createdAt: zod.z.number(),
46018
- updatedAt: zod.z.number()
46019
- });
46020
- var ApiKeyRecordSchema = zod.z.object({
46021
- id: zod.z.string(),
46022
- label: zod.z.string(),
46023
- isAdmin: zod.z.boolean().default(false),
46024
- allowedProviders: AllowedProviderSchema,
46025
- allowedDevices: AllowedDevicesSchema,
46026
- tokenHash: zod.z.string(),
46027
- tokenPrefix: zod.z.string(),
46028
- createdAt: zod.z.number(),
46029
- lastUsedAt: zod.z.number().optional()
46030
- });
46031
- var ScopedTokenSchema = zod.z.object({
46032
- id: zod.z.string(),
46033
- userId: zod.z.string(),
46034
- name: zod.z.string(),
46035
- tokenHash: zod.z.string(),
46036
- tokenPrefix: zod.z.string(),
46037
- scopes: zod.z.array(TokenScopeSchema),
46038
- expiresAt: zod.z.number().nullish(),
46039
- lastUsedAt: zod.z.number().nullish(),
46040
- createdAt: zod.z.number()
46041
- });
46042
- //#endregion
46043
46208
  //#region src/capabilities/oauth-integration.cap.ts
46044
46209
  /**
46045
46210
  * `oauth-integration` — a collection cap by which an addon declares
@@ -55487,6 +55652,18 @@ var storageMigrationCapability = {
55487
55652
  */
55488
55653
  movers: require_sleep.method(zod.z.object({}), zod.z.array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }),
55489
55654
  /**
55655
+ * May a mover that touches these locations run NOW? One claim per physical
55656
+ * root is owned by the storage orchestrator: a single-location repoint holds
55657
+ * it while it carries its subtree, and a mover (`relocateMedia`,
55658
+ * `relocateFootage`, a migration move) asks here AFTER registering its job and
55659
+ * cancels itself on `clear: false`. The repoint, in turn, refuses while a
55660
+ * registered mover touches its root. Asked, never polled (D3).
55661
+ */
55662
+ moverClearance: require_sleep.method(zod.z.object({ locationIds: zod.z.array(zod.z.string()).readonly() }), zod.z.object({
55663
+ clear: zod.z.boolean(),
55664
+ repointLocationId: zod.z.string().optional()
55665
+ }), { auth: "admin" }),
55666
+ /**
55490
55667
  * What each class's SOURCE still holds, from the archive — never from the
55491
55668
  * resident index (D295). Only classes with something left (or something
55492
55669
  * unknown) are listed, so an empty list means there is nothing to drain and
@@ -61222,6 +61399,11 @@ onStatusChanged: { data: zod.z.object({
61222
61399
  *
61223
61400
  * `kind: 'poll'` — cloud REST APIs typically have no push channel; the
61224
61401
  * provider refreshes the slice on an interval and eagerly after commands.
61402
+ *
61403
+ * UNKNOWN IS NOT OFF. Every field the appliance reports separately is
61404
+ * nullable: `null` means "not known right now" (the appliance has not said,
61405
+ * the link is down, or the description does not carry it) and is never
61406
+ * rendered or exported as `false` / `0`. `availability` says why.
61225
61407
  */
61226
61408
  var DishwasherStateSchema = zod.z.enum([
61227
61409
  "idle",
@@ -61231,43 +61413,155 @@ var DishwasherStateSchema = zod.z.enum([
61231
61413
  "error",
61232
61414
  "unavailable"
61233
61415
  ]);
61416
+ /**
61417
+ * The appliance's own operation state, uncollapsed. `state` above is the coarse
61418
+ * view for compact surfaces; this is what the appliance said.
61419
+ */
61420
+ var DishwasherOperationStateSchema = zod.z.enum([
61421
+ "Inactive",
61422
+ "Ready",
61423
+ "DelayedStart",
61424
+ "Run",
61425
+ "Pause",
61426
+ "ActionRequired",
61427
+ "Finished",
61428
+ "Error",
61429
+ "Aborting"
61430
+ ]);
61431
+ /**
61432
+ * Why fields may be `null`:
61433
+ * - `available` — the link is up and the description is loaded;
61434
+ * - `offline` — the local link is down (values are unknown, not last-known);
61435
+ * - `description-missing` — the link is up but the appliance's description could not
61436
+ * be loaded, so its values cannot be decoded.
61437
+ */
61438
+ var DishwasherAvailabilitySchema = zod.z.enum([
61439
+ "available",
61440
+ "offline",
61441
+ "description-missing"
61442
+ ]);
61234
61443
  var DishwasherConsumableLevelSchema = zod.z.enum([
61235
61444
  "ok",
61236
61445
  "low",
61237
61446
  "empty"
61238
61447
  ]);
61239
61448
  var DishwasherStatusSchema = zod.z.object({
61449
+ availability: DishwasherAvailabilitySchema,
61450
+ /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
61240
61451
  state: DishwasherStateSchema,
61241
- /** Active program id/name, or null when none selected / unknown. */
61452
+ /** The appliance's operation state as reported; null when not known. */
61453
+ operationState: DishwasherOperationStateSchema.nullable(),
61454
+ /** Feature key of the ACTIVE (running) program, or null when none runs / not known. */
61242
61455
  program: zod.z.string().nullable(),
61243
- /** Program tokens the hardware accepts — drives the UI selector. */
61456
+ /** Feature key of the SELECTED program (what Start would run), or null when none / not known. */
61457
+ selectedProgram: zod.z.string().nullable(),
61458
+ /** Feature keys of the programs the appliance currently offers — drives the UI selector. */
61244
61459
  availablePrograms: zod.z.array(zod.z.string()),
61245
- /** Minutes remaining on the active cycle, or null when not running. */
61246
- remainingMinutes: zod.z.number().int().nonnegative().nullable(),
61460
+ /** Seconds remaining on the active cycle, or null when not running / not known. */
61461
+ remainingSeconds: zod.z.number().int().nonnegative().nullable(),
61462
+ /** Seconds the delayed start is set to (time until the cycle starts), or null. */
61463
+ delayedStartSeconds: zod.z.number().int().nonnegative().nullable(),
61247
61464
  /** Cycle completion 0..100, or null when not applicable. */
61248
61465
  progressPercent: zod.z.number().min(0).max(100).nullable(),
61249
- /** True when the door is reported open. */
61250
- doorOpen: zod.z.boolean(),
61251
- /** True when remote start is allowed (door closed, power on, etc.). */
61252
- remoteStartAllowed: zod.z.boolean(),
61253
- /** Main power / switched-on state. */
61254
- powerOn: zod.z.boolean(),
61466
+ /** True when the door is reported open; null when the door state is not known. */
61467
+ doorOpen: zod.z.boolean().nullable(),
61468
+ /** True when the door is latched (locked) during a cycle; null when not reported. */
61469
+ doorLocked: zod.z.boolean().nullable(),
61470
+ /** True when remote start is allowed (door closed, power on, etc.); null when not known. */
61471
+ remoteStartAllowed: zod.z.boolean().nullable(),
61472
+ /** True when the appliance accepts remote control now; null when not known. */
61473
+ remoteControlActive: zod.z.boolean().nullable(),
61474
+ /** True while somebody operates the appliance at its panel; null when not reported. */
61475
+ localControlActive: zod.z.boolean().nullable(),
61476
+ /** Main power / switched-on state; null when not known. */
61477
+ powerOn: zod.z.boolean().nullable(),
61478
+ /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
61479
+ powerState: zod.z.string().nullable(),
61255
61480
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
61256
61481
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
61257
- halfLoad: zod.z.boolean(),
61258
- hygienePlus: zod.z.boolean(),
61482
+ /** Option states: null when the appliance does not expose the option or has not said. */
61483
+ halfLoad: zod.z.boolean().nullable(),
61484
+ hygienePlus: zod.z.boolean().nullable(),
61259
61485
  /** Extra dry option when the appliance exposes it. */
61260
- extraDry: zod.z.boolean(),
61486
+ extraDry: zod.z.boolean().nullable(),
61261
61487
  /** Intensive zone (lower basket) when the appliance exposes it. */
61262
- intensiveZone: zod.z.boolean(),
61488
+ intensiveZone: zod.z.boolean().nullable(),
61263
61489
  /** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
61264
- varioSpeedPlus: zod.z.boolean(),
61265
- /** Child lock (controls disabled on the appliance). */
61266
- childLock: zod.z.boolean(),
61490
+ varioSpeedPlus: zod.z.boolean().nullable(),
61491
+ /** Child lock (controls disabled on the appliance); null when not known. */
61492
+ childLock: zod.z.boolean().nullable(),
61493
+ /** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
61494
+ activeEvents: zod.z.array(zod.z.string()),
61495
+ /** Numeric error code when the appliance reports one; null otherwise. */
61267
61496
  errorCode: zod.z.number().nullable(),
61497
+ /** Name of the raised alert-level event while the appliance is in error; null otherwise. */
61268
61498
  errorLabel: zod.z.string().nullable(),
61499
+ /** Ms epoch of the last value received from the appliance; 0 = never. */
61269
61500
  lastFetchedAt: zod.z.number()
61270
61501
  });
61502
+ var DeviceIdSchema = zod.z.number().int().nonnegative();
61503
+ /** A value a program option or setting can take. */
61504
+ var DishwasherValueSchema = zod.z.union([
61505
+ zod.z.boolean(),
61506
+ zod.z.string(),
61507
+ zod.z.number()
61508
+ ]);
61509
+ var DishwasherAccessSchema = zod.z.enum([
61510
+ "none",
61511
+ "read",
61512
+ "readWrite",
61513
+ "writeOnly",
61514
+ "readStatic"
61515
+ ]);
61516
+ /**
61517
+ * One option or setting the appliance declares, with the constraints its description
61518
+ * gives. A `readWrite` descriptor that is `available` is what `setOption` accepts.
61519
+ */
61520
+ var DishwasherOptionDescriptorSchema = zod.z.object({
61521
+ /** Feature key (`Dishcare.Dishwasher.Option.ExtraDry`). */
61522
+ key: zod.z.string(),
61523
+ /** Last segment of the key, for display. */
61524
+ name: zod.z.string(),
61525
+ type: zod.z.enum([
61526
+ "boolean",
61527
+ "number",
61528
+ "enum",
61529
+ "string"
61530
+ ]),
61531
+ access: DishwasherAccessSchema,
61532
+ /** The appliance reports this entity as currently available. */
61533
+ available: zod.z.boolean(),
61534
+ /** Unit the description declares for a number; null when it declares none. */
61535
+ unit: zod.z.string().nullable(),
61536
+ min: zod.z.number().nullable(),
61537
+ max: zod.z.number().nullable(),
61538
+ step: zod.z.number().nullable(),
61539
+ /** Allowed members of an enum; null for other types. */
61540
+ enumValues: zod.z.array(zod.z.string()).nullable(),
61541
+ defaultValue: DishwasherValueSchema.nullable()
61542
+ });
61543
+ var DishwasherProgramSchema = zod.z.object({
61544
+ /** Feature key (`Dishcare.Dishwasher.Program.Eco50`) — what `setProgram` / `start` take. */
61545
+ key: zod.z.string(),
61546
+ name: zod.z.string(),
61547
+ /** The appliance currently offers this program. */
61548
+ available: zod.z.boolean(),
61549
+ /** The options this program lists, with the program-level access / availability / default. */
61550
+ options: zod.z.array(DishwasherOptionDescriptorSchema)
61551
+ });
61552
+ var DishwasherOptionsSchema = zod.z.object({
61553
+ availability: DishwasherAvailabilitySchema,
61554
+ /** What the appliance can be told to do, from the commands its description declares. */
61555
+ supportsStart: zod.z.boolean(),
61556
+ supportsPause: zod.z.boolean(),
61557
+ supportsResume: zod.z.boolean(),
61558
+ supportsStop: zod.z.boolean(),
61559
+ supportsPower: zod.z.boolean(),
61560
+ /** Every program the description lists, with its options. */
61561
+ programs: zod.z.array(DishwasherProgramSchema),
61562
+ /** Every option and setting entity the description lists (programs reference these by key). */
61563
+ options: zod.z.array(DishwasherOptionDescriptorSchema)
61564
+ });
61271
61565
  var dishwasherCapability = {
61272
61566
  name: "dishwasher",
61273
61567
  scope: "device",
@@ -61275,86 +61569,102 @@ var dishwasherCapability = {
61275
61569
  mode: "singleton",
61276
61570
  deviceTypes: [require_err_msg.DeviceType.Dishwasher],
61277
61571
  methods: {
61278
- start: require_sleep.method(zod.z.object({ deviceId: zod.z.number().int().nonnegative() }), zod.z.void(), {
61572
+ /**
61573
+ * Start a program. Without `program` the selected one starts. `options` are
61574
+ * option feature keys; each is checked against the program's constraints.
61575
+ */
61576
+ start: require_sleep.method(zod.z.object({
61577
+ deviceId: DeviceIdSchema,
61578
+ program: zod.z.string().min(1).optional(),
61579
+ options: zod.z.record(zod.z.string(), DishwasherValueSchema).optional()
61580
+ }), zod.z.void(), {
61279
61581
  kind: "mutation",
61280
61582
  auth: "protected"
61281
61583
  }),
61282
- pause: require_sleep.method(zod.z.object({ deviceId: zod.z.number().int().nonnegative() }), zod.z.void(), {
61584
+ pause: require_sleep.method(zod.z.object({ deviceId: DeviceIdSchema }), zod.z.void(), {
61283
61585
  kind: "mutation",
61284
61586
  auth: "protected"
61285
61587
  }),
61286
- stop: require_sleep.method(zod.z.object({ deviceId: zod.z.number().int().nonnegative() }), zod.z.void(), {
61588
+ resume: require_sleep.method(zod.z.object({ deviceId: DeviceIdSchema }), zod.z.void(), {
61287
61589
  kind: "mutation",
61288
61590
  auth: "protected"
61289
61591
  }),
61592
+ stop: require_sleep.method(zod.z.object({ deviceId: DeviceIdSchema }), zod.z.void(), {
61593
+ kind: "mutation",
61594
+ auth: "protected"
61595
+ }),
61596
+ /** Select (not start) a program; refused when the appliance does not offer it. */
61290
61597
  setProgram: require_sleep.method(zod.z.object({
61291
- deviceId: zod.z.number().int().nonnegative(),
61598
+ deviceId: DeviceIdSchema,
61292
61599
  program: zod.z.string().min(1)
61293
61600
  }), zod.z.void(), {
61294
61601
  kind: "mutation",
61295
61602
  auth: "protected"
61296
61603
  }),
61297
61604
  setPower: require_sleep.method(zod.z.object({
61298
- deviceId: zod.z.number().int().nonnegative(),
61605
+ deviceId: DeviceIdSchema,
61299
61606
  on: zod.z.boolean()
61300
61607
  }), zod.z.void(), {
61301
61608
  kind: "mutation",
61302
61609
  auth: "protected"
61303
61610
  }),
61304
61611
  setHalfLoad: require_sleep.method(zod.z.object({
61305
- deviceId: zod.z.number().int().nonnegative(),
61612
+ deviceId: DeviceIdSchema,
61306
61613
  on: zod.z.boolean()
61307
61614
  }), zod.z.void(), {
61308
61615
  kind: "mutation",
61309
61616
  auth: "protected"
61310
61617
  }),
61311
61618
  setHygienePlus: require_sleep.method(zod.z.object({
61312
- deviceId: zod.z.number().int().nonnegative(),
61619
+ deviceId: DeviceIdSchema,
61313
61620
  on: zod.z.boolean()
61314
61621
  }), zod.z.void(), {
61315
61622
  kind: "mutation",
61316
61623
  auth: "protected"
61317
61624
  }),
61318
61625
  setExtraDry: require_sleep.method(zod.z.object({
61319
- deviceId: zod.z.number().int().nonnegative(),
61626
+ deviceId: DeviceIdSchema,
61320
61627
  on: zod.z.boolean()
61321
61628
  }), zod.z.void(), {
61322
61629
  kind: "mutation",
61323
61630
  auth: "protected"
61324
61631
  }),
61325
61632
  setIntensiveZone: require_sleep.method(zod.z.object({
61326
- deviceId: zod.z.number().int().nonnegative(),
61633
+ deviceId: DeviceIdSchema,
61327
61634
  on: zod.z.boolean()
61328
61635
  }), zod.z.void(), {
61329
61636
  kind: "mutation",
61330
61637
  auth: "protected"
61331
61638
  }),
61332
61639
  setVarioSpeedPlus: require_sleep.method(zod.z.object({
61333
- deviceId: zod.z.number().int().nonnegative(),
61640
+ deviceId: DeviceIdSchema,
61334
61641
  on: zod.z.boolean()
61335
61642
  }), zod.z.void(), {
61336
61643
  kind: "mutation",
61337
61644
  auth: "protected"
61338
61645
  }),
61339
61646
  setChildLock: require_sleep.method(zod.z.object({
61340
- deviceId: zod.z.number().int().nonnegative(),
61647
+ deviceId: DeviceIdSchema,
61341
61648
  on: zod.z.boolean()
61342
61649
  }), zod.z.void(), {
61343
61650
  kind: "mutation",
61344
61651
  auth: "protected"
61345
61652
  }),
61653
+ /**
61654
+ * Write any option or setting by feature key. Refused when the description does
61655
+ * not list it, it is not writable or not available now, or the value is outside
61656
+ * its declared range / members.
61657
+ */
61346
61658
  setOption: require_sleep.method(zod.z.object({
61347
- deviceId: zod.z.number().int().nonnegative(),
61659
+ deviceId: DeviceIdSchema,
61348
61660
  key: zod.z.string().min(1),
61349
- value: zod.z.union([
61350
- zod.z.boolean(),
61351
- zod.z.string(),
61352
- zod.z.number()
61353
- ])
61661
+ value: DishwasherValueSchema
61354
61662
  }), zod.z.void(), {
61355
61663
  kind: "mutation",
61356
61664
  auth: "protected"
61357
- })
61665
+ }),
61666
+ /** What this appliance can do, from its own description — the UI is derived from it. */
61667
+ getOptions: require_sleep.method(zod.z.object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" })
61358
61668
  },
61359
61669
  status: {
61360
61670
  schema: DishwasherStatusSchema,
@@ -79838,6 +80148,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
79838
80148
  addonId: null,
79839
80149
  access: "view"
79840
80150
  },
80151
+ "dishwasher.getOptions": {
80152
+ capName: "dishwasher",
80153
+ capScope: "device",
80154
+ addonId: null,
80155
+ access: "view"
80156
+ },
79841
80157
  "dishwasher.getStatus": {
79842
80158
  capName: "dishwasher",
79843
80159
  capScope: "device",
@@ -79850,6 +80166,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
79850
80166
  addonId: null,
79851
80167
  access: "create"
79852
80168
  },
80169
+ "dishwasher.resume": {
80170
+ capName: "dishwasher",
80171
+ capScope: "device",
80172
+ addonId: null,
80173
+ access: "create"
80174
+ },
79853
80175
  "dishwasher.setChildLock": {
79854
80176
  capName: "dishwasher",
79855
80177
  capScope: "device",
@@ -84350,6 +84672,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
84350
84672
  addonId: null,
84351
84673
  access: "view"
84352
84674
  },
84675
+ "storageMigration.moverClearance": {
84676
+ capName: "storage-migration",
84677
+ capScope: "system",
84678
+ addonId: null,
84679
+ access: "view"
84680
+ },
84353
84681
  "storageMigration.movers": {
84354
84682
  capName: "storage-migration",
84355
84683
  capScope: "system",
@@ -89955,6 +90283,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
89955
90283
  form: "single",
89956
90284
  optional: false
89957
90285
  }],
90286
+ "dishwasher.getOptions": [{
90287
+ name: "deviceId",
90288
+ form: "single",
90289
+ optional: false
90290
+ }],
89958
90291
  "dishwasher.getStatus": [{
89959
90292
  name: "deviceId",
89960
90293
  form: "single",
@@ -89965,6 +90298,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
89965
90298
  form: "single",
89966
90299
  optional: false
89967
90300
  }],
90301
+ "dishwasher.resume": [{
90302
+ name: "deviceId",
90303
+ form: "single",
90304
+ optional: false
90305
+ }],
89968
90306
  "dishwasher.setChildLock": [{
89969
90307
  name: "deviceId",
89970
90308
  form: "single",
@@ -93652,6 +93990,7 @@ function createSystemProxy(api) {
93652
93990
  status: (input) => dispatch("storageMigration", "status", "query", input),
93653
93991
  cancel: (input) => dispatch("storageMigration", "cancel", "mutation", input),
93654
93992
  movers: (input) => dispatch("storageMigration", "movers", "query", input),
93993
+ moverClearance: (input) => dispatch("storageMigration", "moverClearance", "query", input),
93655
93994
  residue: (input) => dispatch("storageMigration", "residue", "query", input),
93656
93995
  drain: (input) => dispatch("storageMigration", "drain", "mutation", input),
93657
93996
  cleanupStart: (input) => dispatch("storageMigration", "cleanupStart", "mutation", input),
@@ -94595,7 +94934,7 @@ function systemEventFilterApplies(kind, filter) {
94595
94934
  switch (filter) {
94596
94935
  case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind.startsWith("recording-") || kind === "alarm-triggered";
94597
94936
  case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
94598
- case "nodeIds": return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated" || kind.startsWith("storage-location-");
94937
+ case "nodeIds": return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated" || kind.startsWith("storage-location-") || kind.startsWith("alert-");
94599
94938
  case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "node-updating" || kind === "server-updated";
94600
94939
  case "consumableLowPercent": return NC_CONSUMABLE_SYSTEM_EVENT_KINDS.includes(kind);
94601
94940
  }
@@ -94668,6 +95007,9 @@ var NC_SYSTEM_EVENT_FAMILY = {
94668
95007
  "wrapper-update-available": "system",
94669
95008
  "backup-completed": "system",
94670
95009
  "export-completed": "system",
95010
+ "alert-critical": "system",
95011
+ "alert-error": "system",
95012
+ "alert-critical-resolved": "system",
94671
95013
  "storage-location-low": "system",
94672
95014
  "storage-location-critical": "system",
94673
95015
  "storage-location-ok": "system",
@@ -94810,6 +95152,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
94810
95152
  "storage-location-ok"
94811
95153
  ]
94812
95154
  },
95155
+ {
95156
+ id: "alerts",
95157
+ family: "system",
95158
+ label: "Alerts",
95159
+ kinds: [
95160
+ "alert-critical",
95161
+ "alert-error",
95162
+ "alert-critical-resolved"
95163
+ ]
95164
+ },
94813
95165
  {
94814
95166
  id: "alarm",
94815
95167
  family: "alarm",
@@ -96213,6 +96565,98 @@ function sensorTransitionOffered(sensorKinds) {
96213
96565
  /** What an editor tells the operator when it is about to prune the choice. */
96214
96566
  var NC_SENSOR_TRANSITION_UNSUPPORTED_REASON = "Only a sensor that raises and clears (water, smoke, gas, CO, vibration, tamper, motion, contact) can fire on one edge. Pick only such sensor kinds, or the rule fires on every change.";
96215
96567
  //#endregion
96568
+ //#region src/notification/alert-episode.ts
96569
+ /**
96570
+ * An alert EPISODE as a notification subject.
96571
+ *
96572
+ * The alert centre sends nothing of its own. A critical or error alert reaches
96573
+ * the operator through Notification Center system-event rules, and this file is
96574
+ * the one vocabulary the two sides share: the alert centre mints the episode
96575
+ * identity and announces its two edges on the bus (`alert.episode`), and
96576
+ * Notification Center derives the same identity when it RECONCILES from the
96577
+ * alerts store, because a bus event may be dropped (D8, D11).
96578
+ *
96579
+ * ## Episode identity
96580
+ *
96581
+ * `metadata.episodeId`, minted by the alert centre when an alert opens (new, or
96582
+ * re-opened after it was completed/dismissed, or its emitter changed
96583
+ * `metadata.episodeKey`) and kept through every re-emit while it stays open. An
96584
+ * alert row written before the alert centre minted ids has none: its episode is
96585
+ * `<id>@<createdAt>`, derived here so both sides agree.
96586
+ */
96587
+ /** The bus payload of `EventCategory.AlertEpisode`. */
96588
+ var AlertEpisodePayloadSchema = zod.z.object({
96589
+ phase: zod.z.enum(["raised", "resolved"]),
96590
+ episodeId: zod.z.string().min(1),
96591
+ alertId: zod.z.string().min(1),
96592
+ severity: AlertSeveritySchema,
96593
+ category: zod.z.string(),
96594
+ title: zod.z.string(),
96595
+ message: zod.z.string(),
96596
+ sourceType: zod.z.string().optional(),
96597
+ sourceId: zod.z.string().optional(),
96598
+ nodeId: zod.z.string().optional(),
96599
+ /** The alert's own action link (where the operator acts on it), when it has one. */
96600
+ actionUrl: zod.z.string().optional(),
96601
+ at: zod.z.number()
96602
+ });
96603
+ /** The payload of an `alert.episode` event's `data`, or `null` when it is not one. */
96604
+ function parseAlertEpisodePayload(data) {
96605
+ const parsed = AlertEpisodePayloadSchema.safeParse(data);
96606
+ return parsed.success ? parsed.data : null;
96607
+ }
96608
+ /** An episode is closed once its alert is completed or dismissed. */
96609
+ function isAlertEpisodeOpen(status) {
96610
+ return status !== "completed" && status !== "dismissed";
96611
+ }
96612
+ /** Only these severities are ever announced. */
96613
+ function isAlertEpisodeSeverity(severity) {
96614
+ return severity === "critical" || severity === "error";
96615
+ }
96616
+ function alertEpisodeId(alert) {
96617
+ const minted = alert.metadata?.["episodeId"];
96618
+ return typeof minted === "string" && minted.length > 0 ? minted : `${alert.id}@${String(alert.createdAt)}`;
96619
+ }
96620
+ /** The node an alert is about, from the places emitters put it. */
96621
+ function alertNodeId(alert) {
96622
+ const direct = alert.metadata?.["nodeId"];
96623
+ if (typeof direct === "string") return direct;
96624
+ const runner = alert.metadata?.["runner"];
96625
+ if (typeof runner === "object" && runner !== null && "nodeId" in runner) {
96626
+ const id = runner.nodeId;
96627
+ if (typeof id === "string") return id;
96628
+ }
96629
+ return alert.source?.type === "node" ? alert.source.id : void 0;
96630
+ }
96631
+ /**
96632
+ * The system-event kind of an episode edge, or `null` when none is announced
96633
+ * (an `error` episode announces its opening only).
96634
+ */
96635
+ function alertEpisodeKind(severity, phase) {
96636
+ if (severity === "critical") return phase === "raised" ? "alert-critical" : "alert-critical-resolved";
96637
+ if (severity === "error" && phase === "raised") return "alert-error";
96638
+ return null;
96639
+ }
96640
+ function alertEpisodePayload(alert, phase, at) {
96641
+ const nodeId = alertNodeId(alert);
96642
+ return {
96643
+ phase,
96644
+ episodeId: alertEpisodeId(alert),
96645
+ alertId: alert.id,
96646
+ severity: alert.severity,
96647
+ category: alert.category,
96648
+ title: alert.title,
96649
+ message: alert.message,
96650
+ ...alert.source !== void 0 ? {
96651
+ sourceType: alert.source.type,
96652
+ sourceId: alert.source.id
96653
+ } : {},
96654
+ ...nodeId !== void 0 ? { nodeId } : {},
96655
+ ...alert.action?.href !== void 0 ? { actionUrl: alert.action.href } : {},
96656
+ at
96657
+ };
96658
+ }
96659
+ //#endregion
96216
96660
  //#region src/notification/template-vars.ts
96217
96661
  var RULE_BODY_ONLY = ["body"];
96218
96662
  var RULE_TEXT = ["title", "body"];
@@ -96223,6 +96667,11 @@ var TANK = [
96223
96667
  "device-tank-full",
96224
96668
  "device-tank-normal"
96225
96669
  ];
96670
+ var ALERT_EPISODE = [
96671
+ "alert-critical",
96672
+ "alert-error",
96673
+ "alert-critical-resolved"
96674
+ ];
96226
96675
  var UPDATES = [
96227
96676
  "addon-update-available",
96228
96677
  "server-update-available",
@@ -96747,7 +97196,8 @@ var NC_TEMPLATE_VARS = [
96747
97196
  "server-updated",
96748
97197
  "storage-location-low",
96749
97198
  "storage-location-critical",
96750
- "storage-location-ok"
97199
+ "storage-location-ok",
97200
+ ...ALERT_EPISODE
96751
97201
  ]
96752
97202
  },
96753
97203
  {
@@ -96769,7 +97219,8 @@ var NC_TEMPLATE_VARS = [
96769
97219
  "server-updated",
96770
97220
  "storage-location-low",
96771
97221
  "storage-location-critical",
96772
- "storage-location-ok"
97222
+ "storage-location-ok",
97223
+ ...ALERT_EPISODE
96773
97224
  ]
96774
97225
  },
96775
97226
  {
@@ -96836,7 +97287,7 @@ var NC_TEMPLATE_VARS = [
96836
97287
  families: ["rule"],
96837
97288
  fields: [...RULE_TEXT],
96838
97289
  kinds: ["system"],
96839
- systemEventKinds: ["recording-degraded"]
97290
+ systemEventKinds: ["recording-degraded", ...ALERT_EPISODE]
96840
97291
  },
96841
97292
  {
96842
97293
  name: "locationName",
@@ -97033,13 +97484,53 @@ var NC_TEMPLATE_VARS = [
97033
97484
  },
97034
97485
  {
97035
97486
  name: "title",
97036
- label: "Export title",
97487
+ label: "Export or alert title",
97037
97488
  example: "Ingresso 08:00",
97038
97489
  group: "system",
97039
97490
  families: ["rule"],
97040
97491
  fields: [...RULE_TEXT],
97041
97492
  kinds: ["system"],
97042
- systemEventKinds: ["export-completed"]
97493
+ systemEventKinds: ["export-completed", ...ALERT_EPISODE]
97494
+ },
97495
+ {
97496
+ name: "severity",
97497
+ label: "Alert severity",
97498
+ example: "critical",
97499
+ group: "system",
97500
+ families: ["rule"],
97501
+ fields: [...RULE_TEXT],
97502
+ kinds: ["system"],
97503
+ systemEventKinds: [...ALERT_EPISODE]
97504
+ },
97505
+ {
97506
+ name: "category",
97507
+ label: "Alert category",
97508
+ example: "addon.runner-failed",
97509
+ group: "system",
97510
+ families: ["rule"],
97511
+ fields: [...RULE_TEXT],
97512
+ kinds: ["system"],
97513
+ systemEventKinds: [...ALERT_EPISODE]
97514
+ },
97515
+ {
97516
+ name: "source",
97517
+ label: "Alert source (addon, node or runner)",
97518
+ example: "recorder",
97519
+ group: "system",
97520
+ families: ["rule"],
97521
+ fields: [...RULE_TEXT],
97522
+ kinds: ["system"],
97523
+ systemEventKinds: [...ALERT_EPISODE]
97524
+ },
97525
+ {
97526
+ name: "actionUrl",
97527
+ label: "Alert action link",
97528
+ example: "/system/addons",
97529
+ group: "system",
97530
+ families: ["rule"],
97531
+ fields: [...RULE_TEXT],
97532
+ kinds: ["system"],
97533
+ systemEventKinds: [...ALERT_EPISODE]
97043
97534
  },
97044
97535
  {
97045
97536
  name: "exportId",
@@ -97250,7 +97741,10 @@ var NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS = [
97250
97741
  "device-tank-full",
97251
97742
  "device-tank-normal",
97252
97743
  "node-restarting",
97253
- "node-updating"
97744
+ "node-updating",
97745
+ "alert-critical",
97746
+ "alert-error",
97747
+ "alert-critical-resolved"
97254
97748
  ];
97255
97749
  /**
97256
97750
  * The catalog as `getTemplateCatalog` SERVES it: every descriptor, with the
@@ -101414,6 +101908,73 @@ function setNestedValue(obj, path, value) {
101414
101908
  current[parts[parts.length - 1]] = value;
101415
101909
  }
101416
101910
  //#endregion
101911
+ //#region src/utils/oauth-landing.ts
101912
+ /**
101913
+ * Where an OAuth round-trip ends: the admin-ui completion route
101914
+ * (`/sso-complete`, the page every popup sign-in already lands on), with the
101915
+ * OUTCOME in the URL fragment.
101916
+ *
101917
+ * The outcome is a status plus a reason CODE from a closed list. It never
101918
+ * carries a token, a code, a client secret or a free-form error message: the
101919
+ * page words each code itself, and an unknown code reads as `unknown` rather
101920
+ * than being echoed. Fragment only, so nothing here reaches a server log.
101921
+ *
101922
+ * Pure and browser-safe.
101923
+ */
101924
+ /** The admin-ui route the hub's OAuth completions land on (relative to its mount). */
101925
+ var OAUTH_LANDING_PATH = "/sso-complete";
101926
+ var OAUTH_LANDING_REASONS = [
101927
+ "access_denied",
101928
+ "invalid_state",
101929
+ "invalid_request",
101930
+ "unknown_broker",
101931
+ "not_configured",
101932
+ "exchange_failed",
101933
+ "no_refresh_token",
101934
+ "unavailable",
101935
+ "unknown"
101936
+ ];
101937
+ function isOauthLandingReason(value) {
101938
+ return OAUTH_LANDING_REASONS.some((reason) => reason === value);
101939
+ }
101940
+ /**
101941
+ * The landing URL for `outcome`. `origin` is the hub address the flow already
101942
+ * runs on (from the `local-network` palette role, never a literal); `null`
101943
+ * gives a hub-relative URL.
101944
+ */
101945
+ function oauthLandingUrl(origin, outcome) {
101946
+ const params = new URLSearchParams({
101947
+ return: "oauth",
101948
+ status: outcome.status
101949
+ });
101950
+ if (outcome.addonId !== void 0) params.set("addon", outcome.addonId);
101951
+ if (outcome.brokerId !== void 0) params.set("broker", outcome.brokerId);
101952
+ if (outcome.integration !== void 0) params.set("integration", outcome.integration);
101953
+ if (outcome.status === "error") params.set("reason", outcome.reason ?? "unknown");
101954
+ if (outcome.action === "disconnect") params.set("action", "disconnect");
101955
+ return `${origin === null ? "" : origin.replace(/\/+$/, "")}${OAUTH_LANDING_PATH}#${params.toString()}`;
101956
+ }
101957
+ /** Parse the fragment of a landing URL; `null` for anything that is not one. */
101958
+ function parseOauthLandingFragment(hash) {
101959
+ if (!hash.startsWith("#")) return null;
101960
+ const params = new URLSearchParams(hash.slice(1));
101961
+ if (params.get("return") !== "oauth") return null;
101962
+ const status = params.get("status");
101963
+ if (status !== "success" && status !== "error") return null;
101964
+ const addonId = params.get("addon");
101965
+ const brokerId = params.get("broker");
101966
+ const integration = params.get("integration");
101967
+ const reasonRaw = params.get("reason");
101968
+ return {
101969
+ status,
101970
+ ...addonId !== null && addonId.length > 0 ? { addonId } : {},
101971
+ ...brokerId !== null && brokerId.length > 0 ? { brokerId } : {},
101972
+ ...integration !== null && integration.length > 0 ? { integration } : {},
101973
+ ...status === "error" ? { reason: isOauthLandingReason(reasonRaw) ? reasonRaw : "unknown" } : {},
101974
+ ...params.get("action") === "disconnect" ? { action: "disconnect" } : {}
101975
+ };
101976
+ }
101977
+ //#endregion
101417
101978
  //#region src/utils/pool-memory-watchdog.ts
101418
101979
  var MB = 1024 * 1024;
101419
101980
  var DEFAULT_POOL_MEMORY_POLICY = {
@@ -102425,11 +102986,13 @@ function armRemovalReconcile(opts) {
102425
102986
  //#endregion
102426
102987
  exports.ACCESSORY_LABEL = ACCESSORY_LABEL;
102427
102988
  exports.ACCESS_ROLES = ACCESS_ROLES;
102989
+ exports.ADMIN_SCOPE = ADMIN_SCOPE;
102428
102990
  exports.AGENT_MDNS_QUERY_NAME = AGENT_MDNS_QUERY_NAME;
102429
102991
  exports.AGENT_MDNS_SERVICE_TYPE = AGENT_MDNS_SERVICE_TYPE;
102430
102992
  exports.AGENT_MDNS_TXT_KEYS = AGENT_MDNS_TXT_KEYS;
102431
102993
  exports.ALEXA_EGRESS_PROFILE = ALEXA_EGRESS_PROFILE;
102432
102994
  exports.ALL_CAPABILITY_DEFINITIONS = ALL_CAPABILITY_DEFINITIONS;
102995
+ exports.ALL_METHOD_ACCESS = ALL_METHOD_ACCESS;
102433
102996
  exports.APPEARANCE_BIN_COUNT = APPEARANCE_BIN_COUNT;
102434
102997
  exports.APPEARANCE_BLOCKS = APPEARANCE_BLOCKS;
102435
102998
  exports.APPEARANCE_DESCRIPTOR_VERSION = APPEARANCE_DESCRIPTOR_VERSION;
@@ -102463,6 +103026,7 @@ exports.AddonAutoUpdateSchema = AddonAutoUpdateSchema;
102463
103026
  exports.AddonListItemSchema = AddonListItemSchema;
102464
103027
  exports.AddonPageDeclarationSchema = AddonPageDeclarationSchema;
102465
103028
  exports.AddonPageInfoSchema = AddonPageInfoSchema;
103029
+ exports.AddonRoutesScopeSchema = AddonRoutesScopeSchema;
102466
103030
  exports.AdminLinkTargetEnum = AdminLinkTargetEnum;
102467
103031
  exports.AdoptionAdoptInputSchema = AdoptInputSchema;
102468
103032
  exports.AdoptionAdoptResultSchema = AdoptResultSchema;
@@ -102482,6 +103046,7 @@ exports.AirQualitySensorStatusSchema = AirQualitySensorStatusSchema;
102482
103046
  exports.AlarmArmModeSchema = AlarmArmModeSchema;
102483
103047
  exports.AlarmPanelStatusSchema = AlarmPanelStatusSchema;
102484
103048
  exports.AlarmStateSchema = AlarmStateSchema;
103049
+ exports.AlertEpisodePayloadSchema = AlertEpisodePayloadSchema;
102485
103050
  exports.AlertSchema = AlertSchema;
102486
103051
  exports.AlertSeveritySchema = AlertSeveritySchema;
102487
103052
  exports.AlertSourceSchema = AlertSourceSchema;
@@ -102636,6 +103201,7 @@ exports.CONNECTION_TEST_TIMEOUT_MS = CONNECTION_TEST_TIMEOUT_MS;
102636
103201
  exports.CONTAINER_CHILD_PRIORITY = CONTAINER_CHILD_PRIORITY;
102637
103202
  exports.CORE_BLOCKS_ADDON_ID = CORE_BLOCKS_ADDON_ID;
102638
103203
  exports.CORE_BLOCK_ADDON_PREFIX = CORE_BLOCK_ADDON_PREFIX;
103204
+ exports.CREDENTIAL_TOKEN_KIND = CREDENTIAL_TOKEN_KIND;
102639
103205
  exports.CROP_SUPPLY_SOURCES = CROP_SUPPLY_SOURCES;
102640
103206
  exports.CROP_SUPPLY_STEP_IDS = CROP_SUPPLY_STEP_IDS;
102641
103207
  exports.CUSTOMIZATION_BLOCK_NAME_PREFIX = require_composition.CUSTOMIZATION_BLOCK_NAME_PREFIX;
@@ -102816,6 +103382,8 @@ exports.CreateIntegrationInputSchema = CreateIntegrationInputSchema;
102816
103382
  exports.CreateScopedTokenInputSchema = CreateScopedTokenInputSchema;
102817
103383
  exports.CreateScopedTokenResultSchema = CreateScopedTokenResultSchema;
102818
103384
  exports.CreateUserInputSchema = CreateUserInputSchema;
103385
+ exports.CredentialScopeSchema = CredentialScopeSchema;
103386
+ exports.CredentialTokenClaimsSchema = CredentialTokenClaimsSchema;
102819
103387
  exports.CustomActionInputSchema = CustomActionInputSchema;
102820
103388
  exports.CustomModelDescriptorSchema = CustomModelDescriptorSchema;
102821
103389
  exports.DATABASE_SNAPSHOT_PARTIAL_SUFFIX = DATABASE_SNAPSHOT_PARTIAL_SUFFIX;
@@ -102960,9 +103528,16 @@ exports.DiscoveredChildDeviceSchema = DiscoveredChildDeviceSchema;
102960
103528
  exports.DiscoveredChildStatusSchema = DiscoveredChildStatusSchema;
102961
103529
  exports.DiscoveredDeviceSchema = DiscoveredDeviceSchema;
102962
103530
  exports.DiscoveredTargetSchema = DiscoveredTargetSchema;
103531
+ exports.DishwasherAccessSchema = DishwasherAccessSchema;
103532
+ exports.DishwasherAvailabilitySchema = DishwasherAvailabilitySchema;
102963
103533
  exports.DishwasherConsumableLevelSchema = DishwasherConsumableLevelSchema;
103534
+ exports.DishwasherOperationStateSchema = DishwasherOperationStateSchema;
103535
+ exports.DishwasherOptionDescriptorSchema = DishwasherOptionDescriptorSchema;
103536
+ exports.DishwasherOptionsSchema = DishwasherOptionsSchema;
103537
+ exports.DishwasherProgramSchema = DishwasherProgramSchema;
102964
103538
  exports.DishwasherStateSchema = DishwasherStateSchema;
102965
103539
  exports.DishwasherStatusSchema = DishwasherStatusSchema;
103540
+ exports.DishwasherValueSchema = DishwasherValueSchema;
102966
103541
  exports.DiskReconcileJobSchema = DiskReconcileJobSchema;
102967
103542
  exports.DisposerChain = require_sleep.DisposerChain;
102968
103543
  exports.DoorbellPressEventSchema = DoorbellPressEventSchema;
@@ -103630,6 +104205,8 @@ exports.NotificationFormatSchema = NotificationFormatSchema;
103630
104205
  exports.NotificationSchema = NotificationSchema;
103631
104206
  exports.NotifierStatusSchema = NotifierStatusSchema;
103632
104207
  exports.NumericSensorStatusSchema = NumericSensorStatusSchema;
104208
+ exports.OAUTH_LANDING_PATH = OAUTH_LANDING_PATH;
104209
+ exports.OAUTH_LANDING_REASONS = OAUTH_LANDING_REASONS;
103633
104210
  exports.OPERATOR_WRITTEN_STALE_MS = OPERATOR_WRITTEN_STALE_MS;
103634
104211
  exports.OPS_LOG_DEFAULT_LIMIT = OPS_LOG_DEFAULT_LIMIT;
103635
104212
  exports.OPS_LOG_RING_DEFAULT_MAX = OPS_LOG_RING_DEFAULT_MAX;
@@ -103971,6 +104548,7 @@ exports.SETTINGS_ARRAY_ADOPTS_PREFIX = require_sleep.SETTINGS_ARRAY_ADOPTS_PREFI
103971
104548
  exports.SETTINGS_BROKERS_ADOPTS_PREFIX = require_sleep.SETTINGS_BROKERS_ADOPTS_PREFIX;
103972
104549
  exports.SHARE_SOURCE_SETTING_KEY = SHARE_SOURCE_SETTING_KEY;
103973
104550
  exports.SHARE_VIEW_KINDS = require_sleep.SHARE_VIEW_KINDS;
104551
+ exports.SHARE_VIEW_MAX_DEVICES = SHARE_VIEW_MAX_DEVICES;
103974
104552
  exports.SINGLE_HUB_ADDRESS_ROLES = SINGLE_HUB_ADDRESS_ROLES;
103975
104553
  exports.SOURCE_CAPS = require_composition.SOURCE_CAPS;
103976
104554
  exports.SOURCE_CAP_ACTIVE_FIELD = require_composition.SOURCE_CAP_ACTIVE_FIELD;
@@ -104035,6 +104613,8 @@ exports.SettingsRecordSchema = SettingsRecordSchema;
104035
104613
  exports.SettingsSchemaWithValuesSchema = SettingsSchemaWithValuesSchema;
104036
104614
  exports.SettingsUpdateResultSchema = SettingsUpdateResultSchema;
104037
104615
  exports.ShareSourceSchema = ShareSourceSchema;
104616
+ exports.ShareViewGrantSchema = ShareViewGrantSchema;
104617
+ exports.ShareViewScopeSchema = ShareViewScopeSchema;
104038
104618
  exports.ShareWeightsSchema = ShareWeightsSchema;
104039
104619
  exports.SiteLocationSchema = SiteLocationSchema;
104040
104620
  exports.SiteLocationSourceSchema = SiteLocationSourceSchema;
@@ -104310,6 +104890,10 @@ exports.alarmDeviceSecureOnArm = alarmDeviceSecureOnArm;
104310
104890
  exports.alarmPanelCapability = alarmPanelCapability;
104311
104891
  exports.alarmPatchLanded = alarmPatchLanded;
104312
104892
  exports.alarmProfileById = alarmProfileById;
104893
+ exports.alertEpisodeId = alertEpisodeId;
104894
+ exports.alertEpisodeKind = alertEpisodeKind;
104895
+ exports.alertEpisodePayload = alertEpisodePayload;
104896
+ exports.alertNodeId = alertNodeId;
104313
104897
  exports.alertsCapability = alertsCapability;
104314
104898
  exports.allDoActions = allDoActions;
104315
104899
  exports.allowedSuppliedEffect = allowedSuppliedEffect;
@@ -104391,6 +104975,7 @@ exports.canConvertUnit = canConvertUnit;
104391
104975
  exports.canonicalEgressPlan = canonicalEgressPlan;
104392
104976
  exports.canonicalIconKey = canonicalIconKey;
104393
104977
  exports.canonicalizeAppCallback = canonicalizeAppCallback;
104978
+ exports.capabilityScopesOf = capabilityScopesOf;
104394
104979
  exports.capacitySessionsOf = capacitySessionsOf;
104395
104980
  exports.carbonMonoxideCapability = carbonMonoxideCapability;
104396
104981
  exports.cellsToRects = cellsToRects;
@@ -104666,6 +105251,8 @@ exports.invertPresetFeature = invertPresetFeature;
104666
105251
  exports.invocationFromEncodeProfile = require_composition.invocationFromEncodeProfile;
104667
105252
  exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
104668
105253
  exports.isAlarmControllableCap = isAlarmControllableCap;
105254
+ exports.isAlertEpisodeOpen = isAlertEpisodeOpen;
105255
+ exports.isAlertEpisodeSeverity = isAlertEpisodeSeverity;
104669
105256
  exports.isAppLinkBase = isAppLinkBase;
104670
105257
  exports.isAppStartRefusal = isAppStartRefusal;
104671
105258
  exports.isArrayOutputSchema = isArrayOutputSchema;
@@ -104701,6 +105288,7 @@ exports.isLabelSupplyStepId = isLabelSupplyStepId;
104701
105288
  exports.isLocationEnabled = isLocationEnabled;
104702
105289
  exports.isMediaOwnerType = isMediaOwnerType;
104703
105290
  exports.isNode = isNode;
105291
+ exports.isOauthLandingReason = isOauthLandingReason;
104704
105292
  exports.isObjectInput = isObjectInput;
104705
105293
  exports.isOccupancyRule = isOccupancyRule;
104706
105294
  exports.isOwnerOnlyEventCategory = require_event_category.isOwnerOnlyEventCategory;
@@ -104824,6 +105412,7 @@ exports.notificationRulesCapability = notificationRulesCapability;
104824
105412
  exports.notifierCapability = notifierCapability;
104825
105413
  exports.numericSensorCapability = numericSensorCapability;
104826
105414
  exports.oauthIntegrationCapability = oauthIntegrationCapability;
105415
+ exports.oauthLandingUrl = oauthLandingUrl;
104827
105416
  exports.objectInputDeclaresAddonId = objectInputDeclaresAddonId;
104828
105417
  exports.objectInputDeclaresRequiredDeviceId = objectInputDeclaresRequiredDeviceId;
104829
105418
  exports.occupancyScope = occupancyScope;
@@ -104836,16 +105425,19 @@ exports.osdManagerCapability = osdManagerCapability;
104836
105425
  exports.overlayClusterStepSettings = overlayClusterStepSettings;
104837
105426
  exports.packagePickerItems = packagePickerItems;
104838
105427
  exports.parseAdminBase = parseAdminBase;
105428
+ exports.parseAlertEpisodePayload = parseAlertEpisodePayload;
104839
105429
  exports.parseAppAuthCallback = parseAppAuthCallback;
104840
105430
  exports.parseAppFlowRequest = parseAppFlowRequest;
104841
105431
  exports.parseAppPageLang = parseAppPageLang;
104842
105432
  exports.parseCameraStreamConfig = parseCameraStreamConfig;
105433
+ exports.parseCredentialScopes = parseCredentialScopes;
104843
105434
  exports.parseDeviceEnrollmentLink = parseDeviceEnrollmentLink;
104844
105435
  exports.parseExpression = require_composition.parseExpression;
104845
105436
  exports.parseJsonArray = require_sleep.parseJsonArray;
104846
105437
  exports.parseJsonObject = require_sleep.parseJsonObject;
104847
105438
  exports.parseJsonUnknown = require_sleep.parseJsonUnknown;
104848
105439
  exports.parseMediaOwnerKey = parseMediaOwnerKey;
105440
+ exports.parseOauthLandingFragment = parseOauthLandingFragment;
104849
105441
  exports.parseOccupancyScope = parseOccupancyScope;
104850
105442
  exports.parseProcStatus = parseProcStatus;
104851
105443
  exports.parseProfileBrokerId = require_sleep.parseProfileBrokerId;
@@ -105010,7 +105602,9 @@ exports.schemaDeclaresAnyField = require_sleep.schemaDeclaresAnyField;
105010
105602
  exports.scopeInherits = scopeInherits;
105011
105603
  exports.scopeKey = require_sleep.scopeKey;
105012
105604
  exports.scopesAllowAddon = scopesAllowAddon;
105605
+ exports.scopesAllowAddonRoutes = scopesAllowAddonRoutes;
105013
105606
  exports.scopesAllowDeviceCap = scopesAllowDeviceCap;
105607
+ exports.scopesGrantAdmin = scopesGrantAdmin;
105014
105608
  exports.scoreRuntimes = scoreRuntimes;
105015
105609
  exports.scriptRunnerCapability = scriptRunnerCapability;
105016
105610
  exports.scrubKnownSecrets = require_sleep.scrubKnownSecrets;
@@ -105034,6 +105628,7 @@ exports.settingsArrayAdoptsFrom = require_sleep.settingsArrayAdoptsFrom;
105034
105628
  exports.settingsBelow = settingsBelow;
105035
105629
  exports.settingsBrokersAdoptsFrom = require_sleep.settingsBrokersAdoptsFrom;
105036
105630
  exports.settingsStoreCapability = settingsStoreCapability;
105631
+ exports.shareViewGrantOf = shareViewGrantOf;
105037
105632
  exports.shortHostname = shortHostname;
105038
105633
  exports.shortSecretRefHash = require_sleep.shortSecretRefHash;
105039
105634
  exports.signalPercentFromBars = signalPercentFromBars;
@@ -105048,6 +105643,7 @@ exports.smtpProviderCapability = smtpProviderCapability;
105048
105643
  exports.snapshotCapability = snapshotCapability;
105049
105644
  exports.splitTranslationRef = splitTranslationRef;
105050
105645
  exports.ssoBridgeCapability = ssoBridgeCapability;
105646
+ exports.startMoverUnderClearance = startMoverUnderClearance;
105051
105647
  exports.startReachabilityPoll = startReachabilityPoll;
105052
105648
  exports.stateLabel = stateLabel;
105053
105649
  exports.stateVocabularyFor = stateVocabularyFor;