Skip to content

Commit 0f7fe77

Browse files
committed
add type decleration
1 parent bd85671 commit 0f7fe77

File tree

7 files changed

+94
-48
lines changed

7 files changed

+94
-48
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
11
# Email Validator
2+
3+
, , disposable email blacklists, DNS records and SMTP server response.
4+
5+
- Validates RFC compliant regex.
6+
- Validates common typos e.g. [email protected].
7+
- Validates email was not generated by disposable email service.
8+
- Validates MX records are present on DNS.
9+
- Validates SMTP server is running and mailbox exists.
10+
- Native typescript support
11+
12+
```
13+
yarn add deep-email-validator
14+
```

package.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
{
2-
"name": "email-validator",
3-
"version": "0.1.0",
2+
"name": "deep-email-validator",
3+
"version": "0.1.2",
44
"description": "Validates emails based on regex, common typos, disposable email blacklists, DNS records and SMTP server response.",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
57
"repository": {
68
"type": "git",
79
"url": "https://github.com/mfbx9da4/email-validator"
810
},
911
"author": "David Alberto Adler",
1012
"license": "MIT",
13+
"keywords": [
14+
"email-validation",
15+
"email-typos",
16+
"email-regex",
17+
"disposable-emails",
18+
"smtp",
19+
"mx-records"
20+
],
1121
"scripts": {
1222
"start": "yarn serve",
1323
"build": "tsc",

src/output/output.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,45 @@
1-
export type ValidatorOutput = {
1+
import { ElementType } from '../types'
2+
3+
const OrderedLevels = ['regex', 'typo', 'disposable', 'mx', 'smtp'] as const
4+
5+
export type SubOutputFormat = {
26
valid: boolean
37
reason?: string
48
}
59

6-
const NullOutputFormat = {
10+
const NullOutputFormat: OutputFormat = {
711
valid: true,
812
validators: {
9-
regex: { valid: true } as ValidatorOutput,
10-
typo: { valid: true } as ValidatorOutput,
11-
disposable: { valid: true } as ValidatorOutput,
12-
mx: { valid: true } as ValidatorOutput,
13-
smtp: { valid: true } as ValidatorOutput,
13+
regex: { valid: true },
14+
typo: { valid: true },
15+
disposable: { valid: true },
16+
mx: { valid: true },
17+
smtp: { valid: true },
1418
},
1519
}
16-
17-
export type OutputFormat = typeof NullOutputFormat
18-
19-
type Levels = keyof OutputFormat['validators']
20+
type Level = ElementType<typeof OrderedLevels>
21+
export type OutputFormat = SubOutputFormat & {
22+
validators: {
23+
[K in Level]: SubOutputFormat
24+
}
25+
}
2026

2127
export const createOutput = (
22-
failLevel?: Levels,
28+
failLevel?: Level,
2329
failReason?: string
2430
): OutputFormat => {
25-
const levels = Object.typedKeys(NullOutputFormat.validators)
26-
const out: OutputFormat = NullOutputFormat
27-
for (let i = 0; i < levels.length; i++) {
28-
const level = levels[i]
31+
const out = NullOutputFormat
32+
let valid = true
33+
for (let i = 0; i < OrderedLevels.length; i++) {
34+
const level = OrderedLevels[i]
2935
let reason
3036
if (level === failLevel) {
31-
out.valid = false
37+
valid = false
38+
out.valid = valid
3239
reason = failReason
40+
out.reason = failLevel
3341
}
34-
out.validators[level] = { valid: out.valid, reason }
42+
out.validators[level] = { valid: valid, reason }
3543
}
3644
return out
3745
}

src/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
export {}
21
declare global {
32
interface ObjectConstructor {
43
typedKeys<T>(o: T): Array<keyof T>
54
}
65
}
76
Object.typedKeys = Object.keys as any
7+
8+
export type ElementType<
9+
T extends ReadonlyArray<unknown>
10+
> = T extends ReadonlyArray<infer ElementType> ? ElementType : never

test/__snapshots__/index.test.ts.snap

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,66 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`validation tests bad username 1`] = `
3+
exports[`validation tests fails with bad dns 1`] = `
44
Object {
5+
"reason": "mx",
56
"valid": false,
67
"validators": Object {
78
"disposable": Object {
89
"reason": undefined,
9-
"valid": false,
10+
"valid": true,
1011
},
1112
"mx": Object {
12-
"reason": undefined,
13+
"reason": "MX record not found",
1314
"valid": false,
1415
},
1516
"regex": Object {
1617
"reason": undefined,
17-
"valid": false,
18+
"valid": true,
1819
},
1920
"smtp": Object {
20-
"reason": "Invalid Mailbox",
21+
"reason": undefined,
2122
"valid": false,
2223
},
2324
"typo": Object {
2425
"reason": undefined,
25-
"valid": false,
26+
"valid": true,
2627
},
2728
},
2829
}
2930
`;
3031

31-
exports[`validation tests fails with bad dns 1`] = `
32+
exports[`validation tests fails with bad mailbox 1`] = `
3233
Object {
34+
"reason": "smtp",
3335
"valid": false,
3436
"validators": Object {
3537
"disposable": Object {
3638
"reason": undefined,
37-
"valid": false,
39+
"valid": true,
3840
},
3941
"mx": Object {
40-
"reason": "MX record not found",
41-
"valid": false,
42+
"reason": undefined,
43+
"valid": true,
4244
},
4345
"regex": Object {
4446
"reason": undefined,
45-
"valid": false,
47+
"valid": true,
4648
},
4749
"smtp": Object {
48-
"reason": undefined,
50+
"reason": "Invalid Mailbox",
4951
"valid": false,
5052
},
5153
"typo": Object {
5254
"reason": undefined,
53-
"valid": false,
55+
"valid": true,
5456
},
5557
},
5658
}
5759
`;
5860

5961
exports[`validation tests fails with bad regex 1`] = `
6062
Object {
63+
"reason": "regex",
6164
"valid": false,
6265
"validators": Object {
6366
"disposable": Object {
@@ -84,8 +87,9 @@ Object {
8487
}
8588
`;
8689

87-
exports[`validation tests fails with bad username 1`] = `
90+
exports[`validation tests fails with common typo 1`] = `
8891
Object {
92+
"reason": "typo",
8993
"valid": false,
9094
"validators": Object {
9195
"disposable": Object {
@@ -98,26 +102,27 @@ Object {
98102
},
99103
"regex": Object {
100104
"reason": undefined,
101-
"valid": false,
105+
"valid": true,
102106
},
103107
"smtp": Object {
104-
"reason": "Invalid Mailbox",
108+
"reason": undefined,
105109
"valid": false,
106110
},
107111
"typo": Object {
108-
"reason": undefined,
112+
"reason": "Likely typo, suggested email: [email protected]",
109113
"valid": false,
110114
},
111115
},
112116
}
113117
`;
114118

115-
exports[`validation tests fails with common typo 1`] = `
119+
exports[`validation tests fails with disposable email 1`] = `
116120
Object {
121+
"reason": "disposable",
117122
"valid": false,
118123
"validators": Object {
119124
"disposable": Object {
120-
"reason": undefined,
125+
"reason": "Email was created using a disposable email service",
121126
"valid": false,
122127
},
123128
"mx": Object {
@@ -126,15 +131,15 @@ Object {
126131
},
127132
"regex": Object {
128133
"reason": undefined,
129-
"valid": false,
134+
"valid": true,
130135
},
131136
"smtp": Object {
132137
"reason": undefined,
133138
"valid": false,
134139
},
135140
"typo": Object {
136-
"reason": "Likely typo, suggested email: [email protected]",
137-
"valid": false,
141+
"reason": undefined,
142+
"valid": true,
138143
},
139144
},
140145
}

test/index.test.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ describe('validation tests', () => {
1010
const res = await validate('[email protected]')
1111
expect(res).toMatchSnapshot()
1212
})
13-
// it('fails with bad dns', async () => {
14-
// const res = await validate('[email protected]')
15-
// expect(res).toMatchSnapshot()
16-
// })
17-
it('fails with bad username', async () => {
13+
it('fails with disposable email', async () => {
14+
const res = await validate('[email protected]')
15+
expect(res).toMatchSnapshot()
16+
})
17+
18+
it('fails with bad dns', async () => {
19+
const res = await validate('[email protected]')
20+
expect(res).toMatchSnapshot()
21+
})
22+
23+
it('fails with bad mailbox', async () => {
1824
const res = await validate('[email protected]')
1925
expect(res).toMatchSnapshot()
2026
})

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"allowSyntheticDefaultImports": true,
66
"target": "es6",
77
"noImplicitAny": true,
8+
"declaration": true,
89
"moduleResolution": "node",
910
"sourceMap": true,
1011
"strict": true,

0 commit comments

Comments
 (0)