@apocaliss92/nodelink-js 0.5.2 → 0.6.1
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/{chunk-7HSTETZR.js → chunk-EAHRVNEX.js} +61 -11
- package/dist/chunk-EAHRVNEX.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +60 -10
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +1 -1
- package/dist/index.cjs +132 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +100 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.js +73 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7HSTETZR.js.map +0 -1
|
@@ -645,12 +645,28 @@ async function getServerBinding(uid, options = {}) {
|
|
|
645
645
|
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
646
646
|
const logger = options.logger;
|
|
647
647
|
if (typeof fetchImpl !== "function") {
|
|
648
|
-
logger?.
|
|
648
|
+
logger?.log?.(
|
|
649
649
|
`[server-binding] global fetch unavailable; skipping cloud lookup`
|
|
650
650
|
);
|
|
651
651
|
cache.set(uid, { kind: "err", expires: now + NEGATIVE_TTL_MS });
|
|
652
652
|
return void 0;
|
|
653
653
|
}
|
|
654
|
+
try {
|
|
655
|
+
const apiHostname = new URL(baseUrl).hostname;
|
|
656
|
+
const dns2 = await import("dns/promises");
|
|
657
|
+
const answers = await dns2.lookup(apiHostname, { family: 4, all: true });
|
|
658
|
+
const sinkholed = answers.find(
|
|
659
|
+
(a) => a.address?.startsWith("127.") || a.address === "0.0.0.0" || a.address?.startsWith("10.") || a.address?.startsWith("192.168.") || /^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(a.address ?? "")
|
|
660
|
+
);
|
|
661
|
+
if (sinkholed) {
|
|
662
|
+
logger?.log?.(
|
|
663
|
+
`[server-binding] ${uid}: DNS for ${apiHostname} resolves to ${sinkholed.address} (sinkhole / /etc/hosts override). Cloud directory unreachable \u2014 falling back to the 22-hostname P2P sweep. Whitelist ${apiHostname} to enable.`
|
|
664
|
+
);
|
|
665
|
+
cache.set(uid, { kind: "err", expires: now + NEGATIVE_TTL_MS });
|
|
666
|
+
return void 0;
|
|
667
|
+
}
|
|
668
|
+
} catch {
|
|
669
|
+
}
|
|
654
670
|
const url = `${baseUrl}/devices/${encodeURIComponent(uid)}/server-binding?language=${encodeURIComponent(language)}`;
|
|
655
671
|
const controller = new AbortController();
|
|
656
672
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -661,8 +677,8 @@ async function getServerBinding(uid, options = {}) {
|
|
|
661
677
|
headers: { Accept: "application/json" }
|
|
662
678
|
});
|
|
663
679
|
if (!res.ok) {
|
|
664
|
-
logger?.
|
|
665
|
-
`[server-binding] ${uid}: HTTP ${res.status} ${res.statusText}`
|
|
680
|
+
logger?.log?.(
|
|
681
|
+
`[server-binding] ${uid}: HTTP ${res.status} ${res.statusText} from ${url}`
|
|
666
682
|
);
|
|
667
683
|
cache.set(uid, { kind: "err", expires: now + NEGATIVE_TTL_MS });
|
|
668
684
|
return void 0;
|
|
@@ -670,8 +686,15 @@ async function getServerBinding(uid, options = {}) {
|
|
|
670
686
|
const json = await res.json();
|
|
671
687
|
const parsed = parseServerBindingResponse(json);
|
|
672
688
|
if (!parsed) {
|
|
673
|
-
logger?.
|
|
674
|
-
`[server-binding] ${uid}: response shape did not match expectations`
|
|
689
|
+
logger?.log?.(
|
|
690
|
+
`[server-binding] ${uid}: response shape did not match expectations (Reolink schema change?)`
|
|
691
|
+
);
|
|
692
|
+
cache.set(uid, { kind: "err", expires: now + NEGATIVE_TTL_MS });
|
|
693
|
+
return void 0;
|
|
694
|
+
}
|
|
695
|
+
if (parsed.availableZones.length === 0) {
|
|
696
|
+
logger?.log?.(
|
|
697
|
+
`[server-binding] ${uid}: cloud returned 0 zones \u2014 UID not registered with Reolink cloud (or wrong region)`
|
|
675
698
|
);
|
|
676
699
|
cache.set(uid, { kind: "err", expires: now + NEGATIVE_TTL_MS });
|
|
677
700
|
return void 0;
|
|
@@ -690,9 +713,23 @@ async function getServerBinding(uid, options = {}) {
|
|
|
690
713
|
);
|
|
691
714
|
return parsed;
|
|
692
715
|
} catch (e) {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
)
|
|
716
|
+
const msg = e?.message ?? String(e);
|
|
717
|
+
const errName = e?.name;
|
|
718
|
+
if (errName === "AbortError" || msg.includes("aborted")) {
|
|
719
|
+
logger?.log?.(
|
|
720
|
+
`[server-binding] ${uid}: timed out after ${timeoutMs}ms (cloud unreachable)`
|
|
721
|
+
);
|
|
722
|
+
} else if (msg.includes("ENOTFOUND") || msg.includes("EAI_AGAIN")) {
|
|
723
|
+
logger?.log?.(
|
|
724
|
+
`[server-binding] ${uid}: DNS failed (${msg}) \u2014 apis.reolink.com may be blocked at resolver`
|
|
725
|
+
);
|
|
726
|
+
} else if (msg.includes("ECONNREFUSED") || msg.includes("EHOSTUNREACH") || msg.includes("ENETUNREACH")) {
|
|
727
|
+
logger?.log?.(
|
|
728
|
+
`[server-binding] ${uid}: network unreachable (${msg}) \u2014 cloud port blocked`
|
|
729
|
+
);
|
|
730
|
+
} else {
|
|
731
|
+
logger?.log?.(`[server-binding] ${uid}: fetch failed \u2014 ${msg}`);
|
|
732
|
+
}
|
|
696
733
|
cache.set(uid, { kind: "err", expires: now + NEGATIVE_TTL_MS });
|
|
697
734
|
return void 0;
|
|
698
735
|
} finally {
|
|
@@ -1128,12 +1165,19 @@ var BcUdpStream = class extends EventEmitter {
|
|
|
1128
1165
|
const tid = (Math.floor(Math.random() * 2147483647) | 0) >>> 0;
|
|
1129
1166
|
const xml = buildC2mQ({ uid });
|
|
1130
1167
|
const pkt = encodeDiscoveryPacket(tid, xml);
|
|
1168
|
+
const counters = { sentBytes: 0, rxBytes: 0 };
|
|
1131
1169
|
return await new Promise((resolve, reject) => {
|
|
1132
1170
|
const deadline = setTimeout(() => {
|
|
1133
1171
|
cleanup();
|
|
1134
|
-
|
|
1172
|
+
const err = new Error(
|
|
1173
|
+
`P2P UID lookup timeout (${dest.host}:${dest.port}) \u2014 sent=${counters.sentBytes}B rx=${counters.rxBytes}B`
|
|
1174
|
+
);
|
|
1175
|
+
err.sentBytes = counters.sentBytes;
|
|
1176
|
+
err.rxBytes = counters.rxBytes;
|
|
1177
|
+
reject(err);
|
|
1135
1178
|
}, timeoutMs);
|
|
1136
1179
|
const onMsg = (msg) => {
|
|
1180
|
+
counters.rxBytes += msg.length;
|
|
1137
1181
|
try {
|
|
1138
1182
|
const p = decodeBcUdpPacket(msg);
|
|
1139
1183
|
if (p.kind !== "discovery") return;
|
|
@@ -1141,13 +1185,19 @@ var BcUdpStream = class extends EventEmitter {
|
|
|
1141
1185
|
const qr = parseM2cQr(p.xml);
|
|
1142
1186
|
if (!qr?.reg || !qr?.relay) return;
|
|
1143
1187
|
cleanup();
|
|
1144
|
-
resolve({
|
|
1188
|
+
resolve({
|
|
1189
|
+
reg: qr.reg,
|
|
1190
|
+
relay: qr.relay,
|
|
1191
|
+
sentBytes: counters.sentBytes,
|
|
1192
|
+
rxBytes: counters.rxBytes
|
|
1193
|
+
});
|
|
1145
1194
|
} catch {
|
|
1146
1195
|
}
|
|
1147
1196
|
};
|
|
1148
1197
|
const send = () => {
|
|
1149
1198
|
try {
|
|
1150
1199
|
sock.send(pkt, dest.port, dest.host);
|
|
1200
|
+
counters.sentBytes += pkt.length;
|
|
1151
1201
|
} catch {
|
|
1152
1202
|
}
|
|
1153
1203
|
};
|
|
@@ -25268,4 +25318,4 @@ export {
|
|
|
25268
25318
|
tcpReachabilityProbe,
|
|
25269
25319
|
autoDetectDeviceType
|
|
25270
25320
|
};
|
|
25271
|
-
//# sourceMappingURL=chunk-
|
|
25321
|
+
//# sourceMappingURL=chunk-EAHRVNEX.js.map
|