@visulima/email-verifier 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -11
- package/dist/checks/character.d.ts +17 -17
- package/dist/checks/mx.d.ts +1 -1
- package/dist/checks/mx.js +1 -1
- package/dist/checks/role.d.ts +32 -32
- package/dist/checks/role.js +1 -1
- package/dist/checks/smtp.d.ts +26 -51
- package/dist/checks/smtp.js +4 -4
- package/dist/checks/symbol.d.ts +15 -15
- package/dist/checks/syntax.d.ts +16 -16
- package/dist/checks/tag.d.ts +17 -17
- package/dist/enrich/name.d.ts +18 -18
- package/dist/enrich/provider.d.ts +21 -21
- package/dist/enrich/typo.d.ts +31 -31
- package/dist/index.d.ts +18 -18
- package/dist/packem_shared/mx.d-HxIDdxvR.d.ts +104 -0
- package/dist/packem_shared/{score.d-BTcZnl2L.d.ts → score.d-a6cl6fPu.d.ts} +49 -43
- package/dist/score.d.ts +2 -2
- package/dist/score.js +1 -1
- package/dist/verify-email.d.ts +29 -29
- package/dist/verify-email.js +1 -1
- package/package.json +19 -19
- package/dist/packem_shared/mx.d-NAesS5sg.d.ts +0 -117
package/dist/enrich/typo.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A suggested correction for a likely-misspelled email address.
|
|
3
|
-
*/
|
|
2
|
+
* A suggested correction for a likely-misspelled email address.
|
|
3
|
+
*/
|
|
4
4
|
interface TypoSuggestion {
|
|
5
5
|
/** The suggested corrected domain. */
|
|
6
6
|
domain: string;
|
|
@@ -8,52 +8,52 @@ interface TypoSuggestion {
|
|
|
8
8
|
full: string;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Options for typo suggestion.
|
|
12
|
-
*/
|
|
11
|
+
* Options for typo suggestion.
|
|
12
|
+
*/
|
|
13
13
|
interface TypoOptions {
|
|
14
14
|
/** Popular full domains to match against (e.g. `gmail.com`). */
|
|
15
15
|
domains?: string[];
|
|
16
16
|
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
* Distance threshold for the full-domain match.
|
|
18
|
+
* @default 2
|
|
19
|
+
*/
|
|
20
20
|
domainThreshold?: number;
|
|
21
21
|
/** Popular second-level domains to match against (e.g. `gmail`). */
|
|
22
22
|
secondLevelDomains?: string[];
|
|
23
23
|
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
* Distance threshold for the second-level match.
|
|
25
|
+
* @default 2
|
|
26
|
+
*/
|
|
27
27
|
secondLevelThreshold?: number;
|
|
28
28
|
/** Popular top-level domains to match against (e.g. `com`). */
|
|
29
29
|
topLevelDomains?: string[];
|
|
30
30
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
* Distance threshold for the top-level match.
|
|
32
|
+
* @default 2
|
|
33
|
+
*/
|
|
34
34
|
topLevelThreshold?: number;
|
|
35
35
|
}
|
|
36
36
|
declare const sift3Distance: (s1: string, s2: string) => number;
|
|
37
37
|
/**
|
|
38
|
-
* Suggests a corrected domain for a likely-misspelled one, using the mailcheck
|
|
39
|
-
* algorithm (full-domain match, then second-level + top-level matching).
|
|
40
|
-
* @param domain The domain to check.
|
|
41
|
-
* @param options Override domain lists and thresholds.
|
|
42
|
-
* @returns The suggested domain, or `undefined` when the domain looks fine.
|
|
43
|
-
*/
|
|
38
|
+
* Suggests a corrected domain for a likely-misspelled one, using the mailcheck
|
|
39
|
+
* algorithm (full-domain match, then second-level + top-level matching).
|
|
40
|
+
* @param domain The domain to check.
|
|
41
|
+
* @param options Override domain lists and thresholds.
|
|
42
|
+
* @returns The suggested domain, or `undefined` when the domain looks fine.
|
|
43
|
+
*/
|
|
44
44
|
declare const suggestDomain: (domain: string, options?: TypoOptions) => string | undefined;
|
|
45
45
|
/**
|
|
46
|
-
* Suggests a corrected email address when the domain looks misspelled
|
|
47
|
-
* (e.g. `user@gmial.com` → `user@gmail.com`).
|
|
48
|
-
* @param email The email address to check.
|
|
49
|
-
* @param options Override domain lists and thresholds.
|
|
50
|
-
* @returns A {@link TypoSuggestion}, or `undefined` when nothing looks wrong.
|
|
51
|
-
* @example
|
|
52
|
-
* ```ts
|
|
53
|
-
* import { suggestEmailTypo } from "@visulima/email-verifier/enrich/typo";
|
|
54
|
-
*
|
|
55
|
-
* suggestEmailTypo("user@gmial.com")?.full; // "user@gmail.com"
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
46
|
+
* Suggests a corrected email address when the domain looks misspelled
|
|
47
|
+
* (e.g. `user@gmial.com` → `user@gmail.com`).
|
|
48
|
+
* @param email The email address to check.
|
|
49
|
+
* @param options Override domain lists and thresholds.
|
|
50
|
+
* @returns A {@link TypoSuggestion}, or `undefined` when nothing looks wrong.
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { suggestEmailTypo } from "@visulima/email-verifier/enrich/typo";
|
|
54
|
+
*
|
|
55
|
+
* suggestEmailTypo("user@gmial.com")?.full; // "user@gmail.com"
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
58
|
declare const suggestEmailTypo: (email: string, options?: TypoOptions) => TypoSuggestion | undefined;
|
|
59
59
|
export { type TypoOptions, type TypoSuggestion, suggestEmailTypo as default, sift3Distance, suggestDomain, suggestEmailTypo };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { type CharacterResult, analyzeCharacters } from "./checks/character.js";
|
|
2
2
|
export { type DisposableEmailOptions, areDisposableEmails, isDisposableDomain, isDisposableEmail } from '@visulima/disposable-email-domains';
|
|
3
3
|
export { type FreeEmailOptions, areFreeEmails, isFreeDomain, isFreeEmail } from '@visulima/free-email-domains';
|
|
4
|
-
export { type C as Cache, I as InMemoryCache, type a as InMemoryCacheOptions, type M as MxCheckOptions, type b as MxCheckResult, type c as MxRecord, type d as MxResolution, e as checkMxRecords } from "./packem_shared/mx.d-
|
|
4
|
+
export { type C as Cache, I as InMemoryCache, type a as InMemoryCacheOptions, type M as MxCheckOptions, type b as MxCheckResult, type c as MxRecord, type d as MxResolution, e as checkMxRecords } from "./packem_shared/mx.d-HxIDdxvR.js";
|
|
5
5
|
export { NO_REPLY_PREFIXES, ROLE_ACCOUNT_PREFIXES, isNoReply, default as isRoleAccount } from "./checks/role.js";
|
|
6
6
|
export { type SmtpVerificationOptions, type SmtpVerificationResult, default as verifySmtp } from "./checks/smtp.js";
|
|
7
7
|
export { type SymbolResult, analyzeSymbols } from "./checks/symbol.js";
|
|
@@ -10,12 +10,12 @@ export { type TagResult, default as detectTag } from "./checks/tag.js";
|
|
|
10
10
|
export { type NameResult, default as parseName } from "./enrich/name.js";
|
|
11
11
|
export { type ProviderDetails, type ProviderEnrichOptions, default as enrichProvider } from "./enrich/provider.js";
|
|
12
12
|
export { type TypoOptions, type TypoSuggestion, sift3Distance, suggestDomain, default as suggestEmailTypo } from "./enrich/typo.js";
|
|
13
|
-
export { D as DEFAULT_WEIGHTS, type a as DomainReport, type E as EmailVerificationReport, type S as ScoreInput, type b as ScoreResult, type c as ScoreWeights, type V as VerificationState, s as scoreReport } from "./packem_shared/score.d-
|
|
13
|
+
export { D as DEFAULT_WEIGHTS, type a as DomainReport, type E as EmailVerificationReport, type S as ScoreInput, type b as ScoreResult, type c as ScoreWeights, type V as VerificationState, s as scoreReport } from "./packem_shared/score.d-a6cl6fPu.js";
|
|
14
14
|
export { type VerifyEmailOptions, default as verifyEmail } from "./verify-email.js";
|
|
15
15
|
export { type MxProviderInfo, classifyMx, classifyMxRecords, isSecureEmailGateway } from '@visulima/email-provider-mx';
|
|
16
16
|
/**
|
|
17
|
-
* The split parts of an email address.
|
|
18
|
-
*/
|
|
17
|
+
* The split parts of an email address.
|
|
18
|
+
*/
|
|
19
19
|
interface AddressParts {
|
|
20
20
|
/** The full normalized (lowercased, trimmed) address. */
|
|
21
21
|
address: string;
|
|
@@ -25,21 +25,21 @@ interface AddressParts {
|
|
|
25
25
|
localPart: string;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Splits an email address into its normalized local and domain parts.
|
|
29
|
-
*
|
|
30
|
-
* Uses the last `@` as the separator so quoted local parts containing `@` are
|
|
31
|
-
* handled the same way the SMTP/MX probes treat them. Inputs containing
|
|
32
|
-
* whitespace (after trimming) are rejected so a payload that embeds a CRLF
|
|
33
|
-
* followed by a second SMTP command cannot be smuggled into the SMTP dialogue
|
|
34
|
-
* by callers of the standalone probes.
|
|
35
|
-
* @param email The email address to split.
|
|
36
|
-
* @returns The normalized parts, or `undefined` if the address is structurally invalid.
|
|
37
|
-
*/
|
|
28
|
+
* Splits an email address into its normalized local and domain parts.
|
|
29
|
+
*
|
|
30
|
+
* Uses the last `@` as the separator so quoted local parts containing `@` are
|
|
31
|
+
* handled the same way the SMTP/MX probes treat them. Inputs containing
|
|
32
|
+
* whitespace (after trimming) are rejected so a payload that embeds a CRLF
|
|
33
|
+
* followed by a second SMTP command cannot be smuggled into the SMTP dialogue
|
|
34
|
+
* by callers of the standalone probes.
|
|
35
|
+
* @param email The email address to split.
|
|
36
|
+
* @returns The normalized parts, or `undefined` if the address is structurally invalid.
|
|
37
|
+
*/
|
|
38
38
|
declare const splitAddress: (email: string) => AddressParts | undefined;
|
|
39
39
|
/**
|
|
40
|
-
* Extracts and normalizes just the domain from an email address.
|
|
41
|
-
* @param email The email address to extract the domain from.
|
|
42
|
-
* @returns The normalized domain, or `undefined` if invalid.
|
|
43
|
-
*/
|
|
40
|
+
* Extracts and normalizes just the domain from an email address.
|
|
41
|
+
* @param email The email address to extract the domain from.
|
|
42
|
+
* @returns The normalized domain, or `undefined` if invalid.
|
|
43
|
+
*/
|
|
44
44
|
declare const extractDomain: (email: string) => string | undefined;
|
|
45
45
|
export { type AddressParts, extractDomain, splitAddress };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic cache interface for caching any type of data.
|
|
3
|
+
* Implementations can use in-memory cache, LRU cache, Redis, etc.
|
|
4
|
+
*/
|
|
5
|
+
interface Cache<T = unknown> {
|
|
6
|
+
/**
|
|
7
|
+
* Clears all cached entries.
|
|
8
|
+
*/
|
|
9
|
+
clear: () => Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Deletes a cached entry.
|
|
12
|
+
* @param key The cache key.
|
|
13
|
+
*/
|
|
14
|
+
delete: (key: string) => Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Gets a cached value.
|
|
17
|
+
* @param key The cache key.
|
|
18
|
+
* @returns The cached value or undefined if not found or expired.
|
|
19
|
+
*/
|
|
20
|
+
get: (key: string) => Promise<T | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* Sets a cached value.
|
|
23
|
+
* @param key The cache key.
|
|
24
|
+
* @param value The value to cache.
|
|
25
|
+
* @param ttl Time-to-live in milliseconds.
|
|
26
|
+
*/
|
|
27
|
+
set: (key: string, value: T, ttl: number) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Options for creating an in-memory cache.
|
|
31
|
+
*/
|
|
32
|
+
interface InMemoryCacheOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Maximum number of entries in the cache.
|
|
35
|
+
* @default 500
|
|
36
|
+
*/
|
|
37
|
+
max?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Default TTL in milliseconds for entries.
|
|
40
|
+
* @default 3600000 (1 hour)
|
|
41
|
+
*/
|
|
42
|
+
ttl?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Default in-memory cache implementation using LRU cache.
|
|
46
|
+
*
|
|
47
|
+
* Shared by the MX and SMTP probes so repeated lookups against the same domain
|
|
48
|
+
* (e.g. when verifying a list) avoid redundant DNS/socket work.
|
|
49
|
+
*/
|
|
50
|
+
declare class InMemoryCache<T extends object = Record<string, unknown>> implements Cache<T> {
|
|
51
|
+
private readonly cache;
|
|
52
|
+
constructor(options?: InMemoryCacheOptions);
|
|
53
|
+
clear: () => Promise<void>;
|
|
54
|
+
delete: (key: string) => Promise<void>;
|
|
55
|
+
get: (key: string) => Promise<T | undefined>;
|
|
56
|
+
set: (key: string, value: T, ttl: number) => Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* MX record information.
|
|
60
|
+
*/
|
|
61
|
+
interface MxRecord {
|
|
62
|
+
exchange: string;
|
|
63
|
+
priority: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* How the domain's mail-acceptance was established.
|
|
67
|
+
*
|
|
68
|
+
* - `mx`: the domain published MX records.
|
|
69
|
+
* - `address`: the domain has no MX but resolves to an A/AAAA record, so by RFC 5321 §5.1 the address itself is treated as an implicit MX.
|
|
70
|
+
* - `none`: neither MX nor address records exist.
|
|
71
|
+
*/
|
|
72
|
+
type MxResolution = "address" | "mx" | "none";
|
|
73
|
+
/**
|
|
74
|
+
* Result of an MX/domain check.
|
|
75
|
+
*/
|
|
76
|
+
interface MxCheckResult {
|
|
77
|
+
/**
|
|
78
|
+
* True when the lookup was inconclusive because of a transient DNS failure
|
|
79
|
+
* (timeout, SERVFAIL, refused, …) rather than a definitive "no records"
|
|
80
|
+
* answer. Such a result is neither cached nor treated as undeliverable.
|
|
81
|
+
*/
|
|
82
|
+
deferred?: boolean;
|
|
83
|
+
/** True when the domain itself resolves but publishes no MX records. */
|
|
84
|
+
domainResolves: boolean;
|
|
85
|
+
error?: string;
|
|
86
|
+
records?: MxRecord[];
|
|
87
|
+
resolvedVia: MxResolution;
|
|
88
|
+
/** True when the domain can accept mail (has MX or A/AAAA records). */
|
|
89
|
+
valid: boolean;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Options for MX record checking.
|
|
93
|
+
*/
|
|
94
|
+
interface MxCheckOptions {
|
|
95
|
+
cache?: Cache<MxCheckResult>;
|
|
96
|
+
/**
|
|
97
|
+
* When true (the default), a domain with no MX records but a resolvable
|
|
98
|
+
* A/AAAA record is still considered able to accept mail (implicit MX).
|
|
99
|
+
*/
|
|
100
|
+
fallbackToAddress?: boolean;
|
|
101
|
+
ttl?: number;
|
|
102
|
+
}
|
|
103
|
+
declare const checkMxRecords: (domain: string, options?: MxCheckOptions) => Promise<MxCheckResult>;
|
|
104
|
+
export { Cache as C, InMemoryCache as I, MxCheckOptions as M, InMemoryCacheOptions as a, MxCheckResult as b, MxRecord as c, MxResolution as d, checkMxRecords as e };
|
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { CharacterResult } from "../checks/character.js";
|
|
2
|
-
import { c as MxRecord, d as MxResolution } from "./mx.d-
|
|
2
|
+
import { c as MxRecord, d as MxResolution } from "./mx.d-HxIDdxvR.js";
|
|
3
3
|
import { SmtpVerificationResult } from "../checks/smtp.js";
|
|
4
4
|
import { SymbolResult } from "../checks/symbol.js";
|
|
5
5
|
import { TagResult } from "../checks/tag.js";
|
|
6
6
|
import { NameResult } from "../enrich/name.js";
|
|
7
7
|
import { MxProviderInfo } from '@visulima/email-provider-mx';
|
|
8
8
|
/**
|
|
9
|
-
* The overall deliverability verdict for an address, mirroring emailable's states.
|
|
10
|
-
*
|
|
11
|
-
* - `deliverable`: the mailbox almost certainly exists and accepts mail.
|
|
12
|
-
* - `risky`: deliverable but lower-quality (catch-all, role, disposable, full mailbox).
|
|
13
|
-
* - `undeliverable`: syntax/domain/mailbox failure — do not send.
|
|
14
|
-
* - `unknown`: could not be determined (SMTP blocked, greylisted, or not probed).
|
|
15
|
-
*/
|
|
9
|
+
* The overall deliverability verdict for an address, mirroring emailable's states.
|
|
10
|
+
*
|
|
11
|
+
* - `deliverable`: the mailbox almost certainly exists and accepts mail.
|
|
12
|
+
* - `risky`: deliverable but lower-quality (catch-all, role, disposable, full mailbox).
|
|
13
|
+
* - `undeliverable`: syntax/domain/mailbox failure — do not send.
|
|
14
|
+
* - `unknown`: could not be determined (SMTP blocked, greylisted, or not probed).
|
|
15
|
+
*/
|
|
16
16
|
type VerificationState = "deliverable" | "risky" | "undeliverable" | "unknown";
|
|
17
17
|
/**
|
|
18
|
-
* The resolved domain portion of a verification report.
|
|
19
|
-
*/
|
|
18
|
+
* The resolved domain portion of a verification report.
|
|
19
|
+
*/
|
|
20
20
|
interface DomainReport {
|
|
21
|
+
/**
|
|
22
|
+
* True when the domain lookup was inconclusive because of a transient DNS
|
|
23
|
+
* failure (timeout, SERVFAIL, refused). The domain is neither confirmed nor
|
|
24
|
+
* proven undeliverable — treat as `unknown`.
|
|
25
|
+
*/
|
|
26
|
+
deferred?: boolean;
|
|
21
27
|
/** The MX records found (empty when resolved via A/AAAA or not at all). */
|
|
22
28
|
records: MxRecord[];
|
|
23
29
|
/** How mail-acceptance was established (`unchecked` when DNS was skipped). */
|
|
@@ -26,11 +32,11 @@ interface DomainReport {
|
|
|
26
32
|
valid: boolean;
|
|
27
33
|
}
|
|
28
34
|
/**
|
|
29
|
-
* A complete email verification + enrichment report.
|
|
30
|
-
*
|
|
31
|
-
* Aggregates every check and enrichment into a single object whose shape reads
|
|
32
|
-
* as a drop-in mental model for emailable's API response.
|
|
33
|
-
*/
|
|
35
|
+
* A complete email verification + enrichment report.
|
|
36
|
+
*
|
|
37
|
+
* Aggregates every check and enrichment into a single object whose shape reads
|
|
38
|
+
* as a drop-in mental model for emailable's API response.
|
|
39
|
+
*/
|
|
34
40
|
interface EmailVerificationReport {
|
|
35
41
|
/** True when the SMTP server accepts any recipient (catch-all / accept-all). */
|
|
36
42
|
acceptAll: boolean;
|
|
@@ -76,16 +82,16 @@ interface EmailVerificationReport {
|
|
|
76
82
|
tag: TagResult;
|
|
77
83
|
}
|
|
78
84
|
/**
|
|
79
|
-
* The fields of a report the scorer consumes (everything except the derived
|
|
80
|
-
* `score`, `state`, and `reason`).
|
|
81
|
-
*/
|
|
85
|
+
* The fields of a report the scorer consumes (everything except the derived
|
|
86
|
+
* `score`, `state`, and `reason`).
|
|
87
|
+
*/
|
|
82
88
|
type ScoreInput = Omit<EmailVerificationReport, "reason" | "score" | "state">;
|
|
83
89
|
/**
|
|
84
|
-
* Overridable penalty/bonus weights for the quality score.
|
|
85
|
-
*
|
|
86
|
-
* Each value is points applied to a 100-point baseline. Penalties are positive
|
|
87
|
-
* numbers that get subtracted; bonuses are added.
|
|
88
|
-
*/
|
|
90
|
+
* Overridable penalty/bonus weights for the quality score.
|
|
91
|
+
*
|
|
92
|
+
* Each value is points applied to a 100-point baseline. Penalties are positive
|
|
93
|
+
* numbers that get subtracted; bonuses are added.
|
|
94
|
+
*/
|
|
89
95
|
interface ScoreWeights {
|
|
90
96
|
acceptAll: number;
|
|
91
97
|
character: number;
|
|
@@ -102,33 +108,33 @@ interface ScoreWeights {
|
|
|
102
108
|
symbol: number;
|
|
103
109
|
}
|
|
104
110
|
/**
|
|
105
|
-
* The default scoring rubric. Transparent and additive so callers can reason
|
|
106
|
-
* about — and override — every weight.
|
|
107
|
-
*/
|
|
111
|
+
* The default scoring rubric. Transparent and additive so callers can reason
|
|
112
|
+
* about — and override — every weight.
|
|
113
|
+
*/
|
|
108
114
|
declare const DEFAULT_WEIGHTS: ScoreWeights;
|
|
109
115
|
/**
|
|
110
|
-
* The outcome of scoring: the numeric score plus the derived state and reason.
|
|
111
|
-
*/
|
|
116
|
+
* The outcome of scoring: the numeric score plus the derived state and reason.
|
|
117
|
+
*/
|
|
112
118
|
interface ScoreResult {
|
|
113
119
|
reason: string;
|
|
114
120
|
score: number;
|
|
115
121
|
state: VerificationState;
|
|
116
122
|
}
|
|
117
123
|
/**
|
|
118
|
-
* Computes a 0–100 quality score and the deliverability state for a report.
|
|
119
|
-
*
|
|
120
|
-
* The state is derived from hard signals (syntax, domain, SMTP verdict); the
|
|
121
|
-
* score layers transparent penalties/bonuses on top so two `risky` addresses can
|
|
122
|
-
* still be ranked against each other.
|
|
123
|
-
* @param input The verification signals (a report without its derived fields).
|
|
124
|
-
* @param weights Optional weight overrides.
|
|
125
|
-
* @returns The score, state, and reason.
|
|
126
|
-
* @example
|
|
127
|
-
* ```ts
|
|
128
|
-
* import { scoreReport } from "@visulima/email-verifier/score";
|
|
129
|
-
*
|
|
130
|
-
* const { score, state } = scoreReport(report);
|
|
131
|
-
* ```
|
|
132
|
-
*/
|
|
124
|
+
* Computes a 0–100 quality score and the deliverability state for a report.
|
|
125
|
+
*
|
|
126
|
+
* The state is derived from hard signals (syntax, domain, SMTP verdict); the
|
|
127
|
+
* score layers transparent penalties/bonuses on top so two `risky` addresses can
|
|
128
|
+
* still be ranked against each other.
|
|
129
|
+
* @param input The verification signals (a report without its derived fields).
|
|
130
|
+
* @param weights Optional weight overrides.
|
|
131
|
+
* @returns The score, state, and reason.
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* import { scoreReport } from "@visulima/email-verifier/score";
|
|
135
|
+
*
|
|
136
|
+
* const { score, state } = scoreReport(report);
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
133
139
|
declare const scoreReport: (input: ScoreInput, weights?: Partial<ScoreWeights>) => ScoreResult;
|
|
134
140
|
export { DEFAULT_WEIGHTS as D, EmailVerificationReport as E, ScoreInput as S, VerificationState as V, DomainReport as a, ScoreResult as b, ScoreWeights as c, scoreReport as s };
|
package/dist/score.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { D as DEFAULT_WEIGHTS, type S as ScoreInput, type b as ScoreResult, type c as ScoreWeights, s as default, s as scoreReport } from "./packem_shared/score.d-
|
|
1
|
+
export { D as DEFAULT_WEIGHTS, type S as ScoreInput, type b as ScoreResult, type c as ScoreWeights, s as default, s as scoreReport } from "./packem_shared/score.d-a6cl6fPu.js";
|
|
2
2
|
import "./checks/character.js";
|
|
3
|
-
import "./packem_shared/mx.d-
|
|
3
|
+
import "./packem_shared/mx.d-HxIDdxvR.js";
|
|
4
4
|
import "./checks/smtp.js";
|
|
5
5
|
import "./checks/symbol.js";
|
|
6
6
|
import "./checks/tag.js";
|
package/dist/score.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const t={acceptAll:25,character:15,deferred:15,didYouMean:20,disposable:60,free:5,knownProvider:5,mailboxFull:40,mixedScripts:30,noReply:25,role:25,smtpUnverified:10,symbol:10},
|
|
1
|
+
const t={acceptAll:25,character:15,deferred:15,didYouMean:20,disposable:60,free:5,knownProvider:5,mailboxFull:40,mixedScripts:30,noReply:25,role:25,smtpUnverified:10,symbol:10},n=e=>Math.max(0,Math.min(100,Math.round(e))),i=e=>e.smtp!==void 0&&!e.smtp.valid&&!e.smtp.deferred&&!e.mailboxFull&&(e.smtp.code??0)>=500,d=e=>e.disposable?{reason:"disposable_mailbox",state:"risky"}:e.mailboxFull?{reason:"mailbox_full",state:"risky"}:e.acceptAll?{reason:"accept_all",state:"risky"}:e.noReply?{reason:"no_reply",state:"risky"}:e.role?{reason:"role_account",state:"risky"}:{reason:"accepted_email",state:"deliverable"},m=e=>i(e)?{reason:"rejected_email",state:"undeliverable"}:e.smtp?.valid?d(e):e.mailboxFull?{reason:"mailbox_full",state:"risky"}:e.smtp?.deferred?{reason:"greylisted",state:"unknown"}:{reason:"unknown",state:"unknown"},c=e=>e.syntaxValid?e.domain.resolvedVia!=="unchecked"&&!e.domain.valid?e.domain.deferred?{reason:"dns_error",state:"unknown"}:{reason:e.domain.resolvedVia==="none"?"no_mx_records":"invalid_domain",state:"undeliverable"}:e.smtp?m(e):e.disposable?{reason:"disposable_mailbox",state:"risky"}:{reason:"smtp_not_checked",state:"unknown"}:{reason:"invalid_syntax",state:"undeliverable"},p=(e,l={})=>{const s={...t,...l},{reason:o,state:r}=c(e);if(r==="undeliverable")return{reason:o,score:0,state:r};let a=100;return e.smtp?.valid!==!0&&(a-=s.smtpUnverified),e.deferred&&(a-=s.deferred),e.disposable&&(a-=s.disposable),e.acceptAll&&(a-=s.acceptAll),e.mailboxFull&&(a-=s.mailboxFull),e.role&&(a-=s.role),e.noReply&&(a-=s.noReply),e.free&&(a-=s.free),e.character.irregular&&(a-=s.character),e.symbol.hasMixedScripts?a-=s.mixedScripts:e.symbol.hasSymbols&&(a-=s.symbol),e.didYouMean&&(a-=s.didYouMean),e.provider&&(a+=s.knownProvider),{reason:o,score:n(a),state:r}};export{t as DEFAULT_WEIGHTS,p as default,p as scoreReport};
|
package/dist/verify-email.d.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
import { DisposableEmailOptions } from '@visulima/disposable-email-domains';
|
|
2
2
|
import { FreeEmailOptions } from '@visulima/free-email-domains';
|
|
3
|
-
import { b as MxCheckResult, C as Cache } from "./packem_shared/mx.d-
|
|
3
|
+
import { b as MxCheckResult, C as Cache } from "./packem_shared/mx.d-HxIDdxvR.js";
|
|
4
4
|
import { SmtpVerificationOptions } from "./checks/smtp.js";
|
|
5
5
|
import { TypoOptions } from "./enrich/typo.js";
|
|
6
|
-
import { c as ScoreWeights, E as EmailVerificationReport } from "./packem_shared/score.d-
|
|
7
|
-
export type { V as VerificationState } from "./packem_shared/score.d-
|
|
6
|
+
import { c as ScoreWeights, E as EmailVerificationReport } from "./packem_shared/score.d-a6cl6fPu.js";
|
|
7
|
+
export type { V as VerificationState } from "./packem_shared/score.d-a6cl6fPu.js";
|
|
8
8
|
import "./checks/character.js";
|
|
9
9
|
import "./checks/symbol.js";
|
|
10
10
|
import "./checks/tag.js";
|
|
11
11
|
import "./enrich/name.js";
|
|
12
12
|
import '@visulima/email-provider-mx';
|
|
13
13
|
/**
|
|
14
|
-
* Options for `verifyEmail`.
|
|
15
|
-
*/
|
|
14
|
+
* Options for `verifyEmail`.
|
|
15
|
+
*/
|
|
16
16
|
interface VerifyEmailOptions {
|
|
17
17
|
/** Shared cache for MX/SMTP lookups (dedupes work when verifying lists). */
|
|
18
18
|
cache?: Cache<MxCheckResult>;
|
|
19
19
|
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
* Run live SMTP verification (catch-all, mailbox-full, greylist).
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
23
|
checkSmtp?: boolean;
|
|
24
24
|
/** Disposable-list overrides. */
|
|
25
25
|
disposable?: DisposableEmailOptions;
|
|
26
26
|
/** Free-list overrides. */
|
|
27
27
|
free?: FreeEmailOptions;
|
|
28
28
|
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
* Skip all network checks (MX, SMTP, provider) and produce a syntax +
|
|
30
|
+
* heuristic-only report. Overrides `checkSmtp`.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
33
|
offline?: boolean;
|
|
34
34
|
/** Additional role-account prefixes to recognize. */
|
|
35
35
|
roleCustomPrefixes?: Iterable<string>;
|
|
@@ -41,22 +41,22 @@ interface VerifyEmailOptions {
|
|
|
41
41
|
weights?: Partial<ScoreWeights>;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Verifies and enriches a single email address end-to-end.
|
|
45
|
-
*
|
|
46
|
-
* Runs the offline checks (syntax, disposable, free, role, tag, character,
|
|
47
|
-
* symbol, name, typo) immediately, then — unless `offline` is set — resolves the
|
|
48
|
-
* domain's MX and runs the SMTP probe and provider classification concurrently.
|
|
49
|
-
* Everything is aggregated into one {@link EmailVerificationReport} and scored.
|
|
50
|
-
* @param email The email address to verify.
|
|
51
|
-
* @param options Verification options.
|
|
52
|
-
* @returns The complete verification report.
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* import { verifyEmail } from "@visulima/email-verifier";
|
|
56
|
-
*
|
|
57
|
-
* const report = await verifyEmail("user@gmail.com");
|
|
58
|
-
* console.log(report.state, report.score); // "deliverable" 95
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
44
|
+
* Verifies and enriches a single email address end-to-end.
|
|
45
|
+
*
|
|
46
|
+
* Runs the offline checks (syntax, disposable, free, role, tag, character,
|
|
47
|
+
* symbol, name, typo) immediately, then — unless `offline` is set — resolves the
|
|
48
|
+
* domain's MX and runs the SMTP probe and provider classification concurrently.
|
|
49
|
+
* Everything is aggregated into one {@link EmailVerificationReport} and scored.
|
|
50
|
+
* @param email The email address to verify.
|
|
51
|
+
* @param options Verification options.
|
|
52
|
+
* @returns The complete verification report.
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { verifyEmail } from "@visulima/email-verifier";
|
|
56
|
+
*
|
|
57
|
+
* const report = await verifyEmail("user@gmail.com");
|
|
58
|
+
* console.log(report.state, report.score); // "deliverable" 95
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
61
|
declare const verifyEmail: (email: string, options?: VerifyEmailOptions) => Promise<EmailVerificationReport>;
|
|
62
62
|
export { type EmailVerificationReport, type VerifyEmailOptions, verifyEmail as default, verifyEmail };
|
package/dist/verify-email.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{analyzeCharacters as h}from"./checks/character.js";import{checkMxRecords as v}from"./checks/mx.js";import x,{isNoReply as b}from"./checks/role.js";import g from"./checks/smtp.js";import{analyzeSymbols as w}from"./checks/symbol.js";import V from"./checks/syntax.js";import E from"./checks/tag.js";import R from"./enrich/name.js";import
|
|
1
|
+
import{analyzeCharacters as h}from"./checks/character.js";import{checkMxRecords as v}from"./checks/mx.js";import x,{isNoReply as b}from"./checks/role.js";import g from"./checks/smtp.js";import{analyzeSymbols as w}from"./checks/symbol.js";import V from"./checks/syntax.js";import E from"./checks/tag.js";import R from"./enrich/name.js";import k from"./enrich/typo.js";import{splitAddress as A}from"./packem_shared/extractDomain-CYJf1_0N.js";import f from"./score.js";import{classifyMxRecords as F}from"@visulima/email-provider-mx";import{isFreeEmail as C}from"@visulima/free-email-domains";import{isDisposableEmail as M}from"@visulima/disposable-email-domains";const p=(e,a)=>({character:h(e),didYouMean:k(e,a.typo)?.full,disposable:M(e,a.disposable),free:C(e,a.free),name:R(e),noReply:b(e),role:x(e,a.roleCustomPrefixes),symbol:w(e),tag:E(e)}),J=async(e,a={})=>{const{checkSmtp:n=!0,offline:u=!1}=a,r=A(e),d=r?.address??(typeof e=="string"?e.trim().toLowerCase():"");if(!V(r?.address??e)||!r){const s={...p(d,a),acceptAll:!1,deferred:!1,domain:{records:[],resolvedVia:"unchecked",valid:!1},email:d,mailboxFull:!1,secureEmailGateway:!1,syntaxValid:!1};return{...s,...f(s,a.weights)}}const y=p(r.address,a);let t={records:[],resolvedVia:"unchecked",valid:!1},o,l,m=!1;if(!u){const s=await v(r.domain,{cache:a.cache});t={deferred:s.deferred,records:s.records??[],resolvedVia:s.resolvedVia,valid:s.valid};const i=s.records??[];s.valid&&i.length>0&&(l=F(i),m=l?.type==="seg",n&&(o=await g(r.address,{cache:a.cache,...a.smtp,mxRecords:i})))}const c={...y,acceptAll:o?.acceptAll??!1,deferred:o?.deferred??!1,domain:t,email:r.address,mailboxFull:o?.mailboxFull??!1,provider:l,secureEmailGateway:m,smtp:o,syntaxValid:!0};return{...c,...f(c,a.weights)}};export{J as default,J as verifyEmail};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/email-verifier",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Mailer-free email address verification and enrichment: syntax, MX/SMTP probing, disposable/free/role detection, catch-all, provider & secure-email-gateway classification, typo suggestions, and a 0–100 quality score.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accept-all",
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
],
|
|
20
20
|
"homepage": "https://visulima.com/packages/email-verifier",
|
|
21
21
|
"bugs": "https://github.com/visulima/visulima/issues",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": {
|
|
24
|
+
"name": "Daniel Bannert",
|
|
25
|
+
"email": "d.bannert@anolilab.de"
|
|
26
|
+
},
|
|
22
27
|
"repository": {
|
|
23
28
|
"type": "git",
|
|
24
29
|
"url": "git+https://github.com/visulima/visulima.git",
|
|
@@ -34,13 +39,13 @@
|
|
|
34
39
|
"url": "https://anolilab.com/support"
|
|
35
40
|
}
|
|
36
41
|
],
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
"sideEffects": false,
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"README.md",
|
|
45
|
+
"CHANGELOG.md"
|
|
46
|
+
],
|
|
43
47
|
"type": "module",
|
|
48
|
+
"sideEffects": false,
|
|
44
49
|
"exports": {
|
|
45
50
|
".": {
|
|
46
51
|
"types": "./dist/index.d.ts",
|
|
@@ -104,22 +109,17 @@
|
|
|
104
109
|
},
|
|
105
110
|
"./package.json": "./package.json"
|
|
106
111
|
},
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
|
|
111
|
-
],
|
|
112
|
+
"publishConfig": {
|
|
113
|
+
"access": "public",
|
|
114
|
+
"provenance": true
|
|
115
|
+
},
|
|
112
116
|
"dependencies": {
|
|
113
|
-
"@visulima/disposable-email-domains": "1.
|
|
114
|
-
"@visulima/email-provider-mx": "1.0.
|
|
115
|
-
"@visulima/free-email-domains": "1.0.
|
|
117
|
+
"@visulima/disposable-email-domains": "1.1.0",
|
|
118
|
+
"@visulima/email-provider-mx": "1.0.1",
|
|
119
|
+
"@visulima/free-email-domains": "1.0.1",
|
|
116
120
|
"lru-cache": "11.5.1"
|
|
117
121
|
},
|
|
118
122
|
"engines": {
|
|
119
123
|
"node": "^22.14.0 || >=24.10.0"
|
|
120
|
-
},
|
|
121
|
-
"publishConfig": {
|
|
122
|
-
"access": "public",
|
|
123
|
-
"provenance": true
|
|
124
124
|
}
|
|
125
125
|
}
|