Skip to content

Commit 1749b78

Browse files
committed
Replaced async with asynckit. Modernized
- Dropped support for [email protected] - Cleaned up code and tools.
1 parent 158443d commit 1749b78

7 files changed

Lines changed: 95 additions & 113 deletions

File tree

.eslintrc

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
11
{
2-
"env": {
3-
"node": true,
4-
"browser": false
5-
},
62
"rules": {
7-
// 2-space indentation
83
"indent": [2, 2, {"SwitchCase": 1}],
9-
// Require strings to use single quotes
104
"quotes": [2, "single"],
11-
// Allow only unix line-endings
125
"linebreak-style": [2, "unix"],
13-
// Always require semicolons
146
"semi": [2, "always"],
15-
// Require curly braces for multi-line control statements
167
"curly": [2, "multi-line"],
17-
// Always handle callback error cases
188
"handle-callback-err": [2, "^err"],
19-
// Require JSDoc for all function definitions
209
"valid-jsdoc": [2, {
2110
"requireReturn": false,
2211
"requireReturnDescription": false,
@@ -31,34 +20,24 @@
3120
}],
3221
"no-redeclare": [2, { "builtinGlobals": true }],
3322
"no-shadow": [2, { "builtinGlobals": true, "hoist": "all" }],
34-
// Disallow using variables before they've been defined
35-
// functions are ok
3623
"no-use-before-define": [2, "nofunc"],
3724
"no-shadow-restricted-names": 2,
3825
"no-extra-semi": 2,
39-
// Disallow unused variables
4026
"no-unused-vars": 2,
4127
"no-undef": 2,
42-
// Use if () { }
43-
// ^ space
44-
"keyword-spacing": 2,
45-
// Use if () { }
46-
// ^ space
47-
"space-before-blocks": [2, "always"],
48-
// eslint can't handle this, so the check is disabled.
28+
"no-irregular-whitespace": 2,
29+
"no-console": 2,
4930
"key-spacing": 0,
5031
"strict": 0,
51-
// Do not force dot-notation
5232
"dot-notation": 0,
5333
"eol-last": 0,
5434
"no-new": 0,
5535
"semi-spacing": 0,
56-
// Allow multi spaces around operators since they are
57-
// used for alignment. This is not consistent in the
58-
// code.
5936
"no-multi-spaces": 0,
6037
"eqeqeq": 0,
6138
"no-mixed-requires": 0,
62-
"no-console": 0
39+
},
40+
"env": {
41+
"node": true
6342
}
6443
}

.istanbul.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ reporting:
1111
- json
1212
dir: ./coverage
1313
watermarks:
14-
statements: [80, 95]
15-
lines: [80, 95]
16-
functions: [80, 95]
17-
branches: [80, 95]
14+
statements: [90, 95]
15+
lines: [90, 95]
16+
functions: [90, 95]
17+
branches: [90, 95]

.travis.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
11
sudo: false
2+
23
language: node_js
34
node_js:
4-
- "0.10"
55
- "0.12"
66
- "iojs"
77
- "4"
88
- "5"
99
- "6"
10+
11+
os:
12+
- osx
13+
- linux
14+
15+
install:
16+
- travis_retry npm install
17+
1018
script:
19+
- uname -a
1120
- node --version
1221
- npm --version
13-
- npm run lint
22+
- npm run ci-lint
1423
- npm run test
15-
after_script:
24+
- npm run check
25+
26+
after_success:
1627
- "cat coverage/lcov.info | ./node_modules/.bin/coveralls"
28+
1729
notifications:
1830
webhooks:
1931
urls:

Readme.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ A library to create readable ```"multipart/form-data"``` streams. Can be used to
55
The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd].
66

77
[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface
8-
[streams2-thing]: http://nodejs.org/api/stream.html#stream_compatibility_with_older_node_versions
98

10-
[![Linux Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=linux:0.10-6.x)](https://travis-ci.org/form-data/form-data)
11-
[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/form-data/master.svg?label=windows:0.10-6.x)](https://ci.appveyor.com/project/alexindigo/form-data)
12-
[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/master.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master)
9+
[![Linux Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=linux:0.12-6.x)](https://travis-ci.org/form-data/form-data)
10+
[![MacOS Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=macos:0.12-6.x)](https://travis-ci.org/form-data/form-data)
11+
[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/form-data/master.svg?label=windows:0.12-6.x)](https://ci.appveyor.com/project/alexindigo/form-data)
1312

13+
[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/master.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master)
1414
[![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data)
1515
[![bitHound Overall Score](https://www.bithound.io/github/form-data/form-data/badges/score.svg)](https://www.bithound.io/github/form-data/form-data)
1616

@@ -210,7 +210,7 @@ fetch('http://example.com', { method: 'POST', body: form })
210210
## Notes
211211

212212
- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround.
213-
- If it feels like FormData hangs after submit, please check [Compatibility with Older Node Versions][streams2-thing]
213+
- Starting version `2.x` FormData has dropped support for `[email protected]`.
214214

215215
## License
216216

appveyor.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
environment:
22
matrix:
3-
- nodejs_version: '0.10'
43
- nodejs_version: '0.12'
54
- nodejs_version: '1.0'
65
- nodejs_version: '4'

lib/form_data.js

Lines changed: 59 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var https = require('https');
66
var parseUrl = require('url').parse;
77
var fs = require('fs');
88
var mime = require('mime-types');
9-
var async = require('async');
9+
var asynckit = require('asynckit');
1010
var populate = require('./populate.js');
1111

1212
// Public API
@@ -24,12 +24,12 @@ util.inherits(FormData, CombinedStream);
2424
*/
2525
function FormData() {
2626
if (!(this instanceof FormData)) {
27-
throw new TypeError('Failed to construct FormData: Please use the _new_ operator, this object constructor cannot be called as a function.');
27+
return new FormData();
2828
}
2929

3030
this._overheadLength = 0;
3131
this._valueLength = 0;
32-
this._lengthRetrievers = [];
32+
this._valuesToMeasure = [];
3333

3434
CombinedStream.call(this);
3535
}
@@ -101,60 +101,62 @@ FormData.prototype._trackLength = function(header, value, options) {
101101

102102
// no need to bother with the length
103103
if (!options.knownLength) {
104-
this._lengthRetrievers.push(function(next) {
105-
106-
if (value.hasOwnProperty('fd')) {
107-
108-
// take read range into a account
109-
// `end` = Infinity –> read file till the end
110-
//
111-
// TODO: Looks like there is bug in Node fs.createReadStream
112-
// it doesn't respect `end` options without `start` options
113-
// Fix it when node fixes it.
114-
// https://github.com/joyent/node/issues/7819
115-
if (value.end != undefined && value.end != Infinity && value.start != undefined) {
116-
117-
// when end specified
118-
// no need to calculate range
119-
// inclusive, starts with 0
120-
next(null, value.end + 1 - (value.start ? value.start : 0));
121-
122-
// not that fast snoopy
123-
} else {
124-
// still need to fetch file size from fs
125-
fs.stat(value.path, function(err, stat) {
126-
127-
var fileSize;
128-
129-
if (err) {
130-
next(err);
131-
return;
132-
}
133-
134-
// update final size based on the range options
135-
fileSize = stat.size - (value.start ? value.start : 0);
136-
next(null, fileSize);
137-
});
104+
this._valuesToMeasure.push(value);
105+
}
106+
};
107+
108+
FormData.prototype._lengthRetriever = function(value, callback) {
109+
110+
if (value.hasOwnProperty('fd')) {
111+
112+
// take read range into a account
113+
// `end` = Infinity –> read file till the end
114+
//
115+
// TODO: Looks like there is bug in Node fs.createReadStream
116+
// it doesn't respect `end` options without `start` options
117+
// Fix it when node fixes it.
118+
// https://github.com/joyent/node/issues/7819
119+
if (value.end != undefined && value.end != Infinity && value.start != undefined) {
120+
121+
// when end specified
122+
// no need to calculate range
123+
// inclusive, starts with 0
124+
callback(null, value.end + 1 - (value.start ? value.start : 0));
125+
126+
// not that fast snoopy
127+
} else {
128+
// still need to fetch file size from fs
129+
fs.stat(value.path, function(err, stat) {
130+
131+
var fileSize;
132+
133+
if (err) {
134+
callback(err);
135+
return;
138136
}
139137

140-
// or http response
141-
} else if (value.hasOwnProperty('httpVersion')) {
142-
next(null, +value.headers['content-length']);
143-
144-
// or request stream http://github.com/mikeal/request
145-
} else if (value.hasOwnProperty('httpModule')) {
146-
// wait till response come back
147-
value.on('response', function(response) {
148-
value.pause();
149-
next(null, +response.headers['content-length']);
150-
});
151-
value.resume();
152-
153-
// something else
154-
} else {
155-
next('Unknown stream');
156-
}
138+
// update final size based on the range options
139+
fileSize = stat.size - (value.start ? value.start : 0);
140+
callback(null, fileSize);
141+
});
142+
}
143+
144+
// or http response
145+
} else if (value.hasOwnProperty('httpVersion')) {
146+
callback(null, +value.headers['content-length']);
147+
148+
// or request stream http://github.com/mikeal/request
149+
} else if (value.hasOwnProperty('httpModule')) {
150+
// wait till response come back
151+
value.on('response', function(response) {
152+
value.pause();
153+
callback(null, +response.headers['content-length']);
157154
});
155+
value.resume();
156+
157+
// something else
158+
} else {
159+
callback('Unknown stream');
158160
}
159161
};
160162

@@ -291,18 +293,6 @@ FormData.prototype.getHeaders = function(userHeaders) {
291293
return formHeaders;
292294
};
293295

294-
// TODO: Looks like unused function
295-
FormData.prototype.getCustomHeaders = function(contentType) {
296-
contentType = contentType ? contentType : 'multipart/form-data';
297-
298-
var formHeaders = {
299-
'content-type': contentType + '; boundary=' + this.getBoundary(),
300-
'content-length': this.getLengthSync()
301-
};
302-
303-
return formHeaders;
304-
};
305-
306296
FormData.prototype.getBoundary = function() {
307297
if (!this._boundary) {
308298
this._generateBoundary();
@@ -335,7 +325,7 @@ FormData.prototype.getLengthSync = function() {
335325
}
336326

337327
// https://github.com/form-data/form-data/issues/40
338-
if (this._lengthRetrievers.length) {
328+
if (this._valuesToMeasure.length) {
339329
// Some async length retrievers are present
340330
// therefore synchronous length calculation is false.
341331
// Please use getLength(callback) to get proper length
@@ -352,12 +342,12 @@ FormData.prototype.getLength = function(cb) {
352342
knownLength += this._lastBoundary().length;
353343
}
354344

355-
if (!this._lengthRetrievers.length) {
345+
if (!this._valuesToMeasure.length) {
356346
process.nextTick(cb.bind(this, null, knownLength));
357347
return;
358348
}
359349

360-
async.parallel(this._lengthRetrievers, function(err, values) {
350+
asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) {
361351
if (err) {
362352
cb(err);
363353
return;

package.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"pretest": "rimraf coverage test/tmp",
1414
"test": "istanbul cover test/run.js",
1515
"posttest": "istanbul report lcov text",
16-
"lint": "eslint lib/*.js test/*.js test/**/*.js",
16+
"lint": "eslint lib/*.js test/*.js test/integration/*.js",
17+
"ci-lint": "is-node-modern && npm run lint || is-node-not-modern",
1718
"predebug": "rimraf coverage test/tmp",
1819
"debug": "verbose=1 ./test/run.js",
1920
"check": "istanbul check-coverage coverage/coverage*.json",
@@ -30,21 +31,22 @@
3031
"check"
3132
],
3233
"engines": {
33-
"node": ">= 0.10"
34+
"node": ">= 0.12"
3435
},
3536
"dependencies": {
36-
"async": "^2.0.1",
37+
"asynckit": "^0.4.0",
3738
"combined-stream": "^1.0.5",
3839
"mime-types": "^2.1.11"
3940
},
4041
"devDependencies": {
41-
"coveralls": "^2.11.12",
42+
"coveralls": "^2.11.13",
4243
"cross-spawn": "^4.0.0",
43-
"eslint": "^2.13.1",
44+
"eslint": "^3.5.0",
4445
"fake": "^0.2.2",
4546
"far": "^0.0.7",
4647
"formidable": "^1.0.17",
4748
"in-publish": "^2.0.0",
49+
"is-node-modern": "^1.0.0",
4850
"istanbul": "^0.4.5",
4951
"pkgfiles": "^2.3.0",
5052
"pre-commit": "^1.1.3",

0 commit comments

Comments
 (0)