@email-utils/validator-syntax 0.0.1-9 → 1.0.0-rc.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/LICENSE +21 -0
- package/Readme.md +1 -1
- package/THIRD_PARTY_NOTICES.md +37 -0
- package/dist/fixtures.cjs +2229 -0
- package/dist/fixtures.cjs.map +1 -0
- package/dist/fixtures.d.cts +247 -0
- package/dist/fixtures.d.mts +247 -0
- package/dist/fixtures.mjs +2220 -0
- package/dist/fixtures.mjs.map +1 -0
- package/dist/index.cjs +2310 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +96 -0
- package/dist/index.d.mts +96 -0
- package/dist/index.mjs +2307 -0
- package/dist/index.mjs.map +1 -0
- package/dist/result-CNbJ54oT.d.cts +116 -0
- package/dist/result-CNbJ54oT.d.mts +116 -0
- package/package.json +66 -73
- package/.babelrc +0 -8
- package/.eslintignore +0 -5
- package/.nvmrc +0 -1
- package/.nycrc.json +0 -11
- package/@types/index.d.ts +0 -30
- package/Readme.old.md +0 -103
- package/bin/tag.sh +0 -21
- package/dist/index.js +0 -272
- package/dist/index.js.map +0 -1
- package/src/index.ts +0 -342
- package/test/index.test.ts +0 -1612
- package/tsconfig.json +0 -22
package/src/index.ts
DELETED
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
// VALID EMAIL
|
|
2
|
-
// Attempting to follow rules from https://en.wikipedia.org/wiki/Email_address.
|
|
3
|
-
// Checks if the email is valid.
|
|
4
|
-
import * as tlds from 'tlds/index.json'
|
|
5
|
-
class EmailSyntaxValidator {
|
|
6
|
-
defaultConfig: EmailValidatorConfig = {
|
|
7
|
-
local: {
|
|
8
|
-
alphaUpper: true,
|
|
9
|
-
alphaLower: true,
|
|
10
|
-
numeric: true,
|
|
11
|
-
period: true,
|
|
12
|
-
printable: true,
|
|
13
|
-
quote: true,
|
|
14
|
-
hyphen: true,
|
|
15
|
-
spaces: true,
|
|
16
|
-
},
|
|
17
|
-
domain: {
|
|
18
|
-
alphaUpper: true,
|
|
19
|
-
alphaLower: true,
|
|
20
|
-
numeric: true,
|
|
21
|
-
period: true,
|
|
22
|
-
hyphen: true,
|
|
23
|
-
tld: true,
|
|
24
|
-
localhost: false,
|
|
25
|
-
charsBeforeDot: 1, // -1 means don't check.
|
|
26
|
-
charsAfterDot: 2, // -1 means don't check.
|
|
27
|
-
},
|
|
28
|
-
}
|
|
29
|
-
config: EmailValidatorConfig = this.defaultConfig
|
|
30
|
-
chars = {
|
|
31
|
-
alphaLower: 'abcdefghijklmnopqrstuvwxyz',
|
|
32
|
-
alphaUpper: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
|
33
|
-
numeric: '0123456789',
|
|
34
|
-
dot: ',',
|
|
35
|
-
printable: "!#$%&'*+/=?^_`{|}~",
|
|
36
|
-
space: ' ',
|
|
37
|
-
quote: '"',
|
|
38
|
-
hyphen: '-',
|
|
39
|
-
period: '.',
|
|
40
|
-
}
|
|
41
|
-
email = ''
|
|
42
|
-
originalEmail = ''
|
|
43
|
-
|
|
44
|
-
constructor(configParam: EmailValidatorParam = {} as EmailValidatorParam) {
|
|
45
|
-
let key: keyof EmailValidatorConfig
|
|
46
|
-
|
|
47
|
-
for (key in configParam) {
|
|
48
|
-
const configGroup = configParam[key]
|
|
49
|
-
for (const subKey in configGroup) {
|
|
50
|
-
const subKeyType = subKey as keyof typeof configGroup
|
|
51
|
-
this.config[key][subKeyType] = configGroup[subKeyType]
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
private gatherChars(
|
|
56
|
-
charConfig: LocalValidateConfig | DomainValidateConfig
|
|
57
|
-
): string[] {
|
|
58
|
-
let characters = ''
|
|
59
|
-
|
|
60
|
-
if (charConfig.alphaUpper === true) {
|
|
61
|
-
characters += this.chars.alphaUpper
|
|
62
|
-
}
|
|
63
|
-
if (charConfig.alphaLower === true) {
|
|
64
|
-
characters += this.chars.alphaLower
|
|
65
|
-
}
|
|
66
|
-
if (charConfig.numeric === true) {
|
|
67
|
-
characters += this.chars.numeric
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (charConfig.hyphen === true) {
|
|
71
|
-
characters += this.chars.hyphen
|
|
72
|
-
}
|
|
73
|
-
if ('printable' in charConfig && charConfig.printable === true) {
|
|
74
|
-
characters += this.chars.printable
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if ('spaces' in charConfig && charConfig.spaces === true) {
|
|
78
|
-
characters += this.chars.space
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if ('quote' in charConfig && charConfig.quote === true) {
|
|
82
|
-
characters += this.chars.quote
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (charConfig.period === true) {
|
|
86
|
-
characters += this.chars.period
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return characters.split('')
|
|
90
|
-
}
|
|
91
|
-
private validateGeneral(): boolean {
|
|
92
|
-
// Confirm that there is an at symbol and it isn't the first character.
|
|
93
|
-
const atSymbolIndex = this.email.indexOf('@')
|
|
94
|
-
if (atSymbolIndex < 1) {
|
|
95
|
-
return false
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return true
|
|
99
|
-
}
|
|
100
|
-
private validateChars(chars: string[], charsToValidate: string[]): boolean {
|
|
101
|
-
let quoteOpen = false
|
|
102
|
-
for (let l = 0; l < charsToValidate.length; l++) {
|
|
103
|
-
const letter = charsToValidate[l]
|
|
104
|
-
if (this.config.local.quote) {
|
|
105
|
-
if (letter === '"') {
|
|
106
|
-
quoteOpen = !quoteOpen
|
|
107
|
-
|
|
108
|
-
if (l !== 0 && l !== charsToValidate.length - 1) {
|
|
109
|
-
if (quoteOpen && !(charsToValidate[l - 1] === '.')) {
|
|
110
|
-
return false
|
|
111
|
-
} else if (!quoteOpen && !(charsToValidate[l + 1] === '.')) {
|
|
112
|
-
return false
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const letterInAllowed = chars.indexOf(letter) !== -1
|
|
119
|
-
|
|
120
|
-
if (!letterInAllowed) {
|
|
121
|
-
return false
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return true
|
|
126
|
-
}
|
|
127
|
-
private validateLocal(): boolean {
|
|
128
|
-
const validChars = this.gatherChars(this.config.local)
|
|
129
|
-
let localLetters = this.email.slice(0, this.email.indexOf('@')).split('')
|
|
130
|
-
|
|
131
|
-
if (this.config.local.printable) {
|
|
132
|
-
const percentInLocalIndex = localLetters.indexOf('%')
|
|
133
|
-
|
|
134
|
-
if (percentInLocalIndex !== -1) {
|
|
135
|
-
localLetters = localLetters.slice(0, percentInLocalIndex)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const bangInLocalIndex = localLetters.indexOf('!')
|
|
139
|
-
|
|
140
|
-
if (bangInLocalIndex !== -1) {
|
|
141
|
-
localLetters = localLetters.slice(bangInLocalIndex)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Validate local length
|
|
146
|
-
if (localLetters.length > 64) {
|
|
147
|
-
return false
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const charsValid = this.validateChars(validChars, localLetters)
|
|
151
|
-
|
|
152
|
-
if (!charsValid) {
|
|
153
|
-
return false
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Make sure there are not two periods together.
|
|
157
|
-
const indexOfDoublePeriods = this.email.indexOf('..')
|
|
158
|
-
|
|
159
|
-
if (indexOfDoublePeriods !== -1) {
|
|
160
|
-
// If double periods before at symbol it's invalid.
|
|
161
|
-
const atSymbolIndex = this.email.indexOf('@')
|
|
162
|
-
if (indexOfDoublePeriods > atSymbolIndex) {
|
|
163
|
-
return false
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// If double period is not within quotes.
|
|
167
|
-
const indexOfFirstQuoteInLocal = localLetters.indexOf('"')
|
|
168
|
-
const indexOfLastQuoteInLocal =
|
|
169
|
-
localLetters.length -
|
|
170
|
-
`${localLetters}`.split('').reverse().join('').indexOf('"') -
|
|
171
|
-
1
|
|
172
|
-
|
|
173
|
-
if (indexOfFirstQuoteInLocal < 0 || indexOfLastQuoteInLocal < 0) {
|
|
174
|
-
return false
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
indexOfFirstQuoteInLocal >= indexOfDoublePeriods ||
|
|
179
|
-
indexOfDoublePeriods >= indexOfLastQuoteInLocal
|
|
180
|
-
) {
|
|
181
|
-
return false
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Confirm that there is no spaces that are not surrounded by quotes.
|
|
186
|
-
const indexOfSpace = localLetters.indexOf(' ')
|
|
187
|
-
|
|
188
|
-
if (
|
|
189
|
-
indexOfSpace !== -1 &&
|
|
190
|
-
(localLetters[indexOfSpace + 1] !== '"' ||
|
|
191
|
-
localLetters[indexOfSpace - 1] !== '"')
|
|
192
|
-
) {
|
|
193
|
-
return false
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return true
|
|
197
|
-
}
|
|
198
|
-
private validateDomainParts(domain: string): boolean {
|
|
199
|
-
const dotIndex = domain.lastIndexOf('.')
|
|
200
|
-
|
|
201
|
-
if (dotIndex === -1 && this.config.domain.localhost === false) {
|
|
202
|
-
return false
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (dotIndex !== -1) {
|
|
206
|
-
if (this.config.domain.charsBeforeDot !== -1) {
|
|
207
|
-
if (dotIndex <= this.config.domain.charsBeforeDot) {
|
|
208
|
-
return false
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (this.config.domain.charsAfterDot !== -1) {
|
|
213
|
-
if (dotIndex === domain.length - this.config.domain.charsAfterDot) {
|
|
214
|
-
return false
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (this.config.domain.tld) {
|
|
219
|
-
const tld = domain.slice(dotIndex + 1)
|
|
220
|
-
|
|
221
|
-
let tldExists = false
|
|
222
|
-
|
|
223
|
-
for (let t = 0; t < tlds.length; t++) {
|
|
224
|
-
const currentTld = tlds[t]
|
|
225
|
-
|
|
226
|
-
if (tld.toLowerCase() === currentTld) {
|
|
227
|
-
tldExists = true
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (tldExists) {
|
|
231
|
-
break
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (!tldExists) {
|
|
236
|
-
return false
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return true
|
|
242
|
-
}
|
|
243
|
-
private validateDomain(): boolean {
|
|
244
|
-
// Confirm that there is a dot at least 1 character after the at and 2 characters before the end.
|
|
245
|
-
const domain = this.email.slice(this.email.indexOf('@') + 1)
|
|
246
|
-
|
|
247
|
-
const domainPartsValid = this.validateDomainParts(domain)
|
|
248
|
-
|
|
249
|
-
if (!domainPartsValid) {
|
|
250
|
-
return false
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const validChars = this.gatherChars(this.config.domain)
|
|
254
|
-
const domainLetters = domain.split('')
|
|
255
|
-
|
|
256
|
-
if (this.config.local.printable) {
|
|
257
|
-
const localLetters = this.email
|
|
258
|
-
.slice(0, this.email.indexOf('@'))
|
|
259
|
-
.split('')
|
|
260
|
-
|
|
261
|
-
const percentInLocalIndex = localLetters.indexOf('%')
|
|
262
|
-
|
|
263
|
-
if (percentInLocalIndex !== -1) {
|
|
264
|
-
const relayDomain = localLetters.slice(percentInLocalIndex + 1)
|
|
265
|
-
|
|
266
|
-
const relayDomainPartsValid = this.validateDomainParts(
|
|
267
|
-
relayDomain.join('')
|
|
268
|
-
)
|
|
269
|
-
|
|
270
|
-
if (!relayDomainPartsValid) {
|
|
271
|
-
return false
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const charsValid = this.validateChars(validChars, relayDomain)
|
|
275
|
-
|
|
276
|
-
if (!charsValid) {
|
|
277
|
-
return false
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const bangInLocalIndex = localLetters.indexOf('!')
|
|
282
|
-
|
|
283
|
-
if (bangInLocalIndex !== -1) {
|
|
284
|
-
const relayDomain = localLetters.slice(0, bangInLocalIndex)
|
|
285
|
-
|
|
286
|
-
const relayDomainPartsValid = this.validateDomainParts(
|
|
287
|
-
relayDomain.join('')
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
if (!relayDomainPartsValid) {
|
|
291
|
-
return false
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const charsValid = this.validateChars(validChars, relayDomain)
|
|
295
|
-
|
|
296
|
-
if (!charsValid) {
|
|
297
|
-
return false
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const charsValid = this.validateChars(validChars, domainLetters)
|
|
303
|
-
|
|
304
|
-
if (!charsValid) {
|
|
305
|
-
return false
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return true
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
public async validate(email: string): Promise<boolean> {
|
|
312
|
-
if (typeof email !== 'string') {
|
|
313
|
-
console.error('Email not a string.', email)
|
|
314
|
-
return false
|
|
315
|
-
} else if (!email) {
|
|
316
|
-
console.error('Email not provided.', email)
|
|
317
|
-
return false
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
this.email = email
|
|
321
|
-
// Need to add support for special local chars that are properly quoted.
|
|
322
|
-
// Need to add support for quotes in ().
|
|
323
|
-
const generalValid = this.validateGeneral()
|
|
324
|
-
if (!generalValid) {
|
|
325
|
-
return false
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const localValid = this.validateLocal()
|
|
329
|
-
if (!localValid) {
|
|
330
|
-
return false
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const domainValid = this.validateDomain()
|
|
334
|
-
if (!domainValid) {
|
|
335
|
-
return false
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return true
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export default EmailSyntaxValidator
|