@emailcheck/email-validator-js 3.4.4 → 4.0.0-beta.2

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/types.d.ts CHANGED
@@ -177,47 +177,83 @@ export declare enum EmailProvider {
177
177
  everythingElse = "everything_else"
178
178
  }
179
179
  /**
180
- * Result for SMTP verification with metadata
181
- * Uses camelCase for consistency with TypeScript conventions
180
+ * Verdict from one `verifyMailboxSMTP` call. Flat by design — every field is
181
+ * one boolean / scalar so callers can switch on a few keys instead of walking
182
+ * a tree.
182
183
  */
183
184
  export interface SmtpVerificationResult {
184
- /** Whether SMTP connection was successful */
185
+ /** True when at least one MX×port responded with an SMTP greeting. */
185
186
  canConnectSmtp: boolean;
186
- /** Whether the mailbox is full */
187
+ /** True when the MX returned `552` / `452` (over-quota / mailbox full). */
187
188
  hasFullInbox: boolean;
188
- /** Whether the domain has catch-all enabled */
189
+ /**
190
+ * True when both the real RCPT TO and the random-local probe RCPT TO
191
+ * returned `250` — the MX accepts every recipient and the deliverability
192
+ * signal for the real address is unreliable.
193
+ */
189
194
  isCatchAll: boolean;
190
- /** Whether the email is deliverable */
195
+ /** True when the real RCPT TO returned `250` / `251`. */
191
196
  isDeliverable: boolean;
192
- /** Whether the email/account is disabled */
197
+ /** True when the real RCPT TO was definitively rejected. */
193
198
  isDisabled: boolean;
194
- /** Error message if verification failed */
199
+ /**
200
+ * Short reason key when `isDeliverable === false`. Vocabulary:
201
+ * `not_found` | `over_quota` | `temporary_failure` | `ambiguous` |
202
+ * `connection_error` | `connection_timeout` | `connection_closed` |
203
+ * `tls_upgrade_failed` | `tls_handshake_failed` |
204
+ * `ehlo_failed` | `helo_failed` | `mail_from_rejected` |
205
+ * `no_greeting` | `no_mx_records` | `unrecognized_response` |
206
+ * `step_timeout` | `socket_timeout`
207
+ *
208
+ * Pass to `refineReasonByEnhancedStatus(error, enhancedStatus)` for a
209
+ * richer (mailbox-status-aware) reason when the MX returned a DSN.
210
+ */
195
211
  error?: string;
196
- /** Which provider was detected/used */
197
- providerUsed?: EmailProvider;
198
- /** Additional compatibility properties */
199
- success?: boolean;
200
- canConnect?: boolean;
212
+ /** Most recent 3-digit SMTP code observed during the probe. */
201
213
  responseCode?: number;
202
- /** Provider-specific error details */
203
- providerSpecific?: {
204
- errorCode?: string;
205
- actionRequired?: string;
206
- details?: string;
207
- };
208
- /** Timestamp when this was checked (for cache) */
214
+ /**
215
+ * RFC 3463 enhanced status code from the most recent SMTP reply that
216
+ * carried one — e.g. `"5.1.1"` (mailbox unknown), `"5.7.1"` (policy
217
+ * block), `"4.7.0"` (transient policy). Undefined when no MX reply
218
+ * included an enhanced status.
219
+ */
220
+ enhancedStatus?: string;
221
+ /** Operational counters — always populated. See `SmtpProbeMetrics`. */
222
+ metrics?: SmtpProbeMetrics;
223
+ /** Wall-clock timestamp this verdict was produced (set on every result). */
209
224
  checkedAt?: number;
210
225
  /**
211
- * Server reply lines, in arrival order, prefixed `<port>|s| <line>` so
212
- * multi-port probes stay readable. Present when `captureTranscript` is set.
226
+ * Server reply lines, in arrival order, prefixed `<host>:<port>|s| <line>`
227
+ * so multi-MX dialogues stay readable. Present only when
228
+ * `captureTranscript: true` was passed.
213
229
  */
214
230
  transcript?: string[];
215
231
  /**
216
- * Client commands sent, in send order, prefixed `<port>|c| <command>`.
217
- * Present when `captureTranscript` is set.
232
+ * Client commands sent, in send order, prefixed `<host>:<port>|c| <cmd>`.
233
+ * Present only when `captureTranscript: true` was passed.
218
234
  */
219
235
  commands?: string[];
220
236
  }
237
+ /**
238
+ * Operational counters for one `verifyMailboxSMTP` call. The cost of
239
+ * collecting these is trivial — pure bookkeeping during the existing flow.
240
+ */
241
+ export interface SmtpProbeMetrics {
242
+ /** How many MX hostnames the outer loop attempted before stopping. */
243
+ mxAttempts: number;
244
+ /** Total connection attempts across the whole call (sum across MX×port). */
245
+ portAttempts: number;
246
+ /** MX hostnames attempted in priority order (matches `mxRecords` slice). */
247
+ mxHostsTried: string[];
248
+ /**
249
+ * MX hostname that produced the final answer. Undefined when every MX
250
+ * failed (in which case `result.isDeliverable === false` and the SMTP
251
+ * reason is whatever the last attempted MX returned).
252
+ */
253
+ mxHostUsed?: string;
254
+ /** Total wall-clock time the probe spent, in milliseconds. */
255
+ totalDurationMs: number;
256
+ }
221
257
  /**
222
258
  * Result for batch verification
223
259
  */
@@ -237,14 +273,16 @@ export interface SMTPTLSConfig {
237
273
  minVersion?: 'TLSv1.2' | 'TLSv1.3';
238
274
  }
239
275
  /**
240
- * SMTP protocol steps. Only the steps the verifier actually walks are listed
241
- * STARTTLS upgrade, VRFY, and QUIT used to be separate enum members but were
242
- * never reachable from production callers.
276
+ * SMTP protocol steps walked by the verifier in order. `startTls` is a
277
+ * conditional step it sends the STARTTLS command and upgrades the socket
278
+ * to TLS when the MX advertised support (controlled by
279
+ * `SMTPVerifyOptions.startTls`). On implicit-TLS ports (465) it's a no-op.
243
280
  */
244
281
  export declare enum SMTPStep {
245
282
  greeting = "GREETING",
246
283
  ehlo = "EHLO",
247
284
  helo = "HELO",
285
+ startTls = "STARTTLS",
248
286
  mailFrom = "MAIL_FROM",
249
287
  rcptTo = "RCPT_TO"
250
288
  }
@@ -263,11 +301,47 @@ export interface SMTPVerifyOptions {
263
301
  debug?: boolean;
264
302
  /**
265
303
  * When true, the returned `SmtpVerificationResult` carries `transcript` and
266
- * `commands` arrays prefixed with `<port>|s| …` / `<port>|c| …`. Aggregated
267
- * across every port attempted.
304
+ * `commands` arrays prefixed with `<host>:<port>|s| …` / `<host>:<port>|c| …`.
305
+ * Aggregated across every MX×port attempted.
306
+ *
307
+ * Default: `false`. The strings are O(N×wire-bytes); skip when you don't
308
+ * need the trace.
268
309
  */
269
310
  captureTranscript?: boolean;
270
311
  sequence?: SMTPSequence;
312
+ /**
313
+ * Override the random-local-part generator used by the catch-all probe.
314
+ * Useful for deterministic tests; receives the real local-part and domain
315
+ * so callers can derive a probe-local that matches the MX's syntax rules.
316
+ *
317
+ * Default: `<16 hex chars>-noexist` — long enough to never collide,
318
+ * structured so it's clearly synthetic and passes common syntax filters.
319
+ */
320
+ catchAllProbeLocal?: (realLocal: string, domain: string) => string;
321
+ /**
322
+ * Use SMTP PIPELINING (RFC 2920) to batch the envelope phase
323
+ * (RCPT TO real + RCPT TO probe + RSET) into one `socket.write()` when
324
+ * the MX advertises support.
325
+ *
326
+ * - `'auto'` (default): pipeline when EHLO multi-line includes
327
+ * `PIPELINING`, sequential otherwise.
328
+ * - `'never'`: always sequential — useful for deterministic wire-level
329
+ * assertions in tests, or when investigating a flaky pipeline-buggy MX.
330
+ * - `'force'`: pipeline without checking — testing escape hatch.
331
+ */
332
+ pipelining?: 'auto' | 'never' | 'force';
333
+ /**
334
+ * Controls STARTTLS upgrade on plaintext ports (25, 587). Implicit-TLS
335
+ * ports (465) ignore this option — they're already TLS from the start.
336
+ *
337
+ * - `'auto'` (default): upgrade if the MX advertises STARTTLS in EHLO.
338
+ * Submission-port (587) MXes typically require this — without it,
339
+ * `MAIL FROM` is rejected with `530 Must issue STARTTLS first`.
340
+ * - `'never'`: never upgrade — send `MAIL FROM` / `RCPT TO` in plaintext.
341
+ * - `'force'`: send `STARTTLS` unconditionally. Fails with
342
+ * `tls_upgrade_failed` when the MX doesn't support it. Testing only.
343
+ */
344
+ startTls?: 'auto' | 'never' | 'force';
271
345
  }
272
346
  export interface VerifyMailboxSMTPParams {
273
347
  local: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emailcheck/email-validator-js",
3
- "version": "3.4.4",
3
+ "version": "4.0.0-beta.2",
4
4
  "private": false,
5
5
  "description": "Advanced email validation with MX records, SMTP verification, disposable email detection, batch processing, and caching. Production-ready with TypeScript support.",
6
6
  "keywords": [
@@ -87,6 +87,10 @@
87
87
  "files": [
88
88
  "dist"
89
89
  ],
90
+ "publishConfig": {
91
+ "access": "public",
92
+ "provenance": true
93
+ },
90
94
  "scripts": {
91
95
  "build": "rm -rf dist && rollup -c rollup.config.cjs && rollup -c rollup.config.serverless.cjs && cp src/*.json dist/ && chmod +x dist/cli/index.js",
92
96
  "build:main": "rollup -c rollup.config.cjs",
@@ -136,20 +140,26 @@
136
140
  "@rollup/plugin-node-resolve": "^16.0.3",
137
141
  "@rollup/plugin-terser": "^1.0.0",
138
142
  "@rollup/plugin-typescript": "^12.3.0",
143
+ "@semantic-release/commit-analyzer": "^13.0.1",
144
+ "@semantic-release/github": "^12.0.6",
145
+ "@semantic-release/npm": "^13.1.5",
146
+ "@semantic-release/release-notes-generator": "^14.1.0",
139
147
  "@types/aws-lambda": "^8.10.161",
140
148
  "@types/bun": "^1.3.13",
141
149
  "@types/node": "25.6.0",
150
+ "conventional-changelog-conventionalcommits": "^9.3.1",
142
151
  "esbuild": "^0.28.0",
143
152
  "husky": "9.1.7",
144
153
  "lint-staged": "16.4.0",
145
154
  "rollup": "^4.60.2",
146
155
  "rollup-plugin-esbuild": "^6.2.1",
156
+ "semantic-release": "^25.0.3",
147
157
  "tslib": "^2.8.1",
148
158
  "typescript": "6.0.3"
149
159
  },
150
160
  "packageManager": "bun@1.3.13",
151
161
  "engines": {
152
- "node": ">= 18.0",
162
+ "node": ">= 22.0",
153
163
  "bun": ">= 1.3"
154
164
  }
155
165
  }