@emailcheck/email-validator-js 5.0.0 → 5.1.0
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 +40 -4
- package/dist/cli/index.js +34 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +36 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +36 -2
- package/dist/index.js.map +1 -1
- package/dist/sender-strategy.d.ts +26 -0
- package/dist/serverless/adapters/aws-lambda.cjs.js +5 -5
- package/dist/serverless/adapters/aws-lambda.cjs.js.map +1 -1
- package/dist/serverless/adapters/aws-lambda.esm.js +5 -5
- package/dist/serverless/adapters/aws-lambda.esm.js.map +1 -1
- package/dist/serverless/adapters/azure.cjs.js +5 -5
- package/dist/serverless/adapters/azure.cjs.js.map +1 -1
- package/dist/serverless/adapters/azure.esm.js +5 -5
- package/dist/serverless/adapters/azure.esm.js.map +1 -1
- package/dist/serverless/adapters/cloudflare.cjs.js +5 -5
- package/dist/serverless/adapters/cloudflare.cjs.js.map +1 -1
- package/dist/serverless/adapters/cloudflare.esm.js +5 -5
- package/dist/serverless/adapters/cloudflare.esm.js.map +1 -1
- package/dist/serverless/adapters/gcp.cjs.js +5 -5
- package/dist/serverless/adapters/gcp.cjs.js.map +1 -1
- package/dist/serverless/adapters/gcp.esm.js +5 -5
- package/dist/serverless/adapters/gcp.esm.js.map +1 -1
- package/dist/serverless/adapters/netlify.cjs.js +5 -5
- package/dist/serverless/adapters/netlify.cjs.js.map +1 -1
- package/dist/serverless/adapters/netlify.esm.js +5 -5
- package/dist/serverless/adapters/netlify.esm.js.map +1 -1
- package/dist/serverless/adapters/vercel.cjs.js +5 -5
- package/dist/serverless/adapters/vercel.cjs.js.map +1 -1
- package/dist/serverless/adapters/vercel.esm.js +5 -5
- package/dist/serverless/adapters/vercel.esm.js.map +1 -1
- package/dist/serverless/index.cjs.js +5 -5
- package/dist/serverless/index.cjs.js.map +1 -1
- package/dist/serverless/index.esm.js +5 -5
- package/dist/serverless/index.esm.js.map +1 -1
- package/dist/serverless/verifier.cjs.js +5 -5
- package/dist/serverless/verifier.cjs.js.map +1 -1
- package/dist/serverless/verifier.esm.js +5 -5
- package/dist/serverless/verifier.esm.js.map +1 -1
- package/dist/serverless/verifier.min.js +1 -1
- package/dist/types.d.ts +72 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -268,6 +268,14 @@ Comprehensive email verification with detailed results and error codes.
|
|
|
268
268
|
- `smtpMaxConsecutiveFailures` (number) — Bail after N connection-class failures in a row (`connection_error` / `connection_timeout` / `connection_closed`). Default: unbounded.
|
|
269
269
|
- `smtpMaxMxHosts` (number) — Cap the MX walk to the first N hostnames. Default: unbounded.
|
|
270
270
|
- `smtpRetry` (`{ attempts, delayMs?, backoff? }`) — Retry connection-class failures on the same MX × port. Default: no retries.
|
|
271
|
+
- **SMTP envelope controls** (anti-spam — recommended for production):
|
|
272
|
+
- `smtpSender` (`SMTPSenderStrategy`) — Strategy for the `MAIL FROM:` envelope. The library default is `<recipient@domain>`, which blocklists key on as the textbook verification-probe fingerprint. Pick a deliberate strategy:
|
|
273
|
+
- `{ kind: 'null-sender' }` → `MAIL FROM:<>` (RFC 5321 §4.5.5; DSN-shaped, best on Gmail / Outlook).
|
|
274
|
+
- `{ kind: 'fixed', address: 'verify@your-domain.com' }` → fixed real address (best with valid SPF / PTR / DMARC).
|
|
275
|
+
- `{ kind: 'random-at-recipient', localPrefix? }` → random local-part on the recipient's domain.
|
|
276
|
+
- `{ kind: 'random-at-domain', domain, localPrefix? }` → random local-part on a configured domain.
|
|
277
|
+
- `{ kind: 'custom', build: r => ... }` → full escape hatch.
|
|
278
|
+
- `smtpHeloHostname` (string) — Hostname presented to the MX in `EHLO` / `HELO`. Default: `'localhost'` (a spam-bot signature from a public IP — override with a real FQDN in production).
|
|
271
279
|
- `whoisTimeoutMs` (number) — Per-WHOIS-query timeout (default: `5000`).
|
|
272
280
|
- `debug` (boolean) — Per-line `console.debug` trace (default: `false`).
|
|
273
281
|
- `captureTranscript` (boolean) — Populate `result.transcript` with a per-step structured trace (default: `false`).
|
|
@@ -1133,10 +1141,38 @@ clearAllCaches();
|
|
|
1133
1141
|
|
|
1134
1142
|
## 💻 Command-line Tool (`email-validate`)
|
|
1135
1143
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1144
|
+
The package ships an `email-validate` binary that runs the full validation
|
|
1145
|
+
pipeline against one address, captures a structured transcript, prints the
|
|
1146
|
+
result to stdout, and saves the JSON result to `./logs/` by default.
|
|
1147
|
+
|
|
1148
|
+
### Run without installing (npx / bunx / pnpm dlx)
|
|
1149
|
+
|
|
1150
|
+
```bash
|
|
1151
|
+
# One-off check — pulls the latest published version, no install required
|
|
1152
|
+
npx -p @emailcheck/email-validator-js email-validate alice@example.com
|
|
1153
|
+
|
|
1154
|
+
# Same with bunx / pnpm dlx
|
|
1155
|
+
bunx -p @emailcheck/email-validator-js email-validate alice@example.com
|
|
1156
|
+
pnpm dlx -p @emailcheck/email-validator-js email-validate alice@example.com
|
|
1157
|
+
|
|
1158
|
+
# Pin a version (avoids npx caching surprises in CI)
|
|
1159
|
+
npx -p @emailcheck/email-validator-js@4.0.0 email-validate alice@example.com
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
> The `-p <package>` form is the safest because the bin name
|
|
1163
|
+
> (`email-validate`) differs from the package name. The shorthand
|
|
1164
|
+
> `npx @emailcheck/email-validator-js alice@example.com` also works since the
|
|
1165
|
+
> package has exactly one bin.
|
|
1166
|
+
|
|
1167
|
+
### Install globally
|
|
1168
|
+
|
|
1169
|
+
```bash
|
|
1170
|
+
bun add -g @emailcheck/email-validator-js
|
|
1171
|
+
# or: npm i -g @emailcheck/email-validator-js
|
|
1172
|
+
# or: pnpm add -g @emailcheck/email-validator-js
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
### Examples
|
|
1140
1176
|
|
|
1141
1177
|
```bash
|
|
1142
1178
|
# Quick interactive check — full pipeline, pretty colored output
|
package/dist/cli/index.js
CHANGED
|
@@ -1015,6 +1015,31 @@ function detectNameFromEmail(params) {
|
|
|
1015
1015
|
return defaultNameDetectionMethod(email);
|
|
1016
1016
|
}
|
|
1017
1017
|
|
|
1018
|
+
const DEFAULT_LOCAL_PREFIX = "probe";
|
|
1019
|
+
function resolveSenderAddress(strategy, recipient) {
|
|
1020
|
+
switch (strategy.kind) {
|
|
1021
|
+
case "null-sender":
|
|
1022
|
+
return "<>";
|
|
1023
|
+
case "fixed":
|
|
1024
|
+
return wrap(strategy.address);
|
|
1025
|
+
case "random-at-recipient":
|
|
1026
|
+
return wrap(`${randomLocal(strategy.localPrefix)}@${recipient.domain}`);
|
|
1027
|
+
case "random-at-domain":
|
|
1028
|
+
return wrap(`${randomLocal(strategy.localPrefix)}@${strategy.domain}`);
|
|
1029
|
+
case "custom":
|
|
1030
|
+
return strategy.build({ local: recipient.local, domain: recipient.domain });
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
function wrap(address) {
|
|
1034
|
+
if (address.startsWith("<") && address.endsWith(">")) return address;
|
|
1035
|
+
return `<${address}>`;
|
|
1036
|
+
}
|
|
1037
|
+
function randomLocal(prefix) {
|
|
1038
|
+
const random = node_crypto.randomBytes(8).toString("hex");
|
|
1039
|
+
const safePrefix = prefix ?? DEFAULT_LOCAL_PREFIX;
|
|
1040
|
+
return `${safePrefix}-${random}`;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1018
1043
|
const DEFAULT_PORTS = [25, 587, 465];
|
|
1019
1044
|
const DEFAULT_TIMEOUT_MS = 3e3;
|
|
1020
1045
|
const QUIT_DRAIN_MS = 100;
|
|
@@ -1058,6 +1083,7 @@ async function verifyMailboxSMTP(params) {
|
|
|
1058
1083
|
const debug = options.debug ?? false;
|
|
1059
1084
|
const captureTranscript = options.captureTranscript ?? false;
|
|
1060
1085
|
const sequence = options.sequence;
|
|
1086
|
+
const sender = options.sender;
|
|
1061
1087
|
const cache = options.cache;
|
|
1062
1088
|
const log = debug ? (...args) => console.log("[SMTP]", ...args) : () => {
|
|
1063
1089
|
};
|
|
@@ -1084,6 +1110,7 @@ async function verifyMailboxSMTP(params) {
|
|
|
1084
1110
|
tlsConfig,
|
|
1085
1111
|
heloHostname,
|
|
1086
1112
|
sequence,
|
|
1113
|
+
sender,
|
|
1087
1114
|
log,
|
|
1088
1115
|
catchAllProbeLocal: options.catchAllProbeLocal,
|
|
1089
1116
|
pipelining: options.pipelining ?? "auto",
|
|
@@ -1354,7 +1381,7 @@ class SMTPProbeConnection {
|
|
|
1354
1381
|
this.executeStartTls();
|
|
1355
1382
|
return;
|
|
1356
1383
|
case SMTPStep.mailFrom: {
|
|
1357
|
-
const from = this.p.sequence?.from ?? `<${this.p.local}@${this.p.domain}>`;
|
|
1384
|
+
const from = this.p.sender ? resolveSenderAddress(this.p.sender, { local: this.p.local, domain: this.p.domain }) : this.p.sequence?.from ?? `<${this.p.local}@${this.p.domain}>`;
|
|
1358
1385
|
this.send(`MAIL FROM:${from}`);
|
|
1359
1386
|
return;
|
|
1360
1387
|
}
|
|
@@ -2471,7 +2498,12 @@ async function runSmtp(local, domain, mxRecords, params, result, log, collector)
|
|
|
2471
2498
|
debug: params.debug ?? false,
|
|
2472
2499
|
// Forward transcript capture so the SMTP step's details include
|
|
2473
2500
|
// the full per-port transcript when the caller asked for it.
|
|
2474
|
-
captureTranscript: params.captureTranscript ?? false
|
|
2501
|
+
captureTranscript: params.captureTranscript ?? false,
|
|
2502
|
+
// Forward the high-level envelope strategy and HELO override so
|
|
2503
|
+
// callers can control the spam-fingerprint of the probe without
|
|
2504
|
+
// dropping down to `verifyMailboxSMTP` directly.
|
|
2505
|
+
...params.smtpSender !== void 0 && { sender: params.smtpSender },
|
|
2506
|
+
...params.smtpHeloHostname !== void 0 && { heloHostname: params.smtpHeloHostname }
|
|
2475
2507
|
}
|
|
2476
2508
|
});
|
|
2477
2509
|
await smtpCache.set(cacheKey, probe.smtpResult);
|