@mega-yfue/eufy-sdk 0.6.0-beta.42 → 0.6.0-beta.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -3462,7 +3462,7 @@ function propertiesOf(members, ctx) {
|
|
|
3462
3462
|
// stored value is that payload — see `PropertySpec.raw`.
|
|
3463
3463
|
raw: m.decode ? true : void 0,
|
|
3464
3464
|
readAliases: aliases?.slice(promoted ? 1 : 0).map(({ paramType, invert }) => ({ paramType, invert })),
|
|
3465
|
-
writable: m.write !== void 0 || m.writtenElsewhere === true,
|
|
3465
|
+
writable: m.write !== void 0 && !(ctx && m.unverifiedFor?.(ctx)) || m.writtenElsewhere === true,
|
|
3466
3466
|
reported: ctx?.paramIds ? wasReported(m, borrowedBy(m, members), { ...ctx, paramIds: ctx.paramIds }) : void 0,
|
|
3467
3467
|
description: m.description
|
|
3468
3468
|
}
|
|
@@ -3635,7 +3635,7 @@ function bindMembers(members, deps) {
|
|
|
3635
3635
|
const get = decode ? () => decode(raw(), rawDp2, ctx) : () => narrow(m.type, read, prop, domain);
|
|
3636
3636
|
Object.defineProperty(out, name, { get, enumerable: true, configurable: true });
|
|
3637
3637
|
}
|
|
3638
|
-
if (!m.write || m.unverified || !installs(m, ctx) || !writeRoutable(m, ctx))
|
|
3638
|
+
if (!m.write || m.unverified || m.unverifiedFor?.(ctx) || !installs(m, ctx) || !writeRoutable(m, ctx))
|
|
3639
3639
|
continue;
|
|
3640
3640
|
if (m.writeOnly)
|
|
3641
3641
|
unobservable.push(name);
|
|
@@ -6865,25 +6865,12 @@ var LIGHT_SWITCH_INT_STRING_TYPES = /* @__PURE__ */ new Set([
|
|
|
6865
6865
|
DeviceType.CAMERA3C,
|
|
6866
6866
|
DeviceType.PROFESSIONAL_247
|
|
6867
6867
|
]);
|
|
6868
|
-
function switchCommand(on, ctx) {
|
|
6869
|
-
|
|
6870
|
-
case "json":
|
|
6871
|
-
return setJson(LIGHT_CMD.FLOODLIGHT_SWITCH, { time: 0, type: 2, value: on ? 1 : 0 }, ctx);
|
|
6872
|
-
case "int-string":
|
|
6873
|
-
return setScalar(LIGHT_CMD.FLOODLIGHT_SWITCH, on ? 1 : 0, ctx, "int-string");
|
|
6874
|
-
default:
|
|
6875
|
-
return void 0;
|
|
6876
|
-
}
|
|
6868
|
+
function switchCommand(on, wire, ctx) {
|
|
6869
|
+
return wire === "json" ? setJson(LIGHT_CMD.FLOODLIGHT_SWITCH, { time: 0, type: 2, value: on ? 1 : 0 }, ctx) : setScalar(LIGHT_CMD.FLOODLIGHT_SWITCH, on ? 1 : 0, ctx, "int-string");
|
|
6877
6870
|
}
|
|
6878
6871
|
function directBinary(param, value, ctx) {
|
|
6879
6872
|
return setScalar(param, value, ctx, "direct-binary");
|
|
6880
6873
|
}
|
|
6881
|
-
function switchFrame(on, ctx) {
|
|
6882
|
-
const cmd = switchCommand(on, ctx);
|
|
6883
|
-
if (!cmd)
|
|
6884
|
-
throw new Error(`light: unknown spotlight switch wire format \u2014 confirm it [${describeDevice(ctx)}]`);
|
|
6885
|
-
return cmd;
|
|
6886
|
-
}
|
|
6887
6874
|
var LIGHT_MEMBERS = {
|
|
6888
6875
|
/**
|
|
6889
6876
|
* Whether the lamp is lit RIGHT NOW — the momentary switch, not a setting. Measured on a T8170: 1400
|
|
@@ -6894,9 +6881,8 @@ var LIGHT_MEMBERS = {
|
|
|
6894
6881
|
* So it reads on whenever any client is watching. The setting a user changes and expects to persist
|
|
6895
6882
|
* is {@link spotlightEnabled}.
|
|
6896
6883
|
*
|
|
6897
|
-
* The switch
|
|
6898
|
-
*
|
|
6899
|
-
* letting the generated "not a valid value" blame a boolean that was never the problem.
|
|
6884
|
+
* The switch frame SHAPE is per family ({@link lightSwitchWire}), and the write is `unverifiedFor` the
|
|
6885
|
+
* families it has no shape for.
|
|
6900
6886
|
*/
|
|
6901
6887
|
isOn: {
|
|
6902
6888
|
param: LIGHT_CMD.FLOODLIGHT_SWITCH,
|
|
@@ -6905,7 +6891,11 @@ var LIGHT_MEMBERS = {
|
|
|
6905
6891
|
kind: "boolean",
|
|
6906
6892
|
provenance: "verified",
|
|
6907
6893
|
description: "Light on/off (1400) \u2014 lit right now, not a setting: it follows whichever client is streaming. Verified via P2P state readback (3/3); session-scoped behaviour measured live on a T8170.",
|
|
6908
|
-
write: (v, ctx) =>
|
|
6894
|
+
write: (v, ctx) => {
|
|
6895
|
+
const wire = lightSwitchWire(ctx);
|
|
6896
|
+
return wire && switchCommand(asBool(v), wire, ctx);
|
|
6897
|
+
},
|
|
6898
|
+
unverifiedFor: (ctx) => lightSwitchWire(ctx) === void 0,
|
|
6909
6899
|
writeAs: "set",
|
|
6910
6900
|
aliases: { on: true, off: false }
|
|
6911
6901
|
},
|
|
@@ -6986,14 +6976,15 @@ var LIGHT = {
|
|
|
6986
6976
|
* Only what the member table cannot express: `on`/`off` as no-argument verbs over the same wire as the
|
|
6987
6977
|
* derived `set`, and the write-only auto-spotlight composite. The verbs stay UNDESCRIBED on purpose —
|
|
6988
6978
|
* `set` is the method that takes the value, and describing all three would offer one state as three
|
|
6989
|
-
* controls. `
|
|
6990
|
-
* caller expects, the same shape the derived setter gets from `bindMembers`.
|
|
6979
|
+
* controls. Like `set`, the verbs are absent on a model whose switch shape is unverified.
|
|
6991
6980
|
*/
|
|
6992
6981
|
actions({ ctx, sink }) {
|
|
6993
|
-
const
|
|
6982
|
+
const wire = lightSwitchWire(ctx);
|
|
6994
6983
|
return {
|
|
6995
|
-
|
|
6996
|
-
|
|
6984
|
+
...wire && {
|
|
6985
|
+
on: () => sink.dispatch(switchCommand(true, wire, ctx)),
|
|
6986
|
+
off: () => sink.dispatch(switchCommand(false, wire, ctx))
|
|
6987
|
+
},
|
|
6997
6988
|
setAutoSpotlight: (on, opts) => sink.dispatch(autoSpotlightCommand(asBool(on), ctx, opts))
|
|
6998
6989
|
};
|
|
6999
6990
|
}
|
|
@@ -11862,8 +11853,8 @@ function memberCommand(m, action, value, ctx) {
|
|
|
11862
11853
|
const claims = action === property2 || member.intentNames?.includes(action) === true;
|
|
11863
11854
|
if (!claims && aliased === void 0)
|
|
11864
11855
|
continue;
|
|
11865
|
-
if (member.unverified) {
|
|
11866
|
-
throw new Error(`${m.capability}: ${name} write wire unverified \u2014 confirm it on a device before sending`);
|
|
11856
|
+
if (member.unverified || member.unverifiedFor?.(ctx)) {
|
|
11857
|
+
throw new Error(`${m.capability}: ${name} write wire unverified \u2014 confirm it on a device before sending [${describeDevice(ctx)}]`);
|
|
11867
11858
|
}
|
|
11868
11859
|
if (!member.write || !installs(member, ctx))
|
|
11869
11860
|
continue;
|
|
@@ -16388,19 +16379,19 @@ function buildKeyedActuatePayload(id, devicePublicKeyHex, userName, rnd) {
|
|
|
16388
16379
|
payload: sealInnerPayload(inner, aesKeyHex, id.deviceSn)
|
|
16389
16380
|
};
|
|
16390
16381
|
}
|
|
16391
|
-
function keyedPayloadReportCode(
|
|
16392
|
-
if (
|
|
16382
|
+
function keyedPayloadReportCode(json2, engage) {
|
|
16383
|
+
if (json2?.cmd !== CommandType.P2P_QUERY_STATUS_IN_LOCK)
|
|
16393
16384
|
return void 0;
|
|
16394
|
-
const payload =
|
|
16385
|
+
const payload = json2.payload;
|
|
16395
16386
|
const slState = engage ? "4" : "3";
|
|
16396
16387
|
if (payload?.slState !== slState)
|
|
16397
16388
|
return void 0;
|
|
16398
16389
|
return typeof payload?.code === "number" ? payload.code : void 0;
|
|
16399
16390
|
}
|
|
16400
|
-
function keyedPayloadSeqMark(
|
|
16401
|
-
if (
|
|
16391
|
+
function keyedPayloadSeqMark(json2) {
|
|
16392
|
+
if (json2?.cmd !== CommandType.CMD_DOORLOCK_P2P_SEQ)
|
|
16402
16393
|
return void 0;
|
|
16403
|
-
const seq =
|
|
16394
|
+
const seq = json2.payload?.seq_num;
|
|
16404
16395
|
return typeof seq === "number" && Number.isFinite(seq) ? seq : void 0;
|
|
16405
16396
|
}
|
|
16406
16397
|
|
|
@@ -17696,8 +17687,8 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
17696
17687
|
* `channel`. This is the form the eufy app uses for control commands (confirmed by live capture:
|
|
17697
17688
|
* floodlight = `{"commandType":1400,"data":{...}}`). Returns `false` if no level-2 key.
|
|
17698
17689
|
*/
|
|
17699
|
-
sendRawLevel2(
|
|
17700
|
-
return this.sendRawLevel2Bytes(Buffer.from(
|
|
17690
|
+
sendRawLevel2(json2, channel, outerCmd = CMD_SET_PAYLOAD) {
|
|
17691
|
+
return this.sendRawLevel2Bytes(Buffer.from(json2, "utf-8"), channel, outerCmd);
|
|
17701
17692
|
}
|
|
17702
17693
|
/**
|
|
17703
17694
|
* Like {@link sendRawLevel2} but the plaintext is a raw byte buffer, not a UTF-8 string. Some
|
|
@@ -17805,13 +17796,13 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
|
|
|
17805
17796
|
body.writeUInt32LE(channel >>> 0, 0);
|
|
17806
17797
|
return this.sendRawLevel2Bytes(body, channel, start ? CMD_START_TALKBACK : CMD_STOP_TALKBACK, 8);
|
|
17807
17798
|
}
|
|
17808
|
-
const
|
|
17799
|
+
const json2 = JSON.stringify({
|
|
17809
17800
|
commandType: start ? CMD_START_SPEAK : CMD_END_SPEAK,
|
|
17810
17801
|
data: { transaction: String(Date.now()) }
|
|
17811
17802
|
});
|
|
17812
17803
|
if (this.level2Key)
|
|
17813
|
-
return this.sendRawLevel2(
|
|
17814
|
-
this.sendStringPayloadCommand(CMD_CONTROL_PAYLOAD,
|
|
17804
|
+
return this.sendRawLevel2(json2, channel, CMD_CONTROL_PAYLOAD);
|
|
17805
|
+
this.sendStringPayloadCommand(CMD_CONTROL_PAYLOAD, json2, channel);
|
|
17815
17806
|
return true;
|
|
17816
17807
|
}
|
|
17817
17808
|
/**
|
|
@@ -23736,17 +23727,17 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
23736
23727
|
session.off("data", onData);
|
|
23737
23728
|
};
|
|
23738
23729
|
session.on("data", onData);
|
|
23739
|
-
const
|
|
23730
|
+
const json2 = JSON.stringify({ commandType: param, data });
|
|
23740
23731
|
this.sendBySessionLevel(sn, {
|
|
23741
23732
|
l1: ({ session: s, channel: ch }) => {
|
|
23742
|
-
s.sendStringPayloadCommand(P2P_ENVELOPE.CONTROL_PAYLOAD,
|
|
23733
|
+
s.sendStringPayloadCommand(P2P_ENVELOPE.CONTROL_PAYLOAD, json2, ch);
|
|
23743
23734
|
return Promise.resolve();
|
|
23744
23735
|
},
|
|
23745
23736
|
l2: async ({ session: s, channel: ch, parentSn }) => {
|
|
23746
23737
|
if (!await s.awaitLevel2Key(LEVEL2_GRACE_MS, "call")) {
|
|
23747
23738
|
throw new StationKeyUnavailableError(parentSn);
|
|
23748
23739
|
}
|
|
23749
|
-
s.sendRawLevel2(
|
|
23740
|
+
s.sendRawLevel2(json2, ch, P2P_ENVELOPE.CONTROL_PAYLOAD);
|
|
23750
23741
|
}
|
|
23751
23742
|
}).catch((e) => {
|
|
23752
23743
|
cleanup();
|
|
@@ -24432,17 +24423,17 @@ var P2PCommandRouter = class _P2PCommandRouter {
|
|
|
24432
24423
|
* the session to connect + (for HomeBase) the level-2 key.
|
|
24433
24424
|
*/
|
|
24434
24425
|
async routeControl(sn, outerCmd, inner) {
|
|
24435
|
-
const
|
|
24426
|
+
const json2 = JSON.stringify(inner);
|
|
24436
24427
|
await this.sendBySessionLevel(sn, {
|
|
24437
24428
|
l1: ({ session, channel }) => {
|
|
24438
|
-
session.sendStringPayloadCommand(outerCmd,
|
|
24429
|
+
session.sendStringPayloadCommand(outerCmd, json2, channel);
|
|
24439
24430
|
return Promise.resolve();
|
|
24440
24431
|
},
|
|
24441
24432
|
l2: async ({ session, channel }) => {
|
|
24442
24433
|
if (!await session.awaitLevel2Key(LEVEL2_GRACE_MS, "call")) {
|
|
24443
24434
|
throw new Error(`level-2 key not ready for ${sn} \u2014 cannot route HomeBase command`);
|
|
24444
24435
|
}
|
|
24445
|
-
session.sendRawLevel2(
|
|
24436
|
+
session.sendRawLevel2(json2, channel, outerCmd);
|
|
24446
24437
|
}
|
|
24447
24438
|
});
|
|
24448
24439
|
}
|
|
@@ -25058,7 +25049,7 @@ var PtcsFramer = class {
|
|
|
25058
25049
|
// dist/transport/rtc/scall-sdp.js
|
|
25059
25050
|
var HUB_SDP_MID = "2";
|
|
25060
25051
|
var ANKER_MAX_MESSAGE_SIZE = 262144;
|
|
25061
|
-
function scallJsonToSdp(
|
|
25052
|
+
function scallJsonToSdp(json2, now2 = Date.now) {
|
|
25062
25053
|
let sdp = "";
|
|
25063
25054
|
sdp += "v=0\r\n";
|
|
25064
25055
|
sdp += `o=- ${Math.floor(now2())} 1 IN IP4 127.0.0.1\r
|
|
@@ -25073,42 +25064,42 @@ function scallJsonToSdp(json, now2 = Date.now) {
|
|
|
25073
25064
|
sdp += `a=mid:${HUB_SDP_MID}\r
|
|
25074
25065
|
`;
|
|
25075
25066
|
sdp += "a=ice-options:trickle\r\n";
|
|
25076
|
-
if (
|
|
25077
|
-
sdp += `a=ice-ufrag:${
|
|
25067
|
+
if (json2.ice?.ufrag)
|
|
25068
|
+
sdp += `a=ice-ufrag:${json2.ice.ufrag}\r
|
|
25078
25069
|
`;
|
|
25079
|
-
if (
|
|
25080
|
-
sdp += `a=ice-pwd:${
|
|
25070
|
+
if (json2.ice?.pwd)
|
|
25071
|
+
sdp += `a=ice-pwd:${json2.ice.pwd}\r
|
|
25081
25072
|
`;
|
|
25082
|
-
if (
|
|
25083
|
-
const fp =
|
|
25084
|
-
sdp += `a=fingerprint:${
|
|
25073
|
+
if (json2.ice?.fingerprint) {
|
|
25074
|
+
const fp = json2.ice.fingerprint.replace(/(.{2})(?=.)/g, "$1:");
|
|
25075
|
+
sdp += `a=fingerprint:${json2.ice.fingerprint_type ?? "sha-256"} ${fp}\r
|
|
25085
25076
|
`;
|
|
25086
25077
|
}
|
|
25087
|
-
sdp += `a=setup:${
|
|
25078
|
+
sdp += `a=setup:${json2.setup ?? "actpass"}\r
|
|
25088
25079
|
`;
|
|
25089
25080
|
sdp += "a=sctp-port:5000\r\n";
|
|
25090
25081
|
sdp += `a=max-message-size:${ANKER_MAX_MESSAGE_SIZE}\r
|
|
25091
25082
|
`;
|
|
25092
|
-
for (const c of
|
|
25083
|
+
for (const c of json2.candidate ?? [])
|
|
25093
25084
|
sdp += `a=candidate:${c}\r
|
|
25094
25085
|
`;
|
|
25095
25086
|
return sdp;
|
|
25096
25087
|
}
|
|
25097
25088
|
function sdpToScallJson(sdp) {
|
|
25098
|
-
const
|
|
25089
|
+
const json2 = { ice: { ufrag: "", pwd: "", fingerprint: "" } };
|
|
25099
25090
|
const setup = sdp.match(/a=setup:([^\r\n]+)/)?.[1];
|
|
25100
25091
|
if (setup && setup !== "actpass")
|
|
25101
|
-
|
|
25092
|
+
json2.setup = setup;
|
|
25102
25093
|
const ufrag = sdp.match(/a=ice-ufrag:([^\r\n]+)/)?.[1];
|
|
25103
25094
|
if (ufrag)
|
|
25104
|
-
|
|
25095
|
+
json2.ice.ufrag = ufrag;
|
|
25105
25096
|
const pwd = sdp.match(/a=ice-pwd:([^\r\n]+)/)?.[1];
|
|
25106
25097
|
if (pwd)
|
|
25107
|
-
|
|
25098
|
+
json2.ice.pwd = pwd;
|
|
25108
25099
|
const fp = sdp.match(/a=fingerprint:([^\s]+)\s+([^\r\n]+)/);
|
|
25109
25100
|
if (fp?.[2]) {
|
|
25110
|
-
|
|
25111
|
-
|
|
25101
|
+
json2.ice.fingerprint_type = fp[1];
|
|
25102
|
+
json2.ice.fingerprint = fp[2].replace(/:/g, "");
|
|
25112
25103
|
}
|
|
25113
25104
|
const candidates = [];
|
|
25114
25105
|
for (const line of sdp.split(/\r\n|\r|\n/)) {
|
|
@@ -25117,8 +25108,8 @@ function sdpToScallJson(sdp) {
|
|
|
25117
25108
|
candidates.push(m[1]);
|
|
25118
25109
|
}
|
|
25119
25110
|
if (candidates.length)
|
|
25120
|
-
|
|
25121
|
-
return
|
|
25111
|
+
json2.candidate = candidates;
|
|
25112
|
+
return json2;
|
|
25122
25113
|
}
|
|
25123
25114
|
function iceCandidateType(candidate) {
|
|
25124
25115
|
return candidate.match(/typ (\w+)/)?.[1] ?? "unknown";
|
|
@@ -27630,10 +27621,10 @@ function deriveBodyKey(requestId, ecode) {
|
|
|
27630
27621
|
const hex = createHmac5("sha256", requestId).update(msg, "utf-8").digest("hex");
|
|
27631
27622
|
return Buffer.from(hex.slice(0, 16), "ascii");
|
|
27632
27623
|
}
|
|
27633
|
-
function encryptBody2(key,
|
|
27624
|
+
function encryptBody2(key, json2) {
|
|
27634
27625
|
const nonce = randomBytes6(12);
|
|
27635
27626
|
const cipher = createCipheriv7("aes-128-gcm", key, nonce);
|
|
27636
|
-
const ciphertext = Buffer.concat([cipher.update(Buffer.from(
|
|
27627
|
+
const ciphertext = Buffer.concat([cipher.update(Buffer.from(json2, "utf-8")), cipher.final()]);
|
|
27637
27628
|
return Buffer.concat([nonce, ciphertext, cipher.getAuthTag()]).toString("base64");
|
|
27638
27629
|
}
|
|
27639
27630
|
function decryptReply(key, resultB64) {
|
|
@@ -28822,11 +28813,11 @@ var PushClient = class _PushClient extends EventEmitter13 {
|
|
|
28822
28813
|
const data = {};
|
|
28823
28814
|
for (const kv of object?.appData ?? []) {
|
|
28824
28815
|
if (kv.key === "payload") {
|
|
28825
|
-
const
|
|
28816
|
+
const json2 = readNullTerminated(Buffer.from(kv.value, "base64"));
|
|
28826
28817
|
try {
|
|
28827
|
-
data.payload = JSON.parse(
|
|
28818
|
+
data.payload = JSON.parse(json2);
|
|
28828
28819
|
} catch {
|
|
28829
|
-
data.payload =
|
|
28820
|
+
data.payload = json2;
|
|
28830
28821
|
}
|
|
28831
28822
|
} else {
|
|
28832
28823
|
data[kv.key] = kv.value;
|
|
@@ -29340,7 +29331,71 @@ function cameraInfo(facts, qualifier, value) {
|
|
|
29340
29331
|
return typeof spec.value === "string" && spec.value === reported;
|
|
29341
29332
|
if (qualifier === "RE")
|
|
29342
29333
|
return typeof spec.regex === "string" && re(spec.regex, reported);
|
|
29343
|
-
|
|
29334
|
+
if (qualifier !== "json_match" || !spec.json_match || typeof spec.json_match !== "object")
|
|
29335
|
+
return false;
|
|
29336
|
+
const target = json(reported);
|
|
29337
|
+
return !!target && typeof target === "object" && !Array.isArray(target) && jsonMatch(target, spec.json_match);
|
|
29338
|
+
}
|
|
29339
|
+
var content = (v) => v === null || v === void 0 || typeof v === "object" ? void 0 : String(v);
|
|
29340
|
+
var json = (text2) => {
|
|
29341
|
+
try {
|
|
29342
|
+
return JSON.parse(text2);
|
|
29343
|
+
} catch {
|
|
29344
|
+
return void 0;
|
|
29345
|
+
}
|
|
29346
|
+
};
|
|
29347
|
+
var asInt = (v, fallback) => {
|
|
29348
|
+
const n = Number.parseInt(String(v), 10);
|
|
29349
|
+
return Number.isNaN(n) ? fallback : n;
|
|
29350
|
+
};
|
|
29351
|
+
var ASSOCIATED = {
|
|
29352
|
+
/** `true` once `APP_CMD_SET_SILENT_OTA_SWITCH` (6287) is reported. */
|
|
29353
|
+
is_support_silent_ota_switch: (p) => p[6287] === void 0 ? void 0 : "true",
|
|
29354
|
+
/** `APP_CMD_HB3_AI_Empowerment` (1299): its JSON value, else the value as an integer (0 when none). */
|
|
29355
|
+
ai_empower: (p) => {
|
|
29356
|
+
const v = p[1299];
|
|
29357
|
+
if (v === void 0)
|
|
29358
|
+
return void 0;
|
|
29359
|
+
const parsed = json(v);
|
|
29360
|
+
if (parsed === void 0)
|
|
29361
|
+
return String(asInt(v, 0));
|
|
29362
|
+
return content(parsed) ?? JSON.stringify(parsed);
|
|
29363
|
+
},
|
|
29364
|
+
/** `APP_CMD_GET_POWER_SUPPLY_MODE` (6445): its JSON `power_source`, else `source`, as an integer; 1 when empty. */
|
|
29365
|
+
device_power_supply_mode: (p) => {
|
|
29366
|
+
const v = p[6445];
|
|
29367
|
+
if (v === void 0)
|
|
29368
|
+
return void 0;
|
|
29369
|
+
if (v === "")
|
|
29370
|
+
return "1";
|
|
29371
|
+
const parsed = json(v);
|
|
29372
|
+
return parsed === void 0 ? void 0 : String(asInt(parsed?.power_source ?? parsed?.source, 1));
|
|
29373
|
+
}
|
|
29374
|
+
};
|
|
29375
|
+
function jsonMatch(target, match) {
|
|
29376
|
+
const checks = [];
|
|
29377
|
+
const keys = (k) => Array.isArray(match[k]) ? match[k].map(content).filter((x) => x !== void 0) : [];
|
|
29378
|
+
const pairs = (k) => match[k] && typeof match[k] === "object" ? Object.entries(match[k]).map(([key, v]) => [key, content(v)]) : [];
|
|
29379
|
+
for (const k of keys("contains_key"))
|
|
29380
|
+
checks.push(Object.hasOwn(target, k));
|
|
29381
|
+
for (const k of keys("not_contains_key"))
|
|
29382
|
+
checks.push(!Object.hasOwn(target, k));
|
|
29383
|
+
const valued = (k, test) => {
|
|
29384
|
+
for (const [key, expected] of pairs(k)) {
|
|
29385
|
+
const actual = content(target[key]);
|
|
29386
|
+
checks.push(expected !== void 0 && actual !== void 0 && test(actual, expected));
|
|
29387
|
+
}
|
|
29388
|
+
};
|
|
29389
|
+
valued("value_equals", (a, e) => a === e);
|
|
29390
|
+
valued("value_not_equals", (a, e) => a !== e);
|
|
29391
|
+
valued("value_regex", (a, e) => {
|
|
29392
|
+
try {
|
|
29393
|
+
return new RegExp(e).test(a);
|
|
29394
|
+
} catch {
|
|
29395
|
+
return false;
|
|
29396
|
+
}
|
|
29397
|
+
});
|
|
29398
|
+
return match.mode === "any" ? checks.some(Boolean) : checks.every(Boolean);
|
|
29344
29399
|
}
|
|
29345
29400
|
function condition(c, facts) {
|
|
29346
29401
|
const station = facts.stationSerial ?? facts.serial ?? "";
|
|
@@ -29358,15 +29413,10 @@ function condition(c, facts) {
|
|
|
29358
29413
|
return re(c.value, facts.serial ?? "");
|
|
29359
29414
|
case "user_country":
|
|
29360
29415
|
return re(c.value, facts.country ?? "");
|
|
29361
|
-
case "user_domain":
|
|
29362
|
-
return re(c.value, "");
|
|
29363
29416
|
case "sdk_version":
|
|
29364
29417
|
return version(APP_SDK_VERSION, c.qualifier, c.value);
|
|
29365
29418
|
case "associated_field":
|
|
29366
|
-
|
|
29367
|
-
return compare("", c.qualifier, c.value);
|
|
29368
|
-
case "user_permission":
|
|
29369
|
-
return c.qualifier === "in";
|
|
29419
|
+
return compare(ASSOCIATED[c.propId ?? ""]?.(facts.params ?? {}) ?? "", c.qualifier, c.value);
|
|
29370
29420
|
case "camera_info":
|
|
29371
29421
|
return cameraInfo(facts, c.qualifier, c.value);
|
|
29372
29422
|
default:
|
|
@@ -29399,7 +29449,7 @@ function resolveThing(td, facts) {
|
|
|
29399
29449
|
const p = td.properties[chosen];
|
|
29400
29450
|
if (!p || !conditionsPass(p.availableConditions, facts))
|
|
29401
29451
|
continue;
|
|
29402
|
-
properties[base] =
|
|
29452
|
+
properties[base] = p;
|
|
29403
29453
|
}
|
|
29404
29454
|
const available = (entries) => {
|
|
29405
29455
|
const out = /* @__PURE__ */ Object.create(null);
|
|
@@ -29450,7 +29500,6 @@ function property(p) {
|
|
|
29450
29500
|
...num2(specs.step) !== void 0 ? { step: num2(specs.step) } : {},
|
|
29451
29501
|
...optStr(specs.unit) !== void 0 ? { unit: str3(specs.unit) } : {},
|
|
29452
29502
|
readConditions: conditions(p.read_conditions),
|
|
29453
|
-
writeConditions: conditions(p.write_conditions),
|
|
29454
29503
|
availableConditions: conditions(p.available_conditions)
|
|
29455
29504
|
};
|
|
29456
29505
|
}
|