-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathindex.js
99 lines (80 loc) · 2.31 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
'use strict'
const punycode = require('punycode/')
const nearley = require('nearley')
const grammar = nearley.Grammar.fromCompiled(require('./grammar.js'))
grammar.start = 'main'
// a class encapsulating an email address per RFC-5321
class Address {
constructor(user, host) {
if (typeof user === 'object' && user.original) {
// Assume constructing from JSON parse
for (const k in user) {
this[k] = user[k]
}
return this
}
if (!host) {
this.original = user
this.parse(user)
} else {
this.original = `${user}@${host}`
this.user = user
this.original_host = host
if (/[\u0080-\uFFFF]/.test(host)) {
this.is_utf8 = true
host = punycode.toASCII(host)
}
this.host = host.toLowerCase()
}
}
parse(addr) {
// empty addr is ok
if (addr === '' || addr === '<>') {
this.user = ''
this.host = ''
return
}
// bare postmaster is permissible: RFC-5321 (4.1.1.3)
switch (addr.toLowerCase()) {
case 'postmaster':
case '<postmaster>':
this.user = 'postmaster'
this.host = ''
return
}
const parser = new nearley.Parser(grammar)
parser.feed(addr)
const result = parser.results[0][0]
let domainpart = result.domain
this.original_host = domainpart
if (/[\u0080-\uFFFF]/.test(domainpart)) {
this.is_utf8 = true
domainpart = punycode.toASCII(domainpart)
}
this.host = domainpart.toLowerCase()
this.user = result.local_part
}
isNull() {
return this.user ? 0 : 1
}
format(use_punycode) {
if (this.isNull()) return '<>'
return `<${this.address(null, use_punycode)}>`
}
address(set, use_punycode) {
if (set) {
this.original = set
this.parse(set)
}
return (
(this.user || '') +
(this.original_host
? `@${use_punycode ? this.host : this.original_host}`
: '')
)
}
toString() {
return this.format()
}
}
exports.Address = Address