Skip to content

Commit 219fe22

Browse files
authored
Release v2.2.0 (#63)
- feat: option to allow comma in display name #52 - dep(email-addresses): bump from 4.0.0 to 5.0.0 #58 - chore: replace a couple regex with slice (perf & sec) #63 - test: a few more tests to boost coverage #63 - test: drop node 10, add node 16 #61 - ci: restore GH workflow for PRs #57 - ci: add dependabot.yml #55 - doc: add inline documentation for parse #60 - doc(Changes): make PR #s into links #54 - doc(README): add result of console.logs #56 - doc(README): add links to RFC 2822, 5322 #53 - doc(README): enabled syntax highlighting with code fences #51
1 parent 37d2733 commit 219fe22

File tree

11 files changed

+91
-50
lines changed

11 files changed

+91
-50
lines changed

.codeclimate.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
engines:
22
eslint:
33
enabled: true
4-
channel: "eslint-6"
4+
channel: "eslint-8"
55
config:
66
config: ".eslintrc.yaml"
77

88
ratings:
99
paths:
1010
- "**.js"
11+
12+
checks:
13+
method-complexity:
14+
config:
15+
threshold: 10

.github/workflows/coveralls.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ jobs:
1515
with:
1616
fetch-depth: 1
1717

18-
- name: Use Node.js 16
18+
- name: Use Node.js
1919
uses: actions/setup-node@master
20-
with:
21-
node-version: 16.x
2220

2321
- name: install, run
2422
run: |

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule ".release"]
2+
path = .release
3+
url = [email protected]:msimerson/.release.git

.release

Submodule .release added at 0890e94

Changes.md

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,79 @@
11

2-
## 2.1.0 - 2021-02-26
2+
### Unreleased
3+
4+
5+
### [2.2.0] - 2024-02-23
6+
7+
- feat: option to allow comma in display name #52
8+
- dep(email-addresses): bump from 4.0.0 to 5.0.0 #58
9+
- chore: replace a couple regex with slice (perf & sec) #63
10+
- test: a few more tests to boost coverage #63
11+
- test: drop node 10, add node 16 #61
12+
- ci: restore GH workflow for PRs #57
13+
- ci: add dependabot.yml #55
14+
- doc: add inline documentation for parse #60
15+
- doc(Changes): make PR #s into links #54
16+
- doc(README): add result of console.logs #56
17+
- doc(README): add links to RFC 2822, 5322 #53
18+
- doc(README): enabled syntax highlighting with code fences #51
19+
20+
21+
### 2.1.0 - 2021-02-26
322

423
- make parse accept an options object as second argument
524
- allow comma (,) in display name, default off [#52](https://github.com/haraka/node-address-rfc2822/pull/52)
625

726

8-
## 2.0.6 - 2020-11-17
27+
### 2.0.6 - 2020-11-17
928

1029
- replace travis/appveyor CI tests with Github Actions [#48](https://github.com/haraka/node-address-rfc2822/pull/48)
1130
- test: when splitting lines, use os.EOL
1231
- allow @ symbol in display name [#47](https://github.com/haraka/node-address-rfc2822/pull/47)
1332

1433

15-
## 2.0.5 - 2020-06-02
34+
### 2.0.5 - 2020-06-02
1635

1736
- update email-addresses to 3.1.0 [#46](https://github.com/haraka/node-address-rfc2822/pull/46)
1837
- test framework: nodeunit -> mocha
1938

2039

21-
## 2.0.4 - 2018-06-29
40+
### 2.0.4 - 2018-06-29
2241

2342
- throw a proper error object, not a string.
2443

2544

26-
## 2.0.3 - 2018-03-01
45+
### 2.0.3 - 2018-03-01
2746

2847
- use es6 classes
2948
- export the Address class [#29](https://github.com/haraka/node-address-rfc2822/pull/29)
3049

3150

32-
## 2.0.2 - 2018-02-24
51+
### 2.0.2 - 2018-02-24
3352

3453
- Fix a possible regexp backtracking DoS [#28](https://github.com/haraka/node-address-rfc2822/pull/28)
3554

3655

37-
## 2.0.1 - 2017-06-26
56+
### 2.0.1 - 2017-06-26
3857

3958
- trim the line in parse() [#24](https://github.com/haraka/node-address-rfc2822/pull/24)
4059

4160

42-
## 1.0.2 - 2016-06-16
61+
### 1.0.2 - 2016-06-16
4362

4463
- updated for eslint 4 compat [#23](https://github.com/haraka/node-address-rfc2822/pull/23)
4564
- use email-addresses for parser [#20](https://github.com/haraka/node-address-rfc2822/pull/20)
4665

4766

48-
## 1.0.1 - 2016-09-23
67+
### 1.0.1 - 2016-09-23
4968

5069
- use native to[lower|upper]Case functions vs regex
5170
- remove node 0.12 testing
5271
- remove node 0.10, 5, add node 6
5372
- throw error on nothing to parse
5473

5574

56-
## 1.0.0 - 2016-02-23
75+
### 1.0.0 - 2016-02-23
5776

5877
- Initial implementation
78+
79+
[2.2.0]: https://github.com/haraka/node-address-rfc2822/releases/tag/2.2.0

README.md

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,19 @@
33
[![Coverage Status][cov-img]][cov-url]
44

55

6-
address-rfc2822
7-
==================
6+
# address-rfc2822
87

98
Parser for RFC 2822 & 5322 (Header) format email addresses.
109

1110
This module parses RFC 2822 headers containing addresses such as From, To, CC, and BCC headers.
1211

1312
It is almost a direct port of the perl module Mail::Address and I'm grateful to the original authors of that module for the clean code and the tests.
1413

15-
Installation
16-
------------
14+
## Installation
1715

1816
`npm install address-rfc2822`
1917

20-
Usage
21-
-----
18+
## Usage
2219

2320
```js
2421
const addrparser = require('address-rfc2822');
@@ -31,18 +28,15 @@ console.log(`Email name: ${address.name()}`); // Matt Sergeant
3128
console.log(`Reformatted: ${address.format()}`); // Matt Sergeant <[email protected]>
3229
console.log(`User part: ${address.user()}`); // helpme+npm
3330
console.log(`Host part: ${address.host()}`); // gmail.com
34-
3531
```
3632

33+
## More Info
3734

38-
More Info
39-
-------
4035
- [RFC 2822](https://tools.ietf.org/html/rfc2822)
4136
- [RFC 5322](https://tools.ietf.org/html/rfc5322)
4237

4338

44-
License
45-
-------
39+
## License
4640

4741
This module is MIT licensed.
4842

index.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ function _quote_no_esc (str) {
186186
let match;
187187
while ((match = /^[\s\S]*?([\s\S])"/.exec(str))) {
188188
if (match[1] !== '\\') return true;
189-
190189
str = str.substr(match[0].length);
191190
}
192191
return false;
@@ -227,27 +226,32 @@ function _extract_name (name) {
227226
// Using encodings, too hard. See Mail::Message::Field::Full.
228227
if (/=?.*?\?=/.test(name)) return '';
229228

230-
// trim whitespace
231-
name = name.trim();
232-
name = name.replace(/\s+/, ' ');
229+
// trim & condense whitespace
230+
name = name.trim().replace(/\s+/, ' ');
233231

234232
// Disregard numeric names (e.g. [email protected])
235233
if (/^[\d ]+$/.test(name)) return '';
236234

237-
name = name.replace(/^\((.*)\)$/, '$1') // remove outermost parenthesis
238-
.replace(/^"(.*)"$/, '$1') // remove outer quotation marks
239-
.replace(/\(.*?\)/g, '') // remove minimal embedded comments
240-
.replace(/\\/g, '') // remove all escapes
241-
.replace(/^"(.*)"$/, '$1') // remove internal quotation marks
242-
.replace(/^([^\s]+) ?, ?(.*)$/, '$2 $1') // reverse "Last, First M." if applicable
235+
// remove outermost parenthesis
236+
if (name.slice(0,1) === '(' && name.slice(-1) === ')') name = name.slice(1,name.length-1)
237+
238+
// remove outer quotation marks
239+
if (name.slice(0,1) === '"' && name.slice(-1) === '"') name = name.slice(1,name.length-1)
240+
241+
name = name.replace(/\(.*?\)/g, '') // remove minimal embedded comments
242+
.replace(/\\/g, ''); // remove all escapes
243+
244+
// remove internal quotation marks
245+
if (name.slice(0,1) === '"' && name.slice(-1) === '"') name = name.slice(1,name.length-1)
246+
247+
name = name.replace(/^([^\s]+) ?, ?(.*)$/, '$2 $1') // reverse "Last, First M." if applicable
243248
.replace(/,.*/, '');
244249

245250
// Change casing only when the name contains only upper or only
246251
// lower cased characters.
247252
if ( exports.isAllUpper(name) || exports.isAllLower(name) ) {
248-
// console.log("Changing case of: " + name);
253+
// console.log(`Changing case: ${name} to ${exports.nameCase(name)}`);
249254
name = exports.nameCase(name);
250-
// console.log("Now: " + name);
251255
}
252256

253257
// some cleanup

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "address-rfc2822",
3-
"version": "2.1.0",
3+
"version": "2.2.0",
44
"description": "RFC 2822 & 5322 (Header) email address parser",
55
"main": "index.js",
66
"homepage": "https://github.com/haraka/node-address-rfc2822",
@@ -25,9 +25,8 @@
2525
"url": "https://github.com/haraka/node-address-rfc2822.git"
2626
},
2727
"devDependencies": {
28-
"eslint": "*",
29-
"eslint-plugin-haraka": "*",
30-
"mocha": "*"
28+
"eslint": "8.56.0",
29+
"eslint-plugin-haraka": "1.0.15"
3130
},
3231
"license": "MIT",
3332
"dependencies": {

test/Address.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
1-
const assert = require('assert')
1+
const assert = require('node:assert/strict')
22

33
const address = require('../index')
44

55

66
describe('Address', function () {
7-
it('host', function (done) {
7+
it('host', function () {
88
const r = new address.Address(null, '[email protected]');
99
assert.equal(r.host(), 'example.com');
10-
done();
1110
})
1211

13-
it('user', function (done) {
12+
it('host, email missing domain', function () {
13+
const r = new address.Address(null, 'user');
14+
assert.equal(r.host(), null);
15+
})
16+
17+
it('user', function () {
1418
const r = new address.Address(null, '[email protected]');
1519
assert.equal(r.user(), 'user');
16-
done();
20+
})
21+
22+
it('host, user missing domain', function () {
23+
const r = new address.Address(null, 'user');
24+
assert.equal(r.user(), null);
1725
})
1826
})

test/basic.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
const assert = require('assert')
2+
const assert = require('node:assert/strict')
33
const fs = require('fs')
44
const path = require('path')
55

@@ -8,14 +8,18 @@ const parse = require('../index').parse;
88
const raw_data = fs.readFileSync(path.join(__dirname, 'emails.txt'), "UTF-8");
99
const EOLRE = new RegExp(require('os').EOL)
1010

11-
const tests = raw_data.split(/\n\n/).map(function (rows) {
11+
const tests = raw_data.split(/\n\n/).map((rows) => {
1212
const lines = rows.split(EOLRE);
1313
// console.log(lines)
1414
if (lines[0] === '') lines.shift();
1515
return lines.filter((l) => { return !/^#/.test(l) });
1616
});
1717

18-
describe('basic parse', function () {
18+
describe('parse', function () {
19+
20+
it('throws on empty line', function () {
21+
assert.throws(() => { parse(''); }, { message: 'Nothing to parse' })
22+
})
1923

2024
tests.forEach(function (test) {
2125

@@ -29,7 +33,7 @@ describe('basic parse', function () {
2933
// console.log(`Parsed: ${parsed}`);
3034

3135
for (const k in details) {
32-
assert.strictEqual(parsed[k](), details[k], `Test '${k}' for '${parsed[k]()}' = '${details[k]}' from ${JSON.stringify(parsed)}`);
36+
assert.equal(parsed[k](), details[k], `Test '${k}' for '${parsed[k]()}' = '${details[k]}' from ${JSON.stringify(parsed)}`);
3337
}
3438
})
3539
})

0 commit comments

Comments
 (0)