@camstack/addon-import-alexa 0.2.197 → 0.2.199
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/CHANGELOG.md +12 -0
- package/dist/addon.js +762 -737
- package/dist/addon.mjs +762 -737
- package/package.json +2 -2
package/dist/addon.js
CHANGED
|
@@ -5676,7 +5676,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
5676
5676
|
return EventCategory;
|
|
5677
5677
|
}({});
|
|
5678
5678
|
//#endregion
|
|
5679
|
-
//#region ../types/dist/device-type-
|
|
5679
|
+
//#region ../types/dist/device-type-DxCT0krO.mjs
|
|
5680
5680
|
/**
|
|
5681
5681
|
import { errMsg } from '@camstack/types'
|
|
5682
5682
|
* Extract a human-readable message from an unknown error value.
|
|
@@ -5838,6 +5838,13 @@ var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
|
5838
5838
|
* filters that want "all devices with on-motion behaviour".
|
|
5839
5839
|
*/
|
|
5840
5840
|
DeviceFeature["MotionTrigger"] = "motion-trigger";
|
|
5841
|
+
/**
|
|
5842
|
+
* Device can be run for a chosen time and then stopped. Mirrors the
|
|
5843
|
+
* `timed-run` wrapper cap — the cap is bound by the core-blocks addon, not by
|
|
5844
|
+
* a driver, so the flag is derived from the device's bindings
|
|
5845
|
+
* (`featuresOfBoundCaps`). Gates the quick-run control in the viewer.
|
|
5846
|
+
*/
|
|
5847
|
+
DeviceFeature["TimedRun"] = "timed-run";
|
|
5841
5848
|
/** Light supports rgb-triplet color via `color` cap. */
|
|
5842
5849
|
DeviceFeature["LightColorRgb"] = "light-color-rgb";
|
|
5843
5850
|
/** Light supports HSV color via `color` cap. */
|
|
@@ -6061,7 +6068,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
6061
6068
|
return DeviceRole;
|
|
6062
6069
|
}({});
|
|
6063
6070
|
//#endregion
|
|
6064
|
-
//#region ../types/dist/sleep-
|
|
6071
|
+
//#region ../types/dist/sleep-CGPZyzB5.mjs
|
|
6065
6072
|
/**
|
|
6066
6073
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6067
6074
|
* window to float samples (D455).
|
|
@@ -7293,6 +7300,7 @@ var RecordIntegrationInstances = class {
|
|
|
7293
7300
|
this.secretKeys = topLevelSecretKeys(kind.declaration.secretPaths);
|
|
7294
7301
|
this.secretMaps = secretMapKeys(kind.declaration.secretPaths);
|
|
7295
7302
|
this.nameField = kind.declaration.entry?.nameField ?? "name";
|
|
7303
|
+
if (hooks.kindOf === void 0 && hooks.description.kinds.length !== 1) throw new Error(`record kind '${kind.name}': describe().kinds has ${hooks.description.kinds.length} entries, so kindOf is required to say which one an instance is`);
|
|
7296
7304
|
}
|
|
7297
7305
|
/**
|
|
7298
7306
|
* One instance read for the addon's own runtime; null when absent. When the keychain is
|
|
@@ -7334,10 +7342,21 @@ var RecordIntegrationInstances = class {
|
|
|
7334
7342
|
}
|
|
7335
7343
|
return out;
|
|
7336
7344
|
}
|
|
7345
|
+
/** The kind an instance body is of: the provider's `kindOf`, else its one declared kind. */
|
|
7346
|
+
kindOfBody(body) {
|
|
7347
|
+
if (this.hooks.kindOf !== void 0) {
|
|
7348
|
+
const id = this.hooks.kindOf(body);
|
|
7349
|
+
if (!this.hooks.description.kinds.some((declared) => declared.id === id)) throw new Error(`record kind '${this.kind.name}': kindOf returned '${id}', which describe().kinds does not declare (D1013)`);
|
|
7350
|
+
return id;
|
|
7351
|
+
}
|
|
7352
|
+
const only = this.hooks.description.kinds[0];
|
|
7353
|
+
if (only === void 0) throw new Error(`record kind '${this.kind.name}' declares no kinds`);
|
|
7354
|
+
return only.id;
|
|
7355
|
+
}
|
|
7337
7356
|
viewOf(record) {
|
|
7338
7357
|
const shown = secretViewsOf(this.records.owner, this.kind.name, record.id, this.kind.declaration, record.data);
|
|
7339
7358
|
const rawName = record.data[this.nameField];
|
|
7340
|
-
const kind = this.
|
|
7359
|
+
const kind = this.kindOfBody(record.data);
|
|
7341
7360
|
const health = this.hooks.health?.(record.data, record.id);
|
|
7342
7361
|
return {
|
|
7343
7362
|
id: record.id,
|
|
@@ -7345,7 +7364,7 @@ var RecordIntegrationInstances = class {
|
|
|
7345
7364
|
configured: this.hooks.configured(record.data),
|
|
7346
7365
|
enabled: isInstanceEnabled(record.data),
|
|
7347
7366
|
formValues: shown,
|
|
7348
|
-
|
|
7367
|
+
kind,
|
|
7349
7368
|
...health?.status !== void 0 ? { status: health.status } : {},
|
|
7350
7369
|
...health?.lastCheckedAt !== void 0 ? { lastCheckedAt: health.lastCheckedAt } : {}
|
|
7351
7370
|
};
|
|
@@ -8446,7 +8465,7 @@ function boundOf(list) {
|
|
|
8446
8465
|
* Base class for CamStack addons. Eliminates settings boilerplate:
|
|
8447
8466
|
*
|
|
8448
8467
|
* - Typed `config` property with automatic resolution from store + defaults
|
|
8449
|
-
* -
|
|
8468
|
+
* - the scoped settings API (`clusterSettings` / `nodeSettings` / `deviceDefaults`) auto-implemented
|
|
8450
8469
|
* - `getAddonSettings()` / `updateAddonSettings()` auto-implemented
|
|
8451
8470
|
* - `getDeviceSettings()` / `updateDeviceSettings()` auto-implemented
|
|
8452
8471
|
* - `ctx` accessor for the AddonContext (no manual `this.ctxRef` storage)
|
|
@@ -8456,7 +8475,7 @@ function boundOf(list) {
|
|
|
8456
8475
|
* Subclasses override:
|
|
8457
8476
|
* - `onInitialize()` — addon-specific init logic, return ProviderRegistration[]
|
|
8458
8477
|
* - `onShutdown()` — cleanup
|
|
8459
|
-
* - `
|
|
8478
|
+
* - `clusterSettingsSchema()` / `nodeSettingsSchema()` / `deviceSettingsSchema()` — UI schemas
|
|
8460
8479
|
*
|
|
8461
8480
|
* @example
|
|
8462
8481
|
* ```ts
|
|
@@ -8470,7 +8489,7 @@ function boundOf(list) {
|
|
|
8470
8489
|
* super({ maxRetries: 3, endpoint: 'http://localhost' })
|
|
8471
8490
|
* }
|
|
8472
8491
|
*
|
|
8473
|
-
* protected
|
|
8492
|
+
* protected clusterSettingsSchema() {
|
|
8474
8493
|
* return this.schema({
|
|
8475
8494
|
* sections: [{
|
|
8476
8495
|
* id: 'main', title: 'Settings',
|
|
@@ -8513,7 +8532,7 @@ var BaseAddon = class {
|
|
|
8513
8532
|
defaults;
|
|
8514
8533
|
/**
|
|
8515
8534
|
* Hidden-state paths that hold secrets (D787) — values the addon writes
|
|
8516
|
-
* itself (`
|
|
8535
|
+
* itself (`state()`, the scoped writers) that no form field declares.
|
|
8517
8536
|
* Stored in the keychain exactly like a `password` field. Syntax:
|
|
8518
8537
|
* `'snapshotSigningKey'`, `'identity.pincode'`, `'tokens[userId].accessToken'`
|
|
8519
8538
|
* (`key[<id field>]` addresses array items by id, never by index).
|
|
@@ -8523,7 +8542,7 @@ var BaseAddon = class {
|
|
|
8523
8542
|
/**
|
|
8524
8543
|
* D986 M4: the scoped schemas this addon declared, resolved once per capability
|
|
8525
8544
|
* (`loadScopedSchemas`) so the sync readers (`perNodeKeys`, the secret tree, the restart check)
|
|
8526
|
-
* see them. Empty until loaded
|
|
8545
|
+
* see them. Empty until loaded.
|
|
8527
8546
|
*/
|
|
8528
8547
|
_scopedByCap = /* @__PURE__ */ new Map();
|
|
8529
8548
|
_nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
@@ -8709,7 +8728,7 @@ var BaseAddon = class {
|
|
|
8709
8728
|
/** Addon-specific cleanup. Override if needed. */
|
|
8710
8729
|
async onShutdown() {}
|
|
8711
8730
|
/**
|
|
8712
|
-
* Called after config is resolved during
|
|
8731
|
+
* Called after config is resolved during a settings write.
|
|
8713
8732
|
* Override to react to config changes (e.g. restart a sampler, reconnect a service).
|
|
8714
8733
|
* Not called during initialize() — use onInitialize() for initial setup.
|
|
8715
8734
|
*/
|
|
@@ -8738,82 +8757,12 @@ var BaseAddon = class {
|
|
|
8738
8757
|
scopedSettingsCapabilities() {
|
|
8739
8758
|
return [];
|
|
8740
8759
|
}
|
|
8741
|
-
/** Override to provide global-level settings UI schema. */
|
|
8742
|
-
globalSettingsSchema(_cap) {
|
|
8743
|
-
return null;
|
|
8744
|
-
}
|
|
8745
8760
|
/** Override to provide device-level settings UI schema. */
|
|
8746
8761
|
deviceSettingsSchema() {
|
|
8747
8762
|
return null;
|
|
8748
8763
|
}
|
|
8749
8764
|
/**
|
|
8750
|
-
*
|
|
8751
|
-
* ARE the configuration of its integration.
|
|
8752
|
-
*
|
|
8753
|
-
* Return the `ConfigSection.id`s, from {@link globalSettingsSchema}, that an
|
|
8754
|
-
* operator should find on the addon's integration page (System →
|
|
8755
|
-
* Integrations → <name>) rather than only in the cluster-wide list of every
|
|
8756
|
-
* addon. Empty (the default) means the addon has no integration-level
|
|
8757
|
-
* settings and no such surface is offered — this is opt-in, because whether
|
|
8758
|
-
* an addon's configuration IS its integration's configuration depends on the
|
|
8759
|
-
* nature of the integration.
|
|
8760
|
-
*
|
|
8761
|
-
* WHAT THIS IS NOT. It is not a scope. The selected sections keep living in
|
|
8762
|
-
* the ONE global schema, in the ONE addon store, written by the ONE
|
|
8763
|
-
* `updateGlobalSettings` path. There is deliberately no
|
|
8764
|
-
* `updateIntegrationSettings`: a second write path is how a surface acquires
|
|
8765
|
-
* a second store key, and this repo has shipped that twice (`btmPath@hub`,
|
|
8766
|
-
* D266). Selecting sections cannot introduce a key that selecting cannot.
|
|
8767
|
-
*
|
|
8768
|
-
* WHY IT IS A LIST OF SECTION IDS AND NOT A MARKER ON THE SECTION.
|
|
8769
|
-
* `ConfigFieldBase` used to carry `scope?: 'device' | 'global'` and it was
|
|
8770
|
-
* removed with the reason recorded at
|
|
8771
|
-
* `packages/types/src/interfaces/config-ui.ts:249` — *"a field's scope is
|
|
8772
|
-
* determined by WHICH schema it lives in, not by a field-level marker."* A
|
|
8773
|
-
* marker sprinkled across sections also has to borrow a field that already
|
|
8774
|
-
* means something else; borrowing `section.tab` put the literal word
|
|
8775
|
-
* "integration" into an operator-facing tab bar, because `tab` means "how to
|
|
8776
|
-
* GROUP this visually" and cannot also mean "where this lives" (D269
|
|
8777
|
-
* supersedes D268). One declaration, in one place, next to the schema whose
|
|
8778
|
-
* ids it names.
|
|
8779
|
-
*/
|
|
8780
|
-
integrationSettingSections() {
|
|
8781
|
-
return [];
|
|
8782
|
-
}
|
|
8783
|
-
async getGlobalSettings(overlay, cap, nodeId) {
|
|
8784
|
-
await this.loadScopedSchemas(cap);
|
|
8785
|
-
const schema = this.globalSettingsSchema(cap) ?? this.scopedFormSchema(cap);
|
|
8786
|
-
if (!schema) return { sections: [] };
|
|
8787
|
-
const projected = await this.readRawProjectedStore(nodeId, cap);
|
|
8788
|
-
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(projected, overlay) : projected, { inlineSecretsAsViews: true });
|
|
8789
|
-
}
|
|
8790
|
-
/**
|
|
8791
|
-
* The integration-level view of this addon's settings: exactly the sections
|
|
8792
|
-
* named by {@link integrationSettingSections}, hydrated from the SAME store
|
|
8793
|
-
* `getGlobalSettings` reads, and narrowed to cluster-scoped fields.
|
|
8794
|
-
*
|
|
8795
|
-
* Returns `null` when the addon declared nothing — an addon that opts out has
|
|
8796
|
-
* no integration settings surface at all, rather than an empty one that reads
|
|
8797
|
-
* as a failed load.
|
|
8798
|
-
*
|
|
8799
|
-
* Three properties hold BY CONSTRUCTION, which is why they are here in core
|
|
8800
|
-
* and not in whichever UI happens to render this:
|
|
8801
|
-
*
|
|
8802
|
-
* 1. **One key.** The payload is a SUBSET of the global schema, so a field
|
|
8803
|
-
* shown here is the same field, with the same bare key, that the addon's
|
|
8804
|
-
* own page shows. There is no integration-specific writer — callers save
|
|
8805
|
-
* through `updateGlobalSettings` — so a second store key is unreachable,
|
|
8806
|
-
* not merely discouraged.
|
|
8807
|
-
* 2. **No node scope.** `perNode: true` fields are DROPPED. Their store key
|
|
8808
|
-
* is `<key>@<nodeId>` and an integration is not a node; whichever node
|
|
8809
|
-
* such a field silently picked would be a wrong answer for the operator
|
|
8810
|
-
* who opened the page (D266).
|
|
8811
|
-
* 3. **No silent typo.** A declared id that names no section throws. The
|
|
8812
|
-
* alternative — skip it — turns a rename into a surface that quietly
|
|
8813
|
-
* empties, which looks exactly like an addon with nothing to configure.
|
|
8814
|
-
*/
|
|
8815
|
-
/**
|
|
8816
|
-
* The form schema of ONE integration instance, or `null` to use {@link globalSettingsSchema}.
|
|
8765
|
+
* The form schema of ONE integration instance, or `null` to use the scoped form.
|
|
8817
8766
|
*
|
|
8818
8767
|
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
8819
8768
|
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
@@ -8986,6 +8935,19 @@ var BaseAddon = class {
|
|
|
8986
8935
|
const overlay = await this.scopedSettingsOverlay(scope, cap, nodeId);
|
|
8987
8936
|
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(stored, overlay) : stored, { inlineSecretsAsViews: true });
|
|
8988
8937
|
}
|
|
8938
|
+
/**
|
|
8939
|
+
* The scoped schemas this addon serves: one entry per loaded (capability, scope), capabilities
|
|
8940
|
+
* in declaration order, scopes in {@link SCOPED_SETTINGS_SCOPES} order. `[]` when it declares
|
|
8941
|
+
* nothing.
|
|
8942
|
+
*/
|
|
8943
|
+
async listScopedSettings() {
|
|
8944
|
+
await this.loadScopedSchemas();
|
|
8945
|
+
return [...this._scopedByCap].flatMap(([cap, entries]) => entries.map((entry) => ({
|
|
8946
|
+
cap,
|
|
8947
|
+
scope: entry.scope,
|
|
8948
|
+
sectionIds: entry.schema.sections.map((section) => section.id)
|
|
8949
|
+
})));
|
|
8950
|
+
}
|
|
8989
8951
|
/** The OPERATOR's write of declared keys of one scope (D787 secret semantics). */
|
|
8990
8952
|
async updateScopedSettings(scope, cap, patch, nodeId) {
|
|
8991
8953
|
this._operatorWriteDepth++;
|
|
@@ -9011,32 +8973,15 @@ var BaseAddon = class {
|
|
|
9011
8973
|
*/
|
|
9012
8974
|
async getIntegrationFormSchema(instance, nodeId) {
|
|
9013
8975
|
const scoped = await this.integrationFormSchema(instance);
|
|
9014
|
-
if (scoped === null) return this.
|
|
8976
|
+
if (scoped === null) return this.scopedForm(nodeId);
|
|
9015
8977
|
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
9016
8978
|
}
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
const schema = this.
|
|
9021
|
-
if (!schema)
|
|
9022
|
-
|
|
9023
|
-
const sections = [];
|
|
9024
|
-
for (const id of declared) {
|
|
9025
|
-
const section = byId.get(id);
|
|
9026
|
-
if (!section) throw new Error(`${this.constructor.name}: integrationSettingSections() names unknown section "${id}". Known sections: [${[...byId.keys()].join(", ")}].`);
|
|
9027
|
-
const fields = dropPerNodeFields(section.fields);
|
|
9028
|
-
if (fields.length === 0) continue;
|
|
9029
|
-
sections.push({
|
|
9030
|
-
...section,
|
|
9031
|
-
fields
|
|
9032
|
-
});
|
|
9033
|
-
}
|
|
9034
|
-
if (sections.length === 0) return null;
|
|
9035
|
-
const projected = await this.readRawProjectedStore(nodeId);
|
|
9036
|
-
return hydrateSchema({
|
|
9037
|
-
...schema,
|
|
9038
|
-
sections
|
|
9039
|
-
}, projected, { inlineSecretsAsViews: true });
|
|
8979
|
+
/** The form of the scoped schemas this addon declared, hydrated from its store. */
|
|
8980
|
+
async scopedForm(nodeId) {
|
|
8981
|
+
await this.loadScopedSchemas();
|
|
8982
|
+
const schema = this.scopedFormSchema();
|
|
8983
|
+
if (!schema) return { sections: [] };
|
|
8984
|
+
return hydrateSchema(schema, await this.readRawProjectedStore(nodeId), { inlineSecretsAsViews: true });
|
|
9040
8985
|
}
|
|
9041
8986
|
/**
|
|
9042
8987
|
* The raw addon store PROJECTED onto the target node's bare per-node keys:
|
|
@@ -9045,8 +8990,8 @@ var BaseAddon = class {
|
|
|
9045
8990
|
* bare fallback), all `@`-scoped and stray bare per-node keys are dropped.
|
|
9046
8991
|
* A no-op passthrough when the schema declares no `perNode` field.
|
|
9047
8992
|
*
|
|
9048
|
-
* This is the sanctioned way for
|
|
9049
|
-
* the store for custom
|
|
8993
|
+
* This is the sanctioned way for an addon that needs
|
|
8994
|
+
* the store for custom logic (option narrowing, value snapping) to
|
|
9050
8995
|
* read it per-node — never `ctx.settings.readAddonStore()` directly.
|
|
9051
8996
|
* `nodeId` omitted ⇒ the local node (node-blind injection from ctx).
|
|
9052
8997
|
*
|
|
@@ -9098,7 +9043,7 @@ var BaseAddon = class {
|
|
|
9098
9043
|
}
|
|
9099
9044
|
/**
|
|
9100
9045
|
* Whether ONE global key of this addon's store was written, read three-way
|
|
9101
|
-
* (D651). For a question a hydrated view cannot answer:
|
|
9046
|
+
* (D651). For a question a hydrated view cannot answer: a hydrated form
|
|
9102
9047
|
* reports `value ?? default`, so "the operator chose the default" and "nobody
|
|
9103
9048
|
* chose" look the same, and a failed read looks like both. A `perNode` key is
|
|
9104
9049
|
* not supported here: its stored name is scoped.
|
|
@@ -9132,7 +9077,7 @@ var BaseAddon = class {
|
|
|
9132
9077
|
}
|
|
9133
9078
|
/**
|
|
9134
9079
|
* The OPERATOR's write — a settings form or an admin API call, dispatched by
|
|
9135
|
-
* the kernel.
|
|
9080
|
+
* the kernel. The one in-process write of the addon blob that is not a scoped write; a secret
|
|
9136
9081
|
* the operator sends is stored as sent even when it equals a pre-keychain
|
|
9137
9082
|
* inline value: the operator re-entering a password is a change, an addon
|
|
9138
9083
|
* writing back what it read is not (D787).
|
|
@@ -9145,9 +9090,6 @@ var BaseAddon = class {
|
|
|
9145
9090
|
this._operatorWriteDepth--;
|
|
9146
9091
|
}
|
|
9147
9092
|
}
|
|
9148
|
-
async updateGlobalSettings(patch, nodeId) {
|
|
9149
|
-
await this.applyGlobalPatch(patch, nodeId);
|
|
9150
|
-
}
|
|
9151
9093
|
/**
|
|
9152
9094
|
* REMOVE stored secrets — their keychain values and their markers (D787).
|
|
9153
9095
|
*
|
|
@@ -9190,8 +9132,7 @@ var BaseAddon = class {
|
|
|
9190
9132
|
await this.resolveConfig();
|
|
9191
9133
|
await this.onConfigChanged();
|
|
9192
9134
|
this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
|
|
9193
|
-
|
|
9194
|
-
this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
|
|
9135
|
+
this.maybeAutoRestart(Object.keys(barePatch), this.loadedScopedSchemas().map((entry) => entry.schema));
|
|
9195
9136
|
return true;
|
|
9196
9137
|
}
|
|
9197
9138
|
/**
|
|
@@ -9229,10 +9170,7 @@ var BaseAddon = class {
|
|
|
9229
9170
|
this._nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
9230
9171
|
this._addonSecretTree = null;
|
|
9231
9172
|
}
|
|
9232
|
-
/**
|
|
9233
|
-
* The form the settings API serves while an addon declares no {@link globalSettingsSchema}: the
|
|
9234
|
-
* sections of its scoped schemas, so dropping the old hook does not blank the form.
|
|
9235
|
-
*/
|
|
9173
|
+
/** The form of an addon's scoped schemas: their sections, each shown once. */
|
|
9236
9174
|
scopedFormSchema(cap) {
|
|
9237
9175
|
const byId = /* @__PURE__ */ new Map();
|
|
9238
9176
|
for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
|
|
@@ -9244,8 +9182,7 @@ var BaseAddon = class {
|
|
|
9244
9182
|
return [...this._scopedByCap.values()].flat();
|
|
9245
9183
|
}
|
|
9246
9184
|
/**
|
|
9247
|
-
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}
|
|
9248
|
-
* the fields the legacy {@link globalSettingsSchema} still marks `perNode: true`. Derived once
|
|
9185
|
+
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}. Derived once
|
|
9249
9186
|
* per `cap` argument and memoized (schemas are static declarations). Empty set ⇒ every
|
|
9250
9187
|
* per-node code path is bypassed and the settings API behaves like the node-agnostic one.
|
|
9251
9188
|
* Call {@link loadScopedSchemas} first (the async seams do).
|
|
@@ -9254,8 +9191,7 @@ var BaseAddon = class {
|
|
|
9254
9191
|
const cacheKey = cap ?? "";
|
|
9255
9192
|
const cached = this._nodeKeysByCap.get(cacheKey);
|
|
9256
9193
|
if (cached) return cached;
|
|
9257
|
-
const
|
|
9258
|
-
const keys = new Set(legacy ? legacy.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
|
|
9194
|
+
const keys = /* @__PURE__ */ new Set();
|
|
9259
9195
|
for (const { scope, schema } of this.loadedScopedSchemas(cap)) {
|
|
9260
9196
|
if (scope !== "node") continue;
|
|
9261
9197
|
for (const section of schema.sections) for (const key of collectValueFieldKeys(section.fields)) keys.add(key);
|
|
@@ -9473,8 +9409,6 @@ var BaseAddon = class {
|
|
|
9473
9409
|
}
|
|
9474
9410
|
declaredKeySet() {
|
|
9475
9411
|
const keys = new Set(Object.keys(this.defaults));
|
|
9476
|
-
const schema = this.globalSettingsSchema();
|
|
9477
|
-
if (schema) for (const section of schema.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
9478
9412
|
for (const { schema: scoped } of this.loadedScopedSchemas()) for (const section of scoped.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
9479
9413
|
for (const key of this._declaredStateKeys) keys.add(key);
|
|
9480
9414
|
for (const path of this.secretStatePaths) {
|
|
@@ -9572,7 +9506,7 @@ var BaseAddon = class {
|
|
|
9572
9506
|
/** The addon store's secret tree: schema fields by TYPE, plus `secretStatePaths`. */
|
|
9573
9507
|
addonSecretTree() {
|
|
9574
9508
|
if (this._addonSecretTree === null) {
|
|
9575
|
-
const tree = new Map(
|
|
9509
|
+
const tree = /* @__PURE__ */ new Map();
|
|
9576
9510
|
for (const { schema } of this.loadedScopedSchemas()) for (const [key, node] of secretTreeFromSchema(schema)) tree.set(key, node);
|
|
9577
9511
|
this._addonSecretTree = mergeSecretStatePaths(tree, this.secretStatePaths);
|
|
9578
9512
|
}
|
|
@@ -9784,47 +9718,6 @@ function classifyStoreError(err) {
|
|
|
9784
9718
|
if (TRANSPORT_PHRASES.some((f) => message.includes(f))) return "transport";
|
|
9785
9719
|
return "permanent";
|
|
9786
9720
|
}
|
|
9787
|
-
/**
|
|
9788
|
-
* Collect the keys of every field marked `perNode: true`, recursing into
|
|
9789
|
-
* layout containers (`group` fields and `sub-tabs` tabs) the same way
|
|
9790
|
-
* `hydrateSchema` does. Valueless structural fields (separator/info/…)
|
|
9791
|
-
* don't declare `perNode` and are excluded by the `in` narrowing.
|
|
9792
|
-
*/
|
|
9793
|
-
/**
|
|
9794
|
-
* The same fields with every `perNode: true` one removed, recursing into layout
|
|
9795
|
-
* containers exactly as {@link collectPerNodeFieldKeys} does. A container left
|
|
9796
|
-
* with no child is dropped rather than rendered empty.
|
|
9797
|
-
*
|
|
9798
|
-
* Used by `getIntegrationSettings`: an integration is not a node, so a field
|
|
9799
|
-
* whose store key is `<key>@<nodeId>` has no node to belong to there.
|
|
9800
|
-
*/
|
|
9801
|
-
function dropPerNodeFields(fields) {
|
|
9802
|
-
const kept = [];
|
|
9803
|
-
for (const field of fields) {
|
|
9804
|
-
if (field.type === "group") {
|
|
9805
|
-
const inner = dropPerNodeFields(field.fields);
|
|
9806
|
-
if (inner.length > 0) kept.push({
|
|
9807
|
-
...field,
|
|
9808
|
-
fields: inner
|
|
9809
|
-
});
|
|
9810
|
-
continue;
|
|
9811
|
-
}
|
|
9812
|
-
if (field.type === "sub-tabs") {
|
|
9813
|
-
const tabs = field.tabs.map((tab) => ({
|
|
9814
|
-
...tab,
|
|
9815
|
-
fields: dropPerNodeFields(tab.fields)
|
|
9816
|
-
})).filter((tab) => tab.fields.length > 0);
|
|
9817
|
-
if (tabs.length > 0) kept.push({
|
|
9818
|
-
...field,
|
|
9819
|
-
tabs
|
|
9820
|
-
});
|
|
9821
|
-
continue;
|
|
9822
|
-
}
|
|
9823
|
-
if ("perNode" in field && field.perNode === true) continue;
|
|
9824
|
-
kept.push(field);
|
|
9825
|
-
}
|
|
9826
|
-
return kept;
|
|
9827
|
-
}
|
|
9828
9721
|
/** The keys of the value-holding fields, recursing into layout containers. */
|
|
9829
9722
|
function collectValueFieldKeys(fields) {
|
|
9830
9723
|
const collected = [];
|
|
@@ -9857,21 +9750,6 @@ function collectFieldKeys(fields) {
|
|
|
9857
9750
|
}
|
|
9858
9751
|
return collected;
|
|
9859
9752
|
}
|
|
9860
|
-
function collectPerNodeFieldKeys(fields) {
|
|
9861
|
-
const collected = [];
|
|
9862
|
-
for (const field of fields) {
|
|
9863
|
-
if (field.type === "group") {
|
|
9864
|
-
collected.push(...collectPerNodeFieldKeys(field.fields));
|
|
9865
|
-
continue;
|
|
9866
|
-
}
|
|
9867
|
-
if (field.type === "sub-tabs") {
|
|
9868
|
-
for (const tab of field.tabs) collected.push(...collectPerNodeFieldKeys(tab.fields));
|
|
9869
|
-
continue;
|
|
9870
|
-
}
|
|
9871
|
-
if ("perNode" in field && field.perNode === true) collected.push(field.key);
|
|
9872
|
-
}
|
|
9873
|
-
return collected;
|
|
9874
|
-
}
|
|
9875
9753
|
/**
|
|
9876
9754
|
* Normalize an `ICamstackAddon.initialize()` return value into the
|
|
9877
9755
|
* `AddonInitResult` envelope. Arrays are wrapped into `{ providers }`;
|
|
@@ -12632,13 +12510,25 @@ Object.freeze({
|
|
|
12632
12510
|
"path": "temperature",
|
|
12633
12511
|
"valueType": "number"
|
|
12634
12512
|
}],
|
|
12635
|
-
"timed-run": [
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12513
|
+
"timed-run": [
|
|
12514
|
+
{
|
|
12515
|
+
"path": "activeUntil",
|
|
12516
|
+
"valueType": "number"
|
|
12517
|
+
},
|
|
12518
|
+
{
|
|
12519
|
+
"path": "requestedBy",
|
|
12520
|
+
"valueType": "string"
|
|
12521
|
+
},
|
|
12522
|
+
{
|
|
12523
|
+
"path": "quickRun.duration",
|
|
12524
|
+
"valueType": "number"
|
|
12525
|
+
},
|
|
12526
|
+
{
|
|
12527
|
+
"path": "quickRun.unit",
|
|
12528
|
+
"valueType": "enum",
|
|
12529
|
+
"enumValues": ["s", "min"]
|
|
12530
|
+
}
|
|
12531
|
+
],
|
|
12642
12532
|
"update": [
|
|
12643
12533
|
{
|
|
12644
12534
|
"path": "currentVersion",
|
|
@@ -12862,7 +12752,7 @@ object({
|
|
|
12862
12752
|
params: record(string(), union([string(), number$1()])).optional()
|
|
12863
12753
|
});
|
|
12864
12754
|
//#endregion
|
|
12865
|
-
//#region ../types/dist/composition-
|
|
12755
|
+
//#region ../types/dist/composition-Bx0JvKUU.mjs
|
|
12866
12756
|
/**
|
|
12867
12757
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
12868
12758
|
*
|
|
@@ -14024,6 +13914,387 @@ var NodeColorIdSchema = _enum([
|
|
|
14024
13914
|
"node-h"
|
|
14025
13915
|
]);
|
|
14026
13916
|
//#endregion
|
|
13917
|
+
//#region ../types/dist/convert-BAzH15HU.mjs
|
|
13918
|
+
/**
|
|
13919
|
+
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
13920
|
+
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
13921
|
+
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
13922
|
+
* decimals). K derives from `°C = K − 273.15`.
|
|
13923
|
+
*/
|
|
13924
|
+
var UNIT_TABLE = {
|
|
13925
|
+
"°C": {
|
|
13926
|
+
dimension: "temperature",
|
|
13927
|
+
factor: 1,
|
|
13928
|
+
offset: 0
|
|
13929
|
+
},
|
|
13930
|
+
"°F": {
|
|
13931
|
+
dimension: "temperature",
|
|
13932
|
+
factor: 5 / 9,
|
|
13933
|
+
offset: -160 / 9
|
|
13934
|
+
},
|
|
13935
|
+
K: {
|
|
13936
|
+
dimension: "temperature",
|
|
13937
|
+
factor: 1,
|
|
13938
|
+
offset: -273.15
|
|
13939
|
+
},
|
|
13940
|
+
hPa: {
|
|
13941
|
+
dimension: "pressure",
|
|
13942
|
+
factor: 1,
|
|
13943
|
+
offset: 0
|
|
13944
|
+
},
|
|
13945
|
+
kPa: {
|
|
13946
|
+
dimension: "pressure",
|
|
13947
|
+
factor: 10,
|
|
13948
|
+
offset: 0
|
|
13949
|
+
},
|
|
13950
|
+
Pa: {
|
|
13951
|
+
dimension: "pressure",
|
|
13952
|
+
factor: .01,
|
|
13953
|
+
offset: 0
|
|
13954
|
+
},
|
|
13955
|
+
mbar: {
|
|
13956
|
+
dimension: "pressure",
|
|
13957
|
+
factor: 1,
|
|
13958
|
+
offset: 0
|
|
13959
|
+
},
|
|
13960
|
+
bar: {
|
|
13961
|
+
dimension: "pressure",
|
|
13962
|
+
factor: 1e3,
|
|
13963
|
+
offset: 0
|
|
13964
|
+
},
|
|
13965
|
+
inHg: {
|
|
13966
|
+
dimension: "pressure",
|
|
13967
|
+
factor: 33.8639,
|
|
13968
|
+
offset: 0
|
|
13969
|
+
},
|
|
13970
|
+
mmHg: {
|
|
13971
|
+
dimension: "pressure",
|
|
13972
|
+
factor: 1.33322,
|
|
13973
|
+
offset: 0
|
|
13974
|
+
},
|
|
13975
|
+
psi: {
|
|
13976
|
+
dimension: "pressure",
|
|
13977
|
+
factor: 68.9476,
|
|
13978
|
+
offset: 0
|
|
13979
|
+
},
|
|
13980
|
+
"m/s": {
|
|
13981
|
+
dimension: "speed",
|
|
13982
|
+
factor: 1,
|
|
13983
|
+
offset: 0
|
|
13984
|
+
},
|
|
13985
|
+
"km/h": {
|
|
13986
|
+
dimension: "speed",
|
|
13987
|
+
factor: 1 / 3.6,
|
|
13988
|
+
offset: 0
|
|
13989
|
+
},
|
|
13990
|
+
mph: {
|
|
13991
|
+
dimension: "speed",
|
|
13992
|
+
factor: .44704,
|
|
13993
|
+
offset: 0
|
|
13994
|
+
},
|
|
13995
|
+
kn: {
|
|
13996
|
+
dimension: "speed",
|
|
13997
|
+
factor: .514444,
|
|
13998
|
+
offset: 0
|
|
13999
|
+
},
|
|
14000
|
+
"mm/h": {
|
|
14001
|
+
dimension: "precipitation-rate",
|
|
14002
|
+
factor: 1,
|
|
14003
|
+
offset: 0
|
|
14004
|
+
},
|
|
14005
|
+
"in/h": {
|
|
14006
|
+
dimension: "precipitation-rate",
|
|
14007
|
+
factor: 25.4,
|
|
14008
|
+
offset: 0
|
|
14009
|
+
},
|
|
14010
|
+
m: {
|
|
14011
|
+
dimension: "length",
|
|
14012
|
+
factor: 1,
|
|
14013
|
+
offset: 0
|
|
14014
|
+
},
|
|
14015
|
+
mm: {
|
|
14016
|
+
dimension: "length",
|
|
14017
|
+
factor: .001,
|
|
14018
|
+
offset: 0
|
|
14019
|
+
},
|
|
14020
|
+
cm: {
|
|
14021
|
+
dimension: "length",
|
|
14022
|
+
factor: .01,
|
|
14023
|
+
offset: 0
|
|
14024
|
+
},
|
|
14025
|
+
km: {
|
|
14026
|
+
dimension: "length",
|
|
14027
|
+
factor: 1e3,
|
|
14028
|
+
offset: 0
|
|
14029
|
+
},
|
|
14030
|
+
in: {
|
|
14031
|
+
dimension: "length",
|
|
14032
|
+
factor: .0254,
|
|
14033
|
+
offset: 0
|
|
14034
|
+
},
|
|
14035
|
+
ft: {
|
|
14036
|
+
dimension: "length",
|
|
14037
|
+
factor: .3048,
|
|
14038
|
+
offset: 0
|
|
14039
|
+
},
|
|
14040
|
+
mi: {
|
|
14041
|
+
dimension: "length",
|
|
14042
|
+
factor: 1609.344,
|
|
14043
|
+
offset: 0
|
|
14044
|
+
},
|
|
14045
|
+
"m²": {
|
|
14046
|
+
dimension: "area",
|
|
14047
|
+
factor: 1,
|
|
14048
|
+
offset: 0
|
|
14049
|
+
},
|
|
14050
|
+
lx: {
|
|
14051
|
+
dimension: "illuminance",
|
|
14052
|
+
factor: 1,
|
|
14053
|
+
offset: 0
|
|
14054
|
+
},
|
|
14055
|
+
"W/m²": {
|
|
14056
|
+
dimension: "irradiance",
|
|
14057
|
+
factor: 1,
|
|
14058
|
+
offset: 0
|
|
14059
|
+
},
|
|
14060
|
+
W: {
|
|
14061
|
+
dimension: "power",
|
|
14062
|
+
factor: 1,
|
|
14063
|
+
offset: 0
|
|
14064
|
+
},
|
|
14065
|
+
kW: {
|
|
14066
|
+
dimension: "power",
|
|
14067
|
+
factor: 1e3,
|
|
14068
|
+
offset: 0
|
|
14069
|
+
},
|
|
14070
|
+
VA: {
|
|
14071
|
+
dimension: "apparent-power",
|
|
14072
|
+
factor: 1,
|
|
14073
|
+
offset: 0
|
|
14074
|
+
},
|
|
14075
|
+
Wh: {
|
|
14076
|
+
dimension: "energy",
|
|
14077
|
+
factor: 1,
|
|
14078
|
+
offset: 0
|
|
14079
|
+
},
|
|
14080
|
+
kWh: {
|
|
14081
|
+
dimension: "energy",
|
|
14082
|
+
factor: 1e3,
|
|
14083
|
+
offset: 0
|
|
14084
|
+
},
|
|
14085
|
+
MWh: {
|
|
14086
|
+
dimension: "energy",
|
|
14087
|
+
factor: 1e6,
|
|
14088
|
+
offset: 0
|
|
14089
|
+
},
|
|
14090
|
+
V: {
|
|
14091
|
+
dimension: "voltage",
|
|
14092
|
+
factor: 1,
|
|
14093
|
+
offset: 0
|
|
14094
|
+
},
|
|
14095
|
+
mV: {
|
|
14096
|
+
dimension: "voltage",
|
|
14097
|
+
factor: .001,
|
|
14098
|
+
offset: 0
|
|
14099
|
+
},
|
|
14100
|
+
A: {
|
|
14101
|
+
dimension: "current",
|
|
14102
|
+
factor: 1,
|
|
14103
|
+
offset: 0
|
|
14104
|
+
},
|
|
14105
|
+
mA: {
|
|
14106
|
+
dimension: "current",
|
|
14107
|
+
factor: .001,
|
|
14108
|
+
offset: 0
|
|
14109
|
+
},
|
|
14110
|
+
ppm: {
|
|
14111
|
+
dimension: "concentration-volume",
|
|
14112
|
+
factor: 1,
|
|
14113
|
+
offset: 0
|
|
14114
|
+
},
|
|
14115
|
+
ppb: {
|
|
14116
|
+
dimension: "concentration-volume",
|
|
14117
|
+
factor: .001,
|
|
14118
|
+
offset: 0
|
|
14119
|
+
},
|
|
14120
|
+
"µg/m³": {
|
|
14121
|
+
dimension: "concentration-mass",
|
|
14122
|
+
factor: 1,
|
|
14123
|
+
offset: 0
|
|
14124
|
+
},
|
|
14125
|
+
"mg/m³": {
|
|
14126
|
+
dimension: "concentration-mass",
|
|
14127
|
+
factor: 1e3,
|
|
14128
|
+
offset: 0
|
|
14129
|
+
},
|
|
14130
|
+
kg: {
|
|
14131
|
+
dimension: "mass",
|
|
14132
|
+
factor: 1,
|
|
14133
|
+
offset: 0
|
|
14134
|
+
},
|
|
14135
|
+
g: {
|
|
14136
|
+
dimension: "mass",
|
|
14137
|
+
factor: .001,
|
|
14138
|
+
offset: 0
|
|
14139
|
+
},
|
|
14140
|
+
lb: {
|
|
14141
|
+
dimension: "mass",
|
|
14142
|
+
factor: .453592,
|
|
14143
|
+
offset: 0
|
|
14144
|
+
},
|
|
14145
|
+
oz: {
|
|
14146
|
+
dimension: "mass",
|
|
14147
|
+
factor: .0283495,
|
|
14148
|
+
offset: 0
|
|
14149
|
+
},
|
|
14150
|
+
"%": {
|
|
14151
|
+
dimension: "percentage",
|
|
14152
|
+
factor: 1,
|
|
14153
|
+
offset: 0
|
|
14154
|
+
},
|
|
14155
|
+
L: {
|
|
14156
|
+
dimension: "volume",
|
|
14157
|
+
factor: 1,
|
|
14158
|
+
offset: 0
|
|
14159
|
+
},
|
|
14160
|
+
mL: {
|
|
14161
|
+
dimension: "volume",
|
|
14162
|
+
factor: .001,
|
|
14163
|
+
offset: 0
|
|
14164
|
+
},
|
|
14165
|
+
gal: {
|
|
14166
|
+
dimension: "volume",
|
|
14167
|
+
factor: 3.785411784,
|
|
14168
|
+
offset: 0
|
|
14169
|
+
},
|
|
14170
|
+
s: {
|
|
14171
|
+
dimension: "duration",
|
|
14172
|
+
factor: 1,
|
|
14173
|
+
offset: 0
|
|
14174
|
+
},
|
|
14175
|
+
ms: {
|
|
14176
|
+
dimension: "duration",
|
|
14177
|
+
factor: .001,
|
|
14178
|
+
offset: 0
|
|
14179
|
+
},
|
|
14180
|
+
min: {
|
|
14181
|
+
dimension: "duration",
|
|
14182
|
+
factor: 60,
|
|
14183
|
+
offset: 0
|
|
14184
|
+
},
|
|
14185
|
+
h: {
|
|
14186
|
+
dimension: "duration",
|
|
14187
|
+
factor: 3600,
|
|
14188
|
+
offset: 0
|
|
14189
|
+
},
|
|
14190
|
+
d: {
|
|
14191
|
+
dimension: "duration",
|
|
14192
|
+
factor: 86400,
|
|
14193
|
+
offset: 0
|
|
14194
|
+
},
|
|
14195
|
+
B: {
|
|
14196
|
+
dimension: "information",
|
|
14197
|
+
factor: 1,
|
|
14198
|
+
offset: 0
|
|
14199
|
+
},
|
|
14200
|
+
KiB: {
|
|
14201
|
+
dimension: "information",
|
|
14202
|
+
factor: 1024,
|
|
14203
|
+
offset: 0
|
|
14204
|
+
},
|
|
14205
|
+
MiB: {
|
|
14206
|
+
dimension: "information",
|
|
14207
|
+
factor: 1024 ** 2,
|
|
14208
|
+
offset: 0
|
|
14209
|
+
},
|
|
14210
|
+
GiB: {
|
|
14211
|
+
dimension: "information",
|
|
14212
|
+
factor: 1024 ** 3,
|
|
14213
|
+
offset: 0
|
|
14214
|
+
},
|
|
14215
|
+
TiB: {
|
|
14216
|
+
dimension: "information",
|
|
14217
|
+
factor: 1024 ** 4,
|
|
14218
|
+
offset: 0
|
|
14219
|
+
},
|
|
14220
|
+
kB: {
|
|
14221
|
+
dimension: "information",
|
|
14222
|
+
factor: 1e3,
|
|
14223
|
+
offset: 0
|
|
14224
|
+
},
|
|
14225
|
+
MB: {
|
|
14226
|
+
dimension: "information",
|
|
14227
|
+
factor: 1e6,
|
|
14228
|
+
offset: 0
|
|
14229
|
+
},
|
|
14230
|
+
GB: {
|
|
14231
|
+
dimension: "information",
|
|
14232
|
+
factor: 1e9,
|
|
14233
|
+
offset: 0
|
|
14234
|
+
},
|
|
14235
|
+
"°": {
|
|
14236
|
+
dimension: "angle",
|
|
14237
|
+
factor: 1,
|
|
14238
|
+
offset: 0
|
|
14239
|
+
},
|
|
14240
|
+
dBFS: {
|
|
14241
|
+
dimension: "sound-level",
|
|
14242
|
+
factor: 1,
|
|
14243
|
+
offset: 0
|
|
14244
|
+
},
|
|
14245
|
+
dBm: {
|
|
14246
|
+
dimension: "signal-level",
|
|
14247
|
+
factor: 1,
|
|
14248
|
+
offset: 0
|
|
14249
|
+
},
|
|
14250
|
+
mired: {
|
|
14251
|
+
dimension: "colour-temperature",
|
|
14252
|
+
factor: 1,
|
|
14253
|
+
offset: 0
|
|
14254
|
+
},
|
|
14255
|
+
kbps: {
|
|
14256
|
+
dimension: "bitrate",
|
|
14257
|
+
factor: 1,
|
|
14258
|
+
offset: 0
|
|
14259
|
+
},
|
|
14260
|
+
Mbps: {
|
|
14261
|
+
dimension: "bitrate",
|
|
14262
|
+
factor: 1e3,
|
|
14263
|
+
offset: 0
|
|
14264
|
+
},
|
|
14265
|
+
fps: {
|
|
14266
|
+
dimension: "rate",
|
|
14267
|
+
factor: 1,
|
|
14268
|
+
offset: 0
|
|
14269
|
+
}
|
|
14270
|
+
};
|
|
14271
|
+
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
14272
|
+
function specFor(unit) {
|
|
14273
|
+
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
14274
|
+
}
|
|
14275
|
+
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
14276
|
+
function toCanonical(value, spec) {
|
|
14277
|
+
return value * spec.factor + spec.offset;
|
|
14278
|
+
}
|
|
14279
|
+
/** Canonical-unit value → the unit described by `spec`. */
|
|
14280
|
+
function fromCanonical(canonical, spec) {
|
|
14281
|
+
return (canonical - spec.offset) / spec.factor;
|
|
14282
|
+
}
|
|
14283
|
+
/**
|
|
14284
|
+
* Graceful variant for the render path: returns the converted value, or
|
|
14285
|
+
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
14286
|
+
* Never throws — a render caller falls back to the raw value + source unit.
|
|
14287
|
+
*/
|
|
14288
|
+
function tryConvertUnit(value, from, to) {
|
|
14289
|
+
if (from === to) return value;
|
|
14290
|
+
const fromSpec = specFor(from);
|
|
14291
|
+
if (!fromSpec) return void 0;
|
|
14292
|
+
const toSpec = specFor(to);
|
|
14293
|
+
if (!toSpec) return void 0;
|
|
14294
|
+
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
14295
|
+
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
14296
|
+
}
|
|
14297
|
+
//#endregion
|
|
14027
14298
|
//#region ../types/dist/index.mjs
|
|
14028
14299
|
var SMTP_INBOUND_DEFAULT_PORT = 2525;
|
|
14029
14300
|
var SMTP_INBOUND_DEFAULT_DOMAIN = "camstack.local";
|
|
@@ -15091,43 +15362,44 @@ function notificationTargetParts(records, spec) {
|
|
|
15091
15362
|
const defined = spec.kinds[notificationTargetKindName(descriptor.kind)];
|
|
15092
15363
|
if (defined === void 0) return [];
|
|
15093
15364
|
const canTest = spec.probe !== void 0 && spec.canProbe(descriptor.kind);
|
|
15094
|
-
const
|
|
15095
|
-
|
|
15096
|
-
|
|
15097
|
-
|
|
15098
|
-
|
|
15099
|
-
|
|
15100
|
-
|
|
15101
|
-
formSchema: () => formOf(descriptor),
|
|
15102
|
-
initialBody: (name) => ({ name }),
|
|
15103
|
-
mintId: () => spec.mintId(),
|
|
15104
|
-
configured: () => true,
|
|
15105
|
-
validateWrite: ({ body }) => spec.validate?.({
|
|
15106
|
-
kind: descriptor.kind,
|
|
15107
|
-
config: body
|
|
15108
|
-
}),
|
|
15109
|
-
test: async ({ id, values }) => {
|
|
15110
|
-
if (spec.probe === void 0 || !canTest) return {
|
|
15111
|
-
success: false,
|
|
15112
|
-
status: "unsupported",
|
|
15113
|
-
error: "This kind cannot be tested"
|
|
15114
|
-
};
|
|
15115
|
-
return probeToTestResult(await spec.probe({
|
|
15116
|
-
kind: descriptor.kind,
|
|
15117
|
-
config: values,
|
|
15118
|
-
targetId: id ?? void 0
|
|
15119
|
-
}));
|
|
15120
|
-
}
|
|
15121
|
-
});
|
|
15365
|
+
const kind = {
|
|
15366
|
+
id: descriptor.kind,
|
|
15367
|
+
label: descriptor.label,
|
|
15368
|
+
functionCap: NOTIFICATION_OUTPUT_CAP,
|
|
15369
|
+
role: "services",
|
|
15370
|
+
canTest
|
|
15371
|
+
};
|
|
15122
15372
|
return [{
|
|
15123
|
-
kind
|
|
15124
|
-
|
|
15125
|
-
|
|
15126
|
-
|
|
15127
|
-
|
|
15128
|
-
|
|
15129
|
-
|
|
15130
|
-
|
|
15373
|
+
kind,
|
|
15374
|
+
provider: new RecordIntegrationInstances(records, defined, {
|
|
15375
|
+
description: {
|
|
15376
|
+
role: "services",
|
|
15377
|
+
instanceMode: "multiple",
|
|
15378
|
+
kind: "target",
|
|
15379
|
+
canTest,
|
|
15380
|
+
kinds: [kind]
|
|
15381
|
+
},
|
|
15382
|
+
formSchema: () => formOf(descriptor),
|
|
15383
|
+
initialBody: (name) => ({ name }),
|
|
15384
|
+
mintId: () => spec.mintId(),
|
|
15385
|
+
configured: () => true,
|
|
15386
|
+
validateWrite: ({ body }) => spec.validate?.({
|
|
15387
|
+
kind: descriptor.kind,
|
|
15388
|
+
config: body
|
|
15389
|
+
}),
|
|
15390
|
+
test: async ({ id, values }) => {
|
|
15391
|
+
if (spec.probe === void 0 || !canTest) return {
|
|
15392
|
+
success: false,
|
|
15393
|
+
status: "unsupported",
|
|
15394
|
+
error: "This kind cannot be tested"
|
|
15395
|
+
};
|
|
15396
|
+
return probeToTestResult(await spec.probe({
|
|
15397
|
+
kind: descriptor.kind,
|
|
15398
|
+
config: values,
|
|
15399
|
+
targetId: id ?? void 0
|
|
15400
|
+
}));
|
|
15401
|
+
}
|
|
15402
|
+
}).toProvider()
|
|
15131
15403
|
}];
|
|
15132
15404
|
});
|
|
15133
15405
|
}
|
|
@@ -43488,6 +43760,7 @@ var ExpressionBindingSourceSchema = union([
|
|
|
43488
43760
|
object({
|
|
43489
43761
|
kind: literal("global"),
|
|
43490
43762
|
sourceStableId: string(),
|
|
43763
|
+
addonId: string().optional(),
|
|
43491
43764
|
cap: string(),
|
|
43492
43765
|
fieldPath: string()
|
|
43493
43766
|
})
|
|
@@ -43614,385 +43887,6 @@ function extractSourceInfoFromMetadata(metadata) {
|
|
|
43614
43887
|
return parsed.data;
|
|
43615
43888
|
}
|
|
43616
43889
|
/**
|
|
43617
|
-
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
43618
|
-
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
43619
|
-
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
43620
|
-
* decimals). K derives from `°C = K − 273.15`.
|
|
43621
|
-
*/
|
|
43622
|
-
var UNIT_TABLE = {
|
|
43623
|
-
"°C": {
|
|
43624
|
-
dimension: "temperature",
|
|
43625
|
-
factor: 1,
|
|
43626
|
-
offset: 0
|
|
43627
|
-
},
|
|
43628
|
-
"°F": {
|
|
43629
|
-
dimension: "temperature",
|
|
43630
|
-
factor: 5 / 9,
|
|
43631
|
-
offset: -160 / 9
|
|
43632
|
-
},
|
|
43633
|
-
K: {
|
|
43634
|
-
dimension: "temperature",
|
|
43635
|
-
factor: 1,
|
|
43636
|
-
offset: -273.15
|
|
43637
|
-
},
|
|
43638
|
-
hPa: {
|
|
43639
|
-
dimension: "pressure",
|
|
43640
|
-
factor: 1,
|
|
43641
|
-
offset: 0
|
|
43642
|
-
},
|
|
43643
|
-
kPa: {
|
|
43644
|
-
dimension: "pressure",
|
|
43645
|
-
factor: 10,
|
|
43646
|
-
offset: 0
|
|
43647
|
-
},
|
|
43648
|
-
Pa: {
|
|
43649
|
-
dimension: "pressure",
|
|
43650
|
-
factor: .01,
|
|
43651
|
-
offset: 0
|
|
43652
|
-
},
|
|
43653
|
-
mbar: {
|
|
43654
|
-
dimension: "pressure",
|
|
43655
|
-
factor: 1,
|
|
43656
|
-
offset: 0
|
|
43657
|
-
},
|
|
43658
|
-
bar: {
|
|
43659
|
-
dimension: "pressure",
|
|
43660
|
-
factor: 1e3,
|
|
43661
|
-
offset: 0
|
|
43662
|
-
},
|
|
43663
|
-
inHg: {
|
|
43664
|
-
dimension: "pressure",
|
|
43665
|
-
factor: 33.8639,
|
|
43666
|
-
offset: 0
|
|
43667
|
-
},
|
|
43668
|
-
mmHg: {
|
|
43669
|
-
dimension: "pressure",
|
|
43670
|
-
factor: 1.33322,
|
|
43671
|
-
offset: 0
|
|
43672
|
-
},
|
|
43673
|
-
psi: {
|
|
43674
|
-
dimension: "pressure",
|
|
43675
|
-
factor: 68.9476,
|
|
43676
|
-
offset: 0
|
|
43677
|
-
},
|
|
43678
|
-
"m/s": {
|
|
43679
|
-
dimension: "speed",
|
|
43680
|
-
factor: 1,
|
|
43681
|
-
offset: 0
|
|
43682
|
-
},
|
|
43683
|
-
"km/h": {
|
|
43684
|
-
dimension: "speed",
|
|
43685
|
-
factor: 1 / 3.6,
|
|
43686
|
-
offset: 0
|
|
43687
|
-
},
|
|
43688
|
-
mph: {
|
|
43689
|
-
dimension: "speed",
|
|
43690
|
-
factor: .44704,
|
|
43691
|
-
offset: 0
|
|
43692
|
-
},
|
|
43693
|
-
kn: {
|
|
43694
|
-
dimension: "speed",
|
|
43695
|
-
factor: .514444,
|
|
43696
|
-
offset: 0
|
|
43697
|
-
},
|
|
43698
|
-
"mm/h": {
|
|
43699
|
-
dimension: "precipitation-rate",
|
|
43700
|
-
factor: 1,
|
|
43701
|
-
offset: 0
|
|
43702
|
-
},
|
|
43703
|
-
"in/h": {
|
|
43704
|
-
dimension: "precipitation-rate",
|
|
43705
|
-
factor: 25.4,
|
|
43706
|
-
offset: 0
|
|
43707
|
-
},
|
|
43708
|
-
m: {
|
|
43709
|
-
dimension: "length",
|
|
43710
|
-
factor: 1,
|
|
43711
|
-
offset: 0
|
|
43712
|
-
},
|
|
43713
|
-
mm: {
|
|
43714
|
-
dimension: "length",
|
|
43715
|
-
factor: .001,
|
|
43716
|
-
offset: 0
|
|
43717
|
-
},
|
|
43718
|
-
cm: {
|
|
43719
|
-
dimension: "length",
|
|
43720
|
-
factor: .01,
|
|
43721
|
-
offset: 0
|
|
43722
|
-
},
|
|
43723
|
-
km: {
|
|
43724
|
-
dimension: "length",
|
|
43725
|
-
factor: 1e3,
|
|
43726
|
-
offset: 0
|
|
43727
|
-
},
|
|
43728
|
-
in: {
|
|
43729
|
-
dimension: "length",
|
|
43730
|
-
factor: .0254,
|
|
43731
|
-
offset: 0
|
|
43732
|
-
},
|
|
43733
|
-
ft: {
|
|
43734
|
-
dimension: "length",
|
|
43735
|
-
factor: .3048,
|
|
43736
|
-
offset: 0
|
|
43737
|
-
},
|
|
43738
|
-
mi: {
|
|
43739
|
-
dimension: "length",
|
|
43740
|
-
factor: 1609.344,
|
|
43741
|
-
offset: 0
|
|
43742
|
-
},
|
|
43743
|
-
"m²": {
|
|
43744
|
-
dimension: "area",
|
|
43745
|
-
factor: 1,
|
|
43746
|
-
offset: 0
|
|
43747
|
-
},
|
|
43748
|
-
lx: {
|
|
43749
|
-
dimension: "illuminance",
|
|
43750
|
-
factor: 1,
|
|
43751
|
-
offset: 0
|
|
43752
|
-
},
|
|
43753
|
-
"W/m²": {
|
|
43754
|
-
dimension: "irradiance",
|
|
43755
|
-
factor: 1,
|
|
43756
|
-
offset: 0
|
|
43757
|
-
},
|
|
43758
|
-
W: {
|
|
43759
|
-
dimension: "power",
|
|
43760
|
-
factor: 1,
|
|
43761
|
-
offset: 0
|
|
43762
|
-
},
|
|
43763
|
-
kW: {
|
|
43764
|
-
dimension: "power",
|
|
43765
|
-
factor: 1e3,
|
|
43766
|
-
offset: 0
|
|
43767
|
-
},
|
|
43768
|
-
VA: {
|
|
43769
|
-
dimension: "apparent-power",
|
|
43770
|
-
factor: 1,
|
|
43771
|
-
offset: 0
|
|
43772
|
-
},
|
|
43773
|
-
Wh: {
|
|
43774
|
-
dimension: "energy",
|
|
43775
|
-
factor: 1,
|
|
43776
|
-
offset: 0
|
|
43777
|
-
},
|
|
43778
|
-
kWh: {
|
|
43779
|
-
dimension: "energy",
|
|
43780
|
-
factor: 1e3,
|
|
43781
|
-
offset: 0
|
|
43782
|
-
},
|
|
43783
|
-
MWh: {
|
|
43784
|
-
dimension: "energy",
|
|
43785
|
-
factor: 1e6,
|
|
43786
|
-
offset: 0
|
|
43787
|
-
},
|
|
43788
|
-
V: {
|
|
43789
|
-
dimension: "voltage",
|
|
43790
|
-
factor: 1,
|
|
43791
|
-
offset: 0
|
|
43792
|
-
},
|
|
43793
|
-
mV: {
|
|
43794
|
-
dimension: "voltage",
|
|
43795
|
-
factor: .001,
|
|
43796
|
-
offset: 0
|
|
43797
|
-
},
|
|
43798
|
-
A: {
|
|
43799
|
-
dimension: "current",
|
|
43800
|
-
factor: 1,
|
|
43801
|
-
offset: 0
|
|
43802
|
-
},
|
|
43803
|
-
mA: {
|
|
43804
|
-
dimension: "current",
|
|
43805
|
-
factor: .001,
|
|
43806
|
-
offset: 0
|
|
43807
|
-
},
|
|
43808
|
-
ppm: {
|
|
43809
|
-
dimension: "concentration-volume",
|
|
43810
|
-
factor: 1,
|
|
43811
|
-
offset: 0
|
|
43812
|
-
},
|
|
43813
|
-
ppb: {
|
|
43814
|
-
dimension: "concentration-volume",
|
|
43815
|
-
factor: .001,
|
|
43816
|
-
offset: 0
|
|
43817
|
-
},
|
|
43818
|
-
"µg/m³": {
|
|
43819
|
-
dimension: "concentration-mass",
|
|
43820
|
-
factor: 1,
|
|
43821
|
-
offset: 0
|
|
43822
|
-
},
|
|
43823
|
-
"mg/m³": {
|
|
43824
|
-
dimension: "concentration-mass",
|
|
43825
|
-
factor: 1e3,
|
|
43826
|
-
offset: 0
|
|
43827
|
-
},
|
|
43828
|
-
kg: {
|
|
43829
|
-
dimension: "mass",
|
|
43830
|
-
factor: 1,
|
|
43831
|
-
offset: 0
|
|
43832
|
-
},
|
|
43833
|
-
g: {
|
|
43834
|
-
dimension: "mass",
|
|
43835
|
-
factor: .001,
|
|
43836
|
-
offset: 0
|
|
43837
|
-
},
|
|
43838
|
-
lb: {
|
|
43839
|
-
dimension: "mass",
|
|
43840
|
-
factor: .453592,
|
|
43841
|
-
offset: 0
|
|
43842
|
-
},
|
|
43843
|
-
oz: {
|
|
43844
|
-
dimension: "mass",
|
|
43845
|
-
factor: .0283495,
|
|
43846
|
-
offset: 0
|
|
43847
|
-
},
|
|
43848
|
-
"%": {
|
|
43849
|
-
dimension: "percentage",
|
|
43850
|
-
factor: 1,
|
|
43851
|
-
offset: 0
|
|
43852
|
-
},
|
|
43853
|
-
L: {
|
|
43854
|
-
dimension: "volume",
|
|
43855
|
-
factor: 1,
|
|
43856
|
-
offset: 0
|
|
43857
|
-
},
|
|
43858
|
-
mL: {
|
|
43859
|
-
dimension: "volume",
|
|
43860
|
-
factor: .001,
|
|
43861
|
-
offset: 0
|
|
43862
|
-
},
|
|
43863
|
-
gal: {
|
|
43864
|
-
dimension: "volume",
|
|
43865
|
-
factor: 3.785411784,
|
|
43866
|
-
offset: 0
|
|
43867
|
-
},
|
|
43868
|
-
s: {
|
|
43869
|
-
dimension: "duration",
|
|
43870
|
-
factor: 1,
|
|
43871
|
-
offset: 0
|
|
43872
|
-
},
|
|
43873
|
-
ms: {
|
|
43874
|
-
dimension: "duration",
|
|
43875
|
-
factor: .001,
|
|
43876
|
-
offset: 0
|
|
43877
|
-
},
|
|
43878
|
-
min: {
|
|
43879
|
-
dimension: "duration",
|
|
43880
|
-
factor: 60,
|
|
43881
|
-
offset: 0
|
|
43882
|
-
},
|
|
43883
|
-
h: {
|
|
43884
|
-
dimension: "duration",
|
|
43885
|
-
factor: 3600,
|
|
43886
|
-
offset: 0
|
|
43887
|
-
},
|
|
43888
|
-
d: {
|
|
43889
|
-
dimension: "duration",
|
|
43890
|
-
factor: 86400,
|
|
43891
|
-
offset: 0
|
|
43892
|
-
},
|
|
43893
|
-
B: {
|
|
43894
|
-
dimension: "information",
|
|
43895
|
-
factor: 1,
|
|
43896
|
-
offset: 0
|
|
43897
|
-
},
|
|
43898
|
-
KiB: {
|
|
43899
|
-
dimension: "information",
|
|
43900
|
-
factor: 1024,
|
|
43901
|
-
offset: 0
|
|
43902
|
-
},
|
|
43903
|
-
MiB: {
|
|
43904
|
-
dimension: "information",
|
|
43905
|
-
factor: 1024 ** 2,
|
|
43906
|
-
offset: 0
|
|
43907
|
-
},
|
|
43908
|
-
GiB: {
|
|
43909
|
-
dimension: "information",
|
|
43910
|
-
factor: 1024 ** 3,
|
|
43911
|
-
offset: 0
|
|
43912
|
-
},
|
|
43913
|
-
TiB: {
|
|
43914
|
-
dimension: "information",
|
|
43915
|
-
factor: 1024 ** 4,
|
|
43916
|
-
offset: 0
|
|
43917
|
-
},
|
|
43918
|
-
kB: {
|
|
43919
|
-
dimension: "information",
|
|
43920
|
-
factor: 1e3,
|
|
43921
|
-
offset: 0
|
|
43922
|
-
},
|
|
43923
|
-
MB: {
|
|
43924
|
-
dimension: "information",
|
|
43925
|
-
factor: 1e6,
|
|
43926
|
-
offset: 0
|
|
43927
|
-
},
|
|
43928
|
-
GB: {
|
|
43929
|
-
dimension: "information",
|
|
43930
|
-
factor: 1e9,
|
|
43931
|
-
offset: 0
|
|
43932
|
-
},
|
|
43933
|
-
"°": {
|
|
43934
|
-
dimension: "angle",
|
|
43935
|
-
factor: 1,
|
|
43936
|
-
offset: 0
|
|
43937
|
-
},
|
|
43938
|
-
dBFS: {
|
|
43939
|
-
dimension: "sound-level",
|
|
43940
|
-
factor: 1,
|
|
43941
|
-
offset: 0
|
|
43942
|
-
},
|
|
43943
|
-
dBm: {
|
|
43944
|
-
dimension: "signal-level",
|
|
43945
|
-
factor: 1,
|
|
43946
|
-
offset: 0
|
|
43947
|
-
},
|
|
43948
|
-
mired: {
|
|
43949
|
-
dimension: "colour-temperature",
|
|
43950
|
-
factor: 1,
|
|
43951
|
-
offset: 0
|
|
43952
|
-
},
|
|
43953
|
-
kbps: {
|
|
43954
|
-
dimension: "bitrate",
|
|
43955
|
-
factor: 1,
|
|
43956
|
-
offset: 0
|
|
43957
|
-
},
|
|
43958
|
-
Mbps: {
|
|
43959
|
-
dimension: "bitrate",
|
|
43960
|
-
factor: 1e3,
|
|
43961
|
-
offset: 0
|
|
43962
|
-
},
|
|
43963
|
-
fps: {
|
|
43964
|
-
dimension: "rate",
|
|
43965
|
-
factor: 1,
|
|
43966
|
-
offset: 0
|
|
43967
|
-
}
|
|
43968
|
-
};
|
|
43969
|
-
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
43970
|
-
function specFor(unit) {
|
|
43971
|
-
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
43972
|
-
}
|
|
43973
|
-
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
43974
|
-
function toCanonical(value, spec) {
|
|
43975
|
-
return value * spec.factor + spec.offset;
|
|
43976
|
-
}
|
|
43977
|
-
/** Canonical-unit value → the unit described by `spec`. */
|
|
43978
|
-
function fromCanonical(canonical, spec) {
|
|
43979
|
-
return (canonical - spec.offset) / spec.factor;
|
|
43980
|
-
}
|
|
43981
|
-
/**
|
|
43982
|
-
* Graceful variant for the render path: returns the converted value, or
|
|
43983
|
-
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
43984
|
-
* Never throws — a render caller falls back to the raw value + source unit.
|
|
43985
|
-
*/
|
|
43986
|
-
function tryConvertUnit(value, from, to) {
|
|
43987
|
-
if (from === to) return value;
|
|
43988
|
-
const fromSpec = specFor(from);
|
|
43989
|
-
if (!fromSpec) return void 0;
|
|
43990
|
-
const toSpec = specFor(to);
|
|
43991
|
-
if (!toSpec) return void 0;
|
|
43992
|
-
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
43993
|
-
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
43994
|
-
}
|
|
43995
|
-
/**
|
|
43996
43890
|
* A number a person types for a physical quantity — the input side of the
|
|
43997
43891
|
* value + unit contract (D972).
|
|
43998
43892
|
*
|
|
@@ -45690,26 +45584,23 @@ var SettingsSchemaWithValuesSchema = object({
|
|
|
45690
45584
|
var SettingsPatchSchema = record(string(), unknown());
|
|
45691
45585
|
/** The scope of a scoped-settings call (D986): where the capability declared the values. */
|
|
45692
45586
|
var ScopedSettingsScopeSchema = _enum(SCOPED_SETTINGS_SCOPES);
|
|
45587
|
+
/** One scoped schema an addon serves: its capability, scope and section ids. */
|
|
45588
|
+
var ScopedSettingsDeclarationSchema = object({
|
|
45589
|
+
cap: string(),
|
|
45590
|
+
scope: ScopedSettingsScopeSchema,
|
|
45591
|
+
sectionIds: array(string())
|
|
45592
|
+
});
|
|
45693
45593
|
/** Standard success response for update operations. */
|
|
45694
45594
|
var SettingsUpdateResultSchema = object({ success: literal(true) });
|
|
45695
45595
|
method(object({
|
|
45696
|
-
addonId: string(),
|
|
45697
|
-
nodeId: string().optional(),
|
|
45698
|
-
overlay: record(string(), unknown()).optional(),
|
|
45699
|
-
cap: string().optional()
|
|
45700
|
-
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45701
|
-
addonId: string(),
|
|
45702
|
-
nodeId: string().optional(),
|
|
45703
|
-
patch: SettingsPatchSchema
|
|
45704
|
-
}), SettingsUpdateResultSchema, {
|
|
45705
|
-
kind: "mutation",
|
|
45706
|
-
auth: "admin"
|
|
45707
|
-
}), method(object({
|
|
45708
45596
|
addonId: string(),
|
|
45709
45597
|
cap: string(),
|
|
45710
45598
|
scope: ScopedSettingsScopeSchema,
|
|
45711
45599
|
nodeId: string().optional()
|
|
45712
45600
|
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45601
|
+
addonId: string(),
|
|
45602
|
+
nodeId: string().optional()
|
|
45603
|
+
}), array(ScopedSettingsDeclarationSchema).nullable()), method(object({
|
|
45713
45604
|
addonId: string(),
|
|
45714
45605
|
cap: string(),
|
|
45715
45606
|
scope: ScopedSettingsScopeSchema,
|
|
@@ -45724,9 +45615,6 @@ method(object({
|
|
|
45724
45615
|
scope: ScopedSettingsScopeSchema,
|
|
45725
45616
|
nodeId: string().optional()
|
|
45726
45617
|
}), record(string(), unknown()).nullable()), method(object({
|
|
45727
|
-
addonId: string(),
|
|
45728
|
-
nodeId: string().optional()
|
|
45729
|
-
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45730
45618
|
addonId: string(),
|
|
45731
45619
|
nodeId: string().optional(),
|
|
45732
45620
|
instance: IntegrationInstanceRefSchema
|
|
@@ -47289,7 +47177,7 @@ var BackupDestinationInfoSchema = object({
|
|
|
47289
47177
|
id: string(),
|
|
47290
47178
|
/**
|
|
47291
47179
|
* Manifest id of the owning addon. The Settings button on the
|
|
47292
|
-
* destination card opens that addon's
|
|
47180
|
+
* destination card opens that addon's scoped settings panel.
|
|
47293
47181
|
*/
|
|
47294
47182
|
addonId: string(),
|
|
47295
47183
|
/** Operator-toggled enable flag from the destination-policy table. */
|
|
@@ -50748,7 +50636,7 @@ var mediaPlayerCapability = {
|
|
|
50748
50636
|
isMuted: { kind: "boolean" }
|
|
50749
50637
|
} }
|
|
50750
50638
|
};
|
|
50751
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater;
|
|
50639
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.MediaPlayer;
|
|
50752
50640
|
var NUMBER = {
|
|
50753
50641
|
kind: "fixed",
|
|
50754
50642
|
result: ["number"]
|
|
@@ -52766,6 +52654,7 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
|
|
|
52766
52654
|
kind: "mutation",
|
|
52767
52655
|
auth: "admin"
|
|
52768
52656
|
});
|
|
52657
|
+
var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
|
|
52769
52658
|
/**
|
|
52770
52659
|
* A SITE ZONE — a named part of the property that several locations belong to.
|
|
52771
52660
|
*
|
|
@@ -53252,6 +53141,12 @@ var DeviceInfoSchema = object({
|
|
|
53252
53141
|
addonId: string(),
|
|
53253
53142
|
type: _enum(DeviceType),
|
|
53254
53143
|
name: string(),
|
|
53144
|
+
/** The name a value template uses for this device (`{{ stufa_veranda.temperature }}`),
|
|
53145
|
+
* entity_id style. Generated once from the name at first registration, unique
|
|
53146
|
+
* cluster-wide, editable through `setAlias`, NOT changed by a rename (D1021).
|
|
53147
|
+
* Optional: a record produced by an older build omits it until the boot
|
|
53148
|
+
* backfill has run. */
|
|
53149
|
+
alias: DeviceAliasSchema.optional(),
|
|
53255
53150
|
/** Operator-organisational location label. `null` when unset. */
|
|
53256
53151
|
location: string().nullable(),
|
|
53257
53152
|
/** Soft-disabled flag. */
|
|
@@ -53571,6 +53466,25 @@ method(object({
|
|
|
53571
53466
|
}), _void(), {
|
|
53572
53467
|
kind: "mutation",
|
|
53573
53468
|
auth: "admin"
|
|
53469
|
+
}), method(object({
|
|
53470
|
+
deviceId: number$1(),
|
|
53471
|
+
alias: string()
|
|
53472
|
+
}), discriminatedUnion("ok", [object({
|
|
53473
|
+
ok: literal(true),
|
|
53474
|
+
alias: DeviceAliasSchema
|
|
53475
|
+
}), object({
|
|
53476
|
+
ok: literal(false),
|
|
53477
|
+
reason: _enum([
|
|
53478
|
+
"empty",
|
|
53479
|
+
"too-long",
|
|
53480
|
+
"grammar",
|
|
53481
|
+
"reserved",
|
|
53482
|
+
"taken"
|
|
53483
|
+
]),
|
|
53484
|
+
takenBy: number$1().optional()
|
|
53485
|
+
})]), {
|
|
53486
|
+
kind: "mutation",
|
|
53487
|
+
auth: "admin"
|
|
53574
53488
|
}), method(object({
|
|
53575
53489
|
deviceId: number$1(),
|
|
53576
53490
|
location: string().nullable()
|
|
@@ -57376,10 +57290,11 @@ var IntegrationInstanceDescriptionSchema = object({
|
|
|
57376
57290
|
/** True when `testInstance` really probes the remote. */
|
|
57377
57291
|
canTest: boolean(),
|
|
57378
57292
|
/**
|
|
57379
|
-
* The kinds an instance can be of
|
|
57380
|
-
* Add flow asks which first and sends it as
|
|
57293
|
+
* The kinds an instance can be of (D1013 rule 1), each naming its `functionCap`. One entry:
|
|
57294
|
+
* nothing to choose; more than one: the Add flow asks which first and sends it as
|
|
57295
|
+
* `createInstance.kind`. Never empty: every instance belongs to exactly one kind.
|
|
57381
57296
|
*/
|
|
57382
|
-
kinds: array(IntegrationInstanceKindSchema).
|
|
57297
|
+
kinds: array(IntegrationInstanceKindSchema).min(1),
|
|
57383
57298
|
/**
|
|
57384
57299
|
* The provider accepts `createInstance.id` for an id that once existed (an adopted id, because
|
|
57385
57300
|
* devices carry it). The UI then offers "restore under its old id" on Add. Absent means no.
|
|
@@ -57415,8 +57330,8 @@ var IntegrationInstanceSchema = object({
|
|
|
57415
57330
|
* the body is the one store, `setInstanceEnabled` the one writer (epic #440, step 3).
|
|
57416
57331
|
*/
|
|
57417
57332
|
enabled: boolean().optional(),
|
|
57418
|
-
/** The kind of this instance
|
|
57419
|
-
kind: string().
|
|
57333
|
+
/** The kind of this instance: exactly one of `describe().kinds[].id` (D1013 rule 2). */
|
|
57334
|
+
kind: string().min(1),
|
|
57420
57335
|
/** Values for the instance form; a secret is a `SecretFieldView`, never text. */
|
|
57421
57336
|
formValues: record(string(), unknown()),
|
|
57422
57337
|
status: IntegrationInstanceStatusSchema.optional(),
|
|
@@ -67671,6 +67586,11 @@ var NcScheduleSchema = object({
|
|
|
67671
67586
|
* as a STATE SUMMARY at the end of each window of `schedule`.
|
|
67672
67587
|
*/
|
|
67673
67588
|
var NcSystemEventDeliveryModeSchema = _enum(["instant", "summary"]);
|
|
67589
|
+
_enum([
|
|
67590
|
+
"activation",
|
|
67591
|
+
"deactivation",
|
|
67592
|
+
"schedule"
|
|
67593
|
+
]);
|
|
67674
67594
|
/**
|
|
67675
67595
|
* How a summary window is SENT (D698): `rule` (absent) = ONE notification with
|
|
67676
67596
|
* every section; `section` = one notification per section with something to
|
|
@@ -67687,11 +67607,26 @@ var NcStateSummarySplitSchema = _enum(["rule", "section"]);
|
|
|
67687
67607
|
* midnight crossing); the send time is each window's END. Refused on the
|
|
67688
67608
|
* `alarm` family, which stays instant (`systemEventDeliveryProblems`).
|
|
67689
67609
|
*/
|
|
67690
|
-
var NcSystemEventDeliverySchema = discriminatedUnion("mode", [
|
|
67691
|
-
mode: literal("
|
|
67692
|
-
|
|
67693
|
-
|
|
67694
|
-
|
|
67610
|
+
var NcSystemEventDeliverySchema = discriminatedUnion("mode", [
|
|
67611
|
+
object({ mode: literal("instant") }),
|
|
67612
|
+
object({
|
|
67613
|
+
mode: literal("summary"),
|
|
67614
|
+
schedule: NcScheduleSchema,
|
|
67615
|
+
split: NcStateSummarySplitSchema.optional()
|
|
67616
|
+
}),
|
|
67617
|
+
object({
|
|
67618
|
+
mode: literal("modes"),
|
|
67619
|
+
/** The bad edge, and every kind that has a single edge. */
|
|
67620
|
+
onActivation: boolean(),
|
|
67621
|
+
/** The recovery edges of the classes of the selected kinds (derived, never stored per kind). */
|
|
67622
|
+
onDeactivation: boolean(),
|
|
67623
|
+
/** A state summary at the end of each window; absent = no summary. */
|
|
67624
|
+
onSchedule: object({
|
|
67625
|
+
schedule: NcScheduleSchema,
|
|
67626
|
+
grouping: NcStateSummarySplitSchema
|
|
67627
|
+
}).optional()
|
|
67628
|
+
})
|
|
67629
|
+
]);
|
|
67695
67630
|
/** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
|
|
67696
67631
|
var NcPlateMatcherSchema = object({
|
|
67697
67632
|
/**
|
|
@@ -75765,6 +75700,16 @@ var RemoteLayoutComponentSchema = object({
|
|
|
75765
75700
|
method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
|
|
75766
75701
|
var RUNNING_POWER_START_DELAY_MS = 3e4;
|
|
75767
75702
|
var RUNNING_POWER_STOP_DELAY_MS = 18e4;
|
|
75703
|
+
/**
|
|
75704
|
+
* Per-type overrides of the dwell defaults. A media player draws power the
|
|
75705
|
+
* moment it is on and stops drawing the moment it is off, so it needs neither
|
|
75706
|
+
* a long dwell nor a second sample. A type absent here keeps the global values.
|
|
75707
|
+
*/
|
|
75708
|
+
var RUNNING_POWER_DEFAULTS_BY_TYPE = { [DeviceType.MediaPlayer]: {
|
|
75709
|
+
startDwellMs: 1e4,
|
|
75710
|
+
stopDwellMs: 1e4,
|
|
75711
|
+
minSamples: 1
|
|
75712
|
+
} };
|
|
75768
75713
|
var RunningStateSourceSchema = _enum(["native", "assigned"]);
|
|
75769
75714
|
var RunningStateStatusSchema = object({
|
|
75770
75715
|
/** null = unknown — never coerced to false (D393). */
|
|
@@ -75782,93 +75727,27 @@ var RunningFlipEventDataSchema = object({
|
|
|
75782
75727
|
phase: string().nullable()
|
|
75783
75728
|
});
|
|
75784
75729
|
var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
75785
|
-
/**
|
|
75786
|
-
|
|
75787
|
-
|
|
75788
|
-
|
|
75789
|
-
|
|
75790
|
-
|
|
75791
|
-
|
|
75792
|
-
|
|
75793
|
-
|
|
75794
|
-
|
|
75795
|
-
|
|
75796
|
-
|
|
75797
|
-
|
|
75798
|
-
|
|
75799
|
-
|
|
75800
|
-
|
|
75801
|
-
|
|
75802
|
-
|
|
75803
|
-
|
|
75804
|
-
|
|
75805
|
-
|
|
75806
|
-
DeviceType.WaterHeater,
|
|
75807
|
-
DeviceType.Humidifier,
|
|
75808
|
-
DeviceType.Fan,
|
|
75809
|
-
DeviceType.Climate,
|
|
75810
|
-
DeviceType.Thermostat,
|
|
75811
|
-
DeviceType.PetFeeder,
|
|
75812
|
-
DeviceType.Heater
|
|
75813
|
-
],
|
|
75814
|
-
apply: "add",
|
|
75815
|
-
path: "running",
|
|
75816
|
-
sources: [
|
|
75817
|
-
{
|
|
75818
|
-
kind: "switch",
|
|
75819
|
-
transforms: [{ kind: "identity" }]
|
|
75820
|
-
},
|
|
75821
|
-
{
|
|
75822
|
-
kind: "binary",
|
|
75823
|
-
transforms: [{ kind: "identity" }, { kind: "invert" }]
|
|
75824
|
-
},
|
|
75825
|
-
{
|
|
75826
|
-
kind: "numeric",
|
|
75827
|
-
requiredUnit: "W",
|
|
75828
|
-
transforms: [{
|
|
75829
|
-
kind: "threshold",
|
|
75830
|
-
comparisons: ["gte", "lte"],
|
|
75831
|
-
comparison: "gte",
|
|
75832
|
-
defaultThreshold: 5,
|
|
75833
|
-
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
75834
|
-
defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
|
|
75835
|
-
thresholdUnit: "W"
|
|
75836
|
-
}]
|
|
75837
|
-
}
|
|
75838
|
-
],
|
|
75839
|
-
companions: [
|
|
75840
|
-
{
|
|
75841
|
-
kind: "constant",
|
|
75842
|
-
path: "source",
|
|
75843
|
-
value: "assigned",
|
|
75844
|
-
when: "always"
|
|
75845
|
-
},
|
|
75846
|
-
{
|
|
75847
|
-
kind: "constant",
|
|
75848
|
-
path: "phase",
|
|
75849
|
-
value: null,
|
|
75850
|
-
when: "add"
|
|
75851
|
-
},
|
|
75852
|
-
{
|
|
75853
|
-
kind: "clock",
|
|
75854
|
-
path: "lastFetchedAt",
|
|
75855
|
-
when: "always"
|
|
75856
|
-
},
|
|
75857
|
-
{
|
|
75858
|
-
kind: "transition-time",
|
|
75859
|
-
path: "since",
|
|
75860
|
-
sourceChangedAt: "prefer"
|
|
75861
|
-
}
|
|
75862
|
-
],
|
|
75863
|
-
sourceReport: {
|
|
75864
|
-
status: "assignment-status",
|
|
75865
|
-
runtimeField: "source",
|
|
75866
|
-
nativeValue: "native",
|
|
75867
|
-
assignedValue: "assigned"
|
|
75868
|
-
},
|
|
75869
|
-
advancedExpression: true
|
|
75870
|
-
}]
|
|
75871
|
-
};
|
|
75730
|
+
/**
|
|
75731
|
+
* Customize offers "running" only where a job makes sense (D933): a cycle,
|
|
75732
|
+
* a clean, a mow, playback, or another appliance that is on and working.
|
|
75733
|
+
* The cap itself stays on every type — a camera can still report running
|
|
75734
|
+
* natively; it just has no card.
|
|
75735
|
+
*/
|
|
75736
|
+
var RUNNING_CUSTOMIZE_DEVICE_TYPES = [
|
|
75737
|
+
DeviceType.Washer,
|
|
75738
|
+
DeviceType.Dryer,
|
|
75739
|
+
DeviceType.Dishwasher,
|
|
75740
|
+
DeviceType.Vacuum,
|
|
75741
|
+
DeviceType.LawnMower,
|
|
75742
|
+
DeviceType.MediaPlayer,
|
|
75743
|
+
DeviceType.WaterHeater,
|
|
75744
|
+
DeviceType.Humidifier,
|
|
75745
|
+
DeviceType.Fan,
|
|
75746
|
+
DeviceType.Climate,
|
|
75747
|
+
DeviceType.Thermostat,
|
|
75748
|
+
DeviceType.PetFeeder,
|
|
75749
|
+
DeviceType.Heater
|
|
75750
|
+
];
|
|
75872
75751
|
var runningStateCapability = {
|
|
75873
75752
|
name: "running-state",
|
|
75874
75753
|
scope: "device",
|
|
@@ -75888,7 +75767,79 @@ var runningStateCapability = {
|
|
|
75888
75767
|
durability: "restored",
|
|
75889
75768
|
history: { fields: { running: { kind: "boolean" } } },
|
|
75890
75769
|
volatileStateFields: ["lastFetchedAt"],
|
|
75891
|
-
customize:
|
|
75770
|
+
customize: {
|
|
75771
|
+
version: 1,
|
|
75772
|
+
overridable: [{
|
|
75773
|
+
path: "running",
|
|
75774
|
+
by: "running"
|
|
75775
|
+
}],
|
|
75776
|
+
targets: [{
|
|
75777
|
+
id: "running",
|
|
75778
|
+
cardinality: "scalar",
|
|
75779
|
+
vocabulary: {
|
|
75780
|
+
cap: "running-state",
|
|
75781
|
+
stateField: "running"
|
|
75782
|
+
},
|
|
75783
|
+
deviceTypes: RUNNING_CUSTOMIZE_DEVICE_TYPES,
|
|
75784
|
+
apply: "add",
|
|
75785
|
+
path: "running",
|
|
75786
|
+
sources: [
|
|
75787
|
+
{
|
|
75788
|
+
kind: "switch",
|
|
75789
|
+
transforms: [{ kind: "identity" }]
|
|
75790
|
+
},
|
|
75791
|
+
{
|
|
75792
|
+
kind: "binary",
|
|
75793
|
+
transforms: [{ kind: "identity" }, { kind: "invert" }]
|
|
75794
|
+
},
|
|
75795
|
+
{
|
|
75796
|
+
kind: "numeric",
|
|
75797
|
+
requiredUnit: "W",
|
|
75798
|
+
transforms: [{
|
|
75799
|
+
kind: "threshold",
|
|
75800
|
+
comparisons: ["gte", "lte"],
|
|
75801
|
+
comparison: "gte",
|
|
75802
|
+
defaultThreshold: 5,
|
|
75803
|
+
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
75804
|
+
defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
|
|
75805
|
+
deviceTypeDefaults: RUNNING_POWER_DEFAULTS_BY_TYPE,
|
|
75806
|
+
thresholdUnit: "W"
|
|
75807
|
+
}]
|
|
75808
|
+
}
|
|
75809
|
+
],
|
|
75810
|
+
companions: [
|
|
75811
|
+
{
|
|
75812
|
+
kind: "constant",
|
|
75813
|
+
path: "source",
|
|
75814
|
+
value: "assigned",
|
|
75815
|
+
when: "always"
|
|
75816
|
+
},
|
|
75817
|
+
{
|
|
75818
|
+
kind: "constant",
|
|
75819
|
+
path: "phase",
|
|
75820
|
+
value: null,
|
|
75821
|
+
when: "add"
|
|
75822
|
+
},
|
|
75823
|
+
{
|
|
75824
|
+
kind: "clock",
|
|
75825
|
+
path: "lastFetchedAt",
|
|
75826
|
+
when: "always"
|
|
75827
|
+
},
|
|
75828
|
+
{
|
|
75829
|
+
kind: "transition-time",
|
|
75830
|
+
path: "since",
|
|
75831
|
+
sourceChangedAt: "prefer"
|
|
75832
|
+
}
|
|
75833
|
+
],
|
|
75834
|
+
sourceReport: {
|
|
75835
|
+
status: "assignment-status",
|
|
75836
|
+
runtimeField: "source",
|
|
75837
|
+
nativeValue: "native",
|
|
75838
|
+
assignedValue: "assigned"
|
|
75839
|
+
},
|
|
75840
|
+
advancedExpression: true
|
|
75841
|
+
}]
|
|
75842
|
+
}
|
|
75892
75843
|
};
|
|
75893
75844
|
/**
|
|
75894
75845
|
* scene-monitor — device-scoped reference-region state cap. An operator marks
|
|
@@ -78822,6 +78773,11 @@ var TimedRunUnitSchema = _enum(["s", "min"]);
|
|
|
78822
78773
|
_enum(["switch", "pet-fountain"]);
|
|
78823
78774
|
DeviceType.Heater, DeviceType.PetFountain;
|
|
78824
78775
|
var TIMED_RUN_DEVICE_TYPES = [DeviceType.Heater, DeviceType.PetFountain];
|
|
78776
|
+
/** One duration, as the one-tap run asks for it. */
|
|
78777
|
+
var TimedRunQuickRunSchema = object({
|
|
78778
|
+
duration: number$1().positive().finite(),
|
|
78779
|
+
unit: TimedRunUnitSchema
|
|
78780
|
+
});
|
|
78825
78781
|
/** Why a request was not carried out. Typed, so a caller can say it in words. */
|
|
78826
78782
|
var TimedRunRefusalSchema = _enum([
|
|
78827
78783
|
"unsupported-device",
|
|
@@ -78842,8 +78798,23 @@ var TimedRunStatusSchema = object({
|
|
|
78842
78798
|
activeUntil: number$1().nullable(),
|
|
78843
78799
|
/** Who asked for the run (a user id or an addon id); `null` when nothing is armed or it did not say. */
|
|
78844
78800
|
requestedBy: string().nullable(),
|
|
78801
|
+
/**
|
|
78802
|
+
* The one-tap run of THIS device: what a "Run" button on any surface starts. `null` when
|
|
78803
|
+
* the device is gone or its type has no timed run; a status from before this field
|
|
78804
|
+
* existed has none, and a surface falls back to the type's default.
|
|
78805
|
+
*/
|
|
78806
|
+
quickRun: TimedRunQuickRunSchema.nullable(),
|
|
78845
78807
|
lastFetchedAt: number$1()
|
|
78846
78808
|
});
|
|
78809
|
+
/** What the settings form needs: the unit, the bounds and the type's default. */
|
|
78810
|
+
var TimedRunOptionsSchema = object({
|
|
78811
|
+
unit: TimedRunUnitSchema,
|
|
78812
|
+
/** The longest run, in `unit`. */
|
|
78813
|
+
maxDuration: number$1(),
|
|
78814
|
+
defaultDuration: number$1()
|
|
78815
|
+
});
|
|
78816
|
+
/** The one-tap run duration, in the type's unit; `null` returns to the type's default. */
|
|
78817
|
+
var TimedRunSettingsPatchSchema = object({ quickRunDuration: number$1().positive().finite().nullable().optional() });
|
|
78847
78818
|
var timedRunCapability = {
|
|
78848
78819
|
name: "timed-run",
|
|
78849
78820
|
scope: "device",
|
|
@@ -78851,7 +78822,24 @@ var timedRunCapability = {
|
|
|
78851
78822
|
kind: "wrapper",
|
|
78852
78823
|
defaultActive: true,
|
|
78853
78824
|
deviceTypes: TIMED_RUN_DEVICE_TYPES,
|
|
78825
|
+
deviceConfig: { ui: {
|
|
78826
|
+
kind: "derived-form",
|
|
78827
|
+
builderId: "timed-run",
|
|
78828
|
+
tab: "general"
|
|
78829
|
+
} },
|
|
78854
78830
|
methods: {
|
|
78831
|
+
getOptions: method(object({ deviceId: number$1().int() }), TimedRunOptionsSchema),
|
|
78832
|
+
/**
|
|
78833
|
+
* The one-tap run of this device. A duration above the type's maximum is
|
|
78834
|
+
* REFUSED (thrown), like `runFor`: the maximum is a safety bound.
|
|
78835
|
+
*/
|
|
78836
|
+
setSettings: method(object({
|
|
78837
|
+
deviceId: number$1().int(),
|
|
78838
|
+
settings: TimedRunSettingsPatchSchema
|
|
78839
|
+
}), _void(), {
|
|
78840
|
+
kind: "mutation",
|
|
78841
|
+
auth: "admin"
|
|
78842
|
+
}),
|
|
78855
78843
|
/**
|
|
78856
78844
|
* Turn the device on and arm its off. A run already armed is replaced (the
|
|
78857
78845
|
* new deadline wins). Refuses with a typed reason above the type's maximum.
|
|
@@ -83552,13 +83540,6 @@ Object.freeze({
|
|
|
83552
83540
|
access: "view",
|
|
83553
83541
|
role: "admin"
|
|
83554
83542
|
},
|
|
83555
|
-
"addonSettings.getGlobalSettings": {
|
|
83556
|
-
capName: "addon-settings",
|
|
83557
|
-
capScope: "system",
|
|
83558
|
-
addonId: null,
|
|
83559
|
-
access: "view",
|
|
83560
|
-
role: "admin"
|
|
83561
|
-
},
|
|
83562
83543
|
"addonSettings.getIntegrationFormSchema": {
|
|
83563
83544
|
capName: "addon-settings",
|
|
83564
83545
|
capScope: "system",
|
|
@@ -83566,14 +83547,14 @@ Object.freeze({
|
|
|
83566
83547
|
access: "view",
|
|
83567
83548
|
role: "admin"
|
|
83568
83549
|
},
|
|
83569
|
-
"addonSettings.
|
|
83550
|
+
"addonSettings.getScopedSettings": {
|
|
83570
83551
|
capName: "addon-settings",
|
|
83571
83552
|
capScope: "system",
|
|
83572
83553
|
addonId: null,
|
|
83573
83554
|
access: "view",
|
|
83574
83555
|
role: "admin"
|
|
83575
83556
|
},
|
|
83576
|
-
"addonSettings.
|
|
83557
|
+
"addonSettings.listScopedSettings": {
|
|
83577
83558
|
capName: "addon-settings",
|
|
83578
83559
|
capScope: "system",
|
|
83579
83560
|
addonId: null,
|
|
@@ -83601,13 +83582,6 @@ Object.freeze({
|
|
|
83601
83582
|
access: "create",
|
|
83602
83583
|
role: "admin"
|
|
83603
83584
|
},
|
|
83604
|
-
"addonSettings.updateGlobalSettings": {
|
|
83605
|
-
capName: "addon-settings",
|
|
83606
|
-
capScope: "system",
|
|
83607
|
-
addonId: null,
|
|
83608
|
-
access: "create",
|
|
83609
|
-
role: "admin"
|
|
83610
|
-
},
|
|
83611
83585
|
"addonSettings.updateScopedSettings": {
|
|
83612
83586
|
capName: "addon-settings",
|
|
83613
83587
|
capScope: "system",
|
|
@@ -85778,6 +85752,13 @@ Object.freeze({
|
|
|
85778
85752
|
access: "create",
|
|
85779
85753
|
role: "admin"
|
|
85780
85754
|
},
|
|
85755
|
+
"deviceManager.setAlias": {
|
|
85756
|
+
capName: "device-manager",
|
|
85757
|
+
capScope: "system",
|
|
85758
|
+
addonId: null,
|
|
85759
|
+
access: "create",
|
|
85760
|
+
role: "admin"
|
|
85761
|
+
},
|
|
85781
85762
|
"deviceManager.setChildLayout": {
|
|
85782
85763
|
capName: "device-manager",
|
|
85783
85764
|
capScope: "system",
|
|
@@ -92561,6 +92542,13 @@ Object.freeze({
|
|
|
92561
92542
|
access: "create",
|
|
92562
92543
|
role: "viewer"
|
|
92563
92544
|
},
|
|
92545
|
+
"timedRun.getOptions": {
|
|
92546
|
+
capName: "timed-run",
|
|
92547
|
+
capScope: "device",
|
|
92548
|
+
addonId: null,
|
|
92549
|
+
access: "view",
|
|
92550
|
+
role: "viewer"
|
|
92551
|
+
},
|
|
92564
92552
|
"timedRun.getStatus": {
|
|
92565
92553
|
capName: "timed-run",
|
|
92566
92554
|
capScope: "device",
|
|
@@ -92575,6 +92563,13 @@ Object.freeze({
|
|
|
92575
92563
|
access: "create",
|
|
92576
92564
|
role: "viewer"
|
|
92577
92565
|
},
|
|
92566
|
+
"timedRun.setSettings": {
|
|
92567
|
+
capName: "timed-run",
|
|
92568
|
+
capScope: "device",
|
|
92569
|
+
addonId: null,
|
|
92570
|
+
access: "create",
|
|
92571
|
+
role: "admin"
|
|
92572
|
+
},
|
|
92578
92573
|
"toast.onToast": {
|
|
92579
92574
|
capName: "toast",
|
|
92580
92575
|
capScope: "system",
|
|
@@ -93505,6 +93500,7 @@ function offered(received) {
|
|
|
93505
93500
|
};
|
|
93506
93501
|
}
|
|
93507
93502
|
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
93503
|
+
string().min(1).max(4096);
|
|
93508
93504
|
Object.freeze({
|
|
93509
93505
|
"accessories.getStatus": [{
|
|
93510
93506
|
name: "deviceId",
|
|
@@ -94188,6 +94184,11 @@ Object.freeze({
|
|
|
94188
94184
|
form: "single",
|
|
94189
94185
|
optional: false
|
|
94190
94186
|
}],
|
|
94187
|
+
"deviceManager.setAlias": [{
|
|
94188
|
+
name: "deviceId",
|
|
94189
|
+
form: "single",
|
|
94190
|
+
optional: false
|
|
94191
|
+
}],
|
|
94191
94192
|
"deviceManager.setChildLayout": [{
|
|
94192
94193
|
name: "deviceId",
|
|
94193
94194
|
form: "single",
|
|
@@ -96252,6 +96253,11 @@ Object.freeze({
|
|
|
96252
96253
|
form: "single",
|
|
96253
96254
|
optional: false
|
|
96254
96255
|
}],
|
|
96256
|
+
"timedRun.getOptions": [{
|
|
96257
|
+
name: "deviceId",
|
|
96258
|
+
form: "single",
|
|
96259
|
+
optional: false
|
|
96260
|
+
}],
|
|
96255
96261
|
"timedRun.getStatus": [{
|
|
96256
96262
|
name: "deviceId",
|
|
96257
96263
|
form: "single",
|
|
@@ -96262,6 +96268,11 @@ Object.freeze({
|
|
|
96262
96268
|
form: "single",
|
|
96263
96269
|
optional: false
|
|
96264
96270
|
}],
|
|
96271
|
+
"timedRun.setSettings": [{
|
|
96272
|
+
name: "deviceId",
|
|
96273
|
+
form: "single",
|
|
96274
|
+
optional: false
|
|
96275
|
+
}],
|
|
96265
96276
|
"update.getStatus": [{
|
|
96266
96277
|
name: "deviceId",
|
|
96267
96278
|
form: "single",
|
|
@@ -97331,6 +97342,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
97331
97342
|
[...RULE_TEXT],
|
|
97332
97343
|
[...RULE_TEXT],
|
|
97333
97344
|
[...RULE_TEXT],
|
|
97345
|
+
[...RULE_TEXT],
|
|
97334
97346
|
[...RULE_BODY_ONLY],
|
|
97335
97347
|
[...RULE_TEXT],
|
|
97336
97348
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
@@ -145194,7 +145206,14 @@ function buildAlexaAccountInstances(records, deps) {
|
|
|
145194
145206
|
instanceMode: "multiple",
|
|
145195
145207
|
kind: "account",
|
|
145196
145208
|
canTest: true,
|
|
145197
|
-
allowRestoreId: true
|
|
145209
|
+
allowRestoreId: true,
|
|
145210
|
+
kinds: [{
|
|
145211
|
+
id: ALEXA_ACCOUNT_KIND,
|
|
145212
|
+
label: "Alexa account",
|
|
145213
|
+
functionCap: "broker",
|
|
145214
|
+
role: "services",
|
|
145215
|
+
brokerKind: ALEXA_BROKER_KIND
|
|
145216
|
+
}]
|
|
145198
145217
|
},
|
|
145199
145218
|
formSchema: () => buildConnectionFormSchema(),
|
|
145200
145219
|
initialBody: (name) => ({
|
|
@@ -145248,7 +145267,13 @@ function buildAlexaInstances(records) {
|
|
|
145248
145267
|
role: "devices",
|
|
145249
145268
|
instanceMode: "multiple",
|
|
145250
145269
|
kind: "connection",
|
|
145251
|
-
canTest: false
|
|
145270
|
+
canTest: false,
|
|
145271
|
+
kinds: [{
|
|
145272
|
+
id: "integration",
|
|
145273
|
+
label: "Alexa",
|
|
145274
|
+
functionCap: "device-provider",
|
|
145275
|
+
role: "devices"
|
|
145276
|
+
}]
|
|
145252
145277
|
},
|
|
145253
145278
|
labels: { brokerId: { label: "Alexa account" } }
|
|
145254
145279
|
});
|