@email-utils/validator-syntax
The API of @email-utils/validator-syntax 1.0.0-rc.4.
Interfaces
AddressComment
A comment lifted out of an address.
Properties
position
position:
| "before-local"
| "inside-local"
| "after-local"
| "before-domain"
| "inside-domain"
| "after-domain";Where the comment sat. RFC 5322's obsolete syntax also allows comments
between the words of the local part and the labels of the domain
(test.(comment)test@example.com): those are inside-local and
inside-domain.
text
text: string;The comment's text, without the parentheses.
ParsedAddress
An address split into its parts, as parseAddress returns it.
Properties
comments
comments: AddressComment[];Comments in input order; empty when there are none or they aren't allowed.
domain
domain: string;The domain, without comments or folding whitespace.
local
local: string;The local part, without comments or folding whitespace.
tld?
optional tld?: string;The last label; absent for a domain literal, or a dotless domain the preset allows.
SyntaxOptions
Options for parseAddress and the other entry points.
Properties
allowComments?
optional allowComments?: boolean;Accept RFC 5322 comments, like ada(work)@example.com. In practical
they may sit only at the ends of the local part and the domain; in
rfc5322, around every word and label too.
Remarks
Throws TypeError when true with rfc5321 or html5, whose grammars
have no comments.
Default Value
true in rfc5322, false elsewhere
allowIdn?
optional allowIdn?: boolean;Accept internationalized domain names written as U-labels, like
ada@bücher.example. Each label must convert to an A-label
(xn--bcher-kva) under UTS #46, and the 63 and 253 caps apply to the
A-label form. ParsedAddress.domain and tld keep the labels as
written. A-labels are hostname labels, so every preset accepts them
without this.
Remarks
Throws TypeError when true with html5, whose grammar is ASCII.
Default Value
false
allowIpLiteral?
optional allowIpLiteral?: boolean;Accept a domain literal: an IPv4 or IPv6: address literal
(ada@[192.0.2.1]), or in rfc5322, any text its grammar allows in
brackets. false turns them off in the RFC presets.
Remarks
Throws TypeError when true with html5, whose grammar has none.
Default Value
true in rfc5321 and rfc5322, false elsewhere
allowNoTld?
optional allowNoTld?: boolean;Accept a domain with no dot, like localhost.
Default Value
true in html5, false elsewhere
allowUnicode?
optional allowUnicode?: boolean;Accept non-ASCII characters in the local part, as RFC 6531 (SMTPUTF8)
does, like 用户@example.com: in atoms and quoted strings, and in
comments where they're allowed. The 64 cap then counts UTF-8 octets.
Remarks
Throws TypeError when true with html5, whose grammar is ASCII.
Default Value
false
checkTld?
optional checkTld?: boolean;Check the TLD against the IANA set.
Default Value
true in practical, false elsewhere
maxLength?
optional maxLength?: number;The longest input accepted, counted in UTF-16 code units, as
email.length counts. Longer input fails as syntax.address.too_long
before it's scanned, so it's rejected in constant time however long it
is. A positive integer, or Infinity for no limit.
Remarks
The address caps (254 characters, and 64 and 253 for the local part and
domain where the preset has them) still apply within it. This bounds the
input as written, comments and folding whitespace included, which those
caps don't count. Throws TypeError when it isn't a positive integer or
Infinity.
Default Value
512 in every preset
preset?
optional preset?: Preset;The base rule set:
practical: what real mailboxes look like. Dot-atom local parts, hostname domains, a TLD from the IANA set.rfc5321: what SMTP accepts on the wire, quoted local parts and IP address literals included.rfc5322: RFC 5322's full addr-spec, comments, folding whitespace, and obsolete syntax included.html5: exactly what a browser'sinput[type=email]accepts.
Default Value
'practical'
SyntaxValidator
parseAddress and isValidSyntax with options bound.
Properties
maxLength
readonly maxLength: number;The maxLength this validator applies: the one in its options, or the
default, 512. Infinity when there's no limit.
Remarks
For a dependent that trims or otherwise pre-processes input before parsing it: checking the raw input's length against this first rejects oversized input before any of that work, and padding can't carry input past the limit. The validator is frozen, so this can't be reassigned.
Example
import { createSyntaxValidator } from '@email-utils/validator-syntax';
createSyntaxValidator().maxLength; // => 512
createSyntaxValidator({ maxLength: 1024 }).maxLength; // => 1024
const validator = createSyntaxValidator();
const padded = `${' '.repeat(600)}ada@example.com`;
padded.length > validator.maxLength; // => true
validator.isValid(padded.trim()); // => trueMethods
isValid()
isValid(email): boolean;Parameters
| Parameter | Type |
|---|---|
email | string |
Returns
boolean
parse()
parse(email): Result<ParsedAddress>;Parameters
| Parameter | Type |
|---|---|
email | string |
Returns
Type Aliases
Preset
type Preset = "practical" | "rfc5321" | "rfc5322" | "html5";A base rule set; see SyntaxOptions.preset.
ReasonCode
type ReasonCode =
| "syntax.address.empty"
| "syntax.address.no_at"
| "syntax.address.too_long"
| "syntax.local.empty"
| "syntax.local.too_long"
| "syntax.local.invalid_char"
| "syntax.local.consecutive_dots"
| "syntax.local.unquoted_space"
| "syntax.domain.empty"
| "syntax.domain.no_dot"
| "syntax.domain.label_invalid"
| "syntax.domain.literal_invalid"
| "syntax.domain.too_long"
| "syntax.domain.invalid_char"
| "syntax.comment.not_allowed"
| "syntax.comment.unterminated"
| "syntax.tld.unknown";The syntax.* codes from the reason-code catalogue
(https://email-utils.github.io/meta/docs/reference/reason-codes#validator-syntax).
Result
type Result<T> =
| {
ok: true;
value: T;
}
| {
index?: number;
message?: string;
ok: false;
reason: ReasonCode;
};A validation result: the value on success, or the first check that failed.
Branch on reason, never on message, which isn't semver-stable.
Type Parameters
| Type Parameter |
|---|
T |
Functions
createSyntaxValidator()
function createSyntaxValidator(options?): SyntaxValidator;Binds options once, checking them up front, and returns
parseAddress and isValidSyntax with them applied, and the
maxLength they resolve to. The validator is frozen.
Parameters
| Parameter | Type |
|---|---|
options? | SyntaxOptions |
Returns
Example
import { createSyntaxValidator } from '@email-utils/validator-syntax';
const strict = createSyntaxValidator({ preset: 'rfc5321' });
strict.parse('a b@example.com');
// => { ok: false, reason: 'syntax.local.unquoted_space', index: 1 }
strict.isValid('"a b"@example.com'); // => true
createSyntaxValidator({ preset: 'html5', allowComments: true });
// => throws TypeErrorThrows
TypeError when options are malformed.
isValidSyntax()
function isValidSyntax(email, options?): boolean;Whether email is well-formed: exactly parseAddress(email, options).ok.
Parameters
| Parameter | Type |
|---|---|
email | string |
options? | SyntaxOptions |
Returns
boolean
Example
import { isValidSyntax } from '@email-utils/validator-syntax';
isValidSyntax('ada@example.com'); // => true
isValidSyntax('"ada"@example.com'); // => false
isValidSyntax('"ada"@example.com', { preset: 'rfc5321' }); // => trueThrows
TypeError when email isn't a string, or options are malformed.
parseAddress()
function parseAddress(email, options?): Result<ParsedAddress>;Parses email into its local part, domain, TLD, and comments, or returns
the first check it fails.
Parameters
| Parameter | Type |
|---|---|
email | string |
options? | SyntaxOptions |
Returns
Remarks
Input longer than maxLength (512 UTF-16 code units by default) fails as
syntax.address.too_long before it's scanned. Otherwise the local part is
checked left to right, then its length; then the domain, left to right,
then its length; then the address length, a dotless domain, and the TLD.
index, where a failure has one, points at the offending character.
Example
import { parseAddress } from '@email-utils/validator-syntax';
parseAddress('ada.lovelace@example.co.uk');
// => { ok: true, value: { local: 'ada.lovelace', tld: 'uk' } }
parseAddress('ada..lovelace@example.com');
// => { ok: false, reason: 'syntax.local.consecutive_dots', index: 4 }Throws
TypeError when email isn't a string, or options are malformed.