@camstack/addon-smtp-nodemailer 1.2.152 → 1.2.153

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.
@@ -839,7 +839,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
839
839
  return EventCategory;
840
840
  }({});
841
841
  //#endregion
842
- //#region ../types/dist/device-type-D1fH5kaC.mjs
842
+ //#region ../types/dist/device-type-DxCT0krO.mjs
843
843
  /**
844
844
  import { errMsg } from '@camstack/types'
845
845
  * Extract a human-readable message from an unknown error value.
@@ -1001,6 +1001,13 @@ var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
1001
1001
  * filters that want "all devices with on-motion behaviour".
1002
1002
  */
1003
1003
  DeviceFeature["MotionTrigger"] = "motion-trigger";
1004
+ /**
1005
+ * Device can be run for a chosen time and then stopped. Mirrors the
1006
+ * `timed-run` wrapper cap — the cap is bound by the core-blocks addon, not by
1007
+ * a driver, so the flag is derived from the device's bindings
1008
+ * (`featuresOfBoundCaps`). Gates the quick-run control in the viewer.
1009
+ */
1010
+ DeviceFeature["TimedRun"] = "timed-run";
1004
1011
  /** Light supports rgb-triplet color via `color` cap. */
1005
1012
  DeviceFeature["LightColorRgb"] = "light-color-rgb";
1006
1013
  /** Light supports HSV color via `color` cap. */
@@ -6035,7 +6042,7 @@ var ZodIssueCode = {
6035
6042
  var ZodFirstPartyTypeKind;
6036
6043
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6037
6044
  //#endregion
6038
- //#region ../types/dist/sleep-CQP-REJp.mjs
6045
+ //#region ../types/dist/sleep-7El4r5Bl.mjs
6039
6046
  /**
6040
6047
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6041
6048
  * window to float samples (D455).
@@ -8404,7 +8411,7 @@ function boundOf(list) {
8404
8411
  * Base class for CamStack addons. Eliminates settings boilerplate:
8405
8412
  *
8406
8413
  * - Typed `config` property with automatic resolution from store + defaults
8407
- * - `getGlobalSettings()` / `updateGlobalSettings()` auto-implemented
8414
+ * - the scoped settings API (`clusterSettings` / `nodeSettings` / `deviceDefaults`) auto-implemented
8408
8415
  * - `getAddonSettings()` / `updateAddonSettings()` auto-implemented
8409
8416
  * - `getDeviceSettings()` / `updateDeviceSettings()` auto-implemented
8410
8417
  * - `ctx` accessor for the AddonContext (no manual `this.ctxRef` storage)
@@ -8414,7 +8421,7 @@ function boundOf(list) {
8414
8421
  * Subclasses override:
8415
8422
  * - `onInitialize()` — addon-specific init logic, return ProviderRegistration[]
8416
8423
  * - `onShutdown()` — cleanup
8417
- * - `globalSettingsSchema()` / `deviceSettingsSchema()` — UI schemas
8424
+ * - `clusterSettingsSchema()` / `nodeSettingsSchema()` / `deviceSettingsSchema()` — UI schemas
8418
8425
  *
8419
8426
  * @example
8420
8427
  * ```ts
@@ -8428,7 +8435,7 @@ function boundOf(list) {
8428
8435
  * super({ maxRetries: 3, endpoint: 'http://localhost' })
8429
8436
  * }
8430
8437
  *
8431
- * protected globalSettingsSchema() {
8438
+ * protected clusterSettingsSchema() {
8432
8439
  * return this.schema({
8433
8440
  * sections: [{
8434
8441
  * id: 'main', title: 'Settings',
@@ -8471,7 +8478,7 @@ var BaseAddon = class {
8471
8478
  defaults;
8472
8479
  /**
8473
8480
  * Hidden-state paths that hold secrets (D787) — values the addon writes
8474
- * itself (`updateGlobalSettings`, `state()`) that no form field declares.
8481
+ * itself (`state()`, the scoped writers) that no form field declares.
8475
8482
  * Stored in the keychain exactly like a `password` field. Syntax:
8476
8483
  * `'snapshotSigningKey'`, `'identity.pincode'`, `'tokens[userId].accessToken'`
8477
8484
  * (`key[<id field>]` addresses array items by id, never by index).
@@ -8481,7 +8488,7 @@ var BaseAddon = class {
8481
8488
  /**
8482
8489
  * D986 M4: the scoped schemas this addon declared, resolved once per capability
8483
8490
  * (`loadScopedSchemas`) so the sync readers (`perNodeKeys`, the secret tree, the restart check)
8484
- * see them. Empty until loaded: the readers then fall back to {@link globalSettingsSchema}.
8491
+ * see them. Empty until loaded.
8485
8492
  */
8486
8493
  _scopedByCap = /* @__PURE__ */ new Map();
8487
8494
  _nodeKeysByCap = /* @__PURE__ */ new Map();
@@ -8667,7 +8674,7 @@ var BaseAddon = class {
8667
8674
  /** Addon-specific cleanup. Override if needed. */
8668
8675
  async onShutdown() {}
8669
8676
  /**
8670
- * Called after config is resolved during updateGlobalSettings/updateAddonSettings.
8677
+ * Called after config is resolved during a settings write.
8671
8678
  * Override to react to config changes (e.g. restart a sampler, reconnect a service).
8672
8679
  * Not called during initialize() — use onInitialize() for initial setup.
8673
8680
  */
@@ -8696,82 +8703,12 @@ var BaseAddon = class {
8696
8703
  scopedSettingsCapabilities() {
8697
8704
  return [];
8698
8705
  }
8699
- /** Override to provide global-level settings UI schema. */
8700
- globalSettingsSchema(_cap) {
8701
- return null;
8702
- }
8703
8706
  /** Override to provide device-level settings UI schema. */
8704
8707
  deviceSettingsSchema() {
8705
8708
  return null;
8706
8709
  }
8707
8710
  /**
8708
- * INTEGRATION-LEVEL SETTINGS — declare which of this addon's global sections
8709
- * ARE the configuration of its integration.
8710
- *
8711
- * Return the `ConfigSection.id`s, from {@link globalSettingsSchema}, that an
8712
- * operator should find on the addon's integration page (System →
8713
- * Integrations → <name>) rather than only in the cluster-wide list of every
8714
- * addon. Empty (the default) means the addon has no integration-level
8715
- * settings and no such surface is offered — this is opt-in, because whether
8716
- * an addon's configuration IS its integration's configuration depends on the
8717
- * nature of the integration.
8718
- *
8719
- * WHAT THIS IS NOT. It is not a scope. The selected sections keep living in
8720
- * the ONE global schema, in the ONE addon store, written by the ONE
8721
- * `updateGlobalSettings` path. There is deliberately no
8722
- * `updateIntegrationSettings`: a second write path is how a surface acquires
8723
- * a second store key, and this repo has shipped that twice (`btmPath@hub`,
8724
- * D266). Selecting sections cannot introduce a key that selecting cannot.
8725
- *
8726
- * WHY IT IS A LIST OF SECTION IDS AND NOT A MARKER ON THE SECTION.
8727
- * `ConfigFieldBase` used to carry `scope?: 'device' | 'global'` and it was
8728
- * removed with the reason recorded at
8729
- * `packages/types/src/interfaces/config-ui.ts:249` — *"a field's scope is
8730
- * determined by WHICH schema it lives in, not by a field-level marker."* A
8731
- * marker sprinkled across sections also has to borrow a field that already
8732
- * means something else; borrowing `section.tab` put the literal word
8733
- * "integration" into an operator-facing tab bar, because `tab` means "how to
8734
- * GROUP this visually" and cannot also mean "where this lives" (D269
8735
- * supersedes D268). One declaration, in one place, next to the schema whose
8736
- * ids it names.
8737
- */
8738
- integrationSettingSections() {
8739
- return [];
8740
- }
8741
- async getGlobalSettings(overlay, cap, nodeId) {
8742
- await this.loadScopedSchemas(cap);
8743
- const schema = this.globalSettingsSchema(cap) ?? this.scopedFormSchema(cap);
8744
- if (!schema) return { sections: [] };
8745
- const projected = await this.readRawProjectedStore(nodeId, cap);
8746
- return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(projected, overlay) : projected, { inlineSecretsAsViews: true });
8747
- }
8748
- /**
8749
- * The integration-level view of this addon's settings: exactly the sections
8750
- * named by {@link integrationSettingSections}, hydrated from the SAME store
8751
- * `getGlobalSettings` reads, and narrowed to cluster-scoped fields.
8752
- *
8753
- * Returns `null` when the addon declared nothing — an addon that opts out has
8754
- * no integration settings surface at all, rather than an empty one that reads
8755
- * as a failed load.
8756
- *
8757
- * Three properties hold BY CONSTRUCTION, which is why they are here in core
8758
- * and not in whichever UI happens to render this:
8759
- *
8760
- * 1. **One key.** The payload is a SUBSET of the global schema, so a field
8761
- * shown here is the same field, with the same bare key, that the addon's
8762
- * own page shows. There is no integration-specific writer — callers save
8763
- * through `updateGlobalSettings` — so a second store key is unreachable,
8764
- * not merely discouraged.
8765
- * 2. **No node scope.** `perNode: true` fields are DROPPED. Their store key
8766
- * is `<key>@<nodeId>` and an integration is not a node; whichever node
8767
- * such a field silently picked would be a wrong answer for the operator
8768
- * who opened the page (D266).
8769
- * 3. **No silent typo.** A declared id that names no section throws. The
8770
- * alternative — skip it — turns a rename into a surface that quietly
8771
- * empties, which looks exactly like an addon with nothing to configure.
8772
- */
8773
- /**
8774
- * The form schema of ONE integration instance, or `null` to use {@link globalSettingsSchema}.
8711
+ * The form schema of ONE integration instance, or `null` to use the scoped form.
8775
8712
  *
8776
8713
  * Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
8777
8714
  * needs its connection fields, the default integration the addon's own sections. It is the
@@ -8944,6 +8881,19 @@ var BaseAddon = class {
8944
8881
  const overlay = await this.scopedSettingsOverlay(scope, cap, nodeId);
8945
8882
  return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(stored, overlay) : stored, { inlineSecretsAsViews: true });
8946
8883
  }
8884
+ /**
8885
+ * The scoped schemas this addon serves: one entry per loaded (capability, scope), capabilities
8886
+ * in declaration order, scopes in {@link SCOPED_SETTINGS_SCOPES} order. `[]` when it declares
8887
+ * nothing.
8888
+ */
8889
+ async listScopedSettings() {
8890
+ await this.loadScopedSchemas();
8891
+ return [...this._scopedByCap].flatMap(([cap, entries]) => entries.map((entry) => ({
8892
+ cap,
8893
+ scope: entry.scope,
8894
+ sectionIds: entry.schema.sections.map((section) => section.id)
8895
+ })));
8896
+ }
8947
8897
  /** The OPERATOR's write of declared keys of one scope (D787 secret semantics). */
8948
8898
  async updateScopedSettings(scope, cap, patch, nodeId) {
8949
8899
  this._operatorWriteDepth++;
@@ -8969,32 +8919,15 @@ var BaseAddon = class {
8969
8919
  */
8970
8920
  async getIntegrationFormSchema(instance, nodeId) {
8971
8921
  const scoped = await this.integrationFormSchema(instance);
8972
- if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
8922
+ if (scoped === null) return this.scopedForm(nodeId);
8973
8923
  return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
8974
8924
  }
8975
- async getIntegrationSettings(nodeId) {
8976
- const declared = this.integrationSettingSections();
8977
- if (declared.length === 0) return null;
8978
- const schema = this.globalSettingsSchema();
8979
- if (!schema) throw new Error(`${this.constructor.name}: integrationSettingSections() names [${declared.join(", ")}] but globalSettingsSchema() returns null.`);
8980
- const byId = new Map(schema.sections.map((section) => [section.id, section]));
8981
- const sections = [];
8982
- for (const id of declared) {
8983
- const section = byId.get(id);
8984
- if (!section) throw new Error(`${this.constructor.name}: integrationSettingSections() names unknown section "${id}". Known sections: [${[...byId.keys()].join(", ")}].`);
8985
- const fields = dropPerNodeFields(section.fields);
8986
- if (fields.length === 0) continue;
8987
- sections.push({
8988
- ...section,
8989
- fields
8990
- });
8991
- }
8992
- if (sections.length === 0) return null;
8993
- const projected = await this.readRawProjectedStore(nodeId);
8994
- return hydrateSchema({
8995
- ...schema,
8996
- sections
8997
- }, projected, { inlineSecretsAsViews: true });
8925
+ /** The form of the scoped schemas this addon declared, hydrated from its store. */
8926
+ async scopedForm(nodeId) {
8927
+ await this.loadScopedSchemas();
8928
+ const schema = this.scopedFormSchema();
8929
+ if (!schema) return { sections: [] };
8930
+ return hydrateSchema(schema, await this.readRawProjectedStore(nodeId), { inlineSecretsAsViews: true });
8998
8931
  }
8999
8932
  /**
9000
8933
  * The raw addon store PROJECTED onto the target node's bare per-node keys:
@@ -9003,8 +8936,8 @@ var BaseAddon = class {
9003
8936
  * bare fallback), all `@`-scoped and stray bare per-node keys are dropped.
9004
8937
  * A no-op passthrough when the schema declares no `perNode` field.
9005
8938
  *
9006
- * This is the sanctioned way for a `getGlobalSettings` OVERRIDE that needs
9007
- * the store for custom option logic (option narrowing, value snapping) to
8939
+ * This is the sanctioned way for an addon that needs
8940
+ * the store for custom logic (option narrowing, value snapping) to
9008
8941
  * read it per-node — never `ctx.settings.readAddonStore()` directly.
9009
8942
  * `nodeId` omitted ⇒ the local node (node-blind injection from ctx).
9010
8943
  *
@@ -9056,7 +8989,7 @@ var BaseAddon = class {
9056
8989
  }
9057
8990
  /**
9058
8991
  * Whether ONE global key of this addon's store was written, read three-way
9059
- * (D651). For a question a hydrated view cannot answer: `getGlobalSettings`
8992
+ * (D651). For a question a hydrated view cannot answer: a hydrated form
9060
8993
  * reports `value ?? default`, so "the operator chose the default" and "nobody
9061
8994
  * chose" look the same, and a failed read looks like both. A `perNode` key is
9062
8995
  * not supported here: its stored name is scoped.
@@ -9090,7 +9023,7 @@ var BaseAddon = class {
9090
9023
  }
9091
9024
  /**
9092
9025
  * The OPERATOR's write — a settings form or an admin API call, dispatched by
9093
- * the kernel. Identical to {@link updateGlobalSettings}, except that a secret
9026
+ * the kernel. The one in-process write of the addon blob that is not a scoped write; a secret
9094
9027
  * the operator sends is stored as sent even when it equals a pre-keychain
9095
9028
  * inline value: the operator re-entering a password is a change, an addon
9096
9029
  * writing back what it read is not (D787).
@@ -9103,9 +9036,6 @@ var BaseAddon = class {
9103
9036
  this._operatorWriteDepth--;
9104
9037
  }
9105
9038
  }
9106
- async updateGlobalSettings(patch, nodeId) {
9107
- await this.applyGlobalPatch(patch, nodeId);
9108
- }
9109
9039
  /**
9110
9040
  * REMOVE stored secrets — their keychain values and their markers (D787).
9111
9041
  *
@@ -9148,8 +9078,7 @@ var BaseAddon = class {
9148
9078
  await this.resolveConfig();
9149
9079
  await this.onConfigChanged();
9150
9080
  this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
9151
- const legacy = this.globalSettingsSchema();
9152
- this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
9081
+ this.maybeAutoRestart(Object.keys(barePatch), this.loadedScopedSchemas().map((entry) => entry.schema));
9153
9082
  return true;
9154
9083
  }
9155
9084
  /**
@@ -9187,10 +9116,7 @@ var BaseAddon = class {
9187
9116
  this._nodeKeysByCap = /* @__PURE__ */ new Map();
9188
9117
  this._addonSecretTree = null;
9189
9118
  }
9190
- /**
9191
- * The form the settings API serves while an addon declares no {@link globalSettingsSchema}: the
9192
- * sections of its scoped schemas, so dropping the old hook does not blank the form.
9193
- */
9119
+ /** The form of an addon's scoped schemas: their sections, each shown once. */
9194
9120
  scopedFormSchema(cap) {
9195
9121
  const byId = /* @__PURE__ */ new Map();
9196
9122
  for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
@@ -9202,8 +9128,7 @@ var BaseAddon = class {
9202
9128
  return [...this._scopedByCap.values()].flat();
9203
9129
  }
9204
9130
  /**
9205
- * The field keys that are stored per node: every field of a {@link nodeSettingsSchema}, plus
9206
- * the fields the legacy {@link globalSettingsSchema} still marks `perNode: true`. Derived once
9131
+ * The field keys that are stored per node: every field of a {@link nodeSettingsSchema}. Derived once
9207
9132
  * per `cap` argument and memoized (schemas are static declarations). Empty set ⇒ every
9208
9133
  * per-node code path is bypassed and the settings API behaves like the node-agnostic one.
9209
9134
  * Call {@link loadScopedSchemas} first (the async seams do).
@@ -9212,8 +9137,7 @@ var BaseAddon = class {
9212
9137
  const cacheKey = cap ?? "";
9213
9138
  const cached = this._nodeKeysByCap.get(cacheKey);
9214
9139
  if (cached) return cached;
9215
- const legacy = this.globalSettingsSchema(cap);
9216
- const keys = new Set(legacy ? legacy.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
9140
+ const keys = /* @__PURE__ */ new Set();
9217
9141
  for (const { scope, schema } of this.loadedScopedSchemas(cap)) {
9218
9142
  if (scope !== "node") continue;
9219
9143
  for (const section of schema.sections) for (const key of collectValueFieldKeys(section.fields)) keys.add(key);
@@ -9431,8 +9355,6 @@ var BaseAddon = class {
9431
9355
  }
9432
9356
  declaredKeySet() {
9433
9357
  const keys = new Set(Object.keys(this.defaults));
9434
- const schema = this.globalSettingsSchema();
9435
- if (schema) for (const section of schema.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
9436
9358
  for (const { schema: scoped } of this.loadedScopedSchemas()) for (const section of scoped.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
9437
9359
  for (const key of this._declaredStateKeys) keys.add(key);
9438
9360
  for (const path of this.secretStatePaths) {
@@ -9530,7 +9452,7 @@ var BaseAddon = class {
9530
9452
  /** The addon store's secret tree: schema fields by TYPE, plus `secretStatePaths`. */
9531
9453
  addonSecretTree() {
9532
9454
  if (this._addonSecretTree === null) {
9533
- const tree = new Map(secretTreeFromSchema(this.globalSettingsSchema()));
9455
+ const tree = /* @__PURE__ */ new Map();
9534
9456
  for (const { schema } of this.loadedScopedSchemas()) for (const [key, node] of secretTreeFromSchema(schema)) tree.set(key, node);
9535
9457
  this._addonSecretTree = mergeSecretStatePaths(tree, this.secretStatePaths);
9536
9458
  }
@@ -9742,47 +9664,6 @@ function classifyStoreError(err) {
9742
9664
  if (TRANSPORT_PHRASES.some((f) => message.includes(f))) return "transport";
9743
9665
  return "permanent";
9744
9666
  }
9745
- /**
9746
- * Collect the keys of every field marked `perNode: true`, recursing into
9747
- * layout containers (`group` fields and `sub-tabs` tabs) the same way
9748
- * `hydrateSchema` does. Valueless structural fields (separator/info/…)
9749
- * don't declare `perNode` and are excluded by the `in` narrowing.
9750
- */
9751
- /**
9752
- * The same fields with every `perNode: true` one removed, recursing into layout
9753
- * containers exactly as {@link collectPerNodeFieldKeys} does. A container left
9754
- * with no child is dropped rather than rendered empty.
9755
- *
9756
- * Used by `getIntegrationSettings`: an integration is not a node, so a field
9757
- * whose store key is `<key>@<nodeId>` has no node to belong to there.
9758
- */
9759
- function dropPerNodeFields(fields) {
9760
- const kept = [];
9761
- for (const field of fields) {
9762
- if (field.type === "group") {
9763
- const inner = dropPerNodeFields(field.fields);
9764
- if (inner.length > 0) kept.push({
9765
- ...field,
9766
- fields: inner
9767
- });
9768
- continue;
9769
- }
9770
- if (field.type === "sub-tabs") {
9771
- const tabs = field.tabs.map((tab) => ({
9772
- ...tab,
9773
- fields: dropPerNodeFields(tab.fields)
9774
- })).filter((tab) => tab.fields.length > 0);
9775
- if (tabs.length > 0) kept.push({
9776
- ...field,
9777
- tabs
9778
- });
9779
- continue;
9780
- }
9781
- if ("perNode" in field && field.perNode === true) continue;
9782
- kept.push(field);
9783
- }
9784
- return kept;
9785
- }
9786
9667
  /** The keys of the value-holding fields, recursing into layout containers. */
9787
9668
  function collectValueFieldKeys(fields) {
9788
9669
  const collected = [];
@@ -9815,21 +9696,6 @@ function collectFieldKeys(fields) {
9815
9696
  }
9816
9697
  return collected;
9817
9698
  }
9818
- function collectPerNodeFieldKeys(fields) {
9819
- const collected = [];
9820
- for (const field of fields) {
9821
- if (field.type === "group") {
9822
- collected.push(...collectPerNodeFieldKeys(field.fields));
9823
- continue;
9824
- }
9825
- if (field.type === "sub-tabs") {
9826
- for (const tab of field.tabs) collected.push(...collectPerNodeFieldKeys(tab.fields));
9827
- continue;
9828
- }
9829
- if ("perNode" in field && field.perNode === true) collected.push(field.key);
9830
- }
9831
- return collected;
9832
- }
9833
9699
  /**
9834
9700
  * Normalize an `ICamstackAddon.initialize()` return value into the
9835
9701
  * `AddonInitResult` envelope. Arrays are wrapped into `{ providers }`;
@@ -12586,13 +12452,25 @@ Object.freeze({
12586
12452
  "path": "temperature",
12587
12453
  "valueType": "number"
12588
12454
  }],
12589
- "timed-run": [{
12590
- "path": "activeUntil",
12591
- "valueType": "number"
12592
- }, {
12593
- "path": "requestedBy",
12594
- "valueType": "string"
12595
- }],
12455
+ "timed-run": [
12456
+ {
12457
+ "path": "activeUntil",
12458
+ "valueType": "number"
12459
+ },
12460
+ {
12461
+ "path": "requestedBy",
12462
+ "valueType": "string"
12463
+ },
12464
+ {
12465
+ "path": "quickRun.duration",
12466
+ "valueType": "number"
12467
+ },
12468
+ {
12469
+ "path": "quickRun.unit",
12470
+ "valueType": "enum",
12471
+ "enumValues": ["s", "min"]
12472
+ }
12473
+ ],
12596
12474
  "update": [
12597
12475
  {
12598
12476
  "path": "currentVersion",
@@ -12830,7 +12708,7 @@ function userError(code, params, englishFallback) {
12830
12708
  return new CamstackError(code, params, englishFallback);
12831
12709
  }
12832
12710
  //#endregion
12833
- //#region ../types/dist/composition-BmBHuDTQ.mjs
12711
+ //#region ../types/dist/composition-Bx0JvKUU.mjs
12834
12712
  /**
12835
12713
  * The ffmpeg build every CamStack node downloads, per platform and arch.
12836
12714
  *
@@ -13992,6 +13870,387 @@ var NodeColorIdSchema = _enum([
13992
13870
  "node-h"
13993
13871
  ]);
13994
13872
  //#endregion
13873
+ //#region ../types/dist/convert-BAzH15HU.mjs
13874
+ /**
13875
+ * Frozen unit → spec table. `•` in the doc marks each dimension's canonical
13876
+ * unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
13877
+ * `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
13878
+ * decimals). K derives from `°C = K − 273.15`.
13879
+ */
13880
+ var UNIT_TABLE = {
13881
+ "°C": {
13882
+ dimension: "temperature",
13883
+ factor: 1,
13884
+ offset: 0
13885
+ },
13886
+ "°F": {
13887
+ dimension: "temperature",
13888
+ factor: 5 / 9,
13889
+ offset: -160 / 9
13890
+ },
13891
+ K: {
13892
+ dimension: "temperature",
13893
+ factor: 1,
13894
+ offset: -273.15
13895
+ },
13896
+ hPa: {
13897
+ dimension: "pressure",
13898
+ factor: 1,
13899
+ offset: 0
13900
+ },
13901
+ kPa: {
13902
+ dimension: "pressure",
13903
+ factor: 10,
13904
+ offset: 0
13905
+ },
13906
+ Pa: {
13907
+ dimension: "pressure",
13908
+ factor: .01,
13909
+ offset: 0
13910
+ },
13911
+ mbar: {
13912
+ dimension: "pressure",
13913
+ factor: 1,
13914
+ offset: 0
13915
+ },
13916
+ bar: {
13917
+ dimension: "pressure",
13918
+ factor: 1e3,
13919
+ offset: 0
13920
+ },
13921
+ inHg: {
13922
+ dimension: "pressure",
13923
+ factor: 33.8639,
13924
+ offset: 0
13925
+ },
13926
+ mmHg: {
13927
+ dimension: "pressure",
13928
+ factor: 1.33322,
13929
+ offset: 0
13930
+ },
13931
+ psi: {
13932
+ dimension: "pressure",
13933
+ factor: 68.9476,
13934
+ offset: 0
13935
+ },
13936
+ "m/s": {
13937
+ dimension: "speed",
13938
+ factor: 1,
13939
+ offset: 0
13940
+ },
13941
+ "km/h": {
13942
+ dimension: "speed",
13943
+ factor: 1 / 3.6,
13944
+ offset: 0
13945
+ },
13946
+ mph: {
13947
+ dimension: "speed",
13948
+ factor: .44704,
13949
+ offset: 0
13950
+ },
13951
+ kn: {
13952
+ dimension: "speed",
13953
+ factor: .514444,
13954
+ offset: 0
13955
+ },
13956
+ "mm/h": {
13957
+ dimension: "precipitation-rate",
13958
+ factor: 1,
13959
+ offset: 0
13960
+ },
13961
+ "in/h": {
13962
+ dimension: "precipitation-rate",
13963
+ factor: 25.4,
13964
+ offset: 0
13965
+ },
13966
+ m: {
13967
+ dimension: "length",
13968
+ factor: 1,
13969
+ offset: 0
13970
+ },
13971
+ mm: {
13972
+ dimension: "length",
13973
+ factor: .001,
13974
+ offset: 0
13975
+ },
13976
+ cm: {
13977
+ dimension: "length",
13978
+ factor: .01,
13979
+ offset: 0
13980
+ },
13981
+ km: {
13982
+ dimension: "length",
13983
+ factor: 1e3,
13984
+ offset: 0
13985
+ },
13986
+ in: {
13987
+ dimension: "length",
13988
+ factor: .0254,
13989
+ offset: 0
13990
+ },
13991
+ ft: {
13992
+ dimension: "length",
13993
+ factor: .3048,
13994
+ offset: 0
13995
+ },
13996
+ mi: {
13997
+ dimension: "length",
13998
+ factor: 1609.344,
13999
+ offset: 0
14000
+ },
14001
+ "m²": {
14002
+ dimension: "area",
14003
+ factor: 1,
14004
+ offset: 0
14005
+ },
14006
+ lx: {
14007
+ dimension: "illuminance",
14008
+ factor: 1,
14009
+ offset: 0
14010
+ },
14011
+ "W/m²": {
14012
+ dimension: "irradiance",
14013
+ factor: 1,
14014
+ offset: 0
14015
+ },
14016
+ W: {
14017
+ dimension: "power",
14018
+ factor: 1,
14019
+ offset: 0
14020
+ },
14021
+ kW: {
14022
+ dimension: "power",
14023
+ factor: 1e3,
14024
+ offset: 0
14025
+ },
14026
+ VA: {
14027
+ dimension: "apparent-power",
14028
+ factor: 1,
14029
+ offset: 0
14030
+ },
14031
+ Wh: {
14032
+ dimension: "energy",
14033
+ factor: 1,
14034
+ offset: 0
14035
+ },
14036
+ kWh: {
14037
+ dimension: "energy",
14038
+ factor: 1e3,
14039
+ offset: 0
14040
+ },
14041
+ MWh: {
14042
+ dimension: "energy",
14043
+ factor: 1e6,
14044
+ offset: 0
14045
+ },
14046
+ V: {
14047
+ dimension: "voltage",
14048
+ factor: 1,
14049
+ offset: 0
14050
+ },
14051
+ mV: {
14052
+ dimension: "voltage",
14053
+ factor: .001,
14054
+ offset: 0
14055
+ },
14056
+ A: {
14057
+ dimension: "current",
14058
+ factor: 1,
14059
+ offset: 0
14060
+ },
14061
+ mA: {
14062
+ dimension: "current",
14063
+ factor: .001,
14064
+ offset: 0
14065
+ },
14066
+ ppm: {
14067
+ dimension: "concentration-volume",
14068
+ factor: 1,
14069
+ offset: 0
14070
+ },
14071
+ ppb: {
14072
+ dimension: "concentration-volume",
14073
+ factor: .001,
14074
+ offset: 0
14075
+ },
14076
+ "µg/m³": {
14077
+ dimension: "concentration-mass",
14078
+ factor: 1,
14079
+ offset: 0
14080
+ },
14081
+ "mg/m³": {
14082
+ dimension: "concentration-mass",
14083
+ factor: 1e3,
14084
+ offset: 0
14085
+ },
14086
+ kg: {
14087
+ dimension: "mass",
14088
+ factor: 1,
14089
+ offset: 0
14090
+ },
14091
+ g: {
14092
+ dimension: "mass",
14093
+ factor: .001,
14094
+ offset: 0
14095
+ },
14096
+ lb: {
14097
+ dimension: "mass",
14098
+ factor: .453592,
14099
+ offset: 0
14100
+ },
14101
+ oz: {
14102
+ dimension: "mass",
14103
+ factor: .0283495,
14104
+ offset: 0
14105
+ },
14106
+ "%": {
14107
+ dimension: "percentage",
14108
+ factor: 1,
14109
+ offset: 0
14110
+ },
14111
+ L: {
14112
+ dimension: "volume",
14113
+ factor: 1,
14114
+ offset: 0
14115
+ },
14116
+ mL: {
14117
+ dimension: "volume",
14118
+ factor: .001,
14119
+ offset: 0
14120
+ },
14121
+ gal: {
14122
+ dimension: "volume",
14123
+ factor: 3.785411784,
14124
+ offset: 0
14125
+ },
14126
+ s: {
14127
+ dimension: "duration",
14128
+ factor: 1,
14129
+ offset: 0
14130
+ },
14131
+ ms: {
14132
+ dimension: "duration",
14133
+ factor: .001,
14134
+ offset: 0
14135
+ },
14136
+ min: {
14137
+ dimension: "duration",
14138
+ factor: 60,
14139
+ offset: 0
14140
+ },
14141
+ h: {
14142
+ dimension: "duration",
14143
+ factor: 3600,
14144
+ offset: 0
14145
+ },
14146
+ d: {
14147
+ dimension: "duration",
14148
+ factor: 86400,
14149
+ offset: 0
14150
+ },
14151
+ B: {
14152
+ dimension: "information",
14153
+ factor: 1,
14154
+ offset: 0
14155
+ },
14156
+ KiB: {
14157
+ dimension: "information",
14158
+ factor: 1024,
14159
+ offset: 0
14160
+ },
14161
+ MiB: {
14162
+ dimension: "information",
14163
+ factor: 1024 ** 2,
14164
+ offset: 0
14165
+ },
14166
+ GiB: {
14167
+ dimension: "information",
14168
+ factor: 1024 ** 3,
14169
+ offset: 0
14170
+ },
14171
+ TiB: {
14172
+ dimension: "information",
14173
+ factor: 1024 ** 4,
14174
+ offset: 0
14175
+ },
14176
+ kB: {
14177
+ dimension: "information",
14178
+ factor: 1e3,
14179
+ offset: 0
14180
+ },
14181
+ MB: {
14182
+ dimension: "information",
14183
+ factor: 1e6,
14184
+ offset: 0
14185
+ },
14186
+ GB: {
14187
+ dimension: "information",
14188
+ factor: 1e9,
14189
+ offset: 0
14190
+ },
14191
+ "°": {
14192
+ dimension: "angle",
14193
+ factor: 1,
14194
+ offset: 0
14195
+ },
14196
+ dBFS: {
14197
+ dimension: "sound-level",
14198
+ factor: 1,
14199
+ offset: 0
14200
+ },
14201
+ dBm: {
14202
+ dimension: "signal-level",
14203
+ factor: 1,
14204
+ offset: 0
14205
+ },
14206
+ mired: {
14207
+ dimension: "colour-temperature",
14208
+ factor: 1,
14209
+ offset: 0
14210
+ },
14211
+ kbps: {
14212
+ dimension: "bitrate",
14213
+ factor: 1,
14214
+ offset: 0
14215
+ },
14216
+ Mbps: {
14217
+ dimension: "bitrate",
14218
+ factor: 1e3,
14219
+ offset: 0
14220
+ },
14221
+ fps: {
14222
+ dimension: "rate",
14223
+ factor: 1,
14224
+ offset: 0
14225
+ }
14226
+ };
14227
+ /** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
14228
+ function specFor(unit) {
14229
+ return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
14230
+ }
14231
+ /** Value in `spec`'s unit → its dimension's canonical unit. */
14232
+ function toCanonical(value, spec) {
14233
+ return value * spec.factor + spec.offset;
14234
+ }
14235
+ /** Canonical-unit value → the unit described by `spec`. */
14236
+ function fromCanonical(canonical, spec) {
14237
+ return (canonical - spec.offset) / spec.factor;
14238
+ }
14239
+ /**
14240
+ * Graceful variant for the render path: returns the converted value, or
14241
+ * `undefined` when the conversion is refused (unknown unit / cross-dimension).
14242
+ * Never throws — a render caller falls back to the raw value + source unit.
14243
+ */
14244
+ function tryConvertUnit(value, from, to) {
14245
+ if (from === to) return value;
14246
+ const fromSpec = specFor(from);
14247
+ if (!fromSpec) return void 0;
14248
+ const toSpec = specFor(to);
14249
+ if (!toSpec) return void 0;
14250
+ if (fromSpec.dimension !== toSpec.dimension) return void 0;
14251
+ return fromCanonical(toCanonical(value, fromSpec), toSpec);
14252
+ }
14253
+ //#endregion
13995
14254
  //#region ../types/dist/index.mjs
13996
14255
  /**
13997
14256
  * The `smtp-inbound` broker kind (D999): a mailbox a device can send mail to.
@@ -42974,6 +43233,7 @@ var ExpressionBindingSourceSchema = union([
42974
43233
  object({
42975
43234
  kind: literal("global"),
42976
43235
  sourceStableId: string(),
43236
+ addonId: string().optional(),
42977
43237
  cap: string(),
42978
43238
  fieldPath: string()
42979
43239
  })
@@ -43040,385 +43300,6 @@ var SourceInfoSchema = object({
43040
43300
  raw: record(string(), unknown()).optional()
43041
43301
  });
43042
43302
  /**
43043
- * Frozen unit → spec table. `•` in the doc marks each dimension's canonical
43044
- * unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
43045
- * `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
43046
- * decimals). K derives from `°C = K − 273.15`.
43047
- */
43048
- var UNIT_TABLE = {
43049
- "°C": {
43050
- dimension: "temperature",
43051
- factor: 1,
43052
- offset: 0
43053
- },
43054
- "°F": {
43055
- dimension: "temperature",
43056
- factor: 5 / 9,
43057
- offset: -160 / 9
43058
- },
43059
- K: {
43060
- dimension: "temperature",
43061
- factor: 1,
43062
- offset: -273.15
43063
- },
43064
- hPa: {
43065
- dimension: "pressure",
43066
- factor: 1,
43067
- offset: 0
43068
- },
43069
- kPa: {
43070
- dimension: "pressure",
43071
- factor: 10,
43072
- offset: 0
43073
- },
43074
- Pa: {
43075
- dimension: "pressure",
43076
- factor: .01,
43077
- offset: 0
43078
- },
43079
- mbar: {
43080
- dimension: "pressure",
43081
- factor: 1,
43082
- offset: 0
43083
- },
43084
- bar: {
43085
- dimension: "pressure",
43086
- factor: 1e3,
43087
- offset: 0
43088
- },
43089
- inHg: {
43090
- dimension: "pressure",
43091
- factor: 33.8639,
43092
- offset: 0
43093
- },
43094
- mmHg: {
43095
- dimension: "pressure",
43096
- factor: 1.33322,
43097
- offset: 0
43098
- },
43099
- psi: {
43100
- dimension: "pressure",
43101
- factor: 68.9476,
43102
- offset: 0
43103
- },
43104
- "m/s": {
43105
- dimension: "speed",
43106
- factor: 1,
43107
- offset: 0
43108
- },
43109
- "km/h": {
43110
- dimension: "speed",
43111
- factor: 1 / 3.6,
43112
- offset: 0
43113
- },
43114
- mph: {
43115
- dimension: "speed",
43116
- factor: .44704,
43117
- offset: 0
43118
- },
43119
- kn: {
43120
- dimension: "speed",
43121
- factor: .514444,
43122
- offset: 0
43123
- },
43124
- "mm/h": {
43125
- dimension: "precipitation-rate",
43126
- factor: 1,
43127
- offset: 0
43128
- },
43129
- "in/h": {
43130
- dimension: "precipitation-rate",
43131
- factor: 25.4,
43132
- offset: 0
43133
- },
43134
- m: {
43135
- dimension: "length",
43136
- factor: 1,
43137
- offset: 0
43138
- },
43139
- mm: {
43140
- dimension: "length",
43141
- factor: .001,
43142
- offset: 0
43143
- },
43144
- cm: {
43145
- dimension: "length",
43146
- factor: .01,
43147
- offset: 0
43148
- },
43149
- km: {
43150
- dimension: "length",
43151
- factor: 1e3,
43152
- offset: 0
43153
- },
43154
- in: {
43155
- dimension: "length",
43156
- factor: .0254,
43157
- offset: 0
43158
- },
43159
- ft: {
43160
- dimension: "length",
43161
- factor: .3048,
43162
- offset: 0
43163
- },
43164
- mi: {
43165
- dimension: "length",
43166
- factor: 1609.344,
43167
- offset: 0
43168
- },
43169
- "m²": {
43170
- dimension: "area",
43171
- factor: 1,
43172
- offset: 0
43173
- },
43174
- lx: {
43175
- dimension: "illuminance",
43176
- factor: 1,
43177
- offset: 0
43178
- },
43179
- "W/m²": {
43180
- dimension: "irradiance",
43181
- factor: 1,
43182
- offset: 0
43183
- },
43184
- W: {
43185
- dimension: "power",
43186
- factor: 1,
43187
- offset: 0
43188
- },
43189
- kW: {
43190
- dimension: "power",
43191
- factor: 1e3,
43192
- offset: 0
43193
- },
43194
- VA: {
43195
- dimension: "apparent-power",
43196
- factor: 1,
43197
- offset: 0
43198
- },
43199
- Wh: {
43200
- dimension: "energy",
43201
- factor: 1,
43202
- offset: 0
43203
- },
43204
- kWh: {
43205
- dimension: "energy",
43206
- factor: 1e3,
43207
- offset: 0
43208
- },
43209
- MWh: {
43210
- dimension: "energy",
43211
- factor: 1e6,
43212
- offset: 0
43213
- },
43214
- V: {
43215
- dimension: "voltage",
43216
- factor: 1,
43217
- offset: 0
43218
- },
43219
- mV: {
43220
- dimension: "voltage",
43221
- factor: .001,
43222
- offset: 0
43223
- },
43224
- A: {
43225
- dimension: "current",
43226
- factor: 1,
43227
- offset: 0
43228
- },
43229
- mA: {
43230
- dimension: "current",
43231
- factor: .001,
43232
- offset: 0
43233
- },
43234
- ppm: {
43235
- dimension: "concentration-volume",
43236
- factor: 1,
43237
- offset: 0
43238
- },
43239
- ppb: {
43240
- dimension: "concentration-volume",
43241
- factor: .001,
43242
- offset: 0
43243
- },
43244
- "µg/m³": {
43245
- dimension: "concentration-mass",
43246
- factor: 1,
43247
- offset: 0
43248
- },
43249
- "mg/m³": {
43250
- dimension: "concentration-mass",
43251
- factor: 1e3,
43252
- offset: 0
43253
- },
43254
- kg: {
43255
- dimension: "mass",
43256
- factor: 1,
43257
- offset: 0
43258
- },
43259
- g: {
43260
- dimension: "mass",
43261
- factor: .001,
43262
- offset: 0
43263
- },
43264
- lb: {
43265
- dimension: "mass",
43266
- factor: .453592,
43267
- offset: 0
43268
- },
43269
- oz: {
43270
- dimension: "mass",
43271
- factor: .0283495,
43272
- offset: 0
43273
- },
43274
- "%": {
43275
- dimension: "percentage",
43276
- factor: 1,
43277
- offset: 0
43278
- },
43279
- L: {
43280
- dimension: "volume",
43281
- factor: 1,
43282
- offset: 0
43283
- },
43284
- mL: {
43285
- dimension: "volume",
43286
- factor: .001,
43287
- offset: 0
43288
- },
43289
- gal: {
43290
- dimension: "volume",
43291
- factor: 3.785411784,
43292
- offset: 0
43293
- },
43294
- s: {
43295
- dimension: "duration",
43296
- factor: 1,
43297
- offset: 0
43298
- },
43299
- ms: {
43300
- dimension: "duration",
43301
- factor: .001,
43302
- offset: 0
43303
- },
43304
- min: {
43305
- dimension: "duration",
43306
- factor: 60,
43307
- offset: 0
43308
- },
43309
- h: {
43310
- dimension: "duration",
43311
- factor: 3600,
43312
- offset: 0
43313
- },
43314
- d: {
43315
- dimension: "duration",
43316
- factor: 86400,
43317
- offset: 0
43318
- },
43319
- B: {
43320
- dimension: "information",
43321
- factor: 1,
43322
- offset: 0
43323
- },
43324
- KiB: {
43325
- dimension: "information",
43326
- factor: 1024,
43327
- offset: 0
43328
- },
43329
- MiB: {
43330
- dimension: "information",
43331
- factor: 1024 ** 2,
43332
- offset: 0
43333
- },
43334
- GiB: {
43335
- dimension: "information",
43336
- factor: 1024 ** 3,
43337
- offset: 0
43338
- },
43339
- TiB: {
43340
- dimension: "information",
43341
- factor: 1024 ** 4,
43342
- offset: 0
43343
- },
43344
- kB: {
43345
- dimension: "information",
43346
- factor: 1e3,
43347
- offset: 0
43348
- },
43349
- MB: {
43350
- dimension: "information",
43351
- factor: 1e6,
43352
- offset: 0
43353
- },
43354
- GB: {
43355
- dimension: "information",
43356
- factor: 1e9,
43357
- offset: 0
43358
- },
43359
- "°": {
43360
- dimension: "angle",
43361
- factor: 1,
43362
- offset: 0
43363
- },
43364
- dBFS: {
43365
- dimension: "sound-level",
43366
- factor: 1,
43367
- offset: 0
43368
- },
43369
- dBm: {
43370
- dimension: "signal-level",
43371
- factor: 1,
43372
- offset: 0
43373
- },
43374
- mired: {
43375
- dimension: "colour-temperature",
43376
- factor: 1,
43377
- offset: 0
43378
- },
43379
- kbps: {
43380
- dimension: "bitrate",
43381
- factor: 1,
43382
- offset: 0
43383
- },
43384
- Mbps: {
43385
- dimension: "bitrate",
43386
- factor: 1e3,
43387
- offset: 0
43388
- },
43389
- fps: {
43390
- dimension: "rate",
43391
- factor: 1,
43392
- offset: 0
43393
- }
43394
- };
43395
- /** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
43396
- function specFor(unit) {
43397
- return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
43398
- }
43399
- /** Value in `spec`'s unit → its dimension's canonical unit. */
43400
- function toCanonical(value, spec) {
43401
- return value * spec.factor + spec.offset;
43402
- }
43403
- /** Canonical-unit value → the unit described by `spec`. */
43404
- function fromCanonical(canonical, spec) {
43405
- return (canonical - spec.offset) / spec.factor;
43406
- }
43407
- /**
43408
- * Graceful variant for the render path: returns the converted value, or
43409
- * `undefined` when the conversion is refused (unknown unit / cross-dimension).
43410
- * Never throws — a render caller falls back to the raw value + source unit.
43411
- */
43412
- function tryConvertUnit(value, from, to) {
43413
- if (from === to) return value;
43414
- const fromSpec = specFor(from);
43415
- if (!fromSpec) return void 0;
43416
- const toSpec = specFor(to);
43417
- if (!toSpec) return void 0;
43418
- if (fromSpec.dimension !== toSpec.dimension) return void 0;
43419
- return fromCanonical(toCanonical(value, fromSpec), toSpec);
43420
- }
43421
- /**
43422
43303
  * A number a person types for a physical quantity — the input side of the
43423
43304
  * value + unit contract (D972).
43424
43305
  *
@@ -45097,26 +44978,23 @@ var SettingsSchemaWithValuesSchema = object({
45097
44978
  var SettingsPatchSchema = record(string(), unknown());
45098
44979
  /** The scope of a scoped-settings call (D986): where the capability declared the values. */
45099
44980
  var ScopedSettingsScopeSchema = _enum(SCOPED_SETTINGS_SCOPES);
44981
+ /** One scoped schema an addon serves: its capability, scope and section ids. */
44982
+ var ScopedSettingsDeclarationSchema = object({
44983
+ cap: string(),
44984
+ scope: ScopedSettingsScopeSchema,
44985
+ sectionIds: array(string())
44986
+ });
45100
44987
  /** Standard success response for update operations. */
45101
44988
  var SettingsUpdateResultSchema = object({ success: literal(true) });
45102
44989
  method(object({
45103
- addonId: string(),
45104
- nodeId: string().optional(),
45105
- overlay: record(string(), unknown()).optional(),
45106
- cap: string().optional()
45107
- }), SettingsSchemaWithValuesSchema.nullable()), method(object({
45108
- addonId: string(),
45109
- nodeId: string().optional(),
45110
- patch: SettingsPatchSchema
45111
- }), SettingsUpdateResultSchema, {
45112
- kind: "mutation",
45113
- auth: "admin"
45114
- }), method(object({
45115
44990
  addonId: string(),
45116
44991
  cap: string(),
45117
44992
  scope: ScopedSettingsScopeSchema,
45118
44993
  nodeId: string().optional()
45119
44994
  }), SettingsSchemaWithValuesSchema.nullable()), method(object({
44995
+ addonId: string(),
44996
+ nodeId: string().optional()
44997
+ }), array(ScopedSettingsDeclarationSchema).nullable()), method(object({
45120
44998
  addonId: string(),
45121
44999
  cap: string(),
45122
45000
  scope: ScopedSettingsScopeSchema,
@@ -45131,9 +45009,6 @@ method(object({
45131
45009
  scope: ScopedSettingsScopeSchema,
45132
45010
  nodeId: string().optional()
45133
45011
  }), record(string(), unknown()).nullable()), method(object({
45134
- addonId: string(),
45135
- nodeId: string().optional()
45136
- }), SettingsSchemaWithValuesSchema.nullable()), method(object({
45137
45012
  addonId: string(),
45138
45013
  nodeId: string().optional(),
45139
45014
  instance: IntegrationInstanceRefSchema
@@ -46473,7 +46348,7 @@ var BackupDestinationInfoSchema = object({
46473
46348
  id: string(),
46474
46349
  /**
46475
46350
  * Manifest id of the owning addon. The Settings button on the
46476
- * destination card opens that addon's `globalSettingsSchema` panel.
46351
+ * destination card opens that addon's scoped settings panel.
46477
46352
  */
46478
46353
  addonId: string(),
46479
46354
  /** Operator-toggled enable flag from the destination-policy table. */
@@ -50943,6 +50818,7 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
50943
50818
  kind: "mutation",
50944
50819
  auth: "admin"
50945
50820
  });
50821
+ var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
50946
50822
  /**
50947
50823
  * A SITE ZONE — a named part of the property that several locations belong to.
50948
50824
  *
@@ -51336,6 +51212,12 @@ var DeviceInfoSchema = object({
51336
51212
  addonId: string(),
51337
51213
  type: _enum(DeviceType),
51338
51214
  name: string(),
51215
+ /** The name a value template uses for this device (`{{ stufa_veranda.temperature }}`),
51216
+ * entity_id style. Generated once from the name at first registration, unique
51217
+ * cluster-wide, editable through `setAlias`, NOT changed by a rename (D1021).
51218
+ * Optional: a record produced by an older build omits it until the boot
51219
+ * backfill has run. */
51220
+ alias: DeviceAliasSchema.optional(),
51339
51221
  /** Operator-organisational location label. `null` when unset. */
51340
51222
  location: string().nullable(),
51341
51223
  /** Soft-disabled flag. */
@@ -51655,6 +51537,25 @@ method(object({
51655
51537
  }), _void(), {
51656
51538
  kind: "mutation",
51657
51539
  auth: "admin"
51540
+ }), method(object({
51541
+ deviceId: number(),
51542
+ alias: string()
51543
+ }), discriminatedUnion("ok", [object({
51544
+ ok: literal(true),
51545
+ alias: DeviceAliasSchema
51546
+ }), object({
51547
+ ok: literal(false),
51548
+ reason: _enum([
51549
+ "empty",
51550
+ "too-long",
51551
+ "grammar",
51552
+ "reserved",
51553
+ "taken"
51554
+ ]),
51555
+ takenBy: number().optional()
51556
+ })]), {
51557
+ kind: "mutation",
51558
+ auth: "admin"
51658
51559
  }), method(object({
51659
51560
  deviceId: number(),
51660
51561
  location: string().nullable()
@@ -64386,6 +64287,11 @@ var NcScheduleSchema = object({
64386
64287
  * as a STATE SUMMARY at the end of each window of `schedule`.
64387
64288
  */
64388
64289
  var NcSystemEventDeliveryModeSchema = _enum(["instant", "summary"]);
64290
+ _enum([
64291
+ "activation",
64292
+ "deactivation",
64293
+ "schedule"
64294
+ ]);
64389
64295
  /**
64390
64296
  * How a summary window is SENT (D698): `rule` (absent) = ONE notification with
64391
64297
  * every section; `section` = one notification per section with something to
@@ -64402,11 +64308,26 @@ var NcStateSummarySplitSchema = _enum(["rule", "section"]);
64402
64308
  * midnight crossing); the send time is each window's END. Refused on the
64403
64309
  * `alarm` family, which stays instant (`systemEventDeliveryProblems`).
64404
64310
  */
64405
- var NcSystemEventDeliverySchema = discriminatedUnion("mode", [object({ mode: literal("instant") }), object({
64406
- mode: literal("summary"),
64407
- schedule: NcScheduleSchema,
64408
- split: NcStateSummarySplitSchema.optional()
64409
- })]);
64311
+ var NcSystemEventDeliverySchema = discriminatedUnion("mode", [
64312
+ object({ mode: literal("instant") }),
64313
+ object({
64314
+ mode: literal("summary"),
64315
+ schedule: NcScheduleSchema,
64316
+ split: NcStateSummarySplitSchema.optional()
64317
+ }),
64318
+ object({
64319
+ mode: literal("modes"),
64320
+ /** The bad edge, and every kind that has a single edge. */
64321
+ onActivation: boolean(),
64322
+ /** The recovery edges of the classes of the selected kinds (derived, never stored per kind). */
64323
+ onDeactivation: boolean(),
64324
+ /** A state summary at the end of each window; absent = no summary. */
64325
+ onSchedule: object({
64326
+ schedule: NcScheduleSchema,
64327
+ grouping: NcStateSummarySplitSchema
64328
+ }).optional()
64329
+ })
64330
+ ]);
64410
64331
  /** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
64411
64332
  var NcPlateMatcherSchema = object({
64412
64333
  /**
@@ -74267,6 +74188,11 @@ var TimedRunUnitSchema = _enum(["s", "min"]);
74267
74188
  _enum(["switch", "pet-fountain"]);
74268
74189
  DeviceType.Heater, DeviceType.PetFountain;
74269
74190
  DeviceType.Heater, DeviceType.PetFountain;
74191
+ /** One duration, as the one-tap run asks for it. */
74192
+ var TimedRunQuickRunSchema = object({
74193
+ duration: number().positive().finite(),
74194
+ unit: TimedRunUnitSchema
74195
+ });
74270
74196
  /** Why a request was not carried out. Typed, so a caller can say it in words. */
74271
74197
  var TimedRunRefusalSchema = _enum([
74272
74198
  "unsupported-device",
@@ -74287,9 +74213,30 @@ object({
74287
74213
  activeUntil: number().nullable(),
74288
74214
  /** Who asked for the run (a user id or an addon id); `null` when nothing is armed or it did not say. */
74289
74215
  requestedBy: string().nullable(),
74216
+ /**
74217
+ * The one-tap run of THIS device: what a "Run" button on any surface starts. `null` when
74218
+ * the device is gone or its type has no timed run; a status from before this field
74219
+ * existed has none, and a surface falls back to the type's default.
74220
+ */
74221
+ quickRun: TimedRunQuickRunSchema.nullable(),
74290
74222
  lastFetchedAt: number()
74291
74223
  });
74292
- method(object({
74224
+ /** What the settings form needs: the unit, the bounds and the type's default. */
74225
+ var TimedRunOptionsSchema = object({
74226
+ unit: TimedRunUnitSchema,
74227
+ /** The longest run, in `unit`. */
74228
+ maxDuration: number(),
74229
+ defaultDuration: number()
74230
+ });
74231
+ /** The one-tap run duration, in the type's unit; `null` returns to the type's default. */
74232
+ var TimedRunSettingsPatchSchema = object({ quickRunDuration: number().positive().finite().nullable().optional() });
74233
+ method(object({ deviceId: number().int() }), TimedRunOptionsSchema), method(object({
74234
+ deviceId: number().int(),
74235
+ settings: TimedRunSettingsPatchSchema
74236
+ }), _void(), {
74237
+ kind: "mutation",
74238
+ auth: "admin"
74239
+ }), method(object({
74293
74240
  deviceId: number().int(),
74294
74241
  duration: number().positive().finite(),
74295
74242
  unit: TimedRunUnitSchema
@@ -76995,13 +76942,6 @@ Object.freeze({
76995
76942
  access: "view",
76996
76943
  role: "admin"
76997
76944
  },
76998
- "addonSettings.getGlobalSettings": {
76999
- capName: "addon-settings",
77000
- capScope: "system",
77001
- addonId: null,
77002
- access: "view",
77003
- role: "admin"
77004
- },
77005
76945
  "addonSettings.getIntegrationFormSchema": {
77006
76946
  capName: "addon-settings",
77007
76947
  capScope: "system",
@@ -77009,14 +76949,14 @@ Object.freeze({
77009
76949
  access: "view",
77010
76950
  role: "admin"
77011
76951
  },
77012
- "addonSettings.getIntegrationSettings": {
76952
+ "addonSettings.getScopedSettings": {
77013
76953
  capName: "addon-settings",
77014
76954
  capScope: "system",
77015
76955
  addonId: null,
77016
76956
  access: "view",
77017
76957
  role: "admin"
77018
76958
  },
77019
- "addonSettings.getScopedSettings": {
76959
+ "addonSettings.listScopedSettings": {
77020
76960
  capName: "addon-settings",
77021
76961
  capScope: "system",
77022
76962
  addonId: null,
@@ -77044,13 +76984,6 @@ Object.freeze({
77044
76984
  access: "create",
77045
76985
  role: "admin"
77046
76986
  },
77047
- "addonSettings.updateGlobalSettings": {
77048
- capName: "addon-settings",
77049
- capScope: "system",
77050
- addonId: null,
77051
- access: "create",
77052
- role: "admin"
77053
- },
77054
76987
  "addonSettings.updateScopedSettings": {
77055
76988
  capName: "addon-settings",
77056
76989
  capScope: "system",
@@ -79221,6 +79154,13 @@ Object.freeze({
79221
79154
  access: "create",
79222
79155
  role: "admin"
79223
79156
  },
79157
+ "deviceManager.setAlias": {
79158
+ capName: "device-manager",
79159
+ capScope: "system",
79160
+ addonId: null,
79161
+ access: "create",
79162
+ role: "admin"
79163
+ },
79224
79164
  "deviceManager.setChildLayout": {
79225
79165
  capName: "device-manager",
79226
79166
  capScope: "system",
@@ -86004,6 +85944,13 @@ Object.freeze({
86004
85944
  access: "create",
86005
85945
  role: "viewer"
86006
85946
  },
85947
+ "timedRun.getOptions": {
85948
+ capName: "timed-run",
85949
+ capScope: "device",
85950
+ addonId: null,
85951
+ access: "view",
85952
+ role: "viewer"
85953
+ },
86007
85954
  "timedRun.getStatus": {
86008
85955
  capName: "timed-run",
86009
85956
  capScope: "device",
@@ -86018,6 +85965,13 @@ Object.freeze({
86018
85965
  access: "create",
86019
85966
  role: "viewer"
86020
85967
  },
85968
+ "timedRun.setSettings": {
85969
+ capName: "timed-run",
85970
+ capScope: "device",
85971
+ addonId: null,
85972
+ access: "create",
85973
+ role: "admin"
85974
+ },
86021
85975
  "toast.onToast": {
86022
85976
  capName: "toast",
86023
85977
  capScope: "system",
@@ -86948,6 +86902,7 @@ function offered(received) {
86948
86902
  };
86949
86903
  }
86950
86904
  offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
86905
+ string().min(1).max(4096);
86951
86906
  Object.freeze({
86952
86907
  "accessories.getStatus": [{
86953
86908
  name: "deviceId",
@@ -87631,6 +87586,11 @@ Object.freeze({
87631
87586
  form: "single",
87632
87587
  optional: false
87633
87588
  }],
87589
+ "deviceManager.setAlias": [{
87590
+ name: "deviceId",
87591
+ form: "single",
87592
+ optional: false
87593
+ }],
87634
87594
  "deviceManager.setChildLayout": [{
87635
87595
  name: "deviceId",
87636
87596
  form: "single",
@@ -89695,6 +89655,11 @@ Object.freeze({
89695
89655
  form: "single",
89696
89656
  optional: false
89697
89657
  }],
89658
+ "timedRun.getOptions": [{
89659
+ name: "deviceId",
89660
+ form: "single",
89661
+ optional: false
89662
+ }],
89698
89663
  "timedRun.getStatus": [{
89699
89664
  name: "deviceId",
89700
89665
  form: "single",
@@ -89705,6 +89670,11 @@ Object.freeze({
89705
89670
  form: "single",
89706
89671
  optional: false
89707
89672
  }],
89673
+ "timedRun.setSettings": [{
89674
+ name: "deviceId",
89675
+ form: "single",
89676
+ optional: false
89677
+ }],
89708
89678
  "update.getStatus": [{
89709
89679
  name: "deviceId",
89710
89680
  form: "single",
@@ -90567,6 +90537,7 @@ var STATE_SUMMARY_VARS = [
90567
90537
  [...RULE_TEXT],
90568
90538
  [...RULE_TEXT],
90569
90539
  [...RULE_TEXT],
90540
+ [...RULE_TEXT],
90570
90541
  [...RULE_BODY_ONLY],
90571
90542
  [...RULE_TEXT],
90572
90543
  ([...RULE_TEXT], [...DEVICE_EVENTS]),