@camstack/addon-agent-ui 1.2.333 → 1.2.334
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 +6 -0
- package/dist/.bundle-modules.json +33 -35
- package/dist/addon.js +403 -214
- package/dist/assets/{MotionZonesSettings-BveIjuoy.js → MotionZonesSettings-B_kMzz0P.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-DAF5F2AZ.js → PrivacyMaskSettings-B_tdrQjC.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-FxKxdbql.js → SceneMonitorEditor-CwNP7Ptn.js} +1 -1
- package/dist/assets/index-DNQlw9Oo.js +145 -0
- package/dist/index.html +1 -1
- package/package.json +2 -2
- package/dist/assets/index-DMfn1qze.js +0 -145
package/dist/addon.js
CHANGED
|
@@ -5849,7 +5849,7 @@ var ZodIssueCode = {
|
|
|
5849
5849
|
var ZodFirstPartyTypeKind;
|
|
5850
5850
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5851
5851
|
//#endregion
|
|
5852
|
-
//#region ../types/dist/sleep-
|
|
5852
|
+
//#region ../types/dist/sleep-CmjWurK5.mjs
|
|
5853
5853
|
/**
|
|
5854
5854
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5855
5855
|
* window to float samples (D455).
|
|
@@ -6526,6 +6526,250 @@ async function runAddonMigrations(host, migrations, logger, options = {}) {
|
|
|
6526
6526
|
blockOwner
|
|
6527
6527
|
};
|
|
6528
6528
|
}
|
|
6529
|
+
/** The record calls the one-switch migration makes, over the migration API. */
|
|
6530
|
+
function switchRecordsOverMigrationApi(api) {
|
|
6531
|
+
return { kind: (definition) => {
|
|
6532
|
+
const handle = api.records.kind(definition);
|
|
6533
|
+
return {
|
|
6534
|
+
get: (id) => handle.get({ id }),
|
|
6535
|
+
put: (input, opts) => handle.put({
|
|
6536
|
+
...input,
|
|
6537
|
+
...opts?.ifRev === void 0 ? {} : { ifRev: opts.ifRev }
|
|
6538
|
+
}),
|
|
6539
|
+
patch: (id, partial) => handle.patch({
|
|
6540
|
+
id,
|
|
6541
|
+
partial
|
|
6542
|
+
})
|
|
6543
|
+
};
|
|
6544
|
+
} };
|
|
6545
|
+
}
|
|
6546
|
+
function integrationRowsApiOver(api) {
|
|
6547
|
+
return {
|
|
6548
|
+
list: async () => (await api.integrations.list({})).integrations,
|
|
6549
|
+
readLegacyIntegrationRows: (input) => api.legacyRows.read(input),
|
|
6550
|
+
clearLegacyIntegrationRows: (input) => api.legacyRows.clear(input)
|
|
6551
|
+
};
|
|
6552
|
+
}
|
|
6553
|
+
object({
|
|
6554
|
+
cap: string().min(1),
|
|
6555
|
+
kind: string().min(1).optional()
|
|
6556
|
+
});
|
|
6557
|
+
var GLOBAL_SCOPE = { kind: "global" };
|
|
6558
|
+
/** The scope every addon-wide (not per-node, not per-device) setting lives in. */
|
|
6559
|
+
function globalSecretScope() {
|
|
6560
|
+
return GLOBAL_SCOPE;
|
|
6561
|
+
}
|
|
6562
|
+
function encodeSegment(value) {
|
|
6563
|
+
return encodeURIComponent(value);
|
|
6564
|
+
}
|
|
6565
|
+
function decodeSegment(value) {
|
|
6566
|
+
try {
|
|
6567
|
+
return decodeURIComponent(value);
|
|
6568
|
+
} catch {
|
|
6569
|
+
return null;
|
|
6570
|
+
}
|
|
6571
|
+
}
|
|
6572
|
+
/**
|
|
6573
|
+
* The field path of a value inside an array item, addressed by the item's id:
|
|
6574
|
+
* `arrayItemFieldPath('providers', 'authentik', 'clientSecret')` →
|
|
6575
|
+
* `providers[authentik].clientSecret`.
|
|
6576
|
+
*/
|
|
6577
|
+
function arrayItemFieldPath(arrayKey, itemId, fieldKey) {
|
|
6578
|
+
return `${arrayKey}[${encodeSegment(itemId)}].${fieldKey}`;
|
|
6579
|
+
}
|
|
6580
|
+
function parseScope(segments) {
|
|
6581
|
+
switch (segments[0]) {
|
|
6582
|
+
case "global": return {
|
|
6583
|
+
scope: GLOBAL_SCOPE,
|
|
6584
|
+
used: 1
|
|
6585
|
+
};
|
|
6586
|
+
case "node": {
|
|
6587
|
+
const nodeId = segments[1] !== void 0 ? decodeSegment(segments[1]) : null;
|
|
6588
|
+
return nodeId === null || nodeId.length === 0 ? null : {
|
|
6589
|
+
scope: {
|
|
6590
|
+
kind: "node",
|
|
6591
|
+
nodeId
|
|
6592
|
+
},
|
|
6593
|
+
used: 2
|
|
6594
|
+
};
|
|
6595
|
+
}
|
|
6596
|
+
case "device": {
|
|
6597
|
+
const raw = segments[1];
|
|
6598
|
+
if (raw === void 0 || !/^\d+$/.test(raw)) return null;
|
|
6599
|
+
return {
|
|
6600
|
+
scope: {
|
|
6601
|
+
kind: "device",
|
|
6602
|
+
deviceId: Number(raw)
|
|
6603
|
+
},
|
|
6604
|
+
used: 2
|
|
6605
|
+
};
|
|
6606
|
+
}
|
|
6607
|
+
case "integration": {
|
|
6608
|
+
const id = segments[1] !== void 0 ? decodeSegment(segments[1]) : null;
|
|
6609
|
+
return id === null || id.length === 0 ? null : {
|
|
6610
|
+
scope: {
|
|
6611
|
+
kind: "integration",
|
|
6612
|
+
integrationId: id
|
|
6613
|
+
},
|
|
6614
|
+
used: 2
|
|
6615
|
+
};
|
|
6616
|
+
}
|
|
6617
|
+
case "row": {
|
|
6618
|
+
const collection = segments[1] !== void 0 ? decodeSegment(segments[1]) : null;
|
|
6619
|
+
const rowId = segments[2] !== void 0 ? decodeSegment(segments[2]) : null;
|
|
6620
|
+
if (collection === null || rowId === null || collection.length === 0 || rowId.length === 0) return null;
|
|
6621
|
+
return {
|
|
6622
|
+
scope: {
|
|
6623
|
+
kind: "row",
|
|
6624
|
+
collection,
|
|
6625
|
+
rowId
|
|
6626
|
+
},
|
|
6627
|
+
used: 3
|
|
6628
|
+
};
|
|
6629
|
+
}
|
|
6630
|
+
default: return null;
|
|
6631
|
+
}
|
|
6632
|
+
}
|
|
6633
|
+
/** Take a ref apart; `null` when it is not a well-formed ref. */
|
|
6634
|
+
function parseSecretRef(ref) {
|
|
6635
|
+
if (!ref.startsWith("secret://")) return null;
|
|
6636
|
+
const segments = ref.slice(9).split("/");
|
|
6637
|
+
const owner = segments[0] !== void 0 ? decodeSegment(segments[0]) : null;
|
|
6638
|
+
if (owner === null || owner.length === 0) return null;
|
|
6639
|
+
const parsed = parseScope(segments.slice(1));
|
|
6640
|
+
if (parsed === null) return null;
|
|
6641
|
+
const fieldPath = segments.slice(1 + parsed.used).join("/");
|
|
6642
|
+
if (fieldPath.length === 0) return null;
|
|
6643
|
+
return {
|
|
6644
|
+
owner,
|
|
6645
|
+
scope: parsed.scope,
|
|
6646
|
+
fieldPath
|
|
6647
|
+
};
|
|
6648
|
+
}
|
|
6649
|
+
/** Limits and names of `ctx.records` (D881). One authority; the engine and the facade read it. */
|
|
6650
|
+
/** The files a kind may live in. `history` is device-history's (D850), never records. */
|
|
6651
|
+
var RECORD_DATABASES = ["settings", "events"];
|
|
6652
|
+
/** The classes of a kind: the `@durable` vocabulary, one authority (replaces the annotation). */
|
|
6653
|
+
var RECORD_CLASSES = [
|
|
6654
|
+
"config",
|
|
6655
|
+
"ledger",
|
|
6656
|
+
"audit",
|
|
6657
|
+
"mirror",
|
|
6658
|
+
"ephemeral"
|
|
6659
|
+
];
|
|
6660
|
+
var RECORD_DEFAULT_MAX_DATA_BYTES = 64 * 1024;
|
|
6661
|
+
var RECORD_MAX_DATA_BYTES = 1024 * 1024;
|
|
6662
|
+
var RECORD_BATCH_MAX = 1e3;
|
|
6663
|
+
var RECORD_QUERY_MAX = 1e3;
|
|
6664
|
+
/** The body key of the switch; only {@link RecordIntegrationInstances.setInstanceEnabled} writes it. */
|
|
6665
|
+
var SWITCH_KEY = "enabled";
|
|
6666
|
+
/**
|
|
6667
|
+
* The one-switch migration (epic #440, step 3). An integration's on/off state used to live in the
|
|
6668
|
+
* registry's `enabled` column for a device addon; it now lives only in the instance record's
|
|
6669
|
+
* body (`enabled`, D1007 superseded). This moves a registry `enabled = false` into the body, once.
|
|
6670
|
+
*
|
|
6671
|
+
* For every registry row of the addon that is OFF:
|
|
6672
|
+
* - no record under its id: the record is created from `initialBody(name)` with `enabled: false`
|
|
6673
|
+
* (a default integration that never had settings, Reolink's among them);
|
|
6674
|
+
* - a record whose body states no `enabled`: `enabled: false` is written into it;
|
|
6675
|
+
* - a record that already states `enabled` (either way) is the newer truth and is left alone.
|
|
6676
|
+
* A row that is ON writes nothing: an absent field reads as on. A rerun finds every off row with
|
|
6677
|
+
* a stated switch and does nothing, so nothing switched off comes back on and nothing switched on
|
|
6678
|
+
* goes off. The registry column itself is neither read afterwards nor written; its drop is step 5.
|
|
6679
|
+
*
|
|
6680
|
+
* It runs in the addon process, BEFORE the addon registers its `integration-instances` provider,
|
|
6681
|
+
* which is also why `integrations.list` still answers the stored column at that point.
|
|
6682
|
+
*/
|
|
6683
|
+
function registrySwitchToBodyId(addonId, date) {
|
|
6684
|
+
return `${addonId}/${date}-registry-switch-to-body`;
|
|
6685
|
+
}
|
|
6686
|
+
async function moveRegistrySwitchToBody(ports, spec) {
|
|
6687
|
+
const rows = await ports.listIntegrations(spec.addonId);
|
|
6688
|
+
let created = 0;
|
|
6689
|
+
let switched = 0;
|
|
6690
|
+
let kept = 0;
|
|
6691
|
+
for (const row of rows) {
|
|
6692
|
+
if (row.enabled) continue;
|
|
6693
|
+
const body = await ports.readBody(row.id);
|
|
6694
|
+
if (body === null) {
|
|
6695
|
+
if (await ports.createRecord(row.id, {
|
|
6696
|
+
...spec.initialBody(row.name),
|
|
6697
|
+
["enabled"]: false
|
|
6698
|
+
}) === "created") created += 1;
|
|
6699
|
+
else kept += 1;
|
|
6700
|
+
continue;
|
|
6701
|
+
}
|
|
6702
|
+
if ("enabled" in body) {
|
|
6703
|
+
kept += 1;
|
|
6704
|
+
continue;
|
|
6705
|
+
}
|
|
6706
|
+
await ports.switchOff(row.id);
|
|
6707
|
+
switched += 1;
|
|
6708
|
+
}
|
|
6709
|
+
const summary = {
|
|
6710
|
+
integrations: rows.length,
|
|
6711
|
+
off: rows.filter((r) => !r.enabled).length,
|
|
6712
|
+
created,
|
|
6713
|
+
switched,
|
|
6714
|
+
kept
|
|
6715
|
+
};
|
|
6716
|
+
return created === 0 && switched === 0 ? {
|
|
6717
|
+
outcome: "already-done",
|
|
6718
|
+
summary
|
|
6719
|
+
} : {
|
|
6720
|
+
outcome: "done",
|
|
6721
|
+
summary
|
|
6722
|
+
};
|
|
6723
|
+
}
|
|
6724
|
+
/** A migration entry: an addon states its kind and how a new body starts, nothing else. */
|
|
6725
|
+
function registrySwitchToBodyMigration(spec) {
|
|
6726
|
+
return {
|
|
6727
|
+
meta: {
|
|
6728
|
+
id: registrySwitchToBodyId(spec.addonId, spec.date),
|
|
6729
|
+
owner: spec.addonId,
|
|
6730
|
+
level: "addon-state",
|
|
6731
|
+
seq: spec.seq,
|
|
6732
|
+
dependsOn: [],
|
|
6733
|
+
store: "settings",
|
|
6734
|
+
scope: "cluster",
|
|
6735
|
+
onFailure: "block-owner",
|
|
6736
|
+
bodyKind: "procedure",
|
|
6737
|
+
description: "Move the registry enabled flag of every switched-off integration into its instance record body, creating the record when there is none",
|
|
6738
|
+
fixtureMark: "enabled"
|
|
6739
|
+
},
|
|
6740
|
+
procedure: (ports) => moveRegistrySwitchToBody(ports, {
|
|
6741
|
+
addonId: spec.addonId,
|
|
6742
|
+
initialBody: spec.initialBody
|
|
6743
|
+
})
|
|
6744
|
+
};
|
|
6745
|
+
}
|
|
6746
|
+
/** The hub and records sides of {@link registrySwitchToBodyMigration}. */
|
|
6747
|
+
function registrySwitchPortsOver(deps) {
|
|
6748
|
+
const handle = deps.records.kind({
|
|
6749
|
+
name: deps.kind.name,
|
|
6750
|
+
declaration: deps.kind.declaration,
|
|
6751
|
+
schema: record(string(), unknown())
|
|
6752
|
+
});
|
|
6753
|
+
return {
|
|
6754
|
+
listIntegrations: async (addonId) => (await deps.api.list()).filter((i) => i.addonId === addonId).map((i) => ({
|
|
6755
|
+
id: i.id,
|
|
6756
|
+
name: i.name,
|
|
6757
|
+
enabled: i.enabled !== false
|
|
6758
|
+
})),
|
|
6759
|
+
readBody: async (id) => (await handle.get(id))?.data ?? null,
|
|
6760
|
+
createRecord: async (id, body) => {
|
|
6761
|
+
if (await handle.get(id) !== null) return "exists";
|
|
6762
|
+
await handle.put({
|
|
6763
|
+
id,
|
|
6764
|
+
data: body
|
|
6765
|
+
}, { ifRev: 0 });
|
|
6766
|
+
return "created";
|
|
6767
|
+
},
|
|
6768
|
+
switchOff: async (id) => {
|
|
6769
|
+
await handle.patch(id, { [SWITCH_KEY]: false });
|
|
6770
|
+
}
|
|
6771
|
+
};
|
|
6772
|
+
}
|
|
6529
6773
|
/**
|
|
6530
6774
|
* Build a {@link DurableState} over a single store key. Transport-agnostic:
|
|
6531
6775
|
* `read`/`write` are the addon-store or device-store accessors. The whole
|
|
@@ -6657,98 +6901,6 @@ var SCOPED_SETTINGS_SCOPES = [
|
|
|
6657
6901
|
"device-defaults",
|
|
6658
6902
|
"node"
|
|
6659
6903
|
];
|
|
6660
|
-
var GLOBAL_SCOPE = { kind: "global" };
|
|
6661
|
-
/** The scope every addon-wide (not per-node, not per-device) setting lives in. */
|
|
6662
|
-
function globalSecretScope() {
|
|
6663
|
-
return GLOBAL_SCOPE;
|
|
6664
|
-
}
|
|
6665
|
-
function encodeSegment(value) {
|
|
6666
|
-
return encodeURIComponent(value);
|
|
6667
|
-
}
|
|
6668
|
-
function decodeSegment(value) {
|
|
6669
|
-
try {
|
|
6670
|
-
return decodeURIComponent(value);
|
|
6671
|
-
} catch {
|
|
6672
|
-
return null;
|
|
6673
|
-
}
|
|
6674
|
-
}
|
|
6675
|
-
/**
|
|
6676
|
-
* The field path of a value inside an array item, addressed by the item's id:
|
|
6677
|
-
* `arrayItemFieldPath('providers', 'authentik', 'clientSecret')` →
|
|
6678
|
-
* `providers[authentik].clientSecret`.
|
|
6679
|
-
*/
|
|
6680
|
-
function arrayItemFieldPath(arrayKey, itemId, fieldKey) {
|
|
6681
|
-
return `${arrayKey}[${encodeSegment(itemId)}].${fieldKey}`;
|
|
6682
|
-
}
|
|
6683
|
-
function parseScope(segments) {
|
|
6684
|
-
switch (segments[0]) {
|
|
6685
|
-
case "global": return {
|
|
6686
|
-
scope: GLOBAL_SCOPE,
|
|
6687
|
-
used: 1
|
|
6688
|
-
};
|
|
6689
|
-
case "node": {
|
|
6690
|
-
const nodeId = segments[1] !== void 0 ? decodeSegment(segments[1]) : null;
|
|
6691
|
-
return nodeId === null || nodeId.length === 0 ? null : {
|
|
6692
|
-
scope: {
|
|
6693
|
-
kind: "node",
|
|
6694
|
-
nodeId
|
|
6695
|
-
},
|
|
6696
|
-
used: 2
|
|
6697
|
-
};
|
|
6698
|
-
}
|
|
6699
|
-
case "device": {
|
|
6700
|
-
const raw = segments[1];
|
|
6701
|
-
if (raw === void 0 || !/^\d+$/.test(raw)) return null;
|
|
6702
|
-
return {
|
|
6703
|
-
scope: {
|
|
6704
|
-
kind: "device",
|
|
6705
|
-
deviceId: Number(raw)
|
|
6706
|
-
},
|
|
6707
|
-
used: 2
|
|
6708
|
-
};
|
|
6709
|
-
}
|
|
6710
|
-
case "integration": {
|
|
6711
|
-
const id = segments[1] !== void 0 ? decodeSegment(segments[1]) : null;
|
|
6712
|
-
return id === null || id.length === 0 ? null : {
|
|
6713
|
-
scope: {
|
|
6714
|
-
kind: "integration",
|
|
6715
|
-
integrationId: id
|
|
6716
|
-
},
|
|
6717
|
-
used: 2
|
|
6718
|
-
};
|
|
6719
|
-
}
|
|
6720
|
-
case "row": {
|
|
6721
|
-
const collection = segments[1] !== void 0 ? decodeSegment(segments[1]) : null;
|
|
6722
|
-
const rowId = segments[2] !== void 0 ? decodeSegment(segments[2]) : null;
|
|
6723
|
-
if (collection === null || rowId === null || collection.length === 0 || rowId.length === 0) return null;
|
|
6724
|
-
return {
|
|
6725
|
-
scope: {
|
|
6726
|
-
kind: "row",
|
|
6727
|
-
collection,
|
|
6728
|
-
rowId
|
|
6729
|
-
},
|
|
6730
|
-
used: 3
|
|
6731
|
-
};
|
|
6732
|
-
}
|
|
6733
|
-
default: return null;
|
|
6734
|
-
}
|
|
6735
|
-
}
|
|
6736
|
-
/** Take a ref apart; `null` when it is not a well-formed ref. */
|
|
6737
|
-
function parseSecretRef(ref) {
|
|
6738
|
-
if (!ref.startsWith("secret://")) return null;
|
|
6739
|
-
const segments = ref.slice(9).split("/");
|
|
6740
|
-
const owner = segments[0] !== void 0 ? decodeSegment(segments[0]) : null;
|
|
6741
|
-
if (owner === null || owner.length === 0) return null;
|
|
6742
|
-
const parsed = parseScope(segments.slice(1));
|
|
6743
|
-
if (parsed === null) return null;
|
|
6744
|
-
const fieldPath = segments.slice(1 + parsed.used).join("/");
|
|
6745
|
-
if (fieldPath.length === 0) return null;
|
|
6746
|
-
return {
|
|
6747
|
-
owner,
|
|
6748
|
-
scope: parsed.scope,
|
|
6749
|
-
fieldPath
|
|
6750
|
-
};
|
|
6751
|
-
}
|
|
6752
6904
|
/** A write to a secret path could not be stored in the keychain, so it was refused. */
|
|
6753
6905
|
var KeychainWriteRefusedError = class extends Error {
|
|
6754
6906
|
fieldPath;
|
|
@@ -6759,7 +6911,7 @@ var KeychainWriteRefusedError = class extends Error {
|
|
|
6759
6911
|
}
|
|
6760
6912
|
};
|
|
6761
6913
|
var KEEP = { kind: "keep" };
|
|
6762
|
-
function isRecord$
|
|
6914
|
+
function isRecord$4(value) {
|
|
6763
6915
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6764
6916
|
}
|
|
6765
6917
|
function defaultMintId() {
|
|
@@ -6772,7 +6924,7 @@ function collectSecretMarkerRefs(value, out = []) {
|
|
|
6772
6924
|
return out;
|
|
6773
6925
|
}
|
|
6774
6926
|
if (Array.isArray(value)) for (const item of value) collectSecretMarkerRefs(item, out);
|
|
6775
|
-
else if (isRecord$
|
|
6927
|
+
else if (isRecord$4(value)) for (const child of Object.values(value)) collectSecretMarkerRefs(child, out);
|
|
6776
6928
|
return out;
|
|
6777
6929
|
}
|
|
6778
6930
|
async function storedValueEquals(secrets, marker, candidate) {
|
|
@@ -6827,7 +6979,7 @@ function rowId(row, idKey) {
|
|
|
6827
6979
|
return null;
|
|
6828
6980
|
}
|
|
6829
6981
|
async function writeArray(ctx, node, incoming, stored, fieldPath) {
|
|
6830
|
-
const storedRows = Array.isArray(stored) ? stored.filter(isRecord$
|
|
6982
|
+
const storedRows = Array.isArray(stored) ? stored.filter(isRecord$4) : [];
|
|
6831
6983
|
if (!Array.isArray(incoming)) {
|
|
6832
6984
|
ctx.deletes.push(...collectSecretMarkerRefs(storedRows));
|
|
6833
6985
|
return {
|
|
@@ -6843,7 +6995,7 @@ async function writeArray(ctx, node, incoming, stored, fieldPath) {
|
|
|
6843
6995
|
const kept = /* @__PURE__ */ new Set();
|
|
6844
6996
|
const rows = [];
|
|
6845
6997
|
for (const row of incoming) {
|
|
6846
|
-
if (!isRecord$
|
|
6998
|
+
if (!isRecord$4(row)) {
|
|
6847
6999
|
rows.push(row);
|
|
6848
7000
|
continue;
|
|
6849
7001
|
}
|
|
@@ -6868,7 +7020,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
|
|
|
6868
7020
|
case "leaf": return writeLeaf(ctx, incoming, stored, fieldPath);
|
|
6869
7021
|
case "array": return writeArray(ctx, node, incoming, stored, fieldPath);
|
|
6870
7022
|
case "object": {
|
|
6871
|
-
if (!isRecord$
|
|
7023
|
+
if (!isRecord$4(incoming)) {
|
|
6872
7024
|
if (incoming === void 0) return KEEP;
|
|
6873
7025
|
ctx.deletes.push(...collectSecretMarkerRefs(stored));
|
|
6874
7026
|
return {
|
|
@@ -6876,7 +7028,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
|
|
|
6876
7028
|
value: incoming
|
|
6877
7029
|
};
|
|
6878
7030
|
}
|
|
6879
|
-
const storedObj = isRecord$
|
|
7031
|
+
const storedObj = isRecord$4(stored) ? stored : {};
|
|
6880
7032
|
return {
|
|
6881
7033
|
kind: "value",
|
|
6882
7034
|
value: await writeMembers(ctx, node.children, incoming, storedObj, (m) => `${fieldPath}.${m}`)
|
|
@@ -6999,7 +7151,7 @@ async function resolveSecretMarkers(value, secrets, options = {}) {
|
|
|
6999
7151
|
value: items
|
|
7000
7152
|
};
|
|
7001
7153
|
}
|
|
7002
|
-
if (isRecord$
|
|
7154
|
+
if (isRecord$4(v)) {
|
|
7003
7155
|
const out = {};
|
|
7004
7156
|
for (const [k, child] of Object.entries(v)) {
|
|
7005
7157
|
const s = substitute(child);
|
|
@@ -7031,7 +7183,7 @@ var SecretOverwriteRefusedError = class extends Error {
|
|
|
7031
7183
|
this.name = "SecretOverwriteRefusedError";
|
|
7032
7184
|
}
|
|
7033
7185
|
};
|
|
7034
|
-
function isRecord$
|
|
7186
|
+
function isRecord$3(value) {
|
|
7035
7187
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7036
7188
|
}
|
|
7037
7189
|
function resolvedValue(pass, marker) {
|
|
@@ -7060,7 +7212,7 @@ function inArray(pass, incoming, stored) {
|
|
|
7060
7212
|
return incoming.map((item, index) => {
|
|
7061
7213
|
const twin = stored[index];
|
|
7062
7214
|
if (isSecretMarker(twin)) return typeof item === "string" && item === resolvedValue(pass, twin) ? twin : item;
|
|
7063
|
-
if (isRecord$
|
|
7215
|
+
if (isRecord$3(item) && isRecord$3(twin)) return inArrayRow(pass, item, twin);
|
|
7064
7216
|
if (Array.isArray(item) && Array.isArray(twin)) return inArray(pass, item, twin);
|
|
7065
7217
|
return item;
|
|
7066
7218
|
});
|
|
@@ -7071,7 +7223,7 @@ function inArrayRow(pass, incoming, stored) {
|
|
|
7071
7223
|
const twin = stored[key];
|
|
7072
7224
|
if (isSecretMarker(twin)) {
|
|
7073
7225
|
if (typeof value === "string" && value === resolvedValue(pass, twin)) out[key] = twin;
|
|
7074
|
-
} else if (isRecord$
|
|
7226
|
+
} else if (isRecord$3(value) && isRecord$3(twin)) out[key] = inArrayRow(pass, value, twin);
|
|
7075
7227
|
else if (Array.isArray(value) && Array.isArray(twin)) out[key] = inArray(pass, value, twin);
|
|
7076
7228
|
}
|
|
7077
7229
|
return out;
|
|
@@ -7079,7 +7231,7 @@ function inArrayRow(pass, incoming, stored) {
|
|
|
7079
7231
|
async function walk(pass, incoming, stored) {
|
|
7080
7232
|
if (isSecretMarker(stored)) return atMarker(pass, incoming, stored);
|
|
7081
7233
|
if (Array.isArray(incoming) && Array.isArray(stored)) return inArray(pass, incoming, stored);
|
|
7082
|
-
if (!isRecord$
|
|
7234
|
+
if (!isRecord$3(incoming) || !isRecord$3(stored)) return incoming;
|
|
7083
7235
|
const out = { ...incoming };
|
|
7084
7236
|
for (const [key, value] of Object.entries(incoming)) out[key] = await walk(pass, value, stored[key]);
|
|
7085
7237
|
return out;
|
|
@@ -7110,7 +7262,7 @@ async function restoreUnchangedSecrets(input) {
|
|
|
7110
7262
|
function isJsonEqual(a, b) {
|
|
7111
7263
|
if (Object.is(a, b)) return true;
|
|
7112
7264
|
if (Array.isArray(a)) return Array.isArray(b) && a.length === b.length && a.every((v, i) => isJsonEqual(v, b[i]));
|
|
7113
|
-
if (isRecord$
|
|
7265
|
+
if (isRecord$3(a) && isRecord$3(b)) {
|
|
7114
7266
|
const keys = Object.keys(a);
|
|
7115
7267
|
if (keys.length !== Object.keys(b).length) return false;
|
|
7116
7268
|
return keys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && isJsonEqual(a[k], b[k]));
|
|
@@ -7134,7 +7286,7 @@ function markerKeysOf(blob, owner) {
|
|
|
7134
7286
|
}
|
|
7135
7287
|
function nodeFromStored(value, owner) {
|
|
7136
7288
|
if (isSecretMarker(value)) return isSecretRefOwnedBy(value.$secret, owner) ? { kind: "leaf" } : null;
|
|
7137
|
-
if (!isRecord$
|
|
7289
|
+
if (!isRecord$3(value)) return null;
|
|
7138
7290
|
const children = /* @__PURE__ */ new Map();
|
|
7139
7291
|
for (const [key, child] of Object.entries(value)) {
|
|
7140
7292
|
const node = nodeFromStored(child, owner);
|
|
@@ -7631,13 +7783,48 @@ var BaseAddon = class {
|
|
|
7631
7783
|
if (api === void 0) throw new Error(`${this.ctx.id}: the migration API is not available on this context`);
|
|
7632
7784
|
return this.runBound(sets.flatMap((set) => set.bind(api)), options);
|
|
7633
7785
|
}
|
|
7634
|
-
|
|
7786
|
+
/**
|
|
7787
|
+
* A device addon states its instance kind once, before its migrations run, and the one-switch
|
|
7788
|
+
* migration (registry `enabled` to the instance body, epic #440 step 3) joins whatever
|
|
7789
|
+
* catalogue the addon runs, in the SAME declaration (the engine replaces an owner's catalogue
|
|
7790
|
+
* on every declare).
|
|
7791
|
+
*/
|
|
7792
|
+
declareRegistrySwitch(spec) {
|
|
7793
|
+
this.registrySwitchSpec = spec;
|
|
7794
|
+
}
|
|
7795
|
+
registrySwitchSpec = null;
|
|
7796
|
+
registrySwitchBound() {
|
|
7797
|
+
const spec = this.registrySwitchSpec;
|
|
7798
|
+
if (spec === null) return [];
|
|
7799
|
+
const api = this.ctx.migrationApi;
|
|
7800
|
+
if (api === void 0) {
|
|
7801
|
+
this.ctx.logger.warn("the registry switch migration is skipped: the migration API is not available on this context");
|
|
7802
|
+
return [];
|
|
7803
|
+
}
|
|
7804
|
+
return migrationSet([registrySwitchToBodyMigration({
|
|
7805
|
+
addonId: this.ctx.id,
|
|
7806
|
+
date: "2026-11-06",
|
|
7807
|
+
seq: 1e3,
|
|
7808
|
+
initialBody: spec.initialBody
|
|
7809
|
+
})], (a) => registrySwitchPortsOver({
|
|
7810
|
+
api: integrationRowsApiOver(a),
|
|
7811
|
+
records: switchRecordsOverMigrationApi(a),
|
|
7812
|
+
kind: spec.kind
|
|
7813
|
+
})).bind(api);
|
|
7814
|
+
}
|
|
7815
|
+
async runBound(declared, options) {
|
|
7816
|
+
const added = this.registrySwitchBound();
|
|
7817
|
+
const migrations = [...declared, ...added];
|
|
7818
|
+
const phased = options?.only === void 0 || added.length === 0 ? options : {
|
|
7819
|
+
...options,
|
|
7820
|
+
only: [...options.only, ...added.map((m) => m.meta.id)]
|
|
7821
|
+
};
|
|
7635
7822
|
const api = this.ctx.api.migrations;
|
|
7636
7823
|
const report = await runAddonMigrations({
|
|
7637
7824
|
declareOwner: (input) => api.declareOwner.mutate(input),
|
|
7638
7825
|
startMigration: (input) => api.startMigration.mutate(input),
|
|
7639
7826
|
finishMigration: (input) => api.finishMigration.mutate(input)
|
|
7640
|
-
}, migrations, this.ctx.logger,
|
|
7827
|
+
}, migrations, this.ctx.logger, phased);
|
|
7641
7828
|
if (report.blockOwner.length > 0) throw new AddonMigrationsBlockedError(report.blockOwner);
|
|
7642
7829
|
return report;
|
|
7643
7830
|
}
|
|
@@ -8710,21 +8897,6 @@ function normalizeAddonInitResult(result) {
|
|
|
8710
8897
|
if (Array.isArray(result)) return { providers: result };
|
|
8711
8898
|
return result;
|
|
8712
8899
|
}
|
|
8713
|
-
/** Limits and names of `ctx.records` (D881). One authority; the engine and the facade read it. */
|
|
8714
|
-
/** The files a kind may live in. `history` is device-history's (D850), never records. */
|
|
8715
|
-
var RECORD_DATABASES = ["settings", "events"];
|
|
8716
|
-
/** The classes of a kind: the `@durable` vocabulary, one authority (replaces the annotation). */
|
|
8717
|
-
var RECORD_CLASSES = [
|
|
8718
|
-
"config",
|
|
8719
|
-
"ledger",
|
|
8720
|
-
"audit",
|
|
8721
|
-
"mirror",
|
|
8722
|
-
"ephemeral"
|
|
8723
|
-
];
|
|
8724
|
-
var RECORD_DEFAULT_MAX_DATA_BYTES = 64 * 1024;
|
|
8725
|
-
var RECORD_MAX_DATA_BYTES = 1024 * 1024;
|
|
8726
|
-
var RECORD_BATCH_MAX = 1e3;
|
|
8727
|
-
var RECORD_QUERY_MAX = 1e3;
|
|
8728
8900
|
/**
|
|
8729
8901
|
* The share-view scope kinds a share-link token can carry. The hub mints
|
|
8730
8902
|
* and validates them (`ShareViewGrantSchema` builds its
|
|
@@ -8815,20 +8987,6 @@ var RecordKindDeclarationSchema = object({
|
|
|
8815
8987
|
}).strict();
|
|
8816
8988
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8817
8989
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8818
|
-
/**
|
|
8819
|
-
* Entry kinds (D881): every list of user-created entries (notification
|
|
8820
|
-
* targets, brokers, LLM profiles) is ONE record kind with an id, a name and a
|
|
8821
|
-
* kind-specific body, and the admin UI lists/adds/edits/deletes all of them
|
|
8822
|
-
* through the `record-entries` capability with password fields derived from
|
|
8823
|
-
* the schema (`.meta({ secret: true })`).
|
|
8824
|
-
*/
|
|
8825
|
-
/** The body of a plain entry: a name and the fields the kind adds. */
|
|
8826
|
-
function entryBody(shape) {
|
|
8827
|
-
return object({
|
|
8828
|
-
name: string().min(1),
|
|
8829
|
-
...shape
|
|
8830
|
-
});
|
|
8831
|
-
}
|
|
8832
8990
|
object({
|
|
8833
8991
|
field: string().min(1),
|
|
8834
8992
|
on: literal("advance")
|
|
@@ -10660,6 +10818,10 @@ Object.freeze({
|
|
|
10660
10818
|
"all",
|
|
10661
10819
|
"one"
|
|
10662
10820
|
]
|
|
10821
|
+
},
|
|
10822
|
+
{
|
|
10823
|
+
"path": "positionUpdatedAt",
|
|
10824
|
+
"valueType": "number"
|
|
10663
10825
|
}
|
|
10664
10826
|
],
|
|
10665
10827
|
"meter": [{
|
|
@@ -10914,22 +11076,6 @@ Object.freeze({
|
|
|
10914
11076
|
"path": "pumpRunning",
|
|
10915
11077
|
"valueType": "boolean"
|
|
10916
11078
|
},
|
|
10917
|
-
{
|
|
10918
|
-
"path": "lastDrink",
|
|
10919
|
-
"valueType": "number"
|
|
10920
|
-
},
|
|
10921
|
-
{
|
|
10922
|
-
"path": "currentHourDrink",
|
|
10923
|
-
"valueType": "number"
|
|
10924
|
-
},
|
|
10925
|
-
{
|
|
10926
|
-
"path": "last24hDrink",
|
|
10927
|
-
"valueType": "number"
|
|
10928
|
-
},
|
|
10929
|
-
{
|
|
10930
|
-
"path": "todayDrink",
|
|
10931
|
-
"valueType": "number"
|
|
10932
|
-
},
|
|
10933
11079
|
{
|
|
10934
11080
|
"path": "error",
|
|
10935
11081
|
"valueType": "string"
|
|
@@ -11495,6 +11641,60 @@ Object.freeze({
|
|
|
11495
11641
|
}
|
|
11496
11642
|
]
|
|
11497
11643
|
});
|
|
11644
|
+
Object.freeze({
|
|
11645
|
+
"actions": { "run": 363e4 },
|
|
11646
|
+
"audio-analyzer": { "classify": 3e4 },
|
|
11647
|
+
"custom-model-registry": { "importModelBundle": 18e5 },
|
|
11648
|
+
"database-snapshot": { "writeSnapshot": 18e5 },
|
|
11649
|
+
"device-manager": {
|
|
11650
|
+
"migrateDevice": 72e4,
|
|
11651
|
+
"runDiscoverySweep": 12e4
|
|
11652
|
+
},
|
|
11653
|
+
"device-provider": { "reloadDevice": 18e4 },
|
|
11654
|
+
"llm": {
|
|
11655
|
+
"generate": 6e5,
|
|
11656
|
+
"generateVision": 6e5,
|
|
11657
|
+
"testProfile": 6e5
|
|
11658
|
+
},
|
|
11659
|
+
"llm-runtime": {
|
|
11660
|
+
"complete": 6e5,
|
|
11661
|
+
"completeApple": 6e5,
|
|
11662
|
+
"ensureStarted": 6e5,
|
|
11663
|
+
"installModel": 36e5
|
|
11664
|
+
},
|
|
11665
|
+
"local-network": { "scanNetwork": 9e4 },
|
|
11666
|
+
"model-convert": { "convert": 6e5 },
|
|
11667
|
+
"pipeline-analytics": {
|
|
11668
|
+
"addRetrainFrameFromRecording": 6e4,
|
|
11669
|
+
"offerRetrainArchive": 12e4,
|
|
11670
|
+
"proposeRetrainAnnotationsWithLlm": 18e4,
|
|
11671
|
+
"resolveRetrainTrainingCorpus": 6e4,
|
|
11672
|
+
"writeRetrainArchive": 36e5
|
|
11673
|
+
},
|
|
11674
|
+
"server-management": { "applyServerUpdate": 96e4 },
|
|
11675
|
+
"terminal-session": { "pullOutput": 15e3 },
|
|
11676
|
+
"training": {
|
|
11677
|
+
"canaryResult": 12e4,
|
|
11678
|
+
"cancelJob": 12e4,
|
|
11679
|
+
"planJob": 6e4,
|
|
11680
|
+
"registerResult": 18e5,
|
|
11681
|
+
"rollbackCanary": 12e4,
|
|
11682
|
+
"startJob": 12e4,
|
|
11683
|
+
"startJobBatch": 12e4
|
|
11684
|
+
},
|
|
11685
|
+
"training-provider": {
|
|
11686
|
+
"cancelJob": 6e4,
|
|
11687
|
+
"cleanupJob": 3e5,
|
|
11688
|
+
"getJob": 6e4,
|
|
11689
|
+
"listJobEvents": 6e4,
|
|
11690
|
+
"listJobs": 12e4,
|
|
11691
|
+
"offerArtifact": 3e5,
|
|
11692
|
+
"readResult": 3e5,
|
|
11693
|
+
"submitJob": 18e5,
|
|
11694
|
+
"uploadDataset": 72e5,
|
|
11695
|
+
"validateCredentials": 3e4
|
|
11696
|
+
}
|
|
11697
|
+
});
|
|
11498
11698
|
object({
|
|
11499
11699
|
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
11500
11700
|
params: record(string(), union([string(), number()])).optional()
|
|
@@ -12847,10 +13047,6 @@ var IntegrationInstanceRefSchema = object({
|
|
|
12847
13047
|
]),
|
|
12848
13048
|
candidateStableId: string().optional()
|
|
12849
13049
|
});
|
|
12850
|
-
object({
|
|
12851
|
-
cap: string().min(1),
|
|
12852
|
-
kind: string().min(1).optional()
|
|
12853
|
-
});
|
|
12854
13050
|
var EncodeProfileSchema = object({
|
|
12855
13051
|
video: object({
|
|
12856
13052
|
codec: _enum([
|
|
@@ -19025,31 +19221,21 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
19025
19221
|
"pet-fountain": {
|
|
19026
19222
|
scope: "device",
|
|
19027
19223
|
noun: t("Pet fountain", "Fontana per animali"),
|
|
19028
|
-
actions: [
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
|
|
19034
|
-
|
|
19035
|
-
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
args: { on: false }
|
|
19044
|
-
},
|
|
19045
|
-
{
|
|
19046
|
-
id: "petFountain.resetDailyConsumption",
|
|
19047
|
-
method: "resetDailyConsumption",
|
|
19048
|
-
label: t("Clear daily consumption", "Azzera il consumo giornaliero"),
|
|
19049
|
-
phrase: t("Clear the daily water consumption of {device}", "Azzera il consumo giornaliero di acqua di {device}"),
|
|
19050
|
-
icon: "rotate-ccw"
|
|
19051
|
-
}
|
|
19052
|
-
],
|
|
19224
|
+
actions: [{
|
|
19225
|
+
id: "petFountain.pumpOn",
|
|
19226
|
+
method: "setPump",
|
|
19227
|
+
label: t("Pump on", "Pompa accesa"),
|
|
19228
|
+
phrase: t("Start the pump of {device}", "Avvia la pompa di {device}"),
|
|
19229
|
+
icon: "play",
|
|
19230
|
+
args: { on: true }
|
|
19231
|
+
}, {
|
|
19232
|
+
id: "petFountain.pumpOff",
|
|
19233
|
+
method: "setPump",
|
|
19234
|
+
label: t("Pump off", "Pompa spenta"),
|
|
19235
|
+
phrase: t("Stop the pump of {device}", "Ferma la pompa di {device}"),
|
|
19236
|
+
icon: "square",
|
|
19237
|
+
args: { on: false }
|
|
19238
|
+
}],
|
|
19053
19239
|
state: [{
|
|
19054
19240
|
kind: "boolean",
|
|
19055
19241
|
field: "empty",
|
|
@@ -42943,8 +43129,15 @@ var ActionInputSchema = object({
|
|
|
42943
43129
|
var ActionRunOriginSchema = object({
|
|
42944
43130
|
/** The automation block whose step started it. */
|
|
42945
43131
|
blockId: string().min(1).optional() });
|
|
42946
|
-
/**
|
|
42947
|
-
|
|
43132
|
+
/**
|
|
43133
|
+
* `started` = the caller did not ask to wait. `timed-out` = the run reached the
|
|
43134
|
+
* ceiling (`ACTION_RUN_MAX_MS`) and was stopped; it is never a `ran`.
|
|
43135
|
+
*/
|
|
43136
|
+
var ActionRunOutcomeSchema = union([
|
|
43137
|
+
AutomationRunOutcomeSchema,
|
|
43138
|
+
literal("started"),
|
|
43139
|
+
literal("timed-out")
|
|
43140
|
+
]);
|
|
42948
43141
|
var ActionRunResultSchema = object({
|
|
42949
43142
|
runId: string().min(1),
|
|
42950
43143
|
outcome: ActionRunOutcomeSchema,
|
|
@@ -43466,6 +43659,8 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
|
43466
43659
|
kind: "mutation",
|
|
43467
43660
|
auth: "admin"
|
|
43468
43661
|
});
|
|
43662
|
+
/** `timeoutMs` of `actions.run`: a waited call outlives any legal run. */
|
|
43663
|
+
var ACTION_RUN_TIMEOUT_MS = 363e4;
|
|
43469
43664
|
/**
|
|
43470
43665
|
* actions — the ONE surface for runnable actions, for the UI and for
|
|
43471
43666
|
* automations. Provided by the core-blocks builtin on the hub.
|
|
@@ -43484,6 +43679,12 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
|
43484
43679
|
* An admin, and an in-process caller (an automation block), may run any action.
|
|
43485
43680
|
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
43486
43681
|
*
|
|
43682
|
+
* **A run lasts at most `ACTION_RUN_MAX_MS` (60 min).** The provider stops a
|
|
43683
|
+
* run that reaches it and answers `timed-out` (never `ran`); an action whose
|
|
43684
|
+
* `wait` steps alone add up to more is refused at create/update
|
|
43685
|
+
* (`[invalid-steps]`). `run` declares a `timeoutMs` above that ceiling, so a
|
|
43686
|
+
* waited call (an automation step) is never cut by the 60 s transport default.
|
|
43687
|
+
*
|
|
43487
43688
|
* A second `run` of an action that is already running is REFUSED — traced and
|
|
43488
43689
|
* logged — never queued.
|
|
43489
43690
|
*/
|
|
@@ -43510,7 +43711,8 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
|
43510
43711
|
role: "viewer",
|
|
43511
43712
|
auth: "protected",
|
|
43512
43713
|
kind: "mutation",
|
|
43513
|
-
caller: "required"
|
|
43714
|
+
caller: "required",
|
|
43715
|
+
timeoutMs: ACTION_RUN_TIMEOUT_MS
|
|
43514
43716
|
}), method(ActionIdInput, _void(), {
|
|
43515
43717
|
kind: "mutation",
|
|
43516
43718
|
auth: "admin"
|
|
@@ -47527,6 +47729,9 @@ var MediaPlayerStatusSchema = object({
|
|
|
47527
47729
|
/** Repeat mode. Null when no repeat surface.
|
|
47528
47730
|
* Pair with `DeviceFeature.MediaPlayerRepeat`. */
|
|
47529
47731
|
repeat: MediaPlayerRepeatSchema.nullable(),
|
|
47732
|
+
/** Ms epoch when `position` was read from the device. Null when the driver
|
|
47733
|
+
* does not say; a UI that advances the position while playing counts from it. */
|
|
47734
|
+
positionUpdatedAt: number().nullable().default(null),
|
|
47530
47735
|
/** Ms epoch when the slice was last updated. */
|
|
47531
47736
|
lastChangedAt: number()
|
|
47532
47737
|
});
|
|
@@ -53061,6 +53266,7 @@ var IntegrationWithStateSchema = object({
|
|
|
53061
53266
|
id: string(),
|
|
53062
53267
|
addonId: string(),
|
|
53063
53268
|
name: string(),
|
|
53269
|
+
/** A projection of the instance body's switch (`setInstanceEnabled` is the only writer). */
|
|
53064
53270
|
enabled: boolean(),
|
|
53065
53271
|
info: record(string(), unknown()).readonly(),
|
|
53066
53272
|
/** The discovery candidate this integration was set up from (D984). */
|
|
@@ -53073,6 +53279,7 @@ var IntegrationLiteSchema = object({
|
|
|
53073
53279
|
id: string(),
|
|
53074
53280
|
addonId: string(),
|
|
53075
53281
|
name: string(),
|
|
53282
|
+
/** A projection of the instance body's switch (`setInstanceEnabled` is the only writer). */
|
|
53076
53283
|
enabled: boolean(),
|
|
53077
53284
|
info: record(string(), unknown()).readonly(),
|
|
53078
53285
|
/** The discovery candidate this integration was set up from (D984). */
|
|
@@ -53172,7 +53379,6 @@ var TestConnectionResultSchema = object({
|
|
|
53172
53379
|
var CreateIntegrationInputSchema = object({
|
|
53173
53380
|
addonId: string(),
|
|
53174
53381
|
name: string(),
|
|
53175
|
-
enabled: boolean().optional(),
|
|
53176
53382
|
info: record(string(), unknown()).optional(),
|
|
53177
53383
|
/** `stableId` of the discovery candidate the form was seeded from (D984). */
|
|
53178
53384
|
originStableId: string().optional(),
|
|
@@ -53181,6 +53387,11 @@ var CreateIntegrationInputSchema = object({
|
|
|
53181
53387
|
var UpdateIntegrationInputSchema = object({
|
|
53182
53388
|
id: string(),
|
|
53183
53389
|
name: string().optional(),
|
|
53390
|
+
/**
|
|
53391
|
+
* Accepted for a FIXED builtin only (`info.fixed`: alarm panel, camera grid, core blocks,
|
|
53392
|
+
* terminal), which keeps no instance record: the registry flag is its one store. Any other
|
|
53393
|
+
* integration is switched through `integration-instances.setInstanceEnabled`.
|
|
53394
|
+
*/
|
|
53184
53395
|
enabled: boolean().optional(),
|
|
53185
53396
|
info: record(string(), unknown()).optional()
|
|
53186
53397
|
});
|
|
@@ -53228,7 +53439,7 @@ var IntegrationInstanceIdSchema = string().min(1);
|
|
|
53228
53439
|
var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
|
|
53229
53440
|
/**
|
|
53230
53441
|
* What the addon's instances ARE for the Integrations page (planning#416). `devices`: each
|
|
53231
|
-
* instance is an integration that brings devices (
|
|
53442
|
+
* instance is an integration that brings devices (its record body owns the on/off switch);
|
|
53232
53443
|
* `services`: a connection configured from the addon's own function page, never listed on
|
|
53233
53444
|
* Integrations.
|
|
53234
53445
|
* It is the same vocabulary as the manifest's `integrationRole`, which stays as an override.
|
|
@@ -53345,8 +53556,8 @@ var IntegrationInstanceSchema = object({
|
|
|
53345
53556
|
configured: boolean(),
|
|
53346
53557
|
/**
|
|
53347
53558
|
* The instance's own on/off switch (D996), derived from the record body (`enabled !== false`,
|
|
53348
|
-
* so a row written before the field existed is on).
|
|
53349
|
-
*
|
|
53559
|
+
* so a row written before the field existed is on). The same for every role, `devices` included:
|
|
53560
|
+
* the body is the one store, `setInstanceEnabled` the one writer (epic #440, step 3).
|
|
53350
53561
|
*/
|
|
53351
53562
|
enabled: boolean().optional(),
|
|
53352
53563
|
/** The kind of this instance (one of `describe().kinds[].id`), when the provider has kinds. */
|
|
@@ -56182,6 +56393,8 @@ var MigrationIntegrationSchema = object({
|
|
|
56182
56393
|
addonId: string(),
|
|
56183
56394
|
name: string(),
|
|
56184
56395
|
info: Rows,
|
|
56396
|
+
/** The registry's stored switch: read by the one-switch migration, nothing else. */
|
|
56397
|
+
enabled: boolean().optional(),
|
|
56185
56398
|
originStableId: string().optional()
|
|
56186
56399
|
});
|
|
56187
56400
|
var MigrationDeviceSchema = object({
|
|
@@ -65700,14 +65913,6 @@ object({
|
|
|
65700
65913
|
empty: boolean().nullable(),
|
|
65701
65914
|
/** True while the pump is running. Null while unknown. */
|
|
65702
65915
|
pumpRunning: boolean().nullable(),
|
|
65703
|
-
/** Water drunk in the last drink, in litres. */
|
|
65704
|
-
lastDrink: number().min(0).nullable().meta(readingMeta("volume")),
|
|
65705
|
-
/** Water drunk in the current hour, in litres. */
|
|
65706
|
-
currentHourDrink: number().min(0).nullable().meta(readingMeta("volume")),
|
|
65707
|
-
/** Water drunk over the last 24 hours (rolling), in litres. */
|
|
65708
|
-
last24hDrink: number().min(0).nullable().meta(readingMeta("volume")),
|
|
65709
|
-
/** Water drunk since local midnight, in litres. Null when the fountain has no such sensor. */
|
|
65710
|
-
todayDrink: number().min(0).nullable().meta(readingMeta("volume")),
|
|
65711
65916
|
/** Decoded fault message. Null means healthy; a non-null string is an active fault. */
|
|
65712
65917
|
error: string().nullable(),
|
|
65713
65918
|
/** Ms epoch when the slice was last refreshed. */
|
|
@@ -65720,9 +65925,6 @@ DeviceType.PetFountain, method(object({
|
|
|
65720
65925
|
}), _void(), {
|
|
65721
65926
|
kind: "mutation",
|
|
65722
65927
|
auth: "protected"
|
|
65723
|
-
}), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
|
|
65724
|
-
kind: "mutation",
|
|
65725
|
-
auth: "protected"
|
|
65726
65928
|
});
|
|
65727
65929
|
/**
|
|
65728
65930
|
* The wire shapes of the Auto tune plan and apply (D745), used by the
|
|
@@ -81096,13 +81298,6 @@ Object.freeze({
|
|
|
81096
81298
|
access: "view",
|
|
81097
81299
|
role: "viewer"
|
|
81098
81300
|
},
|
|
81099
|
-
"petFountain.resetDailyConsumption": {
|
|
81100
|
-
capName: "pet-fountain",
|
|
81101
|
-
capScope: "device",
|
|
81102
|
-
addonId: null,
|
|
81103
|
-
access: "delete",
|
|
81104
|
-
role: "viewer"
|
|
81105
|
-
},
|
|
81106
81301
|
"petFountain.setPump": {
|
|
81107
81302
|
capName: "pet-fountain",
|
|
81108
81303
|
capScope: "device",
|
|
@@ -87499,11 +87694,6 @@ Object.freeze({
|
|
|
87499
87694
|
form: "single",
|
|
87500
87695
|
optional: false
|
|
87501
87696
|
}],
|
|
87502
|
-
"petFountain.resetDailyConsumption": [{
|
|
87503
|
-
name: "deviceId",
|
|
87504
|
-
form: "single",
|
|
87505
|
-
optional: false
|
|
87506
|
-
}],
|
|
87507
87697
|
"petFountain.setPump": [{
|
|
87508
87698
|
name: "deviceId",
|
|
87509
87699
|
form: "single",
|
|
@@ -90247,7 +90437,6 @@ object({
|
|
|
90247
90437
|
delay: number().nonnegative().optional(),
|
|
90248
90438
|
commands: record(string(), unknown())
|
|
90249
90439
|
});
|
|
90250
|
-
entryBody({ brokerId: string() });
|
|
90251
90440
|
//#endregion
|
|
90252
90441
|
//#region src/addon.ts
|
|
90253
90442
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -90269,7 +90458,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
90269
90458
|
capability: adminUiCapability,
|
|
90270
90459
|
provider: {
|
|
90271
90460
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
90272
|
-
getVersion: async () => ({ version: "1.2.
|
|
90461
|
+
getVersion: async () => ({ version: "1.2.334" })
|
|
90273
90462
|
}
|
|
90274
90463
|
}];
|
|
90275
90464
|
}
|