@emailcheck/email-validator-js 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +102 -6
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +104 -5
- package/dist/index.js.map +1 -1
- package/dist/is-spam-email.d.ts +31 -0
- package/dist/is-spam-name.d.ts +22 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -390,28 +390,28 @@ const name = detectNameFromEmail({
|
|
|
390
390
|
#### `defaultNameDetectionMethod(email: string): DetectedName | null`
|
|
391
391
|
The default name detection implementation, exported for custom extensions.
|
|
392
392
|
|
|
393
|
-
####
|
|
393
|
+
#### Algorithm-Specific Name Cleaning
|
|
394
394
|
|
|
395
|
-
##### `
|
|
396
|
-
Clean a name by removing special characters (dots, underscores, asterisks). Specifically designed for
|
|
395
|
+
##### `cleanNameForAlgorithm(name: string): string`
|
|
396
|
+
Clean a name by removing special characters (dots, underscores, asterisks). Specifically designed for Algorithm name processing.
|
|
397
397
|
|
|
398
398
|
```typescript
|
|
399
|
-
import {
|
|
399
|
+
import { cleanNameForAlgorithm } from '@emailcheck/email-validator-js';
|
|
400
400
|
|
|
401
|
-
const cleanedName =
|
|
401
|
+
const cleanedName = cleanNameForAlgorithm('john.doe_smith*');
|
|
402
402
|
// Returns: 'johndoesmith'
|
|
403
403
|
|
|
404
|
-
const cleanedName2 =
|
|
404
|
+
const cleanedName2 = cleanNameForAlgorithm('first_name.last');
|
|
405
405
|
// Returns: 'firstnamelast'
|
|
406
406
|
```
|
|
407
407
|
|
|
408
|
-
##### `
|
|
409
|
-
Enhanced name detection for
|
|
408
|
+
##### `detectNameForAlgorithm(email: string): DetectedName | null`
|
|
409
|
+
Enhanced name detection for Algorithm with aggressive cleaning. Removes dots, underscores, and asterisks from detected names.
|
|
410
410
|
|
|
411
411
|
```typescript
|
|
412
|
-
import {
|
|
412
|
+
import { detectNameForAlgorithm } from '@emailcheck/email-validator-js';
|
|
413
413
|
|
|
414
|
-
const result =
|
|
414
|
+
const result = detectNameForAlgorithm('john.doe_smith@company.com');
|
|
415
415
|
// Returns: { firstName: 'John', lastName: 'Doesmith', confidence: 0.9025 }
|
|
416
416
|
|
|
417
417
|
// Compared to regular detection:
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from './cache';
|
|
|
6
6
|
export * from './cache-interface';
|
|
7
7
|
export { commonEmailDomains, defaultDomainSuggestionMethod, getDomainSimilarity, isCommonDomain, suggestDomain, suggestEmailDomain, } from './domain-suggester';
|
|
8
8
|
export { isValidEmail, isValidEmailDomain } from './email-validator';
|
|
9
|
+
export { isSpamEmail, isSpamEmailLocalPart } from './is-spam-email';
|
|
10
|
+
export { isSpamName } from './is-spam-name';
|
|
9
11
|
export { cleanNameForAlgorithm, defaultNameDetectionMethod, detectName, detectNameForAlgorithm, detectNameFromEmail, } from './name-detector';
|
|
10
12
|
export * from './types';
|
|
11
13
|
export { getDomainAge, getDomainRegistrationStatus } from './whois';
|
package/dist/index.esm.js
CHANGED
|
@@ -1332,11 +1332,10 @@ function isIPAddress(host) {
|
|
|
1332
1332
|
const ipv6Regex = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,7}:$|^(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})$|^::1(?::(?::[0-9a-fA-F]{1,4}){1,7})|$|:(?:(?::[0-9a-fA-F]{1,4}){1,7}:)$/;
|
|
1333
1333
|
return ipv6Regex.test(host);
|
|
1334
1334
|
}
|
|
1335
|
+
function isHighVolume(smtpReply) {
|
|
1336
|
+
return Boolean(smtpReply && /high number of/gi.test(smtpReply));
|
|
1337
|
+
}
|
|
1335
1338
|
function isOverQuota(smtpReply) {
|
|
1336
|
-
var _a;
|
|
1337
|
-
if ((_a = smtpReply === null || smtpReply === void 0 ? void 0 : smtpReply.toLowerCase()) === null || _a === void 0 ? void 0 : _a.includes("excessively high number of invalid recipients")) {
|
|
1338
|
-
return true;
|
|
1339
|
-
}
|
|
1340
1339
|
return Boolean(smtpReply && /(over quota)/gi.test(smtpReply));
|
|
1341
1340
|
}
|
|
1342
1341
|
function isInvalidMailboxError(smtpReply) {
|
|
@@ -1568,7 +1567,7 @@ async function testSMTPConnection(params) {
|
|
|
1568
1567
|
sendCommand("STARTTLS");
|
|
1569
1568
|
break;
|
|
1570
1569
|
case SMTPStep.mailFrom: {
|
|
1571
|
-
const from = activeSequence.from ||
|
|
1570
|
+
const from = activeSequence.from || `<${local}@${domain}>`;
|
|
1572
1571
|
sendCommand(`MAIL FROM:${from}`);
|
|
1573
1572
|
break;
|
|
1574
1573
|
}
|
|
@@ -1594,6 +1593,10 @@ async function testSMTPConnection(params) {
|
|
|
1594
1593
|
if (isMultilineGreet(response)) {
|
|
1595
1594
|
return;
|
|
1596
1595
|
}
|
|
1596
|
+
if (isHighVolume(response)) {
|
|
1597
|
+
finish(true, "high_volume");
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1597
1600
|
if (isOverQuota(response)) {
|
|
1598
1601
|
finish(false, "over_quota");
|
|
1599
1602
|
return;
|
|
@@ -2643,6 +2646,99 @@ function createErrorResult(email, _error) {
|
|
|
2643
2646
|
};
|
|
2644
2647
|
}
|
|
2645
2648
|
|
|
2649
|
+
function isSpamEmail(email) {
|
|
2650
|
+
if (typeof email !== "string")
|
|
2651
|
+
return false;
|
|
2652
|
+
const atIndex = email.lastIndexOf("@");
|
|
2653
|
+
if (atIndex === -1)
|
|
2654
|
+
return false;
|
|
2655
|
+
const localPart = email.slice(0, atIndex);
|
|
2656
|
+
if (localPart.length < 16)
|
|
2657
|
+
return false;
|
|
2658
|
+
const cleaned = localPart.replace(/[._+-]/g, "");
|
|
2659
|
+
if (cleaned.length < 12)
|
|
2660
|
+
return false;
|
|
2661
|
+
if (!/^[A-Za-z0-9]+$/.test(cleaned))
|
|
2662
|
+
return false;
|
|
2663
|
+
const lettersOnly = cleaned.replace(/[0-9]/g, "");
|
|
2664
|
+
if (lettersOnly.length < 10)
|
|
2665
|
+
return false;
|
|
2666
|
+
function vowelRatio(str) {
|
|
2667
|
+
const vowels = (str.match(/[aeiouAEIOU]/g) || []).length;
|
|
2668
|
+
return vowels / str.length;
|
|
2669
|
+
}
|
|
2670
|
+
function uppercaseRatio(str) {
|
|
2671
|
+
const uppercase = (str.match(/[A-Z]/g) || []).length;
|
|
2672
|
+
return uppercase / str.length;
|
|
2673
|
+
}
|
|
2674
|
+
function hasRepeatedPatterns(str) {
|
|
2675
|
+
const patterns = /(.)\1{2,}/g;
|
|
2676
|
+
const matches = str.match(patterns);
|
|
2677
|
+
return matches !== null && matches.length > 0;
|
|
2678
|
+
}
|
|
2679
|
+
function hasConsonantClusters(str) {
|
|
2680
|
+
const clusters = str.match(/[^aeiouAEIOU]{3,}/g);
|
|
2681
|
+
return clusters !== null && clusters.length > 0;
|
|
2682
|
+
}
|
|
2683
|
+
function hasAlternatingCase(str) {
|
|
2684
|
+
if (str.length < 8)
|
|
2685
|
+
return false;
|
|
2686
|
+
let alternatingChanges = 0;
|
|
2687
|
+
for (let i = 1; i < str.length; i++) {
|
|
2688
|
+
const prevIsUpper = str[i - 1] >= "A" && str[i - 1] <= "Z";
|
|
2689
|
+
const currIsUpper = str[i] >= "A" && str[i] <= "Z";
|
|
2690
|
+
if (prevIsUpper !== currIsUpper) {
|
|
2691
|
+
alternatingChanges++;
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
return alternatingChanges / str.length > 0.7;
|
|
2695
|
+
}
|
|
2696
|
+
const vowelR = vowelRatio(lettersOnly);
|
|
2697
|
+
const upperR = uppercaseRatio(lettersOnly);
|
|
2698
|
+
if (hasAlternatingCase(lettersOnly))
|
|
2699
|
+
return true;
|
|
2700
|
+
if (vowelR > 0.35)
|
|
2701
|
+
return false;
|
|
2702
|
+
if (upperR < 0.15)
|
|
2703
|
+
return false;
|
|
2704
|
+
if (hasRepeatedPatterns(localPart))
|
|
2705
|
+
return true;
|
|
2706
|
+
if (hasConsonantClusters(lettersOnly))
|
|
2707
|
+
return true;
|
|
2708
|
+
if (cleaned.length >= 20 && vowelR < 0.25)
|
|
2709
|
+
return true;
|
|
2710
|
+
return true;
|
|
2711
|
+
}
|
|
2712
|
+
function isSpamEmailLocalPart(email) {
|
|
2713
|
+
return isSpamEmail(email);
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
function isSpamName(name) {
|
|
2717
|
+
if (typeof name !== "string")
|
|
2718
|
+
return false;
|
|
2719
|
+
const cleaned = name.replace(/[,.;:!?]+$/, "").trim();
|
|
2720
|
+
const parts = cleaned.split(/\s+/);
|
|
2721
|
+
if (parts.length !== 2)
|
|
2722
|
+
return false;
|
|
2723
|
+
const [first, second] = parts;
|
|
2724
|
+
if (!/^[A-Za-z]+$/.test(first) || !/^[A-Za-z]+$/.test(second))
|
|
2725
|
+
return false;
|
|
2726
|
+
if (first.length < 16 || second.length < 16)
|
|
2727
|
+
return false;
|
|
2728
|
+
function vowelRatio(str) {
|
|
2729
|
+
const vowels = (str.match(/[aeiouAEIOU]/g) || []).length;
|
|
2730
|
+
return vowels / str.length;
|
|
2731
|
+
}
|
|
2732
|
+
const ratio1 = vowelRatio(first);
|
|
2733
|
+
const ratio2 = vowelRatio(second);
|
|
2734
|
+
const avgRatio = (ratio1 + ratio2) / 2;
|
|
2735
|
+
if (avgRatio > 0.35 && ratio1 > 0.25 && ratio2 > 0.25)
|
|
2736
|
+
return false;
|
|
2737
|
+
if (!/[A-Z]/.test(first) || !/[A-Z]/.test(second))
|
|
2738
|
+
return false;
|
|
2739
|
+
return true;
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2646
2742
|
let disposableEmailProviders;
|
|
2647
2743
|
let freeEmailProviders;
|
|
2648
2744
|
async function isDisposableEmail(params) {
|
|
@@ -2918,5 +3014,5 @@ async function verifyEmail(params) {
|
|
|
2918
3014
|
return result;
|
|
2919
3015
|
}
|
|
2920
3016
|
|
|
2921
|
-
export { DEFAULT_CACHE_OPTIONS, EmailProvider, LRUAdapter, RedisAdapter, SMTPStep, VerificationErrorCode, cleanNameForAlgorithm, clearDefaultCache, commonEmailDomains, defaultDomainSuggestionMethod, defaultNameDetectionMethod, detectName, detectNameForAlgorithm, detectNameFromEmail, domainPorts, getCacheStore, getDefaultCache, getDomainAge, getDomainRegistrationStatus, getDomainSimilarity, isCommonDomain, isDisposableEmail, isFreeEmail, isValidEmail, isValidEmailDomain, parseSmtpError, resetDefaultCache, suggestDomain, suggestEmailDomain, verifyEmail, verifyEmailBatch };
|
|
3017
|
+
export { DEFAULT_CACHE_OPTIONS, EmailProvider, LRUAdapter, RedisAdapter, SMTPStep, VerificationErrorCode, cleanNameForAlgorithm, clearDefaultCache, commonEmailDomains, defaultDomainSuggestionMethod, defaultNameDetectionMethod, detectName, detectNameForAlgorithm, detectNameFromEmail, domainPorts, getCacheStore, getDefaultCache, getDomainAge, getDomainRegistrationStatus, getDomainSimilarity, isCommonDomain, isDisposableEmail, isFreeEmail, isSpamEmail, isSpamEmailLocalPart, isSpamName, isValidEmail, isValidEmailDomain, parseSmtpError, resetDefaultCache, suggestDomain, suggestEmailDomain, verifyEmail, verifyEmailBatch };
|
|
2922
3018
|
//# sourceMappingURL=index.esm.js.map
|