@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/addon.js +51 -3
- package/dist/addon.mjs +51 -3
- package/dist/auth/credential-scope.d.ts +230 -0
- package/dist/capabilities/alerts.cap.d.ts +20 -0
- package/dist/capabilities/dishwasher.cap.d.ts +352 -30
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/notification-rules.cap.d.ts +69 -0
- package/dist/capabilities/osd-manager.cap.d.ts +18 -0
- package/dist/capabilities/storage-migration.cap.d.ts +14 -0
- package/dist/client.js +175 -106
- package/dist/client.mjs +175 -106
- package/dist/enums/event-category.d.ts +10 -1
- package/dist/enums.js +1 -1
- package/dist/enums.mjs +1 -1
- package/dist/{event-category-BvOFi6PY.mjs → event-category-DOl51-Ij.mjs} +10 -1
- package/dist/{event-category-Hoe-mqbd.js → event-category-eSqkye-K.js} +10 -1
- package/dist/generated/addon-api.d.ts +21 -0
- package/dist/generated/addon-cap-facts.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +839 -243
- package/dist/index.mjs +805 -244
- package/dist/interfaces/event-bus.d.ts +2 -0
- package/dist/interfaces/relocate.d.ts +25 -0
- package/dist/notification/alert-episode.d.ts +62 -0
- package/dist/{sleep-REHQvLV6.js → sleep-BE7_6UnC.js} +3 -1
- package/dist/{sleep-BegKjwUu.mjs → sleep-BxjU_fJM.mjs} +3 -1
- package/dist/utils/oauth-landing.d.ts +38 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
3
|
-
const require_event_category = require("./event-category-
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
61246
|
-
|
|
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
|
|
61252
|
-
|
|
61253
|
-
/**
|
|
61254
|
-
|
|
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
|
-
|
|
61258
|
-
|
|
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
|
-
|
|
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:
|
|
61584
|
+
pause: require_sleep.method(zod.z.object({ deviceId: DeviceIdSchema }), zod.z.void(), {
|
|
61283
61585
|
kind: "mutation",
|
|
61284
61586
|
auth: "protected"
|
|
61285
61587
|
}),
|
|
61286
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
61659
|
+
deviceId: DeviceIdSchema,
|
|
61348
61660
|
key: zod.z.string().min(1),
|
|
61349
|
-
value:
|
|
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;
|