@emailcheck/email-validator-js 2.13.1-beta.1 → 2.13.1-beta.3

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 CHANGED
@@ -129,17 +129,16 @@ const result = await verifyEmail({
129
129
  timeout: 3000
130
130
  });
131
131
 
132
- console.log(result.valid); // Overall validity
133
- console.log(result.format.valid); // true
134
- console.log(result.domain.valid); // true or false
135
- console.log(result.smtp.valid); // true or false
132
+ console.log(result.validFormat); // true
133
+ console.log(result.validMx); // true or false
134
+ console.log(result.validSmtp); // true or false
136
135
  ```
137
136
 
138
137
  ## API Reference
139
138
 
140
139
  ### Core Functions
141
140
 
142
- #### `verifyEmail(params: IVerifyEmailParams): Promise<DetailedVerificationResult>`
141
+ #### `verifyEmail(params: IVerifyEmailParams): Promise<VerificationResult>`
143
142
 
144
143
  Comprehensive email verification with detailed results and error codes.
145
144
 
@@ -161,33 +160,26 @@ Comprehensive email verification with detailed results and error codes.
161
160
  - `checkDomainAge` (boolean): Check domain age (default: false)
162
161
  - `checkDomainRegistration` (boolean): Check domain registration status (default: false)
163
162
  - `whoisTimeout` (number): WHOIS lookup timeout (default: 5000)
163
+ - `debug` (boolean): Enable debug logging including WHOIS lookups (default: false)
164
164
  - `cache` (ICache): Optional custom cache instance
165
165
 
166
166
  **Returns:**
167
167
  ```typescript
168
168
  {
169
- valid: boolean;
170
169
  email: string;
171
- format: {
172
- valid: boolean;
173
- error?: VerificationErrorCode;
174
- };
175
- domain: {
176
- valid: boolean | null;
177
- mxRecords?: string[];
178
- error?: VerificationErrorCode;
179
- };
180
- smtp: {
181
- valid: boolean | null;
182
- error?: VerificationErrorCode;
183
- };
184
- disposable: boolean;
185
- freeProvider: boolean;
170
+ validFormat: boolean;
171
+ validMx: boolean | null;
172
+ validSmtp: boolean | null;
173
+ isDisposable: boolean;
174
+ isFree: boolean;
186
175
  detectedName?: DetectedName | null;
176
+ domainAge?: DomainAgeInfo | null;
177
+ domainRegistration?: DomainRegistrationInfo | null;
187
178
  domainSuggestion?: DomainSuggestion | null;
188
179
  metadata?: {
189
180
  verificationTime: number;
190
181
  cached: boolean;
182
+ error?: VerificationErrorCode;
191
183
  };
192
184
  }
193
185
  ```
@@ -199,7 +191,6 @@ Verify multiple emails in parallel with concurrency control.
199
191
  **Parameters:**
200
192
  - `emailAddresses` (string[], required): Array of emails to verify
201
193
  - `concurrency` (number): Parallel processing limit (default: 5)
202
- - `detailed` (boolean): Return detailed results (default: false)
203
194
  - `detectName` (boolean): Detect names from email addresses
204
195
  - `suggestDomain` (boolean): Enable domain typo suggestions
205
196
  - Other parameters from `verifyEmail`
@@ -207,7 +198,7 @@ Verify multiple emails in parallel with concurrency control.
207
198
  **Returns:**
208
199
  ```typescript
209
200
  {
210
- results: Map<string, DetailedVerificationResult | IVerifyEmailResult>;
201
+ results: Map<string, VerificationResult>;
211
202
  summary: {
212
203
  total: number;
213
204
  valid: number;
@@ -395,22 +386,36 @@ const status = await getDomainRegistrationStatus('mydomain.com');
395
386
 
396
387
  ### Utility Functions
397
388
 
398
- #### `isDisposableEmail(emailOrDomain: string): boolean`
389
+ #### `isDisposableEmail(emailOrDomain: string, cache?: ICache, options?: { skipMxCheck?: boolean; skipDomain?: boolean }): boolean`
399
390
  Check if email uses a disposable provider.
400
391
 
401
392
  ```typescript
393
+ // Basic usage
402
394
  isDisposableEmail('user@tempmail.com'); // true
403
395
  isDisposableEmail('tempmail.com'); // true
404
396
  isDisposableEmail('gmail.com'); // false
397
+
398
+ // With options
399
+ isDisposableEmail('user@tempmail.com', null, {
400
+ skipMxCheck: true, // Skip MX record validation
401
+ skipDomain: true // Skip domain validation
402
+ }); // true
405
403
  ```
406
404
 
407
- #### `isFreeEmail(emailOrDomain: string): boolean`
405
+ #### `isFreeEmail(emailOrDomain: string, cache?: ICache, options?: { skipMxCheck?: boolean; skipDomain?: boolean }): boolean`
408
406
  Check if email uses a free provider.
409
407
 
410
408
  ```typescript
409
+ // Basic usage
411
410
  isFreeEmail('user@gmail.com'); // true
412
411
  isFreeEmail('yahoo.com'); // true
413
412
  isFreeEmail('corporate.com'); // false
413
+
414
+ // With options
415
+ isFreeEmail('user@gmail.com', null, {
416
+ skipMxCheck: true, // Skip MX record validation
417
+ skipDomain: true // Skip domain validation
418
+ }); // true
414
419
  ```
415
420
 
416
421
  #### `isValidEmail(emailAddress: string): boolean`
@@ -583,10 +588,9 @@ const result = await verifyEmail({
583
588
  verifySmtp: true,
584
589
  timeout: 3000
585
590
  });
586
- console.log(result.valid); // true
587
- console.log(result.format.valid); // true
588
- console.log(result.domain.valid); // true
589
- console.log(result.smtp.valid); // true
591
+ console.log(result.validFormat); // true
592
+ console.log(result.validMx); // true
593
+ console.log(result.validSmtp); // true
590
594
  ```
591
595
 
592
596
  ### Detailed Verification (NEW)
@@ -600,10 +604,11 @@ const result = await verifyEmail({
600
604
  checkDisposable: true,
601
605
  checkFree: true
602
606
  });
603
- // result.valid: true
604
- // result.disposable: false
605
- // result.freeProvider: false
606
- // result.domain.mxRecords: ['mx1.email.com', 'mx2.email.com']
607
+ // result.validFormat: true
608
+ // result.validMx: true
609
+ // result.validSmtp: true
610
+ // result.isDisposable: false
611
+ // result.isFree: false
607
612
  // result.metadata.verificationTime: 125
608
613
  ```
609
614
 
@@ -617,7 +622,8 @@ const result = await verifyEmailBatch({
617
622
  emailAddresses: emails,
618
623
  concurrency: 5,
619
624
  verifyMx: true,
620
- detailed: true
625
+ checkDisposable: true,
626
+ checkFree: true
621
627
  });
622
628
  // result.summary.valid: 2
623
629
  // result.summary.invalid: 1
@@ -697,16 +703,15 @@ const result = await verifyEmail({
697
703
  verifyMx: true,
698
704
  verifySmtp: true
699
705
  });
700
- // result.valid: false (domain or SMTP failed)
701
- // result.format.valid: true
702
- // result.domain.valid: false
703
- // result.smtp.valid: null (couldn't be performed)
706
+ // result.validFormat: true (format is valid)
707
+ // result.validMx: false (no MX records)
708
+ // result.validSmtp: null (couldn't be performed)
704
709
  ```
705
710
 
706
711
  ### Using Detailed Verification for Better Insights
707
712
 
708
713
  ```typescript
709
- const detailed = await verifyEmail({
714
+ const result = await verifyEmail({
710
715
  emailAddress: 'user@suspicious-domain.com',
711
716
  verifyMx: true,
712
717
  verifySmtp: true,
@@ -714,8 +719,14 @@ const detailed = await verifyEmail({
714
719
  checkFree: true
715
720
  });
716
721
 
717
- if (!detailed.valid) {
718
- switch (detailed.domain.error) {
722
+ if (!result.validFormat) {
723
+ console.log('Invalid email format');
724
+ } else if (!result.validMx) {
725
+ console.log('Invalid domain - no MX records');
726
+ } else if (result.isDisposable) {
727
+ console.log('Disposable email detected');
728
+ } else if (result.metadata?.error) {
729
+ switch (result.metadata.error) {
719
730
  case VerificationErrorCode.DISPOSABLE_EMAIL:
720
731
  console.log('Rejected: Disposable email');
721
732
  break;
@@ -755,7 +766,7 @@ console.log(`Time: ${batch.summary.processingTime}ms`);
755
766
  // Filter out invalid emails
756
767
  const validEmails = [];
757
768
  for (const [email, result] of batch.results) {
758
- if (result.valid) {
769
+ if (result.validFormat) {
759
770
  validEmails.push(email);
760
771
  }
761
772
  }
@@ -1046,7 +1057,7 @@ process.on('SIGTERM', async () => {
1046
1057
  });
1047
1058
  ```
1048
1059
 
1049
- **Note:** Yahoo, Hotmail, and some providers always return `result.smtp.valid: true` as they don't allow mailbox verification.
1060
+ **Note:** Yahoo, Hotmail, and some providers always return `result.validSmtp: true` as they don't allow mailbox verification.
1050
1061
 
1051
1062
  ## 🌐 Serverless Deployment
1052
1063
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ICache } from './cache-interface';
2
- import { type DetailedVerificationResult, type IVerifyEmailParams } from './types';
2
+ import { type IVerifyEmailParams, type VerificationResult } from './types';
3
3
  export { verifyEmailBatch } from './batch';
4
4
  export { clearAllCaches } from './cache';
5
5
  export { COMMON_EMAIL_DOMAINS, defaultDomainSuggestionMethod, getDomainSimilarity, isCommonDomain, suggestDomain, suggestEmailDomain, } from './domain-suggester';
@@ -13,4 +13,4 @@ export declare const domainPorts: Record<string, number>;
13
13
  /**
14
14
  * Verify email address
15
15
  */
16
- export declare function verifyEmail(params: IVerifyEmailParams): Promise<DetailedVerificationResult>;
16
+ export declare function verifyEmail(params: IVerifyEmailParams): Promise<VerificationResult>;
package/dist/index.esm.js CHANGED
@@ -1732,37 +1732,50 @@ const WHOIS_SERVERS = {
1732
1732
  ar: "whois.nic.ar",
1733
1733
  cl: "whois.nic.cl"
1734
1734
  };
1735
- function queryWhoisServer(domain, server, timeout = 5e3) {
1735
+ function queryWhoisServer(domain, server, timeout = 5e3, debug = false) {
1736
+ const log = debug ? console.debug : (..._args) => {
1737
+ };
1736
1738
  return new Promise((resolve, reject) => {
1737
1739
  const client = new net.Socket();
1738
1740
  let data = "";
1741
+ log(`[whois] querying ${server} for domain ${domain}`);
1739
1742
  const timer = setTimeout(() => {
1743
+ log(`[whois] timeout after ${timeout}ms for ${domain} at ${server}`);
1740
1744
  client.destroy();
1741
1745
  reject(new Error("WHOIS query timeout"));
1742
1746
  }, timeout);
1743
1747
  client.connect(43, server, () => {
1748
+ log(`[whois] connected to ${server}, sending query for ${domain}`);
1744
1749
  client.write(`${domain}\r
1745
1750
  `);
1746
1751
  });
1747
1752
  client.on("data", (chunk) => {
1748
- data += chunk.toString();
1753
+ const chunkStr = chunk.toString();
1754
+ data += chunkStr;
1755
+ log(`[whois] received ${chunkStr.length} bytes from ${server}`);
1749
1756
  });
1750
1757
  client.on("close", () => {
1751
1758
  clearTimeout(timer);
1759
+ log(`[whois] connection closed, received total ${data.length} bytes from ${server}`);
1752
1760
  resolve(data);
1753
1761
  });
1754
1762
  client.on("error", (err) => {
1755
1763
  clearTimeout(timer);
1764
+ log(`[whois] error querying ${server}: ${err.message}`);
1756
1765
  reject(err);
1757
1766
  });
1758
1767
  });
1759
1768
  }
1760
- async function getWhoisData(domain, timeout = 5e3) {
1769
+ async function getWhoisData(domain, timeout = 5e3, debug = false) {
1761
1770
  var _a;
1771
+ const log = debug ? console.debug : (..._args) => {
1772
+ };
1762
1773
  const cacheKey = `whois:${domain}`;
1763
1774
  const cache = whoisCacheStore();
1775
+ log(`[whois] getting WHOIS data for ${domain}`);
1764
1776
  const cached = await cache.get(cacheKey);
1765
1777
  if (cached !== null && cached !== void 0) {
1778
+ log(`[whois] using cached data for ${domain}`);
1766
1779
  return cached;
1767
1780
  }
1768
1781
  try {
@@ -1770,41 +1783,55 @@ async function getWhoisData(domain, timeout = 5e3) {
1770
1783
  if (!tld) {
1771
1784
  throw new Error("Invalid domain");
1772
1785
  }
1786
+ log(`[whois] extracted TLD: ${tld} for domain: ${domain}`);
1773
1787
  const whoisServer = WHOIS_SERVERS[tld];
1774
1788
  if (!whoisServer) {
1789
+ log(`[whois] no specific server for TLD ${tld}, trying IANA`);
1775
1790
  const defaultServer = "whois.iana.org";
1776
- const ianaResponse = await queryWhoisServer(domain, defaultServer, timeout);
1791
+ const ianaResponse = await queryWhoisServer(domain, defaultServer, timeout, debug);
1777
1792
  const referMatch = ianaResponse.match(/refer:\s+(\S+)/i);
1778
1793
  if (referMatch === null || referMatch === void 0 ? void 0 : referMatch[1]) {
1779
1794
  const referredServer = referMatch[1];
1780
- const whoisResponse2 = await queryWhoisServer(domain, referredServer, timeout);
1795
+ log(`[whois] IANA referred to ${referredServer} for ${domain}`);
1796
+ const whoisResponse2 = await queryWhoisServer(domain, referredServer, timeout, debug);
1781
1797
  const whoisData3 = parseWhoisData({ rawData: whoisResponse2, domain });
1782
1798
  await cache.set(cacheKey, whoisData3);
1799
+ log(`[whois] successfully retrieved and cached WHOIS data from referred server for ${domain}`);
1783
1800
  return whoisData3;
1784
1801
  }
1785
1802
  const whoisData2 = parseWhoisData({ rawData: ianaResponse, domain });
1786
1803
  await cache.set(cacheKey, whoisData2);
1804
+ log(`[whois] successfully retrieved and cached WHOIS data from IANA for ${domain}`);
1787
1805
  return whoisData2;
1788
1806
  }
1789
- const whoisResponse = await queryWhoisServer(domain, whoisServer, timeout);
1807
+ log(`[whois] using WHOIS server ${whoisServer} for TLD ${tld}`);
1808
+ const whoisResponse = await queryWhoisServer(domain, whoisServer, timeout, debug);
1790
1809
  const whoisData = parseWhoisData({ rawData: whoisResponse, domain });
1791
1810
  await cache.set(cacheKey, whoisData);
1811
+ log(`[whois] successfully retrieved and cached WHOIS data for ${domain}`);
1792
1812
  return whoisData;
1793
1813
  } catch (_error) {
1814
+ log(`[whois] failed to get WHOIS data for ${domain}: ${_error instanceof Error ? _error.message : "Unknown error"}`);
1794
1815
  return null;
1795
1816
  }
1796
1817
  }
1797
- async function getDomainAge(domain, timeout = 5e3) {
1818
+ async function getDomainAge(domain, timeout = 5e3, debug = false) {
1819
+ const log = debug ? console.debug : (..._args) => {
1820
+ };
1798
1821
  try {
1799
1822
  const cleanDomain = domain.replace(/^https?:\/\//, "").split("/")[0].split("@").pop();
1800
1823
  if (!cleanDomain) {
1824
+ log(`[whois] invalid domain format: ${domain}`);
1801
1825
  return null;
1802
1826
  }
1827
+ log(`[whois] checking domain age for ${cleanDomain}`);
1803
1828
  if (!isValid(cleanDomain)) {
1829
+ log(`[whois] domain validation failed: ${cleanDomain}`);
1804
1830
  return null;
1805
1831
  }
1806
- const whoisData = await getWhoisData(cleanDomain, timeout);
1832
+ const whoisData = await getWhoisData(cleanDomain, timeout, debug);
1807
1833
  if (!whoisData || !whoisData.creationDate) {
1834
+ log(`[whois] no creation date found for ${cleanDomain}`);
1808
1835
  return null;
1809
1836
  }
1810
1837
  const now = /* @__PURE__ */ new Date();
@@ -1812,6 +1839,7 @@ async function getDomainAge(domain, timeout = 5e3) {
1812
1839
  const ageInMilliseconds = now.getTime() - creationDate.getTime();
1813
1840
  const ageInDays = Math.floor(ageInMilliseconds / (1e3 * 60 * 60 * 24));
1814
1841
  const ageInYears = ageInDays / 365.25;
1842
+ log(`[whois] calculated age for ${cleanDomain}: ${ageInDays} days (${ageInYears.toFixed(2)} years)`);
1815
1843
  return {
1816
1844
  domain: cleanDomain,
1817
1845
  creationDate,
@@ -1821,20 +1849,27 @@ async function getDomainAge(domain, timeout = 5e3) {
1821
1849
  updatedDate: whoisData.updatedDate ? new Date(whoisData.updatedDate) : null
1822
1850
  };
1823
1851
  } catch (_error) {
1852
+ log(`[whois] error getting domain age for ${domain}: ${_error instanceof Error ? _error.message : "Unknown error"}`);
1824
1853
  return null;
1825
1854
  }
1826
1855
  }
1827
- async function getDomainRegistrationStatus(domain, timeout = 5e3) {
1856
+ async function getDomainRegistrationStatus(domain, timeout = 5e3, debug = false) {
1857
+ const log = debug ? console.debug : (..._args) => {
1858
+ };
1828
1859
  try {
1829
1860
  const cleanDomain = domain.replace(/^https?:\/\//, "").split("/")[0].split("@").pop();
1830
1861
  if (!cleanDomain) {
1862
+ log(`[whois] invalid domain format: ${domain}`);
1831
1863
  return null;
1832
1864
  }
1865
+ log(`[whois] checking domain registration status for ${cleanDomain}`);
1833
1866
  if (!isValid(cleanDomain)) {
1867
+ log(`[whois] domain validation failed: ${cleanDomain}`);
1834
1868
  return null;
1835
1869
  }
1836
- const whoisData = await getWhoisData(cleanDomain, timeout);
1870
+ const whoisData = await getWhoisData(cleanDomain, timeout, debug);
1837
1871
  if (!whoisData || whoisData.isAvailable) {
1872
+ log(`[whois] domain ${cleanDomain} is available or not registered`);
1838
1873
  return {
1839
1874
  domain: cleanDomain,
1840
1875
  isRegistered: false,
@@ -1862,6 +1897,7 @@ async function getDomainRegistrationStatus(domain, timeout = 5e3) {
1862
1897
  if (!isExpired) {
1863
1898
  daysUntilExpiration = Math.floor((expirationTime - currentTime) / (1e3 * 60 * 60 * 24));
1864
1899
  }
1900
+ log(`[whois] domain ${cleanDomain} expires in ${daysUntilExpiration} days`);
1865
1901
  }
1866
1902
  const statusList = whoisData.status || [];
1867
1903
  const formattedStatusList = statusList.map((s) => {
@@ -1870,6 +1906,7 @@ async function getDomainRegistrationStatus(domain, timeout = 5e3) {
1870
1906
  });
1871
1907
  const isPendingDelete = formattedStatusList.some((s) => s.toLowerCase().includes("pendingdelete") || s.toLowerCase().includes("redemption"));
1872
1908
  const isLocked = formattedStatusList.some((s) => s.toLowerCase().includes("clienttransferprohibited") || s.toLowerCase().includes("servertransferprohibited"));
1909
+ log(`[whois] domain ${cleanDomain} - registered: ${isRegistered}, expired: ${isExpired}, locked: ${isLocked}, pending delete: ${isPendingDelete}`);
1873
1910
  return {
1874
1911
  domain: cleanDomain,
1875
1912
  isRegistered,
@@ -1884,12 +1921,13 @@ async function getDomainRegistrationStatus(domain, timeout = 5e3) {
1884
1921
  isLocked
1885
1922
  };
1886
1923
  } catch (_error) {
1924
+ log(`[whois] error getting domain registration status for ${domain}: ${_error instanceof Error ? _error.message : "Unknown error"}`);
1887
1925
  return null;
1888
1926
  }
1889
1927
  }
1890
1928
 
1891
1929
  async function verifyEmailBatch(params) {
1892
- const { emailAddresses, concurrency = 5, timeout = 4e3, verifyMx = true, verifySmtp = false, checkDisposable = true, checkFree = true, detectName = false, nameDetectionMethod, suggestDomain = false, domainSuggestionMethod, commonDomains, cache } = params;
1930
+ const { emailAddresses, concurrency = 5, timeout = 4e3, verifyMx = true, verifySmtp = false, checkDisposable = true, checkFree = true, detectName = false, nameDetectionMethod, suggestDomain = false, domainSuggestionMethod, commonDomains, skipMxForDisposable = false, skipDomainWhoisForDisposable = false, cache } = params;
1893
1931
  const startTime = Date.now();
1894
1932
  const results = /* @__PURE__ */ new Map();
1895
1933
  const batches = [];
@@ -1914,9 +1952,11 @@ async function verifyEmailBatch(params) {
1914
1952
  suggestDomain,
1915
1953
  domainSuggestionMethod,
1916
1954
  commonDomains,
1955
+ skipMxForDisposable,
1956
+ skipDomainWhoisForDisposable,
1917
1957
  cache
1918
1958
  });
1919
- if (result.valid) {
1959
+ if (result.validFormat) {
1920
1960
  totalValid++;
1921
1961
  } else {
1922
1962
  totalInvalid++;
@@ -1926,7 +1966,7 @@ async function verifyEmailBatch(params) {
1926
1966
  totalErrors++;
1927
1967
  return {
1928
1968
  email,
1929
- result: createErrorDetailedResult(email)
1969
+ result: createErrorResult(email)
1930
1970
  };
1931
1971
  }
1932
1972
  });
@@ -1946,18 +1986,18 @@ async function verifyEmailBatch(params) {
1946
1986
  }
1947
1987
  };
1948
1988
  }
1949
- function createErrorDetailedResult(email, _error) {
1989
+ function createErrorResult(email, _error) {
1950
1990
  return {
1951
- valid: false,
1952
1991
  email,
1953
- format: { valid: false },
1954
- domain: { valid: null },
1955
- smtp: { valid: null },
1956
- disposable: false,
1957
- freeProvider: false,
1992
+ validFormat: false,
1993
+ validMx: null,
1994
+ validSmtp: null,
1995
+ isDisposable: false,
1996
+ isFree: false,
1958
1997
  metadata: {
1959
1998
  verificationTime: 0,
1960
- cached: false
1999
+ cached: false,
2000
+ error: VerificationErrorCode.SMTP_CONNECTION_FAILED
1961
2001
  }
1962
2002
  };
1963
2003
  }
@@ -2022,31 +2062,30 @@ const domainPorts = {
2022
2062
  "ovh.net": 465
2023
2063
  };
2024
2064
  async function verifyEmail(params) {
2025
- const { emailAddress, timeout = 4e3, verifyMx = true, verifySmtp = false, debug = false, checkDisposable = true, checkFree = true, detectName: detectName2 = false, nameDetectionMethod, suggestDomain: suggestDomain2 = true, domainSuggestionMethod, commonDomains, checkDomainAge = false, checkDomainRegistration = false, whoisTimeout = 5e3 } = params;
2065
+ const { emailAddress, timeout = 4e3, verifyMx = true, verifySmtp = false, debug = false, checkDisposable = true, checkFree = true, detectName: detectName2 = false, nameDetectionMethod, suggestDomain: suggestDomain2 = true, domainSuggestionMethod, commonDomains, checkDomainAge = false, checkDomainRegistration = false, whoisTimeout = 5e3, skipMxForDisposable = false, skipDomainWhoisForDisposable = false } = params;
2026
2066
  const startTime = Date.now();
2027
2067
  const log = debug ? console.debug : (..._args) => {
2028
2068
  };
2029
2069
  const result = {
2030
- valid: false,
2031
2070
  email: emailAddress,
2032
- format: { valid: false },
2033
- domain: { valid: null },
2034
- smtp: { valid: null },
2035
- disposable: false,
2036
- freeProvider: false,
2071
+ validFormat: false,
2072
+ validMx: null,
2073
+ validSmtp: null,
2074
+ isDisposable: false,
2075
+ isFree: false,
2037
2076
  metadata: {
2038
2077
  verificationTime: 0,
2039
2078
  cached: false
2040
2079
  }
2041
2080
  };
2042
2081
  if (!isValidEmail(emailAddress)) {
2043
- result.format.error = VerificationErrorCode.INVALID_FORMAT;
2044
2082
  if (result.metadata) {
2045
2083
  result.metadata.verificationTime = Date.now() - startTime;
2084
+ result.metadata.error = VerificationErrorCode.INVALID_FORMAT;
2046
2085
  }
2047
2086
  return result;
2048
2087
  }
2049
- result.format.valid = true;
2088
+ result.validFormat = true;
2050
2089
  if (detectName2) {
2051
2090
  result.detectedName = detectNameFromEmail({
2052
2091
  email: emailAddress,
@@ -2056,64 +2095,69 @@ async function verifyEmail(params) {
2056
2095
  if (suggestDomain2) {
2057
2096
  const [, emailDomain] = emailAddress.split("@");
2058
2097
  if (emailDomain) {
2059
- result.domainSuggestion = domainSuggestionMethod ? domainSuggestionMethod(emailDomain) : await suggestEmailDomain(emailAddress, commonDomains);
2098
+ const suggestion = domainSuggestionMethod ? domainSuggestionMethod(emailDomain) : await suggestEmailDomain(emailAddress, commonDomains);
2099
+ if (suggestion) {
2100
+ result.domainSuggestion = suggestion;
2101
+ } else {
2102
+ result.domainSuggestion = null;
2103
+ }
2060
2104
  }
2061
2105
  }
2062
2106
  const [local, domain] = emailAddress.split("@");
2063
2107
  if (!domain || !local) {
2064
- result.format.error = VerificationErrorCode.INVALID_FORMAT;
2065
2108
  if (result.metadata) {
2066
2109
  result.metadata.verificationTime = Date.now() - startTime;
2110
+ result.metadata.error = VerificationErrorCode.INVALID_FORMAT;
2067
2111
  }
2068
2112
  return result;
2069
2113
  }
2070
2114
  if (!await isValidEmailDomain(domain, params.cache)) {
2071
- result.domain.error = VerificationErrorCode.INVALID_DOMAIN;
2072
2115
  if (result.metadata) {
2073
2116
  result.metadata.verificationTime = Date.now() - startTime;
2117
+ result.metadata.error = VerificationErrorCode.INVALID_DOMAIN;
2074
2118
  }
2075
2119
  return result;
2076
2120
  }
2077
2121
  if (checkDisposable) {
2078
- result.disposable = await isDisposableEmail(emailAddress, params.cache);
2079
- if (result.disposable) {
2080
- result.valid = false;
2081
- result.domain.error = VerificationErrorCode.DISPOSABLE_EMAIL;
2122
+ result.isDisposable = await isDisposableEmail(emailAddress, params.cache);
2123
+ if (result.isDisposable && result.metadata) {
2124
+ result.metadata.error = VerificationErrorCode.DISPOSABLE_EMAIL;
2082
2125
  }
2083
2126
  }
2084
2127
  if (checkFree) {
2085
- result.freeProvider = await isFreeEmail(emailAddress, params.cache);
2128
+ result.isFree = await isFreeEmail(emailAddress, params.cache);
2086
2129
  }
2087
- if (checkDomainAge) {
2130
+ const shouldSkipMx = skipMxForDisposable && result.isDisposable;
2131
+ const shouldSkipDomainWhois = skipDomainWhoisForDisposable && result.isDisposable;
2132
+ if (checkDomainAge && !shouldSkipDomainWhois) {
2088
2133
  try {
2089
- result.domainAge = await getDomainAge(domain, whoisTimeout);
2134
+ result.domainAge = await getDomainAge(domain, whoisTimeout, debug);
2090
2135
  } catch (err) {
2091
- log("[verifyEmailDetailed] Failed to get domain age", err);
2136
+ log("[verifyEmail] Failed to get domain age", err);
2092
2137
  result.domainAge = null;
2093
2138
  }
2094
2139
  }
2095
- if (checkDomainRegistration) {
2140
+ if (checkDomainRegistration && !shouldSkipDomainWhois) {
2096
2141
  try {
2097
- result.domainRegistration = await getDomainRegistrationStatus(domain, whoisTimeout);
2142
+ result.domainRegistration = await getDomainRegistrationStatus(domain, whoisTimeout, debug);
2098
2143
  } catch (err) {
2099
- log("[verifyEmailDetailed] Failed to get domain registration status", err);
2144
+ log("[verifyEmail] Failed to get domain registration status", err);
2100
2145
  result.domainRegistration = null;
2101
2146
  }
2102
2147
  }
2103
- if (verifyMx || verifySmtp) {
2148
+ if ((verifyMx || verifySmtp) && !shouldSkipMx) {
2104
2149
  try {
2105
2150
  const mxRecords = await resolveMxRecords(domain, params.cache);
2106
- result.domain.mxRecords = mxRecords;
2107
- result.domain.valid = mxRecords.length > 0;
2108
- if (!result.domain.valid) {
2109
- result.domain.error = VerificationErrorCode.NO_MX_RECORDS;
2151
+ result.validMx = mxRecords.length > 0;
2152
+ if (!result.validMx && result.metadata) {
2153
+ result.metadata.error = VerificationErrorCode.NO_MX_RECORDS;
2110
2154
  }
2111
2155
  if (verifySmtp && mxRecords.length > 0) {
2112
2156
  const cacheKey = `${emailAddress}:smtp`;
2113
2157
  const smtpCacheInstance = smtpCacheStore(params.cache);
2114
2158
  const cachedSmtp = await smtpCacheInstance.get(cacheKey);
2115
2159
  if (cachedSmtp !== null && cachedSmtp !== void 0) {
2116
- result.smtp.valid = cachedSmtp;
2160
+ result.validSmtp = cachedSmtp;
2117
2161
  if (result.metadata) {
2118
2162
  result.metadata.cached = true;
2119
2163
  }
@@ -2141,21 +2185,22 @@ async function verifyEmail(params) {
2141
2185
  retryAttempts: params.retryAttempts
2142
2186
  });
2143
2187
  await smtpCacheInstance.set(cacheKey, smtpResult);
2144
- result.smtp.valid = smtpResult;
2188
+ result.validSmtp = smtpResult;
2145
2189
  }
2146
- if (result.smtp.valid === false) {
2147
- result.smtp.error = VerificationErrorCode.MAILBOX_NOT_FOUND;
2148
- } else if (result.smtp.valid === null) {
2149
- result.smtp.error = VerificationErrorCode.SMTP_CONNECTION_FAILED;
2190
+ if (result.validSmtp === false && result.metadata) {
2191
+ result.metadata.error = VerificationErrorCode.MAILBOX_NOT_FOUND;
2192
+ } else if (result.validSmtp === null && result.metadata) {
2193
+ result.metadata.error = VerificationErrorCode.SMTP_CONNECTION_FAILED;
2150
2194
  }
2151
2195
  }
2152
2196
  } catch (err) {
2153
- log("[verifyEmailDetailed] Failed to resolve MX records", err);
2154
- result.domain.valid = false;
2155
- result.domain.error = VerificationErrorCode.NO_MX_RECORDS;
2197
+ log("[verifyEmail] Failed to resolve MX records", err);
2198
+ result.validMx = false;
2199
+ if (result.metadata) {
2200
+ result.metadata.error = VerificationErrorCode.NO_MX_RECORDS;
2201
+ }
2156
2202
  }
2157
2203
  }
2158
- result.valid = result.format.valid && result.domain.valid !== false && result.smtp.valid !== false && !result.disposable;
2159
2204
  if (result.metadata) {
2160
2205
  result.metadata.verificationTime = Date.now() - startTime;
2161
2206
  }