bouncevalidator 0.0.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/index.js ADDED
@@ -0,0 +1,2105 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ DnsCache: () => DnsCache,
34
+ SmtpErrorType: () => SmtpErrorType,
35
+ checkDisposable: () => checkDisposable,
36
+ checkFreeProvider: () => checkFreeProvider,
37
+ checkMisc: () => checkMisc,
38
+ checkRoleAccount: () => checkRoleAccount,
39
+ clearDnsCache: () => clearDnsCache,
40
+ default: () => index_default,
41
+ disposableDomains: () => disposableDomains,
42
+ extractParts: () => extractParts,
43
+ freeProviders: () => freeProviders,
44
+ getDnsCacheSize: () => getDnsCacheSize,
45
+ getEmailSuggestion: () => getEmailSuggestion,
46
+ getMxRecords: () => getMxRecords,
47
+ getSuggestion: () => getSuggestion,
48
+ globalDnsCache: () => globalDnsCache,
49
+ hasMxRecords: () => hasMxRecords,
50
+ isDisposableDomain: () => isDisposableDomain,
51
+ isFreeProvider: () => isFreeProvider,
52
+ isRolePrefix: () => isRolePrefix,
53
+ isValidSyntax: () => isValidSyntax,
54
+ normalizeEmail: () => normalizeEmail,
55
+ rolePrefixes: () => rolePrefixes,
56
+ validate: () => validate,
57
+ validateBulk: () => validateBulk,
58
+ validateQuick: () => validateQuick,
59
+ validateSyntax: () => validateSyntax,
60
+ verifyMx: () => verifyMx,
61
+ verifySmtp: () => verifySmtpWithFallback
62
+ });
63
+ module.exports = __toCommonJS(index_exports);
64
+
65
+ // src/utils/normalize.ts
66
+ function normalizeEmail(email, options = {}) {
67
+ let normalized = email.trim().toLowerCase();
68
+ const atIndex = normalized.indexOf("@");
69
+ if (atIndex === -1) {
70
+ return normalized;
71
+ }
72
+ let username = normalized.slice(0, atIndex);
73
+ const domain = normalized.slice(atIndex + 1);
74
+ if (options.removePlusAddressing) {
75
+ const plusIndex = username.indexOf("+");
76
+ if (plusIndex !== -1) {
77
+ username = username.slice(0, plusIndex);
78
+ }
79
+ }
80
+ if (options.removeDots) {
81
+ const gmailDomains = ["gmail.com", "googlemail.com"];
82
+ if (gmailDomains.includes(domain)) {
83
+ username = username.replace(/\./g, "");
84
+ }
85
+ }
86
+ return `${username}@${domain}`;
87
+ }
88
+ function extractParts(email) {
89
+ const atIndex = email.indexOf("@");
90
+ if (atIndex === -1 || atIndex === 0 || atIndex === email.length - 1) {
91
+ return null;
92
+ }
93
+ if (email.indexOf("@", atIndex + 1) !== -1) {
94
+ return null;
95
+ }
96
+ return {
97
+ username: email.slice(0, atIndex),
98
+ domain: email.slice(atIndex + 1)
99
+ };
100
+ }
101
+ function cleanDomain(domain) {
102
+ let cleaned = domain.trim().toLowerCase();
103
+ if (cleaned.endsWith(".")) {
104
+ cleaned = cleaned.slice(0, -1);
105
+ }
106
+ return cleaned;
107
+ }
108
+
109
+ // src/utils/suggestions.ts
110
+ var domainTypos = {
111
+ // Gmail typos
112
+ "gmial.com": "gmail.com",
113
+ "gmal.com": "gmail.com",
114
+ "gamil.com": "gmail.com",
115
+ "gnail.com": "gmail.com",
116
+ "gmaill.com": "gmail.com",
117
+ "gmali.com": "gmail.com",
118
+ "gmai.com": "gmail.com",
119
+ "gmail.co": "gmail.com",
120
+ "gmail.om": "gmail.com",
121
+ "gmail.cm": "gmail.com",
122
+ "gmail.cim": "gmail.com",
123
+ "gmail.con": "gmail.com",
124
+ "gmail.vom": "gmail.com",
125
+ "gmail.xom": "gmail.com",
126
+ "gmail.comm": "gmail.com",
127
+ "gmail.ocm": "gmail.com",
128
+ "gmaul.com": "gmail.com",
129
+ "gmeil.com": "gmail.com",
130
+ "gmsil.com": "gmail.com",
131
+ "gmqil.com": "gmail.com",
132
+ "gemail.com": "gmail.com",
133
+ "g]mail.com": "gmail.com",
134
+ "fmail.com": "gmail.com",
135
+ // Yahoo typos
136
+ "yaho.com": "yahoo.com",
137
+ "yahooo.com": "yahoo.com",
138
+ "yhoo.com": "yahoo.com",
139
+ "yhaoo.com": "yahoo.com",
140
+ "yaoo.com": "yahoo.com",
141
+ "yahoo.co": "yahoo.com",
142
+ "yahoo.om": "yahoo.com",
143
+ "yahoo.cm": "yahoo.com",
144
+ "yahoo.con": "yahoo.com",
145
+ "yahoo.vom": "yahoo.com",
146
+ "tahoo.com": "yahoo.com",
147
+ "uahoo.com": "yahoo.com",
148
+ "yagoo.com": "yahoo.com",
149
+ // Hotmail typos
150
+ "hotmial.com": "hotmail.com",
151
+ "hotmal.com": "hotmail.com",
152
+ "hotmai.com": "hotmail.com",
153
+ "homail.com": "hotmail.com",
154
+ "hotmil.com": "hotmail.com",
155
+ "hotamail.com": "hotmail.com",
156
+ "hotmaill.com": "hotmail.com",
157
+ "hotmail.co": "hotmail.com",
158
+ "hotmail.om": "hotmail.com",
159
+ "hotmail.cm": "hotmail.com",
160
+ "hotmail.con": "hotmail.com",
161
+ "hitmail.com": "hotmail.com",
162
+ "hormail.com": "hotmail.com",
163
+ "hptmail.com": "hotmail.com",
164
+ "hotmaiil.com": "hotmail.com",
165
+ // Outlook typos
166
+ "outlok.com": "outlook.com",
167
+ "outloo.com": "outlook.com",
168
+ "outlook.co": "outlook.com",
169
+ "outlook.om": "outlook.com",
170
+ "outlook.cm": "outlook.com",
171
+ "outlook.con": "outlook.com",
172
+ "outllook.com": "outlook.com",
173
+ "outlookk.com": "outlook.com",
174
+ "outloook.com": "outlook.com",
175
+ "putlook.com": "outlook.com",
176
+ "oitlook.com": "outlook.com",
177
+ "outlool.com": "outlook.com",
178
+ // iCloud typos
179
+ "iclould.com": "icloud.com",
180
+ "icloud.co": "icloud.com",
181
+ "icloud.om": "icloud.com",
182
+ "icoud.com": "icloud.com",
183
+ "icloude.com": "icloud.com",
184
+ "iclud.com": "icloud.com",
185
+ "iclod.com": "icloud.com",
186
+ // Protonmail typos
187
+ "protonmal.com": "protonmail.com",
188
+ "protonmial.com": "protonmail.com",
189
+ "protonmai.com": "protonmail.com",
190
+ "protonmail.co": "protonmail.com",
191
+ "protonmail.om": "protonmail.com",
192
+ "protonmail.cm": "protonmail.com",
193
+ "protnmail.com": "protonmail.com",
194
+ "protommail.com": "protonmail.com",
195
+ // AOL typos
196
+ "aol.co": "aol.com",
197
+ "aol.om": "aol.com",
198
+ "aol.cm": "aol.com",
199
+ "ao.com": "aol.com",
200
+ "aoll.com": "aol.com",
201
+ // Live typos
202
+ "live.co": "live.com",
203
+ "live.om": "live.com",
204
+ "live.cm": "live.com",
205
+ "live.con": "live.com",
206
+ "livve.com": "live.com",
207
+ // MSN typos
208
+ "msn.co": "msn.com",
209
+ "msn.om": "msn.com",
210
+ "msn.cm": "msn.com",
211
+ "mns.com": "msn.com",
212
+ // Common TLD typos
213
+ ".con": ".com",
214
+ ".vom": ".com",
215
+ ".cpm": ".com",
216
+ ".ocm": ".com",
217
+ ".co,": ".com",
218
+ ".xom": ".com",
219
+ ".cim": ".com",
220
+ ".comm": ".com",
221
+ ".ner": ".net",
222
+ ".nte": ".net",
223
+ ".nett": ".net",
224
+ ".rog": ".org",
225
+ ".ogr": ".org",
226
+ ".orgg": ".org"
227
+ };
228
+ var popularDomains = [
229
+ "gmail.com",
230
+ "yahoo.com",
231
+ "hotmail.com",
232
+ "outlook.com",
233
+ "icloud.com",
234
+ "aol.com",
235
+ "protonmail.com",
236
+ "live.com",
237
+ "msn.com",
238
+ "mail.com",
239
+ "zoho.com",
240
+ "yandex.com",
241
+ "gmx.com",
242
+ "fastmail.com"
243
+ ];
244
+ function levenshteinDistance(str1, str2) {
245
+ const m = str1.length;
246
+ const n = str2.length;
247
+ const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
248
+ for (let i = 0; i <= m; i++) dp[i][0] = i;
249
+ for (let j = 0; j <= n; j++) dp[0][j] = j;
250
+ for (let i = 1; i <= m; i++) {
251
+ for (let j = 1; j <= n; j++) {
252
+ if (str1[i - 1] === str2[j - 1]) {
253
+ dp[i][j] = dp[i - 1][j - 1];
254
+ } else {
255
+ dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
256
+ }
257
+ }
258
+ }
259
+ return dp[m][n];
260
+ }
261
+ function getSuggestion(domain) {
262
+ const lowerDomain = domain.toLowerCase();
263
+ if (popularDomains.includes(lowerDomain)) {
264
+ return null;
265
+ }
266
+ if (domainTypos[lowerDomain]) {
267
+ return domainTypos[lowerDomain];
268
+ }
269
+ for (const [typo, correction] of Object.entries(domainTypos)) {
270
+ if (typo.startsWith(".") && lowerDomain.endsWith(typo)) {
271
+ return lowerDomain.slice(0, -typo.length) + correction;
272
+ }
273
+ }
274
+ let bestMatch = null;
275
+ let bestDistance = Infinity;
276
+ for (const popular of popularDomains) {
277
+ const distance = levenshteinDistance(lowerDomain, popular);
278
+ if (distance > 0 && distance <= 2 && distance < bestDistance) {
279
+ bestDistance = distance;
280
+ bestMatch = popular;
281
+ }
282
+ }
283
+ return bestMatch;
284
+ }
285
+ function getEmailSuggestion(email) {
286
+ const atIndex = email.indexOf("@");
287
+ if (atIndex === -1) return null;
288
+ const username = email.slice(0, atIndex);
289
+ const domain = email.slice(atIndex + 1);
290
+ const suggestedDomain = getSuggestion(domain);
291
+ if (suggestedDomain && suggestedDomain !== domain.toLowerCase()) {
292
+ return `${username}@${suggestedDomain}`;
293
+ }
294
+ return null;
295
+ }
296
+
297
+ // src/validators/syntax.ts
298
+ var EMAIL_REGEX = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i;
299
+ var SIMPLE_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
300
+ var MAX_EMAIL_LENGTH = 254;
301
+ var MAX_LOCAL_LENGTH = 64;
302
+ var MAX_DOMAIN_LENGTH = 253;
303
+ function validateSyntax(email) {
304
+ const trimmedEmail = email.trim();
305
+ const normalizedEmail = normalizeEmail(trimmedEmail);
306
+ const invalidResult = {
307
+ address: trimmedEmail,
308
+ domain: "",
309
+ username: "",
310
+ isValidSyntax: false,
311
+ normalizedEmail,
312
+ suggestion: getEmailSuggestion(normalizedEmail)
313
+ };
314
+ if (!trimmedEmail) {
315
+ return invalidResult;
316
+ }
317
+ if (trimmedEmail.length > MAX_EMAIL_LENGTH) {
318
+ return invalidResult;
319
+ }
320
+ const parts = extractParts(trimmedEmail);
321
+ if (!parts) {
322
+ return invalidResult;
323
+ }
324
+ const { username, domain } = parts;
325
+ if (username.length > MAX_LOCAL_LENGTH) {
326
+ return {
327
+ ...invalidResult,
328
+ domain,
329
+ username
330
+ };
331
+ }
332
+ if (domain.length > MAX_DOMAIN_LENGTH) {
333
+ return {
334
+ ...invalidResult,
335
+ domain,
336
+ username
337
+ };
338
+ }
339
+ if (!username || !domain) {
340
+ return {
341
+ ...invalidResult,
342
+ domain,
343
+ username
344
+ };
345
+ }
346
+ if (!domain.includes(".") && !domain.startsWith("[")) {
347
+ return {
348
+ ...invalidResult,
349
+ domain,
350
+ username
351
+ };
352
+ }
353
+ const labels = domain.split(".");
354
+ for (const label of labels) {
355
+ if (label.length === 0 || label.length > 63) {
356
+ return {
357
+ ...invalidResult,
358
+ domain,
359
+ username
360
+ };
361
+ }
362
+ if (label.startsWith("-") || label.endsWith("-")) {
363
+ return {
364
+ ...invalidResult,
365
+ domain,
366
+ username
367
+ };
368
+ }
369
+ if (!/^[a-z0-9-]+$/i.test(label)) {
370
+ return {
371
+ ...invalidResult,
372
+ domain,
373
+ username
374
+ };
375
+ }
376
+ }
377
+ const tld = labels[labels.length - 1];
378
+ if (tld.length < 2 || !/^[a-z]+$/i.test(tld)) {
379
+ return {
380
+ ...invalidResult,
381
+ domain,
382
+ username
383
+ };
384
+ }
385
+ if (!SIMPLE_EMAIL_REGEX.test(trimmedEmail)) {
386
+ return {
387
+ ...invalidResult,
388
+ domain,
389
+ username
390
+ };
391
+ }
392
+ const isValid = EMAIL_REGEX.test(trimmedEmail);
393
+ return {
394
+ address: trimmedEmail,
395
+ domain: domain.toLowerCase(),
396
+ username,
397
+ isValidSyntax: isValid,
398
+ normalizedEmail,
399
+ suggestion: isValid ? getEmailSuggestion(normalizedEmail) : invalidResult.suggestion
400
+ };
401
+ }
402
+ function isValidSyntax(email) {
403
+ return validateSyntax(email).isValidSyntax;
404
+ }
405
+
406
+ // src/validators/dns.ts
407
+ var import_dns = __toESM(require("dns"));
408
+ var import_util = require("util");
409
+
410
+ // src/utils/cache.ts
411
+ var DnsCache = class {
412
+ cache = /* @__PURE__ */ new Map();
413
+ ttl;
414
+ /**
415
+ * Create a new DNS cache
416
+ * @param ttl Time-to-live in milliseconds (default: 5 minutes)
417
+ */
418
+ constructor(ttl = 3e5) {
419
+ this.ttl = ttl;
420
+ }
421
+ /**
422
+ * Get a cached entry for a domain
423
+ * @param domain The domain to look up
424
+ * @returns The cached entry or null if not found/expired
425
+ */
426
+ get(domain) {
427
+ const key = domain.toLowerCase();
428
+ const entry = this.cache.get(key);
429
+ if (!entry) {
430
+ return null;
431
+ }
432
+ if (Date.now() - entry.timestamp > this.ttl) {
433
+ this.cache.delete(key);
434
+ return null;
435
+ }
436
+ return entry;
437
+ }
438
+ /**
439
+ * Set a cache entry for a domain
440
+ * @param domain The domain to cache
441
+ * @param records The MX records
442
+ * @param acceptsMail Whether the domain accepts mail
443
+ */
444
+ set(domain, records, acceptsMail) {
445
+ const key = domain.toLowerCase();
446
+ this.cache.set(key, {
447
+ records,
448
+ acceptsMail,
449
+ timestamp: Date.now()
450
+ });
451
+ }
452
+ /**
453
+ * Clear all cached entries
454
+ */
455
+ clear() {
456
+ this.cache.clear();
457
+ }
458
+ /**
459
+ * Remove expired entries from the cache
460
+ */
461
+ cleanup() {
462
+ const now = Date.now();
463
+ for (const [key, entry] of this.cache.entries()) {
464
+ if (now - entry.timestamp > this.ttl) {
465
+ this.cache.delete(key);
466
+ }
467
+ }
468
+ }
469
+ /**
470
+ * Get the number of cached entries
471
+ */
472
+ get size() {
473
+ return this.cache.size;
474
+ }
475
+ /**
476
+ * Set the TTL for the cache
477
+ * @param ttl Time-to-live in milliseconds
478
+ */
479
+ setTtl(ttl) {
480
+ this.ttl = ttl;
481
+ }
482
+ };
483
+ var globalDnsCache = new DnsCache();
484
+
485
+ // src/validators/dns.ts
486
+ var resolveMx = (0, import_util.promisify)(import_dns.default.resolveMx);
487
+ var resolve4 = (0, import_util.promisify)(import_dns.default.resolve4);
488
+ var resolve6 = (0, import_util.promisify)(import_dns.default.resolve6);
489
+ function sortMxRecords(records) {
490
+ return records.sort((a, b) => a.priority - b.priority).map((r) => cleanDomain(r.exchange));
491
+ }
492
+ async function verifyMx(domain, options = {}, cache) {
493
+ const cleanedDomain = cleanDomain(domain);
494
+ const dnsCache = cache || globalDnsCache;
495
+ if (options.useDnsCache !== false) {
496
+ const cached = dnsCache.get(cleanedDomain);
497
+ if (cached) {
498
+ return {
499
+ acceptsMail: cached.acceptsMail,
500
+ records: cached.records
501
+ };
502
+ }
503
+ }
504
+ try {
505
+ const mxRecords = await resolveMx(cleanedDomain);
506
+ if (!mxRecords || mxRecords.length === 0) {
507
+ return await fallbackToAddressRecords(cleanedDomain, dnsCache, options);
508
+ }
509
+ if (mxRecords.length === 1 && mxRecords[0].priority === 0 && (mxRecords[0].exchange === "" || mxRecords[0].exchange === "." || mxRecords[0].exchange === "0.0.0.0")) {
510
+ const result2 = {
511
+ acceptsMail: false,
512
+ records: []
513
+ };
514
+ if (options.useDnsCache !== false) {
515
+ dnsCache.set(cleanedDomain, [], false);
516
+ }
517
+ return result2;
518
+ }
519
+ const sortedRecords = sortMxRecords(mxRecords);
520
+ const validRecords = sortedRecords.filter(
521
+ (r) => r && r !== "" && r !== "." && r !== "0.0.0.0" && r !== "localhost"
522
+ );
523
+ if (validRecords.length === 0) {
524
+ return await fallbackToAddressRecords(cleanedDomain, dnsCache, options);
525
+ }
526
+ const result = {
527
+ acceptsMail: true,
528
+ records: validRecords
529
+ };
530
+ if (options.useDnsCache !== false) {
531
+ dnsCache.set(cleanedDomain, validRecords, true);
532
+ }
533
+ return result;
534
+ } catch (error) {
535
+ const err = error;
536
+ if (err.code === "ENODATA" || err.code === "ENOTFOUND") {
537
+ return await fallbackToAddressRecords(cleanedDomain, dnsCache, options);
538
+ }
539
+ if (err.code === "ENOTFOUND" || err.code === "SERVFAIL") {
540
+ const result = {
541
+ acceptsMail: false,
542
+ records: []
543
+ };
544
+ if (options.useDnsCache !== false) {
545
+ dnsCache.set(cleanedDomain, [], false);
546
+ }
547
+ return result;
548
+ }
549
+ return {
550
+ acceptsMail: false,
551
+ records: []
552
+ };
553
+ }
554
+ }
555
+ async function fallbackToAddressRecords(domain, cache, options) {
556
+ try {
557
+ const aRecords = await resolve4(domain);
558
+ if (aRecords && aRecords.length > 0) {
559
+ const result2 = {
560
+ acceptsMail: true,
561
+ records: [domain]
562
+ // Use the domain itself as the mail host
563
+ };
564
+ if (options.useDnsCache !== false) {
565
+ cache.set(domain, [domain], true);
566
+ }
567
+ return result2;
568
+ }
569
+ } catch {
570
+ }
571
+ try {
572
+ const aaaaRecords = await resolve6(domain);
573
+ if (aaaaRecords && aaaaRecords.length > 0) {
574
+ const result2 = {
575
+ acceptsMail: true,
576
+ records: [domain]
577
+ // Use the domain itself as the mail host
578
+ };
579
+ if (options.useDnsCache !== false) {
580
+ cache.set(domain, [domain], true);
581
+ }
582
+ return result2;
583
+ }
584
+ } catch {
585
+ }
586
+ const result = {
587
+ acceptsMail: false,
588
+ records: []
589
+ };
590
+ if (options.useDnsCache !== false) {
591
+ cache.set(domain, [], false);
592
+ }
593
+ return result;
594
+ }
595
+ async function hasMxRecords(domain) {
596
+ const result = await verifyMx(domain);
597
+ return result.acceptsMail;
598
+ }
599
+ async function getMxRecords(domain) {
600
+ const result = await verifyMx(domain);
601
+ return result.records;
602
+ }
603
+
604
+ // src/validators/smtp.ts
605
+ var import_net = __toESM(require("net"));
606
+ var import_os = __toESM(require("os"));
607
+ var SMTP_PORT = 25;
608
+ var DEFAULT_TIMEOUT = 1e4;
609
+ var SmtpErrorType = {
610
+ CONNECTION_FAILED: "ConnectionFailed",
611
+ TIMEOUT: "Timeout",
612
+ INVALID_RESPONSE: "InvalidResponse",
613
+ HELO_FAILED: "HeloFailed",
614
+ MAIL_FROM_FAILED: "MailFromFailed",
615
+ RCPT_TO_FAILED: "RcptToFailed",
616
+ MAILBOX_NOT_FOUND: "MailboxNotFound",
617
+ MAILBOX_DISABLED: "MailboxDisabled",
618
+ GREYLISTED: "Greylisted",
619
+ BLOCKED: "Blocked",
620
+ UNKNOWN: "Unknown"
621
+ };
622
+ function parseResponse(data) {
623
+ const lines = data.trim().split("\r\n");
624
+ const lastLine = lines[lines.length - 1];
625
+ const code = parseInt(lastLine.substring(0, 3), 10);
626
+ const message = lastLine.substring(4);
627
+ return { code, message };
628
+ }
629
+ function isSuccessResponse(code) {
630
+ return code >= 200 && code < 400;
631
+ }
632
+ function sendCommand(socket, command, timeout) {
633
+ return new Promise((resolve, reject) => {
634
+ const timeoutId = setTimeout(() => {
635
+ reject(new Error("Command timeout"));
636
+ }, timeout);
637
+ const onData = (data) => {
638
+ clearTimeout(timeoutId);
639
+ socket.removeListener("data", onData);
640
+ socket.removeListener("error", onError);
641
+ const response = parseResponse(data.toString());
642
+ resolve(response);
643
+ };
644
+ const onError = (err) => {
645
+ clearTimeout(timeoutId);
646
+ socket.removeListener("data", onData);
647
+ reject(err);
648
+ };
649
+ socket.once("data", onData);
650
+ socket.once("error", onError);
651
+ if (command) {
652
+ socket.write(command + "\r\n");
653
+ }
654
+ });
655
+ }
656
+ function waitForGreeting(socket, timeout) {
657
+ return new Promise((resolve, reject) => {
658
+ const timeoutId = setTimeout(() => {
659
+ reject(new Error("Greeting timeout"));
660
+ }, timeout);
661
+ const onData = (data) => {
662
+ clearTimeout(timeoutId);
663
+ socket.removeListener("data", onData);
664
+ socket.removeListener("error", onError);
665
+ const response = parseResponse(data.toString());
666
+ resolve(response);
667
+ };
668
+ const onError = (err) => {
669
+ clearTimeout(timeoutId);
670
+ socket.removeListener("data", onData);
671
+ reject(err);
672
+ };
673
+ socket.once("data", onData);
674
+ socket.once("error", onError);
675
+ });
676
+ }
677
+ function generateRandomEmail(domain) {
678
+ const random = Math.random().toString(36).substring(2, 15);
679
+ return `${random}@${domain}`;
680
+ }
681
+ async function verifySmtp(email, mxHost, options = {}) {
682
+ const timeout = options.smtpTimeout || DEFAULT_TIMEOUT;
683
+ const heloHost = options.heloHost || import_os.default.hostname() || "localhost";
684
+ const senderAddress = options.senderAddress || "";
685
+ const detectCatchAll = options.detectCatchAll !== false;
686
+ const domain = email.split("@")[1];
687
+ return new Promise((resolve) => {
688
+ const socket = new import_net.default.Socket();
689
+ let resolved = false;
690
+ const cleanup = () => {
691
+ if (!socket.destroyed) {
692
+ try {
693
+ socket.write("QUIT\r\n");
694
+ } catch {
695
+ }
696
+ socket.destroy();
697
+ }
698
+ };
699
+ const finish = (result) => {
700
+ if (!resolved) {
701
+ resolved = true;
702
+ cleanup();
703
+ resolve(result);
704
+ }
705
+ };
706
+ socket.setTimeout(timeout);
707
+ socket.on("timeout", () => {
708
+ finish({
709
+ canConnectSmtp: false,
710
+ isDeliverable: false,
711
+ isCatchAll: false,
712
+ error: {
713
+ type: SmtpErrorType.TIMEOUT,
714
+ message: "Connection timed out"
715
+ }
716
+ });
717
+ });
718
+ socket.on("error", (err) => {
719
+ finish({
720
+ canConnectSmtp: false,
721
+ isDeliverable: false,
722
+ isCatchAll: false,
723
+ error: {
724
+ type: SmtpErrorType.CONNECTION_FAILED,
725
+ message: err.message
726
+ }
727
+ });
728
+ });
729
+ socket.connect(SMTP_PORT, mxHost, async () => {
730
+ try {
731
+ const greeting = await waitForGreeting(socket, timeout);
732
+ if (!isSuccessResponse(greeting.code)) {
733
+ finish({
734
+ canConnectSmtp: false,
735
+ isDeliverable: false,
736
+ isCatchAll: false,
737
+ error: {
738
+ type: SmtpErrorType.BLOCKED,
739
+ message: `Server rejected connection: ${greeting.message}`
740
+ }
741
+ });
742
+ return;
743
+ }
744
+ let heloResponse = await sendCommand(socket, `EHLO ${heloHost}`, timeout);
745
+ if (!isSuccessResponse(heloResponse.code)) {
746
+ heloResponse = await sendCommand(socket, `HELO ${heloHost}`, timeout);
747
+ if (!isSuccessResponse(heloResponse.code)) {
748
+ finish({
749
+ canConnectSmtp: true,
750
+ isDeliverable: false,
751
+ isCatchAll: false,
752
+ error: {
753
+ type: SmtpErrorType.HELO_FAILED,
754
+ message: `HELO failed: ${heloResponse.message}`
755
+ }
756
+ });
757
+ return;
758
+ }
759
+ }
760
+ const mailFromResponse = await sendCommand(
761
+ socket,
762
+ `MAIL FROM:<${senderAddress}>`,
763
+ timeout
764
+ );
765
+ if (!isSuccessResponse(mailFromResponse.code)) {
766
+ finish({
767
+ canConnectSmtp: true,
768
+ isDeliverable: false,
769
+ isCatchAll: false,
770
+ error: {
771
+ type: SmtpErrorType.MAIL_FROM_FAILED,
772
+ message: `MAIL FROM failed: ${mailFromResponse.message}`
773
+ }
774
+ });
775
+ return;
776
+ }
777
+ const rcptResponse = await sendCommand(socket, `RCPT TO:<${email}>`, timeout);
778
+ let isCatchAll = false;
779
+ if (detectCatchAll && isSuccessResponse(rcptResponse.code)) {
780
+ const randomEmail = generateRandomEmail(domain);
781
+ const catchAllResponse = await sendCommand(
782
+ socket,
783
+ `RCPT TO:<${randomEmail}>`,
784
+ timeout
785
+ );
786
+ isCatchAll = isSuccessResponse(catchAllResponse.code);
787
+ }
788
+ if (isSuccessResponse(rcptResponse.code)) {
789
+ finish({
790
+ canConnectSmtp: true,
791
+ isDeliverable: true,
792
+ isCatchAll,
793
+ error: null
794
+ });
795
+ } else if (rcptResponse.code === 550) {
796
+ finish({
797
+ canConnectSmtp: true,
798
+ isDeliverable: false,
799
+ isCatchAll: false,
800
+ error: {
801
+ type: SmtpErrorType.MAILBOX_NOT_FOUND,
802
+ message: rcptResponse.message
803
+ }
804
+ });
805
+ } else if (rcptResponse.code === 551 || rcptResponse.code === 553) {
806
+ finish({
807
+ canConnectSmtp: true,
808
+ isDeliverable: false,
809
+ isCatchAll: false,
810
+ error: {
811
+ type: SmtpErrorType.MAILBOX_NOT_FOUND,
812
+ message: rcptResponse.message
813
+ }
814
+ });
815
+ } else if (rcptResponse.code === 552) {
816
+ finish({
817
+ canConnectSmtp: true,
818
+ isDeliverable: false,
819
+ isCatchAll: false,
820
+ error: {
821
+ type: SmtpErrorType.MAILBOX_DISABLED,
822
+ message: rcptResponse.message
823
+ }
824
+ });
825
+ } else if (rcptResponse.code === 450 || rcptResponse.code === 451) {
826
+ finish({
827
+ canConnectSmtp: true,
828
+ isDeliverable: false,
829
+ isCatchAll: false,
830
+ error: {
831
+ type: SmtpErrorType.GREYLISTED,
832
+ message: rcptResponse.message
833
+ }
834
+ });
835
+ } else if (rcptResponse.code >= 500) {
836
+ finish({
837
+ canConnectSmtp: true,
838
+ isDeliverable: false,
839
+ isCatchAll: false,
840
+ error: {
841
+ type: SmtpErrorType.RCPT_TO_FAILED,
842
+ message: rcptResponse.message
843
+ }
844
+ });
845
+ } else {
846
+ finish({
847
+ canConnectSmtp: true,
848
+ isDeliverable: false,
849
+ isCatchAll: false,
850
+ error: {
851
+ type: SmtpErrorType.UNKNOWN,
852
+ message: `Unexpected response code ${rcptResponse.code}: ${rcptResponse.message}`
853
+ }
854
+ });
855
+ }
856
+ } catch (err) {
857
+ const error = err;
858
+ finish({
859
+ canConnectSmtp: true,
860
+ isDeliverable: false,
861
+ isCatchAll: false,
862
+ error: {
863
+ type: SmtpErrorType.UNKNOWN,
864
+ message: error.message
865
+ }
866
+ });
867
+ }
868
+ });
869
+ });
870
+ }
871
+ async function verifySmtpWithFallback(email, mxHosts, options = {}) {
872
+ if (mxHosts.length === 0) {
873
+ return {
874
+ canConnectSmtp: false,
875
+ isDeliverable: false,
876
+ isCatchAll: false,
877
+ error: {
878
+ type: SmtpErrorType.CONNECTION_FAILED,
879
+ message: "No MX hosts available"
880
+ }
881
+ };
882
+ }
883
+ let lastResult = null;
884
+ for (const mxHost of mxHosts) {
885
+ const result = await verifySmtp(email, mxHost, options);
886
+ if (result.isDeliverable || result.error?.type === SmtpErrorType.MAILBOX_NOT_FOUND) {
887
+ return result;
888
+ }
889
+ if (result.canConnectSmtp) {
890
+ lastResult = result;
891
+ }
892
+ if (!result.canConnectSmtp) {
893
+ lastResult = result;
894
+ continue;
895
+ }
896
+ }
897
+ return lastResult || {
898
+ canConnectSmtp: false,
899
+ isDeliverable: false,
900
+ isCatchAll: false,
901
+ error: {
902
+ type: SmtpErrorType.CONNECTION_FAILED,
903
+ message: "Failed to connect to any MX host"
904
+ }
905
+ };
906
+ }
907
+
908
+ // src/validators/misc.ts
909
+ var import_crypto = __toESM(require("crypto"));
910
+ var import_https = __toESM(require("https"));
911
+
912
+ // src/data/disposable.ts
913
+ var disposableDomains = /* @__PURE__ */ new Set([
914
+ // Popular disposable email services
915
+ "10minutemail.com",
916
+ "10minutemail.net",
917
+ "20minutemail.com",
918
+ "33mail.com",
919
+ "guerrillamail.com",
920
+ "guerrillamail.org",
921
+ "guerrillamail.net",
922
+ "guerrillamail.biz",
923
+ "guerrillamail.de",
924
+ "guerrillamailblock.com",
925
+ "sharklasers.com",
926
+ "grr.la",
927
+ "pokemail.net",
928
+ "spam4.me",
929
+ "mailinator.com",
930
+ "mailinator.net",
931
+ "mailinator.org",
932
+ "mailinator2.com",
933
+ "mailinater.com",
934
+ "tempmail.com",
935
+ "tempmail.net",
936
+ "temp-mail.org",
937
+ "temp-mail.io",
938
+ "tempail.com",
939
+ "tempmailaddress.com",
940
+ "throwaway.email",
941
+ "throwawaymail.com",
942
+ "trashmail.com",
943
+ "trashmail.net",
944
+ "trashmail.org",
945
+ "trashmail.me",
946
+ "trashemail.de",
947
+ "fakeinbox.com",
948
+ "fakemailgenerator.com",
949
+ "getnada.com",
950
+ "nada.email",
951
+ "getairmail.com",
952
+ "airmail.cc",
953
+ "dispostable.com",
954
+ "disposableemailaddresses.com",
955
+ "emailondeck.com",
956
+ "yopmail.com",
957
+ "yopmail.fr",
958
+ "yopmail.net",
959
+ "cool.fr.nf",
960
+ "jetable.fr.nf",
961
+ "nospam.ze.tc",
962
+ "nomail.xl.cx",
963
+ "mega.zik.dj",
964
+ "speed.1s.fr",
965
+ "courriel.fr.nf",
966
+ "moncourrier.fr.nf",
967
+ "monemail.fr.nf",
968
+ "monmail.fr.nf",
969
+ "mohmal.com",
970
+ "mailnesia.com",
971
+ "maildrop.cc",
972
+ "mailsac.com",
973
+ "mintemail.com",
974
+ "mytemp.email",
975
+ "mytrashmail.com",
976
+ "nowmymail.com",
977
+ "spambox.us",
978
+ "spamfree24.org",
979
+ "spamgourmet.com",
980
+ "spamspot.com",
981
+ "tempinbox.com",
982
+ "tempomail.fr",
983
+ "temporaryemail.net",
984
+ "temporaryforwarding.com",
985
+ "temporaryinbox.com",
986
+ "thankyou2010.com",
987
+ "thisisnotmyrealemail.com",
988
+ "throam.com",
989
+ "tmail.ws",
990
+ "tmpmail.net",
991
+ "tmpmail.org",
992
+ "wegwerfmail.de",
993
+ "wegwerfmail.net",
994
+ "wegwerfmail.org",
995
+ "wh4f.org",
996
+ "willhackforfood.biz",
997
+ "willselfdestruct.com",
998
+ "emailfake.com",
999
+ "emkei.cz",
1000
+ "anonymbox.com",
1001
+ "discard.email",
1002
+ "discardmail.com",
1003
+ "discardmail.de",
1004
+ "spambog.com",
1005
+ "spambog.de",
1006
+ "spambog.ru",
1007
+ "mailcatch.com",
1008
+ "mail-temp.com",
1009
+ "mailtemp.info",
1010
+ "mailzilla.com",
1011
+ "mailzilla.org",
1012
+ "binkmail.com",
1013
+ "bobmail.info",
1014
+ "burnthespam.info",
1015
+ "buyusedlibrarybooks.org",
1016
+ "byom.de",
1017
+ "deadaddress.com",
1018
+ "despam.it",
1019
+ "devnullmail.com",
1020
+ "dfgh.net",
1021
+ "e4ward.com",
1022
+ "emailias.com",
1023
+ "emailigo.de",
1024
+ "emailsensei.com",
1025
+ "emailtemporario.com.br",
1026
+ "emailwarden.com",
1027
+ "explodemail.com",
1028
+ "fastacura.com",
1029
+ "filzmail.com",
1030
+ "fizmail.com",
1031
+ "frapmail.com",
1032
+ "gishpuppy.com",
1033
+ "great-host.in",
1034
+ "greensloth.com",
1035
+ "haltospam.com",
1036
+ "hidzz.com",
1037
+ "hmamail.com",
1038
+ "imails.info",
1039
+ "incognitomail.com",
1040
+ "incognitomail.net",
1041
+ "incognitomail.org",
1042
+ "infocom.zp.ua",
1043
+ "instantemailaddress.com",
1044
+ "ipoo.org",
1045
+ "irish2me.com",
1046
+ "jetable.com",
1047
+ "kasmail.com",
1048
+ "klassmaster.com",
1049
+ "klzlv.com",
1050
+ "koszmail.pl",
1051
+ "kulturbetrieb.info",
1052
+ "kurzepost.de",
1053
+ "lawlita.com",
1054
+ "letthemeatspam.com",
1055
+ "lhsdv.com",
1056
+ "lifebyfood.com",
1057
+ "link2mail.net",
1058
+ "litedrop.com",
1059
+ "lol.ovpn.to",
1060
+ "lookugly.com",
1061
+ "lortemail.dk",
1062
+ "lovemeleaveme.com",
1063
+ "lr78.com",
1064
+ "maboard.com",
1065
+ "mail2rss.org",
1066
+ "mail333.com",
1067
+ "mailbidon.com",
1068
+ "mailblocks.com",
1069
+ "maildu.de",
1070
+ "maileater.com",
1071
+ "mailexpire.com",
1072
+ "mailfa.tk",
1073
+ "mailfork.com",
1074
+ "mailfreeonline.com",
1075
+ "mailguard.me",
1076
+ "mailimate.com",
1077
+ "mailin8r.com",
1078
+ "mailinblack.com",
1079
+ "mailincubator.com",
1080
+ "mailme.ir",
1081
+ "mailme.lv",
1082
+ "mailmetrash.com",
1083
+ "mailmoat.com",
1084
+ "mailnull.com",
1085
+ "mailorg.org",
1086
+ "mailscrap.com",
1087
+ "mailshell.com",
1088
+ "mailsiphon.com",
1089
+ "mailslite.com",
1090
+ "mailtemp.net",
1091
+ "mailtothis.com",
1092
+ "mailzi.ru",
1093
+ "makemetheking.com",
1094
+ "mbx.cc",
1095
+ "mega.zik.dj",
1096
+ "meltmail.com",
1097
+ "messagebeamer.de",
1098
+ "mezimages.net",
1099
+ "mierdamail.com",
1100
+ "migmail.pl",
1101
+ "migumail.com",
1102
+ "mintemail.com",
1103
+ "moburl.com",
1104
+ "moncourrier.fr.nf",
1105
+ "monemail.fr.nf",
1106
+ "monmail.fr.nf",
1107
+ "monumentmail.com",
1108
+ "ms51.hinet.net",
1109
+ "msb.minsmail.com",
1110
+ "mt2009.com",
1111
+ "mx0.wwwnew.eu",
1112
+ "mycleaninbox.net",
1113
+ "mypartyclip.de",
1114
+ "myphantomemail.com",
1115
+ "mysamp.de",
1116
+ "myspaceinc.com",
1117
+ "myspaceinc.net",
1118
+ "myspacepimpedup.com",
1119
+ "mytempemail.com",
1120
+ "neomailbox.com",
1121
+ "nepwk.com",
1122
+ "nervmich.net",
1123
+ "nervtmansen.de",
1124
+ "netmails.com",
1125
+ "netmails.net",
1126
+ "netzidiot.de",
1127
+ "neverbox.com",
1128
+ "no-spam.ws",
1129
+ "nobulk.com",
1130
+ "noclickemail.com",
1131
+ "nogmailspam.info",
1132
+ "nomail.xl.cx",
1133
+ "nomail2me.com",
1134
+ "nomorespamemails.com",
1135
+ "nospam.ze.tc",
1136
+ "nospam4.us",
1137
+ "nospamfor.us",
1138
+ "nospammail.net",
1139
+ "notmailinator.com",
1140
+ "nowhere.org",
1141
+ "nowmymail.com",
1142
+ "nurfuerspam.de",
1143
+ "nus.edu.sg",
1144
+ "objectmail.com",
1145
+ "obobbo.com",
1146
+ "oneoffemail.com",
1147
+ "onewaymail.com",
1148
+ "onlatedotcom.info",
1149
+ "online.ms",
1150
+ "oopi.org",
1151
+ "opayq.com",
1152
+ "ordinaryamerican.net",
1153
+ "otherinbox.com",
1154
+ "ourklips.com",
1155
+ "outlawspam.com",
1156
+ "ovpn.to",
1157
+ "owlpic.com",
1158
+ "pancakemail.com",
1159
+ "pjjkp.com",
1160
+ "plexolan.de",
1161
+ "poczta.onet.pl",
1162
+ "politikerclub.de",
1163
+ "poofy.org",
1164
+ "pookmail.com",
1165
+ "privacy.net",
1166
+ "privy-mail.com",
1167
+ "privymail.de",
1168
+ "proxymail.eu",
1169
+ "prtnx.com",
1170
+ "punkass.com",
1171
+ "putthisinyourspamdatabase.com",
1172
+ "qq.com",
1173
+ "quickinbox.com",
1174
+ "quickmail.nl",
1175
+ "rcpt.at",
1176
+ "reallymymail.com",
1177
+ "realtyalerts.ca",
1178
+ "recode.me",
1179
+ "recursor.net",
1180
+ "recyclemail.dk",
1181
+ "regbypass.com",
1182
+ "regbypass.comsafe-mail.net",
1183
+ "rejectmail.com",
1184
+ "remail.cf",
1185
+ "rhyta.com",
1186
+ "rklips.com",
1187
+ "rmqkr.net",
1188
+ "rppkn.com",
1189
+ "rtrtr.com",
1190
+ "s0ny.net",
1191
+ "safe-mail.net",
1192
+ "safersignup.de",
1193
+ "safetymail.info",
1194
+ "safetypost.de",
1195
+ "sandelf.de",
1196
+ "saynotospams.com",
1197
+ "schafmail.de",
1198
+ "selfdestructingmail.com",
1199
+ "sendspamhere.com",
1200
+ "shieldemail.com",
1201
+ "shiftmail.com",
1202
+ "shitmail.me",
1203
+ "shortmail.net",
1204
+ "shut.name",
1205
+ "shut.ws",
1206
+ "sibmail.com",
1207
+ "sinnlos-mail.de",
1208
+ "siteposter.net",
1209
+ "skeefmail.com",
1210
+ "slaskpost.se",
1211
+ "slopsbox.com",
1212
+ "slowfoodfoothills.xyz",
1213
+ "smashmail.de",
1214
+ "smellfear.com",
1215
+ "snakemail.com",
1216
+ "sneakemail.com",
1217
+ "sneakmail.de",
1218
+ "snkmail.com",
1219
+ "sofimail.com",
1220
+ "sofort-mail.de",
1221
+ "softpls.asia",
1222
+ "sogetthis.com",
1223
+ "sohu.com",
1224
+ "soisz.com",
1225
+ "solvemail.info",
1226
+ "soodonims.com",
1227
+ "spam.la",
1228
+ "spam.su",
1229
+ "spamavert.com",
1230
+ "spambob.com",
1231
+ "spambob.net",
1232
+ "spambob.org",
1233
+ "spambog.com",
1234
+ "spambog.de",
1235
+ "spambog.ru",
1236
+ "spambox.info",
1237
+ "spambox.irishspringrealty.com",
1238
+ "spambox.us",
1239
+ "spamcannon.com",
1240
+ "spamcannon.net",
1241
+ "spamcero.com",
1242
+ "spamcon.org",
1243
+ "spamcorptastic.com",
1244
+ "spamcowboy.com",
1245
+ "spamcowboy.net",
1246
+ "spamcowboy.org",
1247
+ "spamday.com",
1248
+ "spamex.com",
1249
+ "spamfree.eu",
1250
+ "spamfree24.com",
1251
+ "spamfree24.de",
1252
+ "spamfree24.eu",
1253
+ "spamfree24.info",
1254
+ "spamfree24.net",
1255
+ "spamfree24.org",
1256
+ "spamgoes.in",
1257
+ "spamherelots.com",
1258
+ "spamhereplease.com",
1259
+ "spamhole.com",
1260
+ "spamify.com",
1261
+ "spaminator.de",
1262
+ "spamkill.info",
1263
+ "spaml.com",
1264
+ "spaml.de",
1265
+ "spammotel.com",
1266
+ "spamobox.com",
1267
+ "spamoff.de",
1268
+ "spamsalad.in",
1269
+ "spamslicer.com",
1270
+ "spamspot.com",
1271
+ "spamstack.net",
1272
+ "spamthis.co.uk",
1273
+ "spamtroll.net",
1274
+ "speed.1s.fr",
1275
+ "spoofmail.de",
1276
+ "squizzy.de",
1277
+ "ssoia.com",
1278
+ "startkeys.com",
1279
+ "stinkefinger.net",
1280
+ "stop-my-spam.cf",
1281
+ "stop-my-spam.com",
1282
+ "stop-my-spam.ga",
1283
+ "stop-my-spam.ml",
1284
+ "stop-my-spam.tk",
1285
+ "streetwisemail.com",
1286
+ "stuffmail.de",
1287
+ "supergreatmail.com",
1288
+ "supermailer.jp",
1289
+ "superrito.com",
1290
+ "superstachel.de",
1291
+ "suremail.info",
1292
+ "svk.jp",
1293
+ "sweetxxx.de",
1294
+ "tagyourself.com",
1295
+ "talkinator.com",
1296
+ "tapchicuoihoi.com",
1297
+ "techemail.com",
1298
+ "techgroup.me",
1299
+ "teewars.org",
1300
+ "teleosaurs.xyz",
1301
+ "teleworm.com",
1302
+ "teleworm.us",
1303
+ "temp.emeraldwebmail.com",
1304
+ "tempail.com",
1305
+ "tempalias.com",
1306
+ "tempe-mail.com",
1307
+ "tempemail.biz",
1308
+ "tempemail.co.za",
1309
+ "tempemail.com",
1310
+ "tempemail.net",
1311
+ "tempinbox.co.uk",
1312
+ "tempinbox.com",
1313
+ "tempmail.co",
1314
+ "tempmail.de",
1315
+ "tempmail.eu",
1316
+ "tempmail.it",
1317
+ "tempmail.net",
1318
+ "tempmail.us",
1319
+ "tempmail2.com",
1320
+ "tempmaildemo.com",
1321
+ "tempmailer.com",
1322
+ "tempmailer.de",
1323
+ "tempomail.fr",
1324
+ "temporarioemail.com.br",
1325
+ "temporaryemail.net",
1326
+ "temporaryemail.us",
1327
+ "temporaryforwarding.com",
1328
+ "temporaryinbox.com",
1329
+ "temporarymailaddress.com",
1330
+ "tempthe.net",
1331
+ "thankspam.info",
1332
+ "thankyou2010.com",
1333
+ "thecloudindex.com",
1334
+ "thelimestones.com",
1335
+ "thisisnotmyrealemail.com",
1336
+ "throam.com",
1337
+ "throwam.com",
1338
+ "throwawayemailaddress.com",
1339
+ "throwawaymail.com",
1340
+ "tilien.com",
1341
+ "tittbit.in",
1342
+ "tmailinator.com",
1343
+ "tmail.ws",
1344
+ "toiea.com",
1345
+ "tokenmail.de",
1346
+ "toomail.biz",
1347
+ "topranklist.de",
1348
+ "tradermail.info",
1349
+ "trash-amil.com",
1350
+ "trash-mail.at",
1351
+ "trash-mail.com",
1352
+ "trash-mail.de",
1353
+ "trash2009.com",
1354
+ "trash2010.com",
1355
+ "trash2011.com",
1356
+ "trashcanmail.com",
1357
+ "trashdevil.com",
1358
+ "trashdevil.de",
1359
+ "trashemail.de",
1360
+ "trashmail.at",
1361
+ "trashmail.com",
1362
+ "trashmail.de",
1363
+ "trashmail.me",
1364
+ "trashmail.net",
1365
+ "trashmail.org",
1366
+ "trashmail.ws",
1367
+ "trashmailer.com",
1368
+ "trashymail.com",
1369
+ "trashymail.net",
1370
+ "trbvm.com",
1371
+ "trickmail.net",
1372
+ "trillianpro.com",
1373
+ "tryalert.com",
1374
+ "turual.com",
1375
+ "twinmail.de",
1376
+ "tyldd.com",
1377
+ "uggsrock.com",
1378
+ "umail.net",
1379
+ "upliftnow.com",
1380
+ "uplipht.com",
1381
+ "uroid.com",
1382
+ "us.af",
1383
+ "valemail.net",
1384
+ "venompen.com",
1385
+ "veryrealemail.com",
1386
+ "viditag.com",
1387
+ "viralplays.com",
1388
+ "vpn.st",
1389
+ "vsimcard.com",
1390
+ "vubby.com",
1391
+ "wasteland.rfc822.org",
1392
+ "webemail.me",
1393
+ "webm4il.info",
1394
+ "webuser.in",
1395
+ "wee.my",
1396
+ "weg-werf-email.de",
1397
+ "wegwerf-emails.de",
1398
+ "wegwerfadresse.de",
1399
+ "wegwerfemail.com",
1400
+ "wegwerfemail.de",
1401
+ "wegwerfmail.de",
1402
+ "wegwerfmail.info",
1403
+ "wegwerfmail.net",
1404
+ "wegwerfmail.org",
1405
+ "wetrainbayarea.com",
1406
+ "wetrainbayarea.org",
1407
+ "wh4f.org",
1408
+ "whatiaas.com",
1409
+ "whatpaas.com",
1410
+ "whopy.com",
1411
+ "whtjddn.33mail.com",
1412
+ "whyspam.me",
1413
+ "willhackforfood.biz",
1414
+ "willselfdestruct.com",
1415
+ "winemaven.info",
1416
+ "wolfsmail.tk",
1417
+ "wollan.info",
1418
+ "worldspace.link",
1419
+ "wpdork.com",
1420
+ "wronghead.com",
1421
+ "wuzup.net",
1422
+ "wuzupmail.net",
1423
+ "wwwnew.eu",
1424
+ "xagloo.co",
1425
+ "xagloo.com",
1426
+ "xemaps.com",
1427
+ "xents.com",
1428
+ "xmaily.com",
1429
+ "xoxy.net",
1430
+ "yapped.net",
1431
+ "yep.it",
1432
+ "yogamaven.com",
1433
+ "yomail.info",
1434
+ "yopmail.com",
1435
+ "yopmail.fr",
1436
+ "yopmail.gq",
1437
+ "yopmail.net",
1438
+ "you-spam.com",
1439
+ "yourdomain.com",
1440
+ "ypmail.webarnak.fr.eu.org",
1441
+ "yuurok.com",
1442
+ "za.com",
1443
+ "zehnminuten.de",
1444
+ "zehnminutenmail.de",
1445
+ "zippymail.info",
1446
+ "zoaxe.com",
1447
+ "zoemail.com",
1448
+ "zoemail.net",
1449
+ "zoemail.org",
1450
+ "zomg.info",
1451
+ "zxcv.com",
1452
+ "zxcvbnm.com",
1453
+ "zzz.com"
1454
+ ]);
1455
+ function isDisposableDomain(domain) {
1456
+ return disposableDomains.has(domain.toLowerCase());
1457
+ }
1458
+
1459
+ // src/data/roles.ts
1460
+ var rolePrefixes = /* @__PURE__ */ new Set([
1461
+ // Administrative
1462
+ "admin",
1463
+ "administrator",
1464
+ "postmaster",
1465
+ "hostmaster",
1466
+ "webmaster",
1467
+ "root",
1468
+ "sysadmin",
1469
+ "it",
1470
+ "tech",
1471
+ "technical",
1472
+ // Support
1473
+ "support",
1474
+ "help",
1475
+ "helpdesk",
1476
+ "customerservice",
1477
+ "customer-service",
1478
+ "customercare",
1479
+ "customer-care",
1480
+ "service",
1481
+ "assist",
1482
+ "assistance",
1483
+ // Sales and Marketing
1484
+ "sales",
1485
+ "marketing",
1486
+ "advertising",
1487
+ "ads",
1488
+ "promo",
1489
+ "promotions",
1490
+ "partners",
1491
+ "partnership",
1492
+ "partnerships",
1493
+ "affiliate",
1494
+ "affiliates",
1495
+ "leads",
1496
+ "enquiry",
1497
+ "enquiries",
1498
+ "inquiry",
1499
+ "inquiries",
1500
+ // General Contact
1501
+ "info",
1502
+ "information",
1503
+ "contact",
1504
+ "contactus",
1505
+ "contact-us",
1506
+ "hello",
1507
+ "hi",
1508
+ "hey",
1509
+ "mail",
1510
+ "email",
1511
+ "office",
1512
+ "general",
1513
+ "reception",
1514
+ // Human Resources
1515
+ "hr",
1516
+ "humanresources",
1517
+ "human-resources",
1518
+ "jobs",
1519
+ "careers",
1520
+ "career",
1521
+ "recruitment",
1522
+ "recruiting",
1523
+ "talent",
1524
+ "hiring",
1525
+ "resume",
1526
+ "resumes",
1527
+ "cv",
1528
+ "employment",
1529
+ // Finance and Legal
1530
+ "billing",
1531
+ "finance",
1532
+ "accounting",
1533
+ "accounts",
1534
+ "payroll",
1535
+ "invoices",
1536
+ "invoice",
1537
+ "payments",
1538
+ "payment",
1539
+ "legal",
1540
+ "compliance",
1541
+ "privacy",
1542
+ "gdpr",
1543
+ // Media and PR
1544
+ "press",
1545
+ "media",
1546
+ "pr",
1547
+ "publicrelations",
1548
+ "public-relations",
1549
+ "news",
1550
+ "newsroom",
1551
+ "communications",
1552
+ "comms",
1553
+ // Security
1554
+ "security",
1555
+ "abuse",
1556
+ "spam",
1557
+ "phishing",
1558
+ "fraud",
1559
+ "noc",
1560
+ "cert",
1561
+ // Operations
1562
+ "operations",
1563
+ "ops",
1564
+ "devops",
1565
+ "engineering",
1566
+ "dev",
1567
+ "development",
1568
+ "product",
1569
+ "feedback",
1570
+ // Team/Group addresses
1571
+ "team",
1572
+ "staff",
1573
+ "all",
1574
+ "everyone",
1575
+ "group",
1576
+ "department",
1577
+ "board",
1578
+ "management",
1579
+ "exec",
1580
+ "executive",
1581
+ "executives",
1582
+ // E-commerce
1583
+ "orders",
1584
+ "order",
1585
+ "shipping",
1586
+ "returns",
1587
+ "refunds",
1588
+ "shop",
1589
+ "store",
1590
+ "buy",
1591
+ "purchase",
1592
+ "checkout",
1593
+ // Automated/System
1594
+ "noreply",
1595
+ "no-reply",
1596
+ "donotreply",
1597
+ "do-not-reply",
1598
+ "mailer-daemon",
1599
+ "mailerdaemon",
1600
+ "bounce",
1601
+ "bounces",
1602
+ "auto",
1603
+ "autoresponder",
1604
+ "notifications",
1605
+ "notification",
1606
+ "alerts",
1607
+ "alert",
1608
+ "updates",
1609
+ "newsletter",
1610
+ "newsletters",
1611
+ "subscribe",
1612
+ "unsubscribe",
1613
+ // Miscellaneous
1614
+ "ftp",
1615
+ "www",
1616
+ "web",
1617
+ "api",
1618
+ "test",
1619
+ "testing",
1620
+ "demo",
1621
+ "sample",
1622
+ "example"
1623
+ ]);
1624
+ function isRolePrefix(prefix) {
1625
+ return rolePrefixes.has(prefix.toLowerCase());
1626
+ }
1627
+
1628
+ // src/data/free-providers.ts
1629
+ var freeProviders = /* @__PURE__ */ new Set([
1630
+ // Google
1631
+ "gmail.com",
1632
+ "googlemail.com",
1633
+ // Microsoft
1634
+ "outlook.com",
1635
+ "outlook.co.uk",
1636
+ "outlook.com.br",
1637
+ "outlook.com.au",
1638
+ "outlook.de",
1639
+ "outlook.fr",
1640
+ "outlook.it",
1641
+ "outlook.es",
1642
+ "outlook.jp",
1643
+ "hotmail.com",
1644
+ "hotmail.co.uk",
1645
+ "hotmail.com.br",
1646
+ "hotmail.com.au",
1647
+ "hotmail.de",
1648
+ "hotmail.fr",
1649
+ "hotmail.it",
1650
+ "hotmail.es",
1651
+ "hotmail.co.jp",
1652
+ "live.com",
1653
+ "live.co.uk",
1654
+ "live.com.au",
1655
+ "live.de",
1656
+ "live.fr",
1657
+ "live.it",
1658
+ "live.nl",
1659
+ "live.se",
1660
+ "msn.com",
1661
+ // Yahoo
1662
+ "yahoo.com",
1663
+ "yahoo.co.uk",
1664
+ "yahoo.com.br",
1665
+ "yahoo.com.au",
1666
+ "yahoo.de",
1667
+ "yahoo.fr",
1668
+ "yahoo.it",
1669
+ "yahoo.es",
1670
+ "yahoo.co.jp",
1671
+ "yahoo.co.in",
1672
+ "yahoo.ca",
1673
+ "yahoo.com.mx",
1674
+ "yahoo.com.ar",
1675
+ "yahoo.com.sg",
1676
+ "yahoo.co.id",
1677
+ "yahoo.com.ph",
1678
+ "yahoo.com.tw",
1679
+ "yahoo.com.hk",
1680
+ "yahoo.ie",
1681
+ "yahoo.co.nz",
1682
+ "yahoo.com.vn",
1683
+ "ymail.com",
1684
+ "rocketmail.com",
1685
+ // Apple
1686
+ "icloud.com",
1687
+ "me.com",
1688
+ "mac.com",
1689
+ // AOL
1690
+ "aol.com",
1691
+ "aol.co.uk",
1692
+ "aol.de",
1693
+ "aol.fr",
1694
+ "aim.com",
1695
+ // Proton
1696
+ "protonmail.com",
1697
+ "protonmail.ch",
1698
+ "proton.me",
1699
+ "pm.me",
1700
+ // Zoho
1701
+ "zoho.com",
1702
+ "zohomail.com",
1703
+ "zohomail.in",
1704
+ "zohomail.eu",
1705
+ // Mail.com
1706
+ "mail.com",
1707
+ "email.com",
1708
+ "usa.com",
1709
+ "myself.com",
1710
+ "consultant.com",
1711
+ "post.com",
1712
+ "europe.com",
1713
+ "asia.com",
1714
+ "iname.com",
1715
+ "writeme.com",
1716
+ "dr.com",
1717
+ "cheerful.com",
1718
+ "accountant.com",
1719
+ "techie.com",
1720
+ "engineer.com",
1721
+ "activist.com",
1722
+ "contractor.com",
1723
+ "artlover.com",
1724
+ // GMX
1725
+ "gmx.com",
1726
+ "gmx.net",
1727
+ "gmx.de",
1728
+ "gmx.at",
1729
+ "gmx.ch",
1730
+ "gmx.fr",
1731
+ "gmx.co.uk",
1732
+ "gmx.us",
1733
+ // Tutanota/Tuta
1734
+ "tutanota.com",
1735
+ "tutanota.de",
1736
+ "tutamail.com",
1737
+ "tuta.io",
1738
+ "keemail.me",
1739
+ // Fastmail
1740
+ "fastmail.com",
1741
+ "fastmail.fm",
1742
+ // Mailfence
1743
+ "mailfence.com",
1744
+ // Hushmail
1745
+ "hushmail.com",
1746
+ "hush.com",
1747
+ "hush.ai",
1748
+ "mac.hush.com",
1749
+ // Runbox
1750
+ "runbox.com",
1751
+ // Posteo
1752
+ "posteo.de",
1753
+ "posteo.net",
1754
+ // Yandex
1755
+ "yandex.com",
1756
+ "yandex.ru",
1757
+ "yandex.ua",
1758
+ "yandex.by",
1759
+ "yandex.kz",
1760
+ "ya.ru",
1761
+ // Mail.ru
1762
+ "mail.ru",
1763
+ "inbox.ru",
1764
+ "list.ru",
1765
+ "bk.ru",
1766
+ // Chinese providers
1767
+ "qq.com",
1768
+ "163.com",
1769
+ "126.com",
1770
+ "sina.com",
1771
+ "sina.cn",
1772
+ "sohu.com",
1773
+ "aliyun.com",
1774
+ "foxmail.com",
1775
+ // Indian providers
1776
+ "rediffmail.com",
1777
+ "rediff.com",
1778
+ // European providers
1779
+ "web.de",
1780
+ "t-online.de",
1781
+ "freenet.de",
1782
+ "arcor.de",
1783
+ "orange.fr",
1784
+ "laposte.net",
1785
+ "free.fr",
1786
+ "sfr.fr",
1787
+ "wanadoo.fr",
1788
+ "libero.it",
1789
+ "virgilio.it",
1790
+ "tin.it",
1791
+ "alice.it",
1792
+ "tiscali.it",
1793
+ "tiscali.co.uk",
1794
+ "terra.com.br",
1795
+ "uol.com.br",
1796
+ "bol.com.br",
1797
+ "ig.com.br",
1798
+ "wp.pl",
1799
+ "onet.pl",
1800
+ "interia.pl",
1801
+ "o2.pl",
1802
+ "seznam.cz",
1803
+ "centrum.cz",
1804
+ "azet.sk",
1805
+ // Misc
1806
+ "inbox.com",
1807
+ "lycos.com",
1808
+ "naver.com",
1809
+ "daum.net",
1810
+ "hanmail.net",
1811
+ "comcast.net",
1812
+ "verizon.net",
1813
+ "att.net",
1814
+ "sbcglobal.net",
1815
+ "bellsouth.net",
1816
+ "charter.net",
1817
+ "cox.net",
1818
+ "earthlink.net",
1819
+ "juno.com",
1820
+ "netzero.net",
1821
+ "optonline.net",
1822
+ "btinternet.com",
1823
+ "talktalk.net",
1824
+ "virginmedia.com",
1825
+ "sky.com",
1826
+ "ntlworld.com",
1827
+ "shaw.ca",
1828
+ "rogers.com",
1829
+ "sympatico.ca",
1830
+ "telus.net",
1831
+ "bigpond.com",
1832
+ "bigpond.net.au",
1833
+ "optusnet.com.au",
1834
+ "ozemail.com.au"
1835
+ ]);
1836
+ function isFreeProvider(domain) {
1837
+ return freeProviders.has(domain.toLowerCase());
1838
+ }
1839
+
1840
+ // src/validators/misc.ts
1841
+ function checkDisposable(domain) {
1842
+ return isDisposableDomain(domain.toLowerCase());
1843
+ }
1844
+ function checkRoleAccount(username) {
1845
+ const cleanUsername = username.split("+")[0];
1846
+ return isRolePrefix(cleanUsername.toLowerCase());
1847
+ }
1848
+ function checkFreeProvider(domain) {
1849
+ return isFreeProvider(domain.toLowerCase());
1850
+ }
1851
+ function md5(str) {
1852
+ return import_crypto.default.createHash("md5").update(str.trim().toLowerCase()).digest("hex");
1853
+ }
1854
+ function checkGravatar(email) {
1855
+ return new Promise((resolve) => {
1856
+ const hash = md5(email);
1857
+ const url = `https://www.gravatar.com/avatar/${hash}?d=404`;
1858
+ const req = import_https.default.get(url, { timeout: 5e3 }, (res) => {
1859
+ if (res.statusCode === 200) {
1860
+ resolve(`https://www.gravatar.com/avatar/${hash}`);
1861
+ } else {
1862
+ resolve(null);
1863
+ }
1864
+ res.resume();
1865
+ });
1866
+ req.on("error", () => {
1867
+ resolve(null);
1868
+ });
1869
+ req.on("timeout", () => {
1870
+ req.destroy();
1871
+ resolve(null);
1872
+ });
1873
+ });
1874
+ }
1875
+ async function checkMisc(email, options = {}) {
1876
+ const atIndex = email.indexOf("@");
1877
+ if (atIndex === -1) {
1878
+ return {
1879
+ isDisposable: false,
1880
+ isRoleAccount: false,
1881
+ isFreeProvider: false,
1882
+ gravatarUrl: null
1883
+ };
1884
+ }
1885
+ const username = email.slice(0, atIndex);
1886
+ const domain = email.slice(atIndex + 1);
1887
+ const isDisposable = options.checkDisposable !== false ? checkDisposable(domain) : false;
1888
+ const isRoleAccount = options.checkRoleAccount !== false ? checkRoleAccount(username) : false;
1889
+ const isFree = options.checkFreeProvider !== false ? checkFreeProvider(domain) : false;
1890
+ let gravatarUrl = null;
1891
+ if (options.checkGravatar === true) {
1892
+ gravatarUrl = await checkGravatar(email);
1893
+ }
1894
+ return {
1895
+ isDisposable,
1896
+ isRoleAccount,
1897
+ isFreeProvider: isFree,
1898
+ gravatarUrl
1899
+ };
1900
+ }
1901
+
1902
+ // src/index.ts
1903
+ var defaultOptions = {
1904
+ smtpTimeout: 1e4,
1905
+ verifySmtp: true,
1906
+ checkDisposable: true,
1907
+ checkRoleAccount: true,
1908
+ checkFreeProvider: true,
1909
+ checkGravatar: false,
1910
+ heloHost: "",
1911
+ senderAddress: "",
1912
+ dnsCacheTtl: 3e5,
1913
+ useDnsCache: true,
1914
+ detectCatchAll: true,
1915
+ proxy: void 0
1916
+ };
1917
+ function determineReachability(syntaxValid, mxValid, smtpResult, options) {
1918
+ if (!syntaxValid) {
1919
+ return "invalid";
1920
+ }
1921
+ if (!mxValid) {
1922
+ return "invalid";
1923
+ }
1924
+ if (options.verifySmtp === false) {
1925
+ return "risky";
1926
+ }
1927
+ if (!smtpResult) {
1928
+ return "unknown";
1929
+ }
1930
+ if (smtpResult.isCatchAll) {
1931
+ return "risky";
1932
+ }
1933
+ if (smtpResult.isDeliverable) {
1934
+ return "safe";
1935
+ }
1936
+ if (!smtpResult.canConnectSmtp) {
1937
+ return "unknown";
1938
+ }
1939
+ if (smtpResult.error?.type === SmtpErrorType.MAILBOX_NOT_FOUND) {
1940
+ return "invalid";
1941
+ }
1942
+ if (smtpResult.error?.type === SmtpErrorType.GREYLISTED) {
1943
+ return "risky";
1944
+ }
1945
+ return "risky";
1946
+ }
1947
+ async function validate(email, options = {}) {
1948
+ const opts = { ...defaultOptions, ...options };
1949
+ if (opts.useDnsCache && opts.dnsCacheTtl) {
1950
+ globalDnsCache.setTtl(opts.dnsCacheTtl);
1951
+ }
1952
+ const syntaxResult = validateSyntax(email);
1953
+ if (!syntaxResult.isValidSyntax) {
1954
+ return {
1955
+ input: email,
1956
+ isReachable: "invalid",
1957
+ syntax: syntaxResult,
1958
+ mx: {
1959
+ acceptsMail: false,
1960
+ records: []
1961
+ },
1962
+ smtp: {
1963
+ canConnectSmtp: false,
1964
+ isDeliverable: false,
1965
+ isCatchAll: false,
1966
+ error: null
1967
+ },
1968
+ misc: {
1969
+ isDisposable: false,
1970
+ isRoleAccount: false,
1971
+ isFreeProvider: false,
1972
+ gravatarUrl: null
1973
+ }
1974
+ };
1975
+ }
1976
+ const mxResult = await verifyMx(syntaxResult.domain, opts);
1977
+ if (!mxResult.acceptsMail) {
1978
+ const miscResult2 = await checkMisc(email, opts);
1979
+ return {
1980
+ input: email,
1981
+ isReachable: "invalid",
1982
+ syntax: syntaxResult,
1983
+ mx: mxResult,
1984
+ smtp: {
1985
+ canConnectSmtp: false,
1986
+ isDeliverable: false,
1987
+ isCatchAll: false,
1988
+ error: {
1989
+ type: "NoMxRecords",
1990
+ message: "Domain does not accept mail"
1991
+ }
1992
+ },
1993
+ misc: miscResult2
1994
+ };
1995
+ }
1996
+ let smtpResult = {
1997
+ canConnectSmtp: false,
1998
+ isDeliverable: false,
1999
+ isCatchAll: false,
2000
+ error: null
2001
+ };
2002
+ if (opts.verifySmtp) {
2003
+ smtpResult = await verifySmtpWithFallback(email, mxResult.records, opts);
2004
+ }
2005
+ const miscResult = await checkMisc(email, opts);
2006
+ const isReachable = determineReachability(
2007
+ syntaxResult.isValidSyntax,
2008
+ mxResult.acceptsMail,
2009
+ smtpResult,
2010
+ opts
2011
+ );
2012
+ return {
2013
+ input: email,
2014
+ isReachable,
2015
+ syntax: syntaxResult,
2016
+ mx: mxResult,
2017
+ smtp: smtpResult,
2018
+ misc: miscResult
2019
+ };
2020
+ }
2021
+ async function validateBulk(emails, options = {}) {
2022
+ const { concurrency = 5, delayBetween = 0, onProgress, ...validateOptions } = options;
2023
+ const results = [];
2024
+ let completed = 0;
2025
+ for (let i = 0; i < emails.length; i += concurrency) {
2026
+ const batch = emails.slice(i, i + concurrency);
2027
+ const batchPromises = batch.map(async (email) => {
2028
+ const result = await validate(email, validateOptions);
2029
+ completed++;
2030
+ if (onProgress) {
2031
+ onProgress(completed, emails.length, result);
2032
+ }
2033
+ return result;
2034
+ });
2035
+ const batchResults = await Promise.all(batchPromises);
2036
+ results.push(...batchResults);
2037
+ if (delayBetween > 0 && i + concurrency < emails.length) {
2038
+ await new Promise((resolve) => setTimeout(resolve, delayBetween));
2039
+ }
2040
+ }
2041
+ return results;
2042
+ }
2043
+ async function validateQuick(email) {
2044
+ return validate(email, { verifySmtp: false });
2045
+ }
2046
+ function clearDnsCache() {
2047
+ globalDnsCache.clear();
2048
+ }
2049
+ function getDnsCacheSize() {
2050
+ return globalDnsCache.size;
2051
+ }
2052
+ var index_default = {
2053
+ validate,
2054
+ validateBulk,
2055
+ validateQuick,
2056
+ clearDnsCache,
2057
+ getDnsCacheSize,
2058
+ // Utilities
2059
+ normalizeEmail,
2060
+ extractParts,
2061
+ getSuggestion,
2062
+ getEmailSuggestion,
2063
+ // Individual validators
2064
+ validateSyntax,
2065
+ isValidSyntax,
2066
+ verifyMx,
2067
+ hasMxRecords,
2068
+ getMxRecords,
2069
+ checkMisc,
2070
+ checkDisposable,
2071
+ checkRoleAccount,
2072
+ checkFreeProvider
2073
+ };
2074
+ // Annotate the CommonJS export names for ESM import in node:
2075
+ 0 && (module.exports = {
2076
+ DnsCache,
2077
+ SmtpErrorType,
2078
+ checkDisposable,
2079
+ checkFreeProvider,
2080
+ checkMisc,
2081
+ checkRoleAccount,
2082
+ clearDnsCache,
2083
+ disposableDomains,
2084
+ extractParts,
2085
+ freeProviders,
2086
+ getDnsCacheSize,
2087
+ getEmailSuggestion,
2088
+ getMxRecords,
2089
+ getSuggestion,
2090
+ globalDnsCache,
2091
+ hasMxRecords,
2092
+ isDisposableDomain,
2093
+ isFreeProvider,
2094
+ isRolePrefix,
2095
+ isValidSyntax,
2096
+ normalizeEmail,
2097
+ rolePrefixes,
2098
+ validate,
2099
+ validateBulk,
2100
+ validateQuick,
2101
+ validateSyntax,
2102
+ verifyMx,
2103
+ verifySmtp
2104
+ });
2105
+ //# sourceMappingURL=index.js.map