@camstack/addon-smtp-nodemailer 1.2.152 → 1.2.154
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/smtp.addon.js +612 -614
- package/dist/smtp.addon.mjs +612 -614
- package/package.json +2 -2
package/dist/smtp.addon.mjs
CHANGED
|
@@ -839,7 +839,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
839
839
|
return EventCategory;
|
|
840
840
|
}({});
|
|
841
841
|
//#endregion
|
|
842
|
-
//#region ../types/dist/device-type-
|
|
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-
|
|
6045
|
+
//#region ../types/dist/sleep-CGPZyzB5.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).
|
|
@@ -7251,6 +7258,7 @@ var RecordIntegrationInstances = class {
|
|
|
7251
7258
|
this.secretKeys = topLevelSecretKeys(kind.declaration.secretPaths);
|
|
7252
7259
|
this.secretMaps = secretMapKeys(kind.declaration.secretPaths);
|
|
7253
7260
|
this.nameField = kind.declaration.entry?.nameField ?? "name";
|
|
7261
|
+
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`);
|
|
7254
7262
|
}
|
|
7255
7263
|
/**
|
|
7256
7264
|
* One instance read for the addon's own runtime; null when absent. When the keychain is
|
|
@@ -7292,10 +7300,21 @@ var RecordIntegrationInstances = class {
|
|
|
7292
7300
|
}
|
|
7293
7301
|
return out;
|
|
7294
7302
|
}
|
|
7303
|
+
/** The kind an instance body is of: the provider's `kindOf`, else its one declared kind. */
|
|
7304
|
+
kindOfBody(body) {
|
|
7305
|
+
if (this.hooks.kindOf !== void 0) {
|
|
7306
|
+
const id = this.hooks.kindOf(body);
|
|
7307
|
+
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)`);
|
|
7308
|
+
return id;
|
|
7309
|
+
}
|
|
7310
|
+
const only = this.hooks.description.kinds[0];
|
|
7311
|
+
if (only === void 0) throw new Error(`record kind '${this.kind.name}' declares no kinds`);
|
|
7312
|
+
return only.id;
|
|
7313
|
+
}
|
|
7295
7314
|
viewOf(record) {
|
|
7296
7315
|
const shown = secretViewsOf(this.records.owner, this.kind.name, record.id, this.kind.declaration, record.data);
|
|
7297
7316
|
const rawName = record.data[this.nameField];
|
|
7298
|
-
const kind = this.
|
|
7317
|
+
const kind = this.kindOfBody(record.data);
|
|
7299
7318
|
const health = this.hooks.health?.(record.data, record.id);
|
|
7300
7319
|
return {
|
|
7301
7320
|
id: record.id,
|
|
@@ -7303,7 +7322,7 @@ var RecordIntegrationInstances = class {
|
|
|
7303
7322
|
configured: this.hooks.configured(record.data),
|
|
7304
7323
|
enabled: isInstanceEnabled(record.data),
|
|
7305
7324
|
formValues: shown,
|
|
7306
|
-
|
|
7325
|
+
kind,
|
|
7307
7326
|
...health?.status !== void 0 ? { status: health.status } : {},
|
|
7308
7327
|
...health?.lastCheckedAt !== void 0 ? { lastCheckedAt: health.lastCheckedAt } : {}
|
|
7309
7328
|
};
|
|
@@ -8404,7 +8423,7 @@ function boundOf(list) {
|
|
|
8404
8423
|
* Base class for CamStack addons. Eliminates settings boilerplate:
|
|
8405
8424
|
*
|
|
8406
8425
|
* - Typed `config` property with automatic resolution from store + defaults
|
|
8407
|
-
* -
|
|
8426
|
+
* - the scoped settings API (`clusterSettings` / `nodeSettings` / `deviceDefaults`) auto-implemented
|
|
8408
8427
|
* - `getAddonSettings()` / `updateAddonSettings()` auto-implemented
|
|
8409
8428
|
* - `getDeviceSettings()` / `updateDeviceSettings()` auto-implemented
|
|
8410
8429
|
* - `ctx` accessor for the AddonContext (no manual `this.ctxRef` storage)
|
|
@@ -8414,7 +8433,7 @@ function boundOf(list) {
|
|
|
8414
8433
|
* Subclasses override:
|
|
8415
8434
|
* - `onInitialize()` — addon-specific init logic, return ProviderRegistration[]
|
|
8416
8435
|
* - `onShutdown()` — cleanup
|
|
8417
|
-
* - `
|
|
8436
|
+
* - `clusterSettingsSchema()` / `nodeSettingsSchema()` / `deviceSettingsSchema()` — UI schemas
|
|
8418
8437
|
*
|
|
8419
8438
|
* @example
|
|
8420
8439
|
* ```ts
|
|
@@ -8428,7 +8447,7 @@ function boundOf(list) {
|
|
|
8428
8447
|
* super({ maxRetries: 3, endpoint: 'http://localhost' })
|
|
8429
8448
|
* }
|
|
8430
8449
|
*
|
|
8431
|
-
* protected
|
|
8450
|
+
* protected clusterSettingsSchema() {
|
|
8432
8451
|
* return this.schema({
|
|
8433
8452
|
* sections: [{
|
|
8434
8453
|
* id: 'main', title: 'Settings',
|
|
@@ -8471,7 +8490,7 @@ var BaseAddon = class {
|
|
|
8471
8490
|
defaults;
|
|
8472
8491
|
/**
|
|
8473
8492
|
* Hidden-state paths that hold secrets (D787) — values the addon writes
|
|
8474
|
-
* itself (`
|
|
8493
|
+
* itself (`state()`, the scoped writers) that no form field declares.
|
|
8475
8494
|
* Stored in the keychain exactly like a `password` field. Syntax:
|
|
8476
8495
|
* `'snapshotSigningKey'`, `'identity.pincode'`, `'tokens[userId].accessToken'`
|
|
8477
8496
|
* (`key[<id field>]` addresses array items by id, never by index).
|
|
@@ -8481,7 +8500,7 @@ var BaseAddon = class {
|
|
|
8481
8500
|
/**
|
|
8482
8501
|
* D986 M4: the scoped schemas this addon declared, resolved once per capability
|
|
8483
8502
|
* (`loadScopedSchemas`) so the sync readers (`perNodeKeys`, the secret tree, the restart check)
|
|
8484
|
-
* see them. Empty until loaded
|
|
8503
|
+
* see them. Empty until loaded.
|
|
8485
8504
|
*/
|
|
8486
8505
|
_scopedByCap = /* @__PURE__ */ new Map();
|
|
8487
8506
|
_nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
@@ -8667,7 +8686,7 @@ var BaseAddon = class {
|
|
|
8667
8686
|
/** Addon-specific cleanup. Override if needed. */
|
|
8668
8687
|
async onShutdown() {}
|
|
8669
8688
|
/**
|
|
8670
|
-
* Called after config is resolved during
|
|
8689
|
+
* Called after config is resolved during a settings write.
|
|
8671
8690
|
* Override to react to config changes (e.g. restart a sampler, reconnect a service).
|
|
8672
8691
|
* Not called during initialize() — use onInitialize() for initial setup.
|
|
8673
8692
|
*/
|
|
@@ -8696,82 +8715,12 @@ var BaseAddon = class {
|
|
|
8696
8715
|
scopedSettingsCapabilities() {
|
|
8697
8716
|
return [];
|
|
8698
8717
|
}
|
|
8699
|
-
/** Override to provide global-level settings UI schema. */
|
|
8700
|
-
globalSettingsSchema(_cap) {
|
|
8701
|
-
return null;
|
|
8702
|
-
}
|
|
8703
8718
|
/** Override to provide device-level settings UI schema. */
|
|
8704
8719
|
deviceSettingsSchema() {
|
|
8705
8720
|
return null;
|
|
8706
8721
|
}
|
|
8707
8722
|
/**
|
|
8708
|
-
*
|
|
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}.
|
|
8723
|
+
* The form schema of ONE integration instance, or `null` to use the scoped form.
|
|
8775
8724
|
*
|
|
8776
8725
|
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
8777
8726
|
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
@@ -8944,6 +8893,19 @@ var BaseAddon = class {
|
|
|
8944
8893
|
const overlay = await this.scopedSettingsOverlay(scope, cap, nodeId);
|
|
8945
8894
|
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(stored, overlay) : stored, { inlineSecretsAsViews: true });
|
|
8946
8895
|
}
|
|
8896
|
+
/**
|
|
8897
|
+
* The scoped schemas this addon serves: one entry per loaded (capability, scope), capabilities
|
|
8898
|
+
* in declaration order, scopes in {@link SCOPED_SETTINGS_SCOPES} order. `[]` when it declares
|
|
8899
|
+
* nothing.
|
|
8900
|
+
*/
|
|
8901
|
+
async listScopedSettings() {
|
|
8902
|
+
await this.loadScopedSchemas();
|
|
8903
|
+
return [...this._scopedByCap].flatMap(([cap, entries]) => entries.map((entry) => ({
|
|
8904
|
+
cap,
|
|
8905
|
+
scope: entry.scope,
|
|
8906
|
+
sectionIds: entry.schema.sections.map((section) => section.id)
|
|
8907
|
+
})));
|
|
8908
|
+
}
|
|
8947
8909
|
/** The OPERATOR's write of declared keys of one scope (D787 secret semantics). */
|
|
8948
8910
|
async updateScopedSettings(scope, cap, patch, nodeId) {
|
|
8949
8911
|
this._operatorWriteDepth++;
|
|
@@ -8969,32 +8931,15 @@ var BaseAddon = class {
|
|
|
8969
8931
|
*/
|
|
8970
8932
|
async getIntegrationFormSchema(instance, nodeId) {
|
|
8971
8933
|
const scoped = await this.integrationFormSchema(instance);
|
|
8972
|
-
if (scoped === null) return this.
|
|
8934
|
+
if (scoped === null) return this.scopedForm(nodeId);
|
|
8973
8935
|
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
8974
8936
|
}
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
const schema = this.
|
|
8979
|
-
if (!schema)
|
|
8980
|
-
|
|
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 });
|
|
8937
|
+
/** The form of the scoped schemas this addon declared, hydrated from its store. */
|
|
8938
|
+
async scopedForm(nodeId) {
|
|
8939
|
+
await this.loadScopedSchemas();
|
|
8940
|
+
const schema = this.scopedFormSchema();
|
|
8941
|
+
if (!schema) return { sections: [] };
|
|
8942
|
+
return hydrateSchema(schema, await this.readRawProjectedStore(nodeId), { inlineSecretsAsViews: true });
|
|
8998
8943
|
}
|
|
8999
8944
|
/**
|
|
9000
8945
|
* The raw addon store PROJECTED onto the target node's bare per-node keys:
|
|
@@ -9003,8 +8948,8 @@ var BaseAddon = class {
|
|
|
9003
8948
|
* bare fallback), all `@`-scoped and stray bare per-node keys are dropped.
|
|
9004
8949
|
* A no-op passthrough when the schema declares no `perNode` field.
|
|
9005
8950
|
*
|
|
9006
|
-
* This is the sanctioned way for
|
|
9007
|
-
* the store for custom
|
|
8951
|
+
* This is the sanctioned way for an addon that needs
|
|
8952
|
+
* the store for custom logic (option narrowing, value snapping) to
|
|
9008
8953
|
* read it per-node — never `ctx.settings.readAddonStore()` directly.
|
|
9009
8954
|
* `nodeId` omitted ⇒ the local node (node-blind injection from ctx).
|
|
9010
8955
|
*
|
|
@@ -9056,7 +9001,7 @@ var BaseAddon = class {
|
|
|
9056
9001
|
}
|
|
9057
9002
|
/**
|
|
9058
9003
|
* Whether ONE global key of this addon's store was written, read three-way
|
|
9059
|
-
* (D651). For a question a hydrated view cannot answer:
|
|
9004
|
+
* (D651). For a question a hydrated view cannot answer: a hydrated form
|
|
9060
9005
|
* reports `value ?? default`, so "the operator chose the default" and "nobody
|
|
9061
9006
|
* chose" look the same, and a failed read looks like both. A `perNode` key is
|
|
9062
9007
|
* not supported here: its stored name is scoped.
|
|
@@ -9090,7 +9035,7 @@ var BaseAddon = class {
|
|
|
9090
9035
|
}
|
|
9091
9036
|
/**
|
|
9092
9037
|
* The OPERATOR's write — a settings form or an admin API call, dispatched by
|
|
9093
|
-
* the kernel.
|
|
9038
|
+
* the kernel. The one in-process write of the addon blob that is not a scoped write; a secret
|
|
9094
9039
|
* the operator sends is stored as sent even when it equals a pre-keychain
|
|
9095
9040
|
* inline value: the operator re-entering a password is a change, an addon
|
|
9096
9041
|
* writing back what it read is not (D787).
|
|
@@ -9103,9 +9048,6 @@ var BaseAddon = class {
|
|
|
9103
9048
|
this._operatorWriteDepth--;
|
|
9104
9049
|
}
|
|
9105
9050
|
}
|
|
9106
|
-
async updateGlobalSettings(patch, nodeId) {
|
|
9107
|
-
await this.applyGlobalPatch(patch, nodeId);
|
|
9108
|
-
}
|
|
9109
9051
|
/**
|
|
9110
9052
|
* REMOVE stored secrets — their keychain values and their markers (D787).
|
|
9111
9053
|
*
|
|
@@ -9148,8 +9090,7 @@ var BaseAddon = class {
|
|
|
9148
9090
|
await this.resolveConfig();
|
|
9149
9091
|
await this.onConfigChanged();
|
|
9150
9092
|
this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
|
|
9151
|
-
|
|
9152
|
-
this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
|
|
9093
|
+
this.maybeAutoRestart(Object.keys(barePatch), this.loadedScopedSchemas().map((entry) => entry.schema));
|
|
9153
9094
|
return true;
|
|
9154
9095
|
}
|
|
9155
9096
|
/**
|
|
@@ -9187,10 +9128,7 @@ var BaseAddon = class {
|
|
|
9187
9128
|
this._nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
9188
9129
|
this._addonSecretTree = null;
|
|
9189
9130
|
}
|
|
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
|
-
*/
|
|
9131
|
+
/** The form of an addon's scoped schemas: their sections, each shown once. */
|
|
9194
9132
|
scopedFormSchema(cap) {
|
|
9195
9133
|
const byId = /* @__PURE__ */ new Map();
|
|
9196
9134
|
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 +9140,7 @@ var BaseAddon = class {
|
|
|
9202
9140
|
return [...this._scopedByCap.values()].flat();
|
|
9203
9141
|
}
|
|
9204
9142
|
/**
|
|
9205
|
-
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}
|
|
9206
|
-
* the fields the legacy {@link globalSettingsSchema} still marks `perNode: true`. Derived once
|
|
9143
|
+
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}. Derived once
|
|
9207
9144
|
* per `cap` argument and memoized (schemas are static declarations). Empty set ⇒ every
|
|
9208
9145
|
* per-node code path is bypassed and the settings API behaves like the node-agnostic one.
|
|
9209
9146
|
* Call {@link loadScopedSchemas} first (the async seams do).
|
|
@@ -9212,8 +9149,7 @@ var BaseAddon = class {
|
|
|
9212
9149
|
const cacheKey = cap ?? "";
|
|
9213
9150
|
const cached = this._nodeKeysByCap.get(cacheKey);
|
|
9214
9151
|
if (cached) return cached;
|
|
9215
|
-
const
|
|
9216
|
-
const keys = new Set(legacy ? legacy.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
|
|
9152
|
+
const keys = /* @__PURE__ */ new Set();
|
|
9217
9153
|
for (const { scope, schema } of this.loadedScopedSchemas(cap)) {
|
|
9218
9154
|
if (scope !== "node") continue;
|
|
9219
9155
|
for (const section of schema.sections) for (const key of collectValueFieldKeys(section.fields)) keys.add(key);
|
|
@@ -9431,8 +9367,6 @@ var BaseAddon = class {
|
|
|
9431
9367
|
}
|
|
9432
9368
|
declaredKeySet() {
|
|
9433
9369
|
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
9370
|
for (const { schema: scoped } of this.loadedScopedSchemas()) for (const section of scoped.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
9437
9371
|
for (const key of this._declaredStateKeys) keys.add(key);
|
|
9438
9372
|
for (const path of this.secretStatePaths) {
|
|
@@ -9530,7 +9464,7 @@ var BaseAddon = class {
|
|
|
9530
9464
|
/** The addon store's secret tree: schema fields by TYPE, plus `secretStatePaths`. */
|
|
9531
9465
|
addonSecretTree() {
|
|
9532
9466
|
if (this._addonSecretTree === null) {
|
|
9533
|
-
const tree = new Map(
|
|
9467
|
+
const tree = /* @__PURE__ */ new Map();
|
|
9534
9468
|
for (const { schema } of this.loadedScopedSchemas()) for (const [key, node] of secretTreeFromSchema(schema)) tree.set(key, node);
|
|
9535
9469
|
this._addonSecretTree = mergeSecretStatePaths(tree, this.secretStatePaths);
|
|
9536
9470
|
}
|
|
@@ -9742,47 +9676,6 @@ function classifyStoreError(err) {
|
|
|
9742
9676
|
if (TRANSPORT_PHRASES.some((f) => message.includes(f))) return "transport";
|
|
9743
9677
|
return "permanent";
|
|
9744
9678
|
}
|
|
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
9679
|
/** The keys of the value-holding fields, recursing into layout containers. */
|
|
9787
9680
|
function collectValueFieldKeys(fields) {
|
|
9788
9681
|
const collected = [];
|
|
@@ -9815,21 +9708,6 @@ function collectFieldKeys(fields) {
|
|
|
9815
9708
|
}
|
|
9816
9709
|
return collected;
|
|
9817
9710
|
}
|
|
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
9711
|
/**
|
|
9834
9712
|
* Normalize an `ICamstackAddon.initialize()` return value into the
|
|
9835
9713
|
* `AddonInitResult` envelope. Arrays are wrapped into `{ providers }`;
|
|
@@ -12586,13 +12464,25 @@ Object.freeze({
|
|
|
12586
12464
|
"path": "temperature",
|
|
12587
12465
|
"valueType": "number"
|
|
12588
12466
|
}],
|
|
12589
|
-
"timed-run": [
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12467
|
+
"timed-run": [
|
|
12468
|
+
{
|
|
12469
|
+
"path": "activeUntil",
|
|
12470
|
+
"valueType": "number"
|
|
12471
|
+
},
|
|
12472
|
+
{
|
|
12473
|
+
"path": "requestedBy",
|
|
12474
|
+
"valueType": "string"
|
|
12475
|
+
},
|
|
12476
|
+
{
|
|
12477
|
+
"path": "quickRun.duration",
|
|
12478
|
+
"valueType": "number"
|
|
12479
|
+
},
|
|
12480
|
+
{
|
|
12481
|
+
"path": "quickRun.unit",
|
|
12482
|
+
"valueType": "enum",
|
|
12483
|
+
"enumValues": ["s", "min"]
|
|
12484
|
+
}
|
|
12485
|
+
],
|
|
12596
12486
|
"update": [
|
|
12597
12487
|
{
|
|
12598
12488
|
"path": "currentVersion",
|
|
@@ -12830,7 +12720,7 @@ function userError(code, params, englishFallback) {
|
|
|
12830
12720
|
return new CamstackError(code, params, englishFallback);
|
|
12831
12721
|
}
|
|
12832
12722
|
//#endregion
|
|
12833
|
-
//#region ../types/dist/composition-
|
|
12723
|
+
//#region ../types/dist/composition-Bx0JvKUU.mjs
|
|
12834
12724
|
/**
|
|
12835
12725
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
12836
12726
|
*
|
|
@@ -13992,6 +13882,387 @@ var NodeColorIdSchema = _enum([
|
|
|
13992
13882
|
"node-h"
|
|
13993
13883
|
]);
|
|
13994
13884
|
//#endregion
|
|
13885
|
+
//#region ../types/dist/convert-BAzH15HU.mjs
|
|
13886
|
+
/**
|
|
13887
|
+
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
13888
|
+
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
13889
|
+
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
13890
|
+
* decimals). K derives from `°C = K − 273.15`.
|
|
13891
|
+
*/
|
|
13892
|
+
var UNIT_TABLE = {
|
|
13893
|
+
"°C": {
|
|
13894
|
+
dimension: "temperature",
|
|
13895
|
+
factor: 1,
|
|
13896
|
+
offset: 0
|
|
13897
|
+
},
|
|
13898
|
+
"°F": {
|
|
13899
|
+
dimension: "temperature",
|
|
13900
|
+
factor: 5 / 9,
|
|
13901
|
+
offset: -160 / 9
|
|
13902
|
+
},
|
|
13903
|
+
K: {
|
|
13904
|
+
dimension: "temperature",
|
|
13905
|
+
factor: 1,
|
|
13906
|
+
offset: -273.15
|
|
13907
|
+
},
|
|
13908
|
+
hPa: {
|
|
13909
|
+
dimension: "pressure",
|
|
13910
|
+
factor: 1,
|
|
13911
|
+
offset: 0
|
|
13912
|
+
},
|
|
13913
|
+
kPa: {
|
|
13914
|
+
dimension: "pressure",
|
|
13915
|
+
factor: 10,
|
|
13916
|
+
offset: 0
|
|
13917
|
+
},
|
|
13918
|
+
Pa: {
|
|
13919
|
+
dimension: "pressure",
|
|
13920
|
+
factor: .01,
|
|
13921
|
+
offset: 0
|
|
13922
|
+
},
|
|
13923
|
+
mbar: {
|
|
13924
|
+
dimension: "pressure",
|
|
13925
|
+
factor: 1,
|
|
13926
|
+
offset: 0
|
|
13927
|
+
},
|
|
13928
|
+
bar: {
|
|
13929
|
+
dimension: "pressure",
|
|
13930
|
+
factor: 1e3,
|
|
13931
|
+
offset: 0
|
|
13932
|
+
},
|
|
13933
|
+
inHg: {
|
|
13934
|
+
dimension: "pressure",
|
|
13935
|
+
factor: 33.8639,
|
|
13936
|
+
offset: 0
|
|
13937
|
+
},
|
|
13938
|
+
mmHg: {
|
|
13939
|
+
dimension: "pressure",
|
|
13940
|
+
factor: 1.33322,
|
|
13941
|
+
offset: 0
|
|
13942
|
+
},
|
|
13943
|
+
psi: {
|
|
13944
|
+
dimension: "pressure",
|
|
13945
|
+
factor: 68.9476,
|
|
13946
|
+
offset: 0
|
|
13947
|
+
},
|
|
13948
|
+
"m/s": {
|
|
13949
|
+
dimension: "speed",
|
|
13950
|
+
factor: 1,
|
|
13951
|
+
offset: 0
|
|
13952
|
+
},
|
|
13953
|
+
"km/h": {
|
|
13954
|
+
dimension: "speed",
|
|
13955
|
+
factor: 1 / 3.6,
|
|
13956
|
+
offset: 0
|
|
13957
|
+
},
|
|
13958
|
+
mph: {
|
|
13959
|
+
dimension: "speed",
|
|
13960
|
+
factor: .44704,
|
|
13961
|
+
offset: 0
|
|
13962
|
+
},
|
|
13963
|
+
kn: {
|
|
13964
|
+
dimension: "speed",
|
|
13965
|
+
factor: .514444,
|
|
13966
|
+
offset: 0
|
|
13967
|
+
},
|
|
13968
|
+
"mm/h": {
|
|
13969
|
+
dimension: "precipitation-rate",
|
|
13970
|
+
factor: 1,
|
|
13971
|
+
offset: 0
|
|
13972
|
+
},
|
|
13973
|
+
"in/h": {
|
|
13974
|
+
dimension: "precipitation-rate",
|
|
13975
|
+
factor: 25.4,
|
|
13976
|
+
offset: 0
|
|
13977
|
+
},
|
|
13978
|
+
m: {
|
|
13979
|
+
dimension: "length",
|
|
13980
|
+
factor: 1,
|
|
13981
|
+
offset: 0
|
|
13982
|
+
},
|
|
13983
|
+
mm: {
|
|
13984
|
+
dimension: "length",
|
|
13985
|
+
factor: .001,
|
|
13986
|
+
offset: 0
|
|
13987
|
+
},
|
|
13988
|
+
cm: {
|
|
13989
|
+
dimension: "length",
|
|
13990
|
+
factor: .01,
|
|
13991
|
+
offset: 0
|
|
13992
|
+
},
|
|
13993
|
+
km: {
|
|
13994
|
+
dimension: "length",
|
|
13995
|
+
factor: 1e3,
|
|
13996
|
+
offset: 0
|
|
13997
|
+
},
|
|
13998
|
+
in: {
|
|
13999
|
+
dimension: "length",
|
|
14000
|
+
factor: .0254,
|
|
14001
|
+
offset: 0
|
|
14002
|
+
},
|
|
14003
|
+
ft: {
|
|
14004
|
+
dimension: "length",
|
|
14005
|
+
factor: .3048,
|
|
14006
|
+
offset: 0
|
|
14007
|
+
},
|
|
14008
|
+
mi: {
|
|
14009
|
+
dimension: "length",
|
|
14010
|
+
factor: 1609.344,
|
|
14011
|
+
offset: 0
|
|
14012
|
+
},
|
|
14013
|
+
"m²": {
|
|
14014
|
+
dimension: "area",
|
|
14015
|
+
factor: 1,
|
|
14016
|
+
offset: 0
|
|
14017
|
+
},
|
|
14018
|
+
lx: {
|
|
14019
|
+
dimension: "illuminance",
|
|
14020
|
+
factor: 1,
|
|
14021
|
+
offset: 0
|
|
14022
|
+
},
|
|
14023
|
+
"W/m²": {
|
|
14024
|
+
dimension: "irradiance",
|
|
14025
|
+
factor: 1,
|
|
14026
|
+
offset: 0
|
|
14027
|
+
},
|
|
14028
|
+
W: {
|
|
14029
|
+
dimension: "power",
|
|
14030
|
+
factor: 1,
|
|
14031
|
+
offset: 0
|
|
14032
|
+
},
|
|
14033
|
+
kW: {
|
|
14034
|
+
dimension: "power",
|
|
14035
|
+
factor: 1e3,
|
|
14036
|
+
offset: 0
|
|
14037
|
+
},
|
|
14038
|
+
VA: {
|
|
14039
|
+
dimension: "apparent-power",
|
|
14040
|
+
factor: 1,
|
|
14041
|
+
offset: 0
|
|
14042
|
+
},
|
|
14043
|
+
Wh: {
|
|
14044
|
+
dimension: "energy",
|
|
14045
|
+
factor: 1,
|
|
14046
|
+
offset: 0
|
|
14047
|
+
},
|
|
14048
|
+
kWh: {
|
|
14049
|
+
dimension: "energy",
|
|
14050
|
+
factor: 1e3,
|
|
14051
|
+
offset: 0
|
|
14052
|
+
},
|
|
14053
|
+
MWh: {
|
|
14054
|
+
dimension: "energy",
|
|
14055
|
+
factor: 1e6,
|
|
14056
|
+
offset: 0
|
|
14057
|
+
},
|
|
14058
|
+
V: {
|
|
14059
|
+
dimension: "voltage",
|
|
14060
|
+
factor: 1,
|
|
14061
|
+
offset: 0
|
|
14062
|
+
},
|
|
14063
|
+
mV: {
|
|
14064
|
+
dimension: "voltage",
|
|
14065
|
+
factor: .001,
|
|
14066
|
+
offset: 0
|
|
14067
|
+
},
|
|
14068
|
+
A: {
|
|
14069
|
+
dimension: "current",
|
|
14070
|
+
factor: 1,
|
|
14071
|
+
offset: 0
|
|
14072
|
+
},
|
|
14073
|
+
mA: {
|
|
14074
|
+
dimension: "current",
|
|
14075
|
+
factor: .001,
|
|
14076
|
+
offset: 0
|
|
14077
|
+
},
|
|
14078
|
+
ppm: {
|
|
14079
|
+
dimension: "concentration-volume",
|
|
14080
|
+
factor: 1,
|
|
14081
|
+
offset: 0
|
|
14082
|
+
},
|
|
14083
|
+
ppb: {
|
|
14084
|
+
dimension: "concentration-volume",
|
|
14085
|
+
factor: .001,
|
|
14086
|
+
offset: 0
|
|
14087
|
+
},
|
|
14088
|
+
"µg/m³": {
|
|
14089
|
+
dimension: "concentration-mass",
|
|
14090
|
+
factor: 1,
|
|
14091
|
+
offset: 0
|
|
14092
|
+
},
|
|
14093
|
+
"mg/m³": {
|
|
14094
|
+
dimension: "concentration-mass",
|
|
14095
|
+
factor: 1e3,
|
|
14096
|
+
offset: 0
|
|
14097
|
+
},
|
|
14098
|
+
kg: {
|
|
14099
|
+
dimension: "mass",
|
|
14100
|
+
factor: 1,
|
|
14101
|
+
offset: 0
|
|
14102
|
+
},
|
|
14103
|
+
g: {
|
|
14104
|
+
dimension: "mass",
|
|
14105
|
+
factor: .001,
|
|
14106
|
+
offset: 0
|
|
14107
|
+
},
|
|
14108
|
+
lb: {
|
|
14109
|
+
dimension: "mass",
|
|
14110
|
+
factor: .453592,
|
|
14111
|
+
offset: 0
|
|
14112
|
+
},
|
|
14113
|
+
oz: {
|
|
14114
|
+
dimension: "mass",
|
|
14115
|
+
factor: .0283495,
|
|
14116
|
+
offset: 0
|
|
14117
|
+
},
|
|
14118
|
+
"%": {
|
|
14119
|
+
dimension: "percentage",
|
|
14120
|
+
factor: 1,
|
|
14121
|
+
offset: 0
|
|
14122
|
+
},
|
|
14123
|
+
L: {
|
|
14124
|
+
dimension: "volume",
|
|
14125
|
+
factor: 1,
|
|
14126
|
+
offset: 0
|
|
14127
|
+
},
|
|
14128
|
+
mL: {
|
|
14129
|
+
dimension: "volume",
|
|
14130
|
+
factor: .001,
|
|
14131
|
+
offset: 0
|
|
14132
|
+
},
|
|
14133
|
+
gal: {
|
|
14134
|
+
dimension: "volume",
|
|
14135
|
+
factor: 3.785411784,
|
|
14136
|
+
offset: 0
|
|
14137
|
+
},
|
|
14138
|
+
s: {
|
|
14139
|
+
dimension: "duration",
|
|
14140
|
+
factor: 1,
|
|
14141
|
+
offset: 0
|
|
14142
|
+
},
|
|
14143
|
+
ms: {
|
|
14144
|
+
dimension: "duration",
|
|
14145
|
+
factor: .001,
|
|
14146
|
+
offset: 0
|
|
14147
|
+
},
|
|
14148
|
+
min: {
|
|
14149
|
+
dimension: "duration",
|
|
14150
|
+
factor: 60,
|
|
14151
|
+
offset: 0
|
|
14152
|
+
},
|
|
14153
|
+
h: {
|
|
14154
|
+
dimension: "duration",
|
|
14155
|
+
factor: 3600,
|
|
14156
|
+
offset: 0
|
|
14157
|
+
},
|
|
14158
|
+
d: {
|
|
14159
|
+
dimension: "duration",
|
|
14160
|
+
factor: 86400,
|
|
14161
|
+
offset: 0
|
|
14162
|
+
},
|
|
14163
|
+
B: {
|
|
14164
|
+
dimension: "information",
|
|
14165
|
+
factor: 1,
|
|
14166
|
+
offset: 0
|
|
14167
|
+
},
|
|
14168
|
+
KiB: {
|
|
14169
|
+
dimension: "information",
|
|
14170
|
+
factor: 1024,
|
|
14171
|
+
offset: 0
|
|
14172
|
+
},
|
|
14173
|
+
MiB: {
|
|
14174
|
+
dimension: "information",
|
|
14175
|
+
factor: 1024 ** 2,
|
|
14176
|
+
offset: 0
|
|
14177
|
+
},
|
|
14178
|
+
GiB: {
|
|
14179
|
+
dimension: "information",
|
|
14180
|
+
factor: 1024 ** 3,
|
|
14181
|
+
offset: 0
|
|
14182
|
+
},
|
|
14183
|
+
TiB: {
|
|
14184
|
+
dimension: "information",
|
|
14185
|
+
factor: 1024 ** 4,
|
|
14186
|
+
offset: 0
|
|
14187
|
+
},
|
|
14188
|
+
kB: {
|
|
14189
|
+
dimension: "information",
|
|
14190
|
+
factor: 1e3,
|
|
14191
|
+
offset: 0
|
|
14192
|
+
},
|
|
14193
|
+
MB: {
|
|
14194
|
+
dimension: "information",
|
|
14195
|
+
factor: 1e6,
|
|
14196
|
+
offset: 0
|
|
14197
|
+
},
|
|
14198
|
+
GB: {
|
|
14199
|
+
dimension: "information",
|
|
14200
|
+
factor: 1e9,
|
|
14201
|
+
offset: 0
|
|
14202
|
+
},
|
|
14203
|
+
"°": {
|
|
14204
|
+
dimension: "angle",
|
|
14205
|
+
factor: 1,
|
|
14206
|
+
offset: 0
|
|
14207
|
+
},
|
|
14208
|
+
dBFS: {
|
|
14209
|
+
dimension: "sound-level",
|
|
14210
|
+
factor: 1,
|
|
14211
|
+
offset: 0
|
|
14212
|
+
},
|
|
14213
|
+
dBm: {
|
|
14214
|
+
dimension: "signal-level",
|
|
14215
|
+
factor: 1,
|
|
14216
|
+
offset: 0
|
|
14217
|
+
},
|
|
14218
|
+
mired: {
|
|
14219
|
+
dimension: "colour-temperature",
|
|
14220
|
+
factor: 1,
|
|
14221
|
+
offset: 0
|
|
14222
|
+
},
|
|
14223
|
+
kbps: {
|
|
14224
|
+
dimension: "bitrate",
|
|
14225
|
+
factor: 1,
|
|
14226
|
+
offset: 0
|
|
14227
|
+
},
|
|
14228
|
+
Mbps: {
|
|
14229
|
+
dimension: "bitrate",
|
|
14230
|
+
factor: 1e3,
|
|
14231
|
+
offset: 0
|
|
14232
|
+
},
|
|
14233
|
+
fps: {
|
|
14234
|
+
dimension: "rate",
|
|
14235
|
+
factor: 1,
|
|
14236
|
+
offset: 0
|
|
14237
|
+
}
|
|
14238
|
+
};
|
|
14239
|
+
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
14240
|
+
function specFor(unit) {
|
|
14241
|
+
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
14242
|
+
}
|
|
14243
|
+
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
14244
|
+
function toCanonical(value, spec) {
|
|
14245
|
+
return value * spec.factor + spec.offset;
|
|
14246
|
+
}
|
|
14247
|
+
/** Canonical-unit value → the unit described by `spec`. */
|
|
14248
|
+
function fromCanonical(canonical, spec) {
|
|
14249
|
+
return (canonical - spec.offset) / spec.factor;
|
|
14250
|
+
}
|
|
14251
|
+
/**
|
|
14252
|
+
* Graceful variant for the render path: returns the converted value, or
|
|
14253
|
+
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
14254
|
+
* Never throws — a render caller falls back to the raw value + source unit.
|
|
14255
|
+
*/
|
|
14256
|
+
function tryConvertUnit(value, from, to) {
|
|
14257
|
+
if (from === to) return value;
|
|
14258
|
+
const fromSpec = specFor(from);
|
|
14259
|
+
if (!fromSpec) return void 0;
|
|
14260
|
+
const toSpec = specFor(to);
|
|
14261
|
+
if (!toSpec) return void 0;
|
|
14262
|
+
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
14263
|
+
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
14264
|
+
}
|
|
14265
|
+
//#endregion
|
|
13995
14266
|
//#region ../types/dist/index.mjs
|
|
13996
14267
|
/**
|
|
13997
14268
|
* The `smtp-inbound` broker kind (D999): a mailbox a device can send mail to.
|
|
@@ -42974,6 +43245,7 @@ var ExpressionBindingSourceSchema = union([
|
|
|
42974
43245
|
object({
|
|
42975
43246
|
kind: literal("global"),
|
|
42976
43247
|
sourceStableId: string(),
|
|
43248
|
+
addonId: string().optional(),
|
|
42977
43249
|
cap: string(),
|
|
42978
43250
|
fieldPath: string()
|
|
42979
43251
|
})
|
|
@@ -43040,385 +43312,6 @@ var SourceInfoSchema = object({
|
|
|
43040
43312
|
raw: record(string(), unknown()).optional()
|
|
43041
43313
|
});
|
|
43042
43314
|
/**
|
|
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
43315
|
* A number a person types for a physical quantity — the input side of the
|
|
43423
43316
|
* value + unit contract (D972).
|
|
43424
43317
|
*
|
|
@@ -45097,26 +44990,23 @@ var SettingsSchemaWithValuesSchema = object({
|
|
|
45097
44990
|
var SettingsPatchSchema = record(string(), unknown());
|
|
45098
44991
|
/** The scope of a scoped-settings call (D986): where the capability declared the values. */
|
|
45099
44992
|
var ScopedSettingsScopeSchema = _enum(SCOPED_SETTINGS_SCOPES);
|
|
44993
|
+
/** One scoped schema an addon serves: its capability, scope and section ids. */
|
|
44994
|
+
var ScopedSettingsDeclarationSchema = object({
|
|
44995
|
+
cap: string(),
|
|
44996
|
+
scope: ScopedSettingsScopeSchema,
|
|
44997
|
+
sectionIds: array(string())
|
|
44998
|
+
});
|
|
45100
44999
|
/** Standard success response for update operations. */
|
|
45101
45000
|
var SettingsUpdateResultSchema = object({ success: literal(true) });
|
|
45102
45001
|
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
45002
|
addonId: string(),
|
|
45116
45003
|
cap: string(),
|
|
45117
45004
|
scope: ScopedSettingsScopeSchema,
|
|
45118
45005
|
nodeId: string().optional()
|
|
45119
45006
|
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45007
|
+
addonId: string(),
|
|
45008
|
+
nodeId: string().optional()
|
|
45009
|
+
}), array(ScopedSettingsDeclarationSchema).nullable()), method(object({
|
|
45120
45010
|
addonId: string(),
|
|
45121
45011
|
cap: string(),
|
|
45122
45012
|
scope: ScopedSettingsScopeSchema,
|
|
@@ -45131,9 +45021,6 @@ method(object({
|
|
|
45131
45021
|
scope: ScopedSettingsScopeSchema,
|
|
45132
45022
|
nodeId: string().optional()
|
|
45133
45023
|
}), record(string(), unknown()).nullable()), method(object({
|
|
45134
|
-
addonId: string(),
|
|
45135
|
-
nodeId: string().optional()
|
|
45136
|
-
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45137
45024
|
addonId: string(),
|
|
45138
45025
|
nodeId: string().optional(),
|
|
45139
45026
|
instance: IntegrationInstanceRefSchema
|
|
@@ -46473,7 +46360,7 @@ var BackupDestinationInfoSchema = object({
|
|
|
46473
46360
|
id: string(),
|
|
46474
46361
|
/**
|
|
46475
46362
|
* Manifest id of the owning addon. The Settings button on the
|
|
46476
|
-
* destination card opens that addon's
|
|
46363
|
+
* destination card opens that addon's scoped settings panel.
|
|
46477
46364
|
*/
|
|
46478
46365
|
addonId: string(),
|
|
46479
46366
|
/** Operator-toggled enable flag from the destination-policy table. */
|
|
@@ -49072,7 +48959,7 @@ DeviceType.MediaPlayer, method(deviceOnly, _void(), {
|
|
|
49072
48959
|
kind: "mutation",
|
|
49073
48960
|
auth: "protected"
|
|
49074
48961
|
});
|
|
49075
|
-
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;
|
|
48962
|
+
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;
|
|
49076
48963
|
var NUMBER = {
|
|
49077
48964
|
kind: "fixed",
|
|
49078
48965
|
result: ["number"]
|
|
@@ -50943,6 +50830,7 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
|
|
|
50943
50830
|
kind: "mutation",
|
|
50944
50831
|
auth: "admin"
|
|
50945
50832
|
});
|
|
50833
|
+
var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
|
|
50946
50834
|
/**
|
|
50947
50835
|
* A SITE ZONE — a named part of the property that several locations belong to.
|
|
50948
50836
|
*
|
|
@@ -51336,6 +51224,12 @@ var DeviceInfoSchema = object({
|
|
|
51336
51224
|
addonId: string(),
|
|
51337
51225
|
type: _enum(DeviceType),
|
|
51338
51226
|
name: string(),
|
|
51227
|
+
/** The name a value template uses for this device (`{{ stufa_veranda.temperature }}`),
|
|
51228
|
+
* entity_id style. Generated once from the name at first registration, unique
|
|
51229
|
+
* cluster-wide, editable through `setAlias`, NOT changed by a rename (D1021).
|
|
51230
|
+
* Optional: a record produced by an older build omits it until the boot
|
|
51231
|
+
* backfill has run. */
|
|
51232
|
+
alias: DeviceAliasSchema.optional(),
|
|
51339
51233
|
/** Operator-organisational location label. `null` when unset. */
|
|
51340
51234
|
location: string().nullable(),
|
|
51341
51235
|
/** Soft-disabled flag. */
|
|
@@ -51655,6 +51549,25 @@ method(object({
|
|
|
51655
51549
|
}), _void(), {
|
|
51656
51550
|
kind: "mutation",
|
|
51657
51551
|
auth: "admin"
|
|
51552
|
+
}), method(object({
|
|
51553
|
+
deviceId: number(),
|
|
51554
|
+
alias: string()
|
|
51555
|
+
}), discriminatedUnion("ok", [object({
|
|
51556
|
+
ok: literal(true),
|
|
51557
|
+
alias: DeviceAliasSchema
|
|
51558
|
+
}), object({
|
|
51559
|
+
ok: literal(false),
|
|
51560
|
+
reason: _enum([
|
|
51561
|
+
"empty",
|
|
51562
|
+
"too-long",
|
|
51563
|
+
"grammar",
|
|
51564
|
+
"reserved",
|
|
51565
|
+
"taken"
|
|
51566
|
+
]),
|
|
51567
|
+
takenBy: number().optional()
|
|
51568
|
+
})]), {
|
|
51569
|
+
kind: "mutation",
|
|
51570
|
+
auth: "admin"
|
|
51658
51571
|
}), method(object({
|
|
51659
51572
|
deviceId: number(),
|
|
51660
51573
|
location: string().nullable()
|
|
@@ -54776,10 +54689,11 @@ var IntegrationInstanceDescriptionSchema = object({
|
|
|
54776
54689
|
/** True when `testInstance` really probes the remote. */
|
|
54777
54690
|
canTest: boolean(),
|
|
54778
54691
|
/**
|
|
54779
|
-
* The kinds an instance can be of
|
|
54780
|
-
* Add flow asks which first and sends it as
|
|
54692
|
+
* The kinds an instance can be of (D1013 rule 1), each naming its `functionCap`. One entry:
|
|
54693
|
+
* nothing to choose; more than one: the Add flow asks which first and sends it as
|
|
54694
|
+
* `createInstance.kind`. Never empty: every instance belongs to exactly one kind.
|
|
54781
54695
|
*/
|
|
54782
|
-
kinds: array(IntegrationInstanceKindSchema).
|
|
54696
|
+
kinds: array(IntegrationInstanceKindSchema).min(1),
|
|
54783
54697
|
/**
|
|
54784
54698
|
* The provider accepts `createInstance.id` for an id that once existed (an adopted id, because
|
|
54785
54699
|
* devices carry it). The UI then offers "restore under its old id" on Add. Absent means no.
|
|
@@ -54815,8 +54729,8 @@ var IntegrationInstanceSchema = object({
|
|
|
54815
54729
|
* the body is the one store, `setInstanceEnabled` the one writer (epic #440, step 3).
|
|
54816
54730
|
*/
|
|
54817
54731
|
enabled: boolean().optional(),
|
|
54818
|
-
/** The kind of this instance
|
|
54819
|
-
kind: string().
|
|
54732
|
+
/** The kind of this instance: exactly one of `describe().kinds[].id` (D1013 rule 2). */
|
|
54733
|
+
kind: string().min(1),
|
|
54820
54734
|
/** Values for the instance form; a secret is a `SecretFieldView`, never text. */
|
|
54821
54735
|
formValues: record(string(), unknown()),
|
|
54822
54736
|
status: IntegrationInstanceStatusSchema.optional(),
|
|
@@ -64386,6 +64300,11 @@ var NcScheduleSchema = object({
|
|
|
64386
64300
|
* as a STATE SUMMARY at the end of each window of `schedule`.
|
|
64387
64301
|
*/
|
|
64388
64302
|
var NcSystemEventDeliveryModeSchema = _enum(["instant", "summary"]);
|
|
64303
|
+
_enum([
|
|
64304
|
+
"activation",
|
|
64305
|
+
"deactivation",
|
|
64306
|
+
"schedule"
|
|
64307
|
+
]);
|
|
64389
64308
|
/**
|
|
64390
64309
|
* How a summary window is SENT (D698): `rule` (absent) = ONE notification with
|
|
64391
64310
|
* every section; `section` = one notification per section with something to
|
|
@@ -64402,11 +64321,26 @@ var NcStateSummarySplitSchema = _enum(["rule", "section"]);
|
|
|
64402
64321
|
* midnight crossing); the send time is each window's END. Refused on the
|
|
64403
64322
|
* `alarm` family, which stays instant (`systemEventDeliveryProblems`).
|
|
64404
64323
|
*/
|
|
64405
|
-
var NcSystemEventDeliverySchema = discriminatedUnion("mode", [
|
|
64406
|
-
mode: literal("
|
|
64407
|
-
|
|
64408
|
-
|
|
64409
|
-
|
|
64324
|
+
var NcSystemEventDeliverySchema = discriminatedUnion("mode", [
|
|
64325
|
+
object({ mode: literal("instant") }),
|
|
64326
|
+
object({
|
|
64327
|
+
mode: literal("summary"),
|
|
64328
|
+
schedule: NcScheduleSchema,
|
|
64329
|
+
split: NcStateSummarySplitSchema.optional()
|
|
64330
|
+
}),
|
|
64331
|
+
object({
|
|
64332
|
+
mode: literal("modes"),
|
|
64333
|
+
/** The bad edge, and every kind that has a single edge. */
|
|
64334
|
+
onActivation: boolean(),
|
|
64335
|
+
/** The recovery edges of the classes of the selected kinds (derived, never stored per kind). */
|
|
64336
|
+
onDeactivation: boolean(),
|
|
64337
|
+
/** A state summary at the end of each window; absent = no summary. */
|
|
64338
|
+
onSchedule: object({
|
|
64339
|
+
schedule: NcScheduleSchema,
|
|
64340
|
+
grouping: NcStateSummarySplitSchema
|
|
64341
|
+
}).optional()
|
|
64342
|
+
})
|
|
64343
|
+
]);
|
|
64410
64344
|
/** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
|
|
64411
64345
|
var NcPlateMatcherSchema = object({
|
|
64412
64346
|
/**
|
|
@@ -71733,6 +71667,7 @@ var RemoteLayoutComponentSchema = object({
|
|
|
71733
71667
|
});
|
|
71734
71668
|
});
|
|
71735
71669
|
method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
|
|
71670
|
+
DeviceType.MediaPlayer;
|
|
71736
71671
|
var RunningStateSourceSchema = _enum(["native", "assigned"]);
|
|
71737
71672
|
object({
|
|
71738
71673
|
/** null = unknown — never coerced to false (D393). */
|
|
@@ -74267,6 +74202,11 @@ var TimedRunUnitSchema = _enum(["s", "min"]);
|
|
|
74267
74202
|
_enum(["switch", "pet-fountain"]);
|
|
74268
74203
|
DeviceType.Heater, DeviceType.PetFountain;
|
|
74269
74204
|
DeviceType.Heater, DeviceType.PetFountain;
|
|
74205
|
+
/** One duration, as the one-tap run asks for it. */
|
|
74206
|
+
var TimedRunQuickRunSchema = object({
|
|
74207
|
+
duration: number().positive().finite(),
|
|
74208
|
+
unit: TimedRunUnitSchema
|
|
74209
|
+
});
|
|
74270
74210
|
/** Why a request was not carried out. Typed, so a caller can say it in words. */
|
|
74271
74211
|
var TimedRunRefusalSchema = _enum([
|
|
74272
74212
|
"unsupported-device",
|
|
@@ -74287,9 +74227,30 @@ object({
|
|
|
74287
74227
|
activeUntil: number().nullable(),
|
|
74288
74228
|
/** Who asked for the run (a user id or an addon id); `null` when nothing is armed or it did not say. */
|
|
74289
74229
|
requestedBy: string().nullable(),
|
|
74230
|
+
/**
|
|
74231
|
+
* The one-tap run of THIS device: what a "Run" button on any surface starts. `null` when
|
|
74232
|
+
* the device is gone or its type has no timed run; a status from before this field
|
|
74233
|
+
* existed has none, and a surface falls back to the type's default.
|
|
74234
|
+
*/
|
|
74235
|
+
quickRun: TimedRunQuickRunSchema.nullable(),
|
|
74290
74236
|
lastFetchedAt: number()
|
|
74291
74237
|
});
|
|
74292
|
-
|
|
74238
|
+
/** What the settings form needs: the unit, the bounds and the type's default. */
|
|
74239
|
+
var TimedRunOptionsSchema = object({
|
|
74240
|
+
unit: TimedRunUnitSchema,
|
|
74241
|
+
/** The longest run, in `unit`. */
|
|
74242
|
+
maxDuration: number(),
|
|
74243
|
+
defaultDuration: number()
|
|
74244
|
+
});
|
|
74245
|
+
/** The one-tap run duration, in the type's unit; `null` returns to the type's default. */
|
|
74246
|
+
var TimedRunSettingsPatchSchema = object({ quickRunDuration: number().positive().finite().nullable().optional() });
|
|
74247
|
+
method(object({ deviceId: number().int() }), TimedRunOptionsSchema), method(object({
|
|
74248
|
+
deviceId: number().int(),
|
|
74249
|
+
settings: TimedRunSettingsPatchSchema
|
|
74250
|
+
}), _void(), {
|
|
74251
|
+
kind: "mutation",
|
|
74252
|
+
auth: "admin"
|
|
74253
|
+
}), method(object({
|
|
74293
74254
|
deviceId: number().int(),
|
|
74294
74255
|
duration: number().positive().finite(),
|
|
74295
74256
|
unit: TimedRunUnitSchema
|
|
@@ -76995,13 +76956,6 @@ Object.freeze({
|
|
|
76995
76956
|
access: "view",
|
|
76996
76957
|
role: "admin"
|
|
76997
76958
|
},
|
|
76998
|
-
"addonSettings.getGlobalSettings": {
|
|
76999
|
-
capName: "addon-settings",
|
|
77000
|
-
capScope: "system",
|
|
77001
|
-
addonId: null,
|
|
77002
|
-
access: "view",
|
|
77003
|
-
role: "admin"
|
|
77004
|
-
},
|
|
77005
76959
|
"addonSettings.getIntegrationFormSchema": {
|
|
77006
76960
|
capName: "addon-settings",
|
|
77007
76961
|
capScope: "system",
|
|
@@ -77009,14 +76963,14 @@ Object.freeze({
|
|
|
77009
76963
|
access: "view",
|
|
77010
76964
|
role: "admin"
|
|
77011
76965
|
},
|
|
77012
|
-
"addonSettings.
|
|
76966
|
+
"addonSettings.getScopedSettings": {
|
|
77013
76967
|
capName: "addon-settings",
|
|
77014
76968
|
capScope: "system",
|
|
77015
76969
|
addonId: null,
|
|
77016
76970
|
access: "view",
|
|
77017
76971
|
role: "admin"
|
|
77018
76972
|
},
|
|
77019
|
-
"addonSettings.
|
|
76973
|
+
"addonSettings.listScopedSettings": {
|
|
77020
76974
|
capName: "addon-settings",
|
|
77021
76975
|
capScope: "system",
|
|
77022
76976
|
addonId: null,
|
|
@@ -77044,13 +76998,6 @@ Object.freeze({
|
|
|
77044
76998
|
access: "create",
|
|
77045
76999
|
role: "admin"
|
|
77046
77000
|
},
|
|
77047
|
-
"addonSettings.updateGlobalSettings": {
|
|
77048
|
-
capName: "addon-settings",
|
|
77049
|
-
capScope: "system",
|
|
77050
|
-
addonId: null,
|
|
77051
|
-
access: "create",
|
|
77052
|
-
role: "admin"
|
|
77053
|
-
},
|
|
77054
77001
|
"addonSettings.updateScopedSettings": {
|
|
77055
77002
|
capName: "addon-settings",
|
|
77056
77003
|
capScope: "system",
|
|
@@ -79221,6 +79168,13 @@ Object.freeze({
|
|
|
79221
79168
|
access: "create",
|
|
79222
79169
|
role: "admin"
|
|
79223
79170
|
},
|
|
79171
|
+
"deviceManager.setAlias": {
|
|
79172
|
+
capName: "device-manager",
|
|
79173
|
+
capScope: "system",
|
|
79174
|
+
addonId: null,
|
|
79175
|
+
access: "create",
|
|
79176
|
+
role: "admin"
|
|
79177
|
+
},
|
|
79224
79178
|
"deviceManager.setChildLayout": {
|
|
79225
79179
|
capName: "device-manager",
|
|
79226
79180
|
capScope: "system",
|
|
@@ -86004,6 +85958,13 @@ Object.freeze({
|
|
|
86004
85958
|
access: "create",
|
|
86005
85959
|
role: "viewer"
|
|
86006
85960
|
},
|
|
85961
|
+
"timedRun.getOptions": {
|
|
85962
|
+
capName: "timed-run",
|
|
85963
|
+
capScope: "device",
|
|
85964
|
+
addonId: null,
|
|
85965
|
+
access: "view",
|
|
85966
|
+
role: "viewer"
|
|
85967
|
+
},
|
|
86007
85968
|
"timedRun.getStatus": {
|
|
86008
85969
|
capName: "timed-run",
|
|
86009
85970
|
capScope: "device",
|
|
@@ -86018,6 +85979,13 @@ Object.freeze({
|
|
|
86018
85979
|
access: "create",
|
|
86019
85980
|
role: "viewer"
|
|
86020
85981
|
},
|
|
85982
|
+
"timedRun.setSettings": {
|
|
85983
|
+
capName: "timed-run",
|
|
85984
|
+
capScope: "device",
|
|
85985
|
+
addonId: null,
|
|
85986
|
+
access: "create",
|
|
85987
|
+
role: "admin"
|
|
85988
|
+
},
|
|
86021
85989
|
"toast.onToast": {
|
|
86022
85990
|
capName: "toast",
|
|
86023
85991
|
capScope: "system",
|
|
@@ -86948,6 +86916,7 @@ function offered(received) {
|
|
|
86948
86916
|
};
|
|
86949
86917
|
}
|
|
86950
86918
|
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
86919
|
+
string().min(1).max(4096);
|
|
86951
86920
|
Object.freeze({
|
|
86952
86921
|
"accessories.getStatus": [{
|
|
86953
86922
|
name: "deviceId",
|
|
@@ -87631,6 +87600,11 @@ Object.freeze({
|
|
|
87631
87600
|
form: "single",
|
|
87632
87601
|
optional: false
|
|
87633
87602
|
}],
|
|
87603
|
+
"deviceManager.setAlias": [{
|
|
87604
|
+
name: "deviceId",
|
|
87605
|
+
form: "single",
|
|
87606
|
+
optional: false
|
|
87607
|
+
}],
|
|
87634
87608
|
"deviceManager.setChildLayout": [{
|
|
87635
87609
|
name: "deviceId",
|
|
87636
87610
|
form: "single",
|
|
@@ -89695,6 +89669,11 @@ Object.freeze({
|
|
|
89695
89669
|
form: "single",
|
|
89696
89670
|
optional: false
|
|
89697
89671
|
}],
|
|
89672
|
+
"timedRun.getOptions": [{
|
|
89673
|
+
name: "deviceId",
|
|
89674
|
+
form: "single",
|
|
89675
|
+
optional: false
|
|
89676
|
+
}],
|
|
89698
89677
|
"timedRun.getStatus": [{
|
|
89699
89678
|
name: "deviceId",
|
|
89700
89679
|
form: "single",
|
|
@@ -89705,6 +89684,11 @@ Object.freeze({
|
|
|
89705
89684
|
form: "single",
|
|
89706
89685
|
optional: false
|
|
89707
89686
|
}],
|
|
89687
|
+
"timedRun.setSettings": [{
|
|
89688
|
+
name: "deviceId",
|
|
89689
|
+
form: "single",
|
|
89690
|
+
optional: false
|
|
89691
|
+
}],
|
|
89708
89692
|
"update.getStatus": [{
|
|
89709
89693
|
name: "deviceId",
|
|
89710
89694
|
form: "single",
|
|
@@ -90567,6 +90551,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
90567
90551
|
[...RULE_TEXT],
|
|
90568
90552
|
[...RULE_TEXT],
|
|
90569
90553
|
[...RULE_TEXT],
|
|
90554
|
+
[...RULE_TEXT],
|
|
90570
90555
|
[...RULE_BODY_ONLY],
|
|
90571
90556
|
[...RULE_TEXT],
|
|
90572
90557
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
@@ -136222,7 +136207,14 @@ function buildMailboxInstances(records, deps) {
|
|
|
136222
136207
|
role: "services",
|
|
136223
136208
|
instanceMode: "multiple",
|
|
136224
136209
|
kind: "mailbox",
|
|
136225
|
-
canTest: true
|
|
136210
|
+
canTest: true,
|
|
136211
|
+
kinds: [{
|
|
136212
|
+
id: MAILBOX_INSTANCE_KIND,
|
|
136213
|
+
label: "Inbound mailbox (SMTP)",
|
|
136214
|
+
functionCap: "broker",
|
|
136215
|
+
role: "services",
|
|
136216
|
+
brokerKind: SMTP_INBOUND_KIND
|
|
136217
|
+
}]
|
|
136226
136218
|
},
|
|
136227
136219
|
formSchema: () => mailboxSettingsSchema(),
|
|
136228
136220
|
initialBody: (name) => newMailboxBody(name),
|
|
@@ -145958,7 +145950,13 @@ var SmtpNodemailerAddon = class extends BaseAddon {
|
|
|
145958
145950
|
role: "services",
|
|
145959
145951
|
instanceMode: "multiple",
|
|
145960
145952
|
kind: "relays",
|
|
145961
|
-
canTest: true
|
|
145953
|
+
canTest: true,
|
|
145954
|
+
kinds: [{
|
|
145955
|
+
id: "relays",
|
|
145956
|
+
label: "SMTP relay",
|
|
145957
|
+
functionCap: "smtp-provider",
|
|
145958
|
+
role: "services"
|
|
145959
|
+
}]
|
|
145962
145960
|
},
|
|
145963
145961
|
formSchema: () => this.relayForm(),
|
|
145964
145962
|
initialBody: (name) => ({
|