@apocaliss92/nodelink-js 0.4.29 → 0.4.31
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/README.md +20 -13
- package/dist/{chunk-NQ7D5TLR.js → chunk-XVFCEFM6.js} +11 -1
- package/dist/chunk-XVFCEFM6.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +10 -0
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +1 -1
- package/dist/index.cjs +67 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +58 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-NQ7D5TLR.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -6310,9 +6310,19 @@ declare class ReolinkBaichuanApi {
|
|
|
6310
6310
|
subscribeEmailPushEvents(params: {
|
|
6311
6311
|
cameraId: string;
|
|
6312
6312
|
channel?: number;
|
|
6313
|
+
/**
|
|
6314
|
+
* Optional handler invoked with the *full* `EmailPushEvent`
|
|
6315
|
+
* after the simple-event dispatch. Useful for consumers that
|
|
6316
|
+
* need fields beyond what `onSimpleEvent` carries — most
|
|
6317
|
+
* notably `event.attachment` (the JPEG snapshot from the
|
|
6318
|
+
* trigger frame) which a downstream plugin can republish to
|
|
6319
|
+
* MQTT or cache as the camera's last picture.
|
|
6320
|
+
*/
|
|
6321
|
+
onEvent?: (event: EmailPushEvent) => void;
|
|
6313
6322
|
} | {
|
|
6314
6323
|
match: (event: EmailPushEvent) => boolean;
|
|
6315
6324
|
channel?: number;
|
|
6325
|
+
onEvent?: (event: EmailPushEvent) => void;
|
|
6316
6326
|
}): () => void;
|
|
6317
6327
|
/**
|
|
6318
6328
|
* Subscribe to minimal high-level events.
|
package/dist/index.d.ts
CHANGED
|
@@ -7295,9 +7295,19 @@ export declare class ReolinkBaichuanApi {
|
|
|
7295
7295
|
subscribeEmailPushEvents(params: {
|
|
7296
7296
|
cameraId: string;
|
|
7297
7297
|
channel?: number;
|
|
7298
|
+
/**
|
|
7299
|
+
* Optional handler invoked with the *full* `EmailPushEvent`
|
|
7300
|
+
* after the simple-event dispatch. Useful for consumers that
|
|
7301
|
+
* need fields beyond what `onSimpleEvent` carries — most
|
|
7302
|
+
* notably `event.attachment` (the JPEG snapshot from the
|
|
7303
|
+
* trigger frame) which a downstream plugin can republish to
|
|
7304
|
+
* MQTT or cache as the camera's last picture.
|
|
7305
|
+
*/
|
|
7306
|
+
onEvent?: (event: EmailPushEvent) => void;
|
|
7298
7307
|
} | {
|
|
7299
7308
|
match: (event: EmailPushEvent) => boolean;
|
|
7300
7309
|
channel?: number;
|
|
7310
|
+
onEvent?: (event: EmailPushEvent) => void;
|
|
7301
7311
|
}): () => void;
|
|
7302
7312
|
/**
|
|
7303
7313
|
* Subscribe to minimal high-level events.
|
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
setEmailPushCameraResolver,
|
|
66
66
|
setGlobalLogger,
|
|
67
67
|
xmlIndicatesFloodlight
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-XVFCEFM6.js";
|
|
69
69
|
import {
|
|
70
70
|
ReolinkCgiApi,
|
|
71
71
|
ReolinkHttpClient,
|
|
@@ -8284,6 +8284,7 @@ function base64DecodeToBytes(b64) {
|
|
|
8284
8284
|
}
|
|
8285
8285
|
|
|
8286
8286
|
// src/emailPush/server.ts
|
|
8287
|
+
import { format as utilFormat } from "util";
|
|
8287
8288
|
import { SMTPServer } from "smtp-server";
|
|
8288
8289
|
import { simpleParser } from "mailparser";
|
|
8289
8290
|
|
|
@@ -8339,8 +8340,10 @@ function createEmailPushServer(params) {
|
|
|
8339
8340
|
let server;
|
|
8340
8341
|
let status = buildInitialStatus(config);
|
|
8341
8342
|
function parseRecipient(rcpt) {
|
|
8342
|
-
const
|
|
8343
|
-
if (
|
|
8343
|
+
const at = rcpt.lastIndexOf("@");
|
|
8344
|
+
if (at <= 0 || at === rcpt.length - 1) return void 0;
|
|
8345
|
+
const local = rcpt.slice(0, at);
|
|
8346
|
+
const domain = rcpt.slice(at + 1).toLowerCase();
|
|
8344
8347
|
return { local, domain };
|
|
8345
8348
|
}
|
|
8346
8349
|
function resolveCameraIdFromRecipient(rcpt) {
|
|
@@ -8393,10 +8396,19 @@ function createEmailPushServer(params) {
|
|
|
8393
8396
|
disabledCommands: config.requireAuth ? [] : ["AUTH"],
|
|
8394
8397
|
allowInsecureAuth: !config.tls,
|
|
8395
8398
|
size: config.maxMessageBytes,
|
|
8399
|
+
// smtp-server invokes its internal logger as
|
|
8400
|
+
// logger.info(metadata, formatString, ...args)
|
|
8401
|
+
// where `metadata` is an opaque session/connection object and
|
|
8402
|
+
// `formatString` may contain printf-style placeholders.
|
|
8403
|
+
// Naive `.map(String).join(" ")` would surface `[object Object]`
|
|
8404
|
+
// and leave `%s` unresolved (which is what the user was seeing).
|
|
8405
|
+
// Here we strip the metadata (keeping a compact `tnx`/`cid` tag
|
|
8406
|
+
// when present), then apply `util.format` so placeholders are
|
|
8407
|
+
// expanded by Node exactly like the smtp-server defaults do.
|
|
8396
8408
|
logger: {
|
|
8397
|
-
info: (...args) => log.
|
|
8398
|
-
debug: (...args) => log.debug(
|
|
8399
|
-
error: (...args) => log.warn(
|
|
8409
|
+
info: (...args) => log.info(formatSmtpLogArgs(args)),
|
|
8410
|
+
debug: (...args) => log.debug(formatSmtpLogArgs(args)),
|
|
8411
|
+
error: (...args) => log.warn(formatSmtpLogArgs(args))
|
|
8400
8412
|
},
|
|
8401
8413
|
...tlsOptions ? { secure: false, ...tlsOptions } : {},
|
|
8402
8414
|
onConnect(session, callback) {
|
|
@@ -8445,24 +8457,37 @@ function createEmailPushServer(params) {
|
|
|
8445
8457
|
);
|
|
8446
8458
|
return callback(new Error("Invalid username or password"));
|
|
8447
8459
|
},
|
|
8448
|
-
onRcptTo(address,
|
|
8460
|
+
onRcptTo(address, session, callback) {
|
|
8449
8461
|
const cameraId = resolveCameraIdFromRecipient(address.address);
|
|
8450
8462
|
if (!cameraId) {
|
|
8451
8463
|
status.messagesRejected++;
|
|
8464
|
+
log.warn(
|
|
8465
|
+
`SMTP RCPT TO rejected ${address.address} \u2014 unknown recipient (sessionId=${session.id})`
|
|
8466
|
+
);
|
|
8452
8467
|
return callback(
|
|
8453
8468
|
new Error(
|
|
8454
8469
|
`Unknown recipient ${address.address} (not registered)`
|
|
8455
8470
|
)
|
|
8456
8471
|
);
|
|
8457
8472
|
}
|
|
8473
|
+
log.info(
|
|
8474
|
+
`SMTP RCPT TO ${address.address} \u2192 camera=${cameraId} (sessionId=${session.id})`
|
|
8475
|
+
);
|
|
8458
8476
|
callback();
|
|
8459
8477
|
},
|
|
8460
8478
|
onData(stream, session, callback) {
|
|
8479
|
+
const startedAt = Date.now();
|
|
8480
|
+
log.debug(
|
|
8481
|
+
`SMTP DATA start (sessionId=${session.id} from=${session.envelope.mailFrom ? session.envelope.mailFrom.address : "?"})`
|
|
8482
|
+
);
|
|
8461
8483
|
const chunks = [];
|
|
8462
8484
|
stream.on("data", (chunk) => chunks.push(chunk));
|
|
8463
8485
|
stream.on("end", () => {
|
|
8464
8486
|
const recipients = session.envelope.rcptTo?.map((r) => r.address) ?? [];
|
|
8465
8487
|
const buffer = Buffer.concat(chunks);
|
|
8488
|
+
log.info(
|
|
8489
|
+
`SMTP DATA received ${buffer.length}B in ${Date.now() - startedAt}ms for ${recipients.length} recipient(s) (sessionId=${session.id})`
|
|
8490
|
+
);
|
|
8466
8491
|
const matched = recipients.map((r) => ({
|
|
8467
8492
|
recipient: r,
|
|
8468
8493
|
cameraId: resolveCameraIdFromRecipient(r)
|
|
@@ -8471,6 +8496,9 @@ function createEmailPushServer(params) {
|
|
|
8471
8496
|
);
|
|
8472
8497
|
if (matched.length === 0) {
|
|
8473
8498
|
status.messagesRejected++;
|
|
8499
|
+
log.warn(
|
|
8500
|
+
`SMTP DATA dropped \u2014 no recognised recipients in [${recipients.join(", ")}] (sessionId=${session.id})`
|
|
8501
|
+
);
|
|
8474
8502
|
return callback(new Error("No recognised recipients"));
|
|
8475
8503
|
}
|
|
8476
8504
|
Promise.all(
|
|
@@ -8479,13 +8507,15 @@ function createEmailPushServer(params) {
|
|
|
8479
8507
|
)
|
|
8480
8508
|
).then(() => callback()).catch((err) => {
|
|
8481
8509
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8482
|
-
log.error(
|
|
8510
|
+
log.error(
|
|
8511
|
+
`Email push pipeline error (sessionId=${session.id}): ${msg}`
|
|
8512
|
+
);
|
|
8483
8513
|
status.lastErrorMessage = msg;
|
|
8484
8514
|
callback(new Error(msg));
|
|
8485
8515
|
});
|
|
8486
8516
|
});
|
|
8487
8517
|
stream.on("error", (err) => {
|
|
8488
|
-
log.warn(`SMTP stream error: ${err.message}`);
|
|
8518
|
+
log.warn(`SMTP stream error (sessionId=${session.id}): ${err.message}`);
|
|
8489
8519
|
callback(err);
|
|
8490
8520
|
});
|
|
8491
8521
|
}
|
|
@@ -8533,6 +8563,25 @@ function createEmailPushServer(params) {
|
|
|
8533
8563
|
}
|
|
8534
8564
|
};
|
|
8535
8565
|
}
|
|
8566
|
+
function formatSmtpLogArgs(args) {
|
|
8567
|
+
if (args.length === 0) return "[smtp]";
|
|
8568
|
+
const [first, ...rest] = args;
|
|
8569
|
+
let tag = "";
|
|
8570
|
+
let formatArgs = args;
|
|
8571
|
+
if (first && typeof first === "object" && !Array.isArray(first)) {
|
|
8572
|
+
const meta = first;
|
|
8573
|
+
const tnx = typeof meta.tnx === "string" ? meta.tnx : void 0;
|
|
8574
|
+
const cid = typeof meta.cid === "string" ? meta.cid : void 0;
|
|
8575
|
+
const sid = typeof meta.sid === "string" ? meta.sid : void 0;
|
|
8576
|
+
const bits = [];
|
|
8577
|
+
if (tnx) bits.push(tnx);
|
|
8578
|
+
if (cid) bits.push(`cid=${cid}`);
|
|
8579
|
+
if (sid) bits.push(`sid=${sid}`);
|
|
8580
|
+
if (bits.length > 0) tag = ` [${bits.join(" ")}]`;
|
|
8581
|
+
formatArgs = rest;
|
|
8582
|
+
}
|
|
8583
|
+
return `[smtp]${tag} ${utilFormat(...formatArgs)}`;
|
|
8584
|
+
}
|
|
8536
8585
|
function buildInitialStatus(config) {
|
|
8537
8586
|
return {
|
|
8538
8587
|
enabled: true,
|