@mega-yfue/eufy-sdk 0.6.0-beta.42 → 0.6.0-beta.43

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
@@ -16388,19 +16388,19 @@ function buildKeyedActuatePayload(id, devicePublicKeyHex, userName, rnd) {
16388
16388
  payload: sealInnerPayload(inner, aesKeyHex, id.deviceSn)
16389
16389
  };
16390
16390
  }
16391
- function keyedPayloadReportCode(json, engage) {
16392
- if (json?.cmd !== CommandType.P2P_QUERY_STATUS_IN_LOCK)
16391
+ function keyedPayloadReportCode(json2, engage) {
16392
+ if (json2?.cmd !== CommandType.P2P_QUERY_STATUS_IN_LOCK)
16393
16393
  return void 0;
16394
- const payload = json.payload;
16394
+ const payload = json2.payload;
16395
16395
  const slState = engage ? "4" : "3";
16396
16396
  if (payload?.slState !== slState)
16397
16397
  return void 0;
16398
16398
  return typeof payload?.code === "number" ? payload.code : void 0;
16399
16399
  }
16400
- function keyedPayloadSeqMark(json) {
16401
- if (json?.cmd !== CommandType.CMD_DOORLOCK_P2P_SEQ)
16400
+ function keyedPayloadSeqMark(json2) {
16401
+ if (json2?.cmd !== CommandType.CMD_DOORLOCK_P2P_SEQ)
16402
16402
  return void 0;
16403
- const seq = json.payload?.seq_num;
16403
+ const seq = json2.payload?.seq_num;
16404
16404
  return typeof seq === "number" && Number.isFinite(seq) ? seq : void 0;
16405
16405
  }
16406
16406
 
@@ -17696,8 +17696,8 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
17696
17696
  * `channel`. This is the form the eufy app uses for control commands (confirmed by live capture:
17697
17697
  * floodlight = `{"commandType":1400,"data":{...}}`). Returns `false` if no level-2 key.
17698
17698
  */
17699
- sendRawLevel2(json, channel, outerCmd = CMD_SET_PAYLOAD) {
17700
- return this.sendRawLevel2Bytes(Buffer.from(json, "utf-8"), channel, outerCmd);
17699
+ sendRawLevel2(json2, channel, outerCmd = CMD_SET_PAYLOAD) {
17700
+ return this.sendRawLevel2Bytes(Buffer.from(json2, "utf-8"), channel, outerCmd);
17701
17701
  }
17702
17702
  /**
17703
17703
  * Like {@link sendRawLevel2} but the plaintext is a raw byte buffer, not a UTF-8 string. Some
@@ -17805,13 +17805,13 @@ var P2PSession = class _P2PSession extends EventEmitter2 {
17805
17805
  body.writeUInt32LE(channel >>> 0, 0);
17806
17806
  return this.sendRawLevel2Bytes(body, channel, start ? CMD_START_TALKBACK : CMD_STOP_TALKBACK, 8);
17807
17807
  }
17808
- const json = JSON.stringify({
17808
+ const json2 = JSON.stringify({
17809
17809
  commandType: start ? CMD_START_SPEAK : CMD_END_SPEAK,
17810
17810
  data: { transaction: String(Date.now()) }
17811
17811
  });
17812
17812
  if (this.level2Key)
17813
- return this.sendRawLevel2(json, channel, CMD_CONTROL_PAYLOAD);
17814
- this.sendStringPayloadCommand(CMD_CONTROL_PAYLOAD, json, channel);
17813
+ return this.sendRawLevel2(json2, channel, CMD_CONTROL_PAYLOAD);
17814
+ this.sendStringPayloadCommand(CMD_CONTROL_PAYLOAD, json2, channel);
17815
17815
  return true;
17816
17816
  }
17817
17817
  /**
@@ -23736,17 +23736,17 @@ var P2PCommandRouter = class _P2PCommandRouter {
23736
23736
  session.off("data", onData);
23737
23737
  };
23738
23738
  session.on("data", onData);
23739
- const json = JSON.stringify({ commandType: param, data });
23739
+ const json2 = JSON.stringify({ commandType: param, data });
23740
23740
  this.sendBySessionLevel(sn, {
23741
23741
  l1: ({ session: s, channel: ch }) => {
23742
- s.sendStringPayloadCommand(P2P_ENVELOPE.CONTROL_PAYLOAD, json, ch);
23742
+ s.sendStringPayloadCommand(P2P_ENVELOPE.CONTROL_PAYLOAD, json2, ch);
23743
23743
  return Promise.resolve();
23744
23744
  },
23745
23745
  l2: async ({ session: s, channel: ch, parentSn }) => {
23746
23746
  if (!await s.awaitLevel2Key(LEVEL2_GRACE_MS, "call")) {
23747
23747
  throw new StationKeyUnavailableError(parentSn);
23748
23748
  }
23749
- s.sendRawLevel2(json, ch, P2P_ENVELOPE.CONTROL_PAYLOAD);
23749
+ s.sendRawLevel2(json2, ch, P2P_ENVELOPE.CONTROL_PAYLOAD);
23750
23750
  }
23751
23751
  }).catch((e) => {
23752
23752
  cleanup();
@@ -24432,17 +24432,17 @@ var P2PCommandRouter = class _P2PCommandRouter {
24432
24432
  * the session to connect + (for HomeBase) the level-2 key.
24433
24433
  */
24434
24434
  async routeControl(sn, outerCmd, inner) {
24435
- const json = JSON.stringify(inner);
24435
+ const json2 = JSON.stringify(inner);
24436
24436
  await this.sendBySessionLevel(sn, {
24437
24437
  l1: ({ session, channel }) => {
24438
- session.sendStringPayloadCommand(outerCmd, json, channel);
24438
+ session.sendStringPayloadCommand(outerCmd, json2, channel);
24439
24439
  return Promise.resolve();
24440
24440
  },
24441
24441
  l2: async ({ session, channel }) => {
24442
24442
  if (!await session.awaitLevel2Key(LEVEL2_GRACE_MS, "call")) {
24443
24443
  throw new Error(`level-2 key not ready for ${sn} \u2014 cannot route HomeBase command`);
24444
24444
  }
24445
- session.sendRawLevel2(json, channel, outerCmd);
24445
+ session.sendRawLevel2(json2, channel, outerCmd);
24446
24446
  }
24447
24447
  });
24448
24448
  }
@@ -25058,7 +25058,7 @@ var PtcsFramer = class {
25058
25058
  // dist/transport/rtc/scall-sdp.js
25059
25059
  var HUB_SDP_MID = "2";
25060
25060
  var ANKER_MAX_MESSAGE_SIZE = 262144;
25061
- function scallJsonToSdp(json, now2 = Date.now) {
25061
+ function scallJsonToSdp(json2, now2 = Date.now) {
25062
25062
  let sdp = "";
25063
25063
  sdp += "v=0\r\n";
25064
25064
  sdp += `o=- ${Math.floor(now2())} 1 IN IP4 127.0.0.1\r
@@ -25073,42 +25073,42 @@ function scallJsonToSdp(json, now2 = Date.now) {
25073
25073
  sdp += `a=mid:${HUB_SDP_MID}\r
25074
25074
  `;
25075
25075
  sdp += "a=ice-options:trickle\r\n";
25076
- if (json.ice?.ufrag)
25077
- sdp += `a=ice-ufrag:${json.ice.ufrag}\r
25076
+ if (json2.ice?.ufrag)
25077
+ sdp += `a=ice-ufrag:${json2.ice.ufrag}\r
25078
25078
  `;
25079
- if (json.ice?.pwd)
25080
- sdp += `a=ice-pwd:${json.ice.pwd}\r
25079
+ if (json2.ice?.pwd)
25080
+ sdp += `a=ice-pwd:${json2.ice.pwd}\r
25081
25081
  `;
25082
- if (json.ice?.fingerprint) {
25083
- const fp = json.ice.fingerprint.replace(/(.{2})(?=.)/g, "$1:");
25084
- sdp += `a=fingerprint:${json.ice.fingerprint_type ?? "sha-256"} ${fp}\r
25082
+ if (json2.ice?.fingerprint) {
25083
+ const fp = json2.ice.fingerprint.replace(/(.{2})(?=.)/g, "$1:");
25084
+ sdp += `a=fingerprint:${json2.ice.fingerprint_type ?? "sha-256"} ${fp}\r
25085
25085
  `;
25086
25086
  }
25087
- sdp += `a=setup:${json.setup ?? "actpass"}\r
25087
+ sdp += `a=setup:${json2.setup ?? "actpass"}\r
25088
25088
  `;
25089
25089
  sdp += "a=sctp-port:5000\r\n";
25090
25090
  sdp += `a=max-message-size:${ANKER_MAX_MESSAGE_SIZE}\r
25091
25091
  `;
25092
- for (const c of json.candidate ?? [])
25092
+ for (const c of json2.candidate ?? [])
25093
25093
  sdp += `a=candidate:${c}\r
25094
25094
  `;
25095
25095
  return sdp;
25096
25096
  }
25097
25097
  function sdpToScallJson(sdp) {
25098
- const json = { ice: { ufrag: "", pwd: "", fingerprint: "" } };
25098
+ const json2 = { ice: { ufrag: "", pwd: "", fingerprint: "" } };
25099
25099
  const setup = sdp.match(/a=setup:([^\r\n]+)/)?.[1];
25100
25100
  if (setup && setup !== "actpass")
25101
- json.setup = setup;
25101
+ json2.setup = setup;
25102
25102
  const ufrag = sdp.match(/a=ice-ufrag:([^\r\n]+)/)?.[1];
25103
25103
  if (ufrag)
25104
- json.ice.ufrag = ufrag;
25104
+ json2.ice.ufrag = ufrag;
25105
25105
  const pwd = sdp.match(/a=ice-pwd:([^\r\n]+)/)?.[1];
25106
25106
  if (pwd)
25107
- json.ice.pwd = pwd;
25107
+ json2.ice.pwd = pwd;
25108
25108
  const fp = sdp.match(/a=fingerprint:([^\s]+)\s+([^\r\n]+)/);
25109
25109
  if (fp?.[2]) {
25110
- json.ice.fingerprint_type = fp[1];
25111
- json.ice.fingerprint = fp[2].replace(/:/g, "");
25110
+ json2.ice.fingerprint_type = fp[1];
25111
+ json2.ice.fingerprint = fp[2].replace(/:/g, "");
25112
25112
  }
25113
25113
  const candidates = [];
25114
25114
  for (const line of sdp.split(/\r\n|\r|\n/)) {
@@ -25117,8 +25117,8 @@ function sdpToScallJson(sdp) {
25117
25117
  candidates.push(m[1]);
25118
25118
  }
25119
25119
  if (candidates.length)
25120
- json.candidate = candidates;
25121
- return json;
25120
+ json2.candidate = candidates;
25121
+ return json2;
25122
25122
  }
25123
25123
  function iceCandidateType(candidate) {
25124
25124
  return candidate.match(/typ (\w+)/)?.[1] ?? "unknown";
@@ -27630,10 +27630,10 @@ function deriveBodyKey(requestId, ecode) {
27630
27630
  const hex = createHmac5("sha256", requestId).update(msg, "utf-8").digest("hex");
27631
27631
  return Buffer.from(hex.slice(0, 16), "ascii");
27632
27632
  }
27633
- function encryptBody2(key, json) {
27633
+ function encryptBody2(key, json2) {
27634
27634
  const nonce = randomBytes6(12);
27635
27635
  const cipher = createCipheriv7("aes-128-gcm", key, nonce);
27636
- const ciphertext = Buffer.concat([cipher.update(Buffer.from(json, "utf-8")), cipher.final()]);
27636
+ const ciphertext = Buffer.concat([cipher.update(Buffer.from(json2, "utf-8")), cipher.final()]);
27637
27637
  return Buffer.concat([nonce, ciphertext, cipher.getAuthTag()]).toString("base64");
27638
27638
  }
27639
27639
  function decryptReply(key, resultB64) {
@@ -28822,11 +28822,11 @@ var PushClient = class _PushClient extends EventEmitter13 {
28822
28822
  const data = {};
28823
28823
  for (const kv of object?.appData ?? []) {
28824
28824
  if (kv.key === "payload") {
28825
- const json = readNullTerminated(Buffer.from(kv.value, "base64"));
28825
+ const json2 = readNullTerminated(Buffer.from(kv.value, "base64"));
28826
28826
  try {
28827
- data.payload = JSON.parse(json);
28827
+ data.payload = JSON.parse(json2);
28828
28828
  } catch {
28829
- data.payload = json;
28829
+ data.payload = json2;
28830
28830
  }
28831
28831
  } else {
28832
28832
  data[kv.key] = kv.value;
@@ -29340,7 +29340,71 @@ function cameraInfo(facts, qualifier, value) {
29340
29340
  return typeof spec.value === "string" && spec.value === reported;
29341
29341
  if (qualifier === "RE")
29342
29342
  return typeof spec.regex === "string" && re(spec.regex, reported);
29343
- return false;
29343
+ if (qualifier !== "json_match" || !spec.json_match || typeof spec.json_match !== "object")
29344
+ return false;
29345
+ const target = json(reported);
29346
+ return !!target && typeof target === "object" && !Array.isArray(target) && jsonMatch(target, spec.json_match);
29347
+ }
29348
+ var content = (v) => v === null || v === void 0 || typeof v === "object" ? void 0 : String(v);
29349
+ var json = (text2) => {
29350
+ try {
29351
+ return JSON.parse(text2);
29352
+ } catch {
29353
+ return void 0;
29354
+ }
29355
+ };
29356
+ var asInt = (v, fallback) => {
29357
+ const n = Number.parseInt(String(v), 10);
29358
+ return Number.isNaN(n) ? fallback : n;
29359
+ };
29360
+ var ASSOCIATED = {
29361
+ /** `true` once `APP_CMD_SET_SILENT_OTA_SWITCH` (6287) is reported. */
29362
+ is_support_silent_ota_switch: (p) => p[6287] === void 0 ? void 0 : "true",
29363
+ /** `APP_CMD_HB3_AI_Empowerment` (1299): its JSON value, else the value as an integer (0 when none). */
29364
+ ai_empower: (p) => {
29365
+ const v = p[1299];
29366
+ if (v === void 0)
29367
+ return void 0;
29368
+ const parsed = json(v);
29369
+ if (parsed === void 0)
29370
+ return String(asInt(v, 0));
29371
+ return content(parsed) ?? JSON.stringify(parsed);
29372
+ },
29373
+ /** `APP_CMD_GET_POWER_SUPPLY_MODE` (6445): its JSON `power_source`, else `source`, as an integer; 1 when empty. */
29374
+ device_power_supply_mode: (p) => {
29375
+ const v = p[6445];
29376
+ if (v === void 0)
29377
+ return void 0;
29378
+ if (v === "")
29379
+ return "1";
29380
+ const parsed = json(v);
29381
+ return parsed === void 0 ? void 0 : String(asInt(parsed?.power_source ?? parsed?.source, 1));
29382
+ }
29383
+ };
29384
+ function jsonMatch(target, match) {
29385
+ const checks = [];
29386
+ const keys = (k) => Array.isArray(match[k]) ? match[k].map(content).filter((x) => x !== void 0) : [];
29387
+ const pairs = (k) => match[k] && typeof match[k] === "object" ? Object.entries(match[k]).map(([key, v]) => [key, content(v)]) : [];
29388
+ for (const k of keys("contains_key"))
29389
+ checks.push(Object.hasOwn(target, k));
29390
+ for (const k of keys("not_contains_key"))
29391
+ checks.push(!Object.hasOwn(target, k));
29392
+ const valued = (k, test) => {
29393
+ for (const [key, expected] of pairs(k)) {
29394
+ const actual = content(target[key]);
29395
+ checks.push(expected !== void 0 && actual !== void 0 && test(actual, expected));
29396
+ }
29397
+ };
29398
+ valued("value_equals", (a, e) => a === e);
29399
+ valued("value_not_equals", (a, e) => a !== e);
29400
+ valued("value_regex", (a, e) => {
29401
+ try {
29402
+ return new RegExp(e).test(a);
29403
+ } catch {
29404
+ return false;
29405
+ }
29406
+ });
29407
+ return match.mode === "any" ? checks.some(Boolean) : checks.every(Boolean);
29344
29408
  }
29345
29409
  function condition(c, facts) {
29346
29410
  const station = facts.stationSerial ?? facts.serial ?? "";
@@ -29358,15 +29422,10 @@ function condition(c, facts) {
29358
29422
  return re(c.value, facts.serial ?? "");
29359
29423
  case "user_country":
29360
29424
  return re(c.value, facts.country ?? "");
29361
- case "user_domain":
29362
- return re(c.value, "");
29363
29425
  case "sdk_version":
29364
29426
  return version(APP_SDK_VERSION, c.qualifier, c.value);
29365
29427
  case "associated_field":
29366
- case "parent_associated_field":
29367
- return compare("", c.qualifier, c.value);
29368
- case "user_permission":
29369
- return c.qualifier === "in";
29428
+ return compare(ASSOCIATED[c.propId ?? ""]?.(facts.params ?? {}) ?? "", c.qualifier, c.value);
29370
29429
  case "camera_info":
29371
29430
  return cameraInfo(facts, c.qualifier, c.value);
29372
29431
  default:
@@ -29399,7 +29458,7 @@ function resolveThing(td, facts) {
29399
29458
  const p = td.properties[chosen];
29400
29459
  if (!p || !conditionsPass(p.availableConditions, facts))
29401
29460
  continue;
29402
- properties[base] = conditionsPass(p.writeConditions, facts) ? p : { ...p, accessMode: "R" };
29461
+ properties[base] = p;
29403
29462
  }
29404
29463
  const available = (entries) => {
29405
29464
  const out = /* @__PURE__ */ Object.create(null);
@@ -29450,7 +29509,6 @@ function property(p) {
29450
29509
  ...num2(specs.step) !== void 0 ? { step: num2(specs.step) } : {},
29451
29510
  ...optStr(specs.unit) !== void 0 ? { unit: str3(specs.unit) } : {},
29452
29511
  readConditions: conditions(p.read_conditions),
29453
- writeConditions: conditions(p.write_conditions),
29454
29512
  availableConditions: conditions(p.available_conditions)
29455
29513
  };
29456
29514
  }