then-busboy
Advanced tools
Comparing version 2.0.0-beta.4 to 2.0.0-beta.5
@@ -18,10 +18,9 @@ "use strict"; | ||
const onField = (options, cb) => (fieldname, value) => { | ||
let path = null; | ||
try { | ||
path = (0, _getFieldPath2.default)(fieldname); | ||
const path = (0, _getFieldPath2.default)(fieldname); | ||
cb(null, [path, options.restoreTypes ? (0, _restoreType2.default)(value) : value]); | ||
} catch (err) { | ||
return cb(err); | ||
} | ||
cb(null, [path, options.restoreTypes ? (0, _restoreType2.default)(value) : value]); | ||
}; | ||
@@ -28,0 +27,0 @@ |
@@ -22,17 +22,19 @@ "use strict"; | ||
const onFile = (options, cb) => (fieldname, stream, filename, enc, mime) => { | ||
let path = null; | ||
try { | ||
path = (0, _getFieldPath2.default)(fieldname); | ||
} catch (err) { | ||
return cb(err); | ||
} | ||
const path = (0, _getFieldPath2.default)(fieldname); | ||
const contents = (0, _cloneableReadable2.default)(stream); | ||
// We need to clone file Readable stream before creating a File instance. | ||
const contents = (0, _cloneableReadable2.default)(stream); | ||
const file = new _File2.default({ filename, contents, enc, mime }); | ||
const file = new _File2.default({ filename, contents, enc, mime }); | ||
// Busboy will not fire "finish" event if I don't call this one. | ||
stream.emit("end"); | ||
// Busboy will not fire "finish" event because of we're don't read data from | ||
// a file stream. So, here we just fire "end" manually to prevent | ||
// an inifinite Promise pending. | ||
stream.emit("end"); | ||
cb(null, [path, file]); | ||
cb(null, [path, file]); | ||
} catch (err) { | ||
return cb(err); | ||
} | ||
}; | ||
@@ -39,0 +41,0 @@ |
@@ -29,5 +29,5 @@ "use strict"; | ||
var _eachListener = require("./util/eachListener"); | ||
var _mapListeners = require("./util/mapListeners"); | ||
var _eachListener2 = _interopRequireDefault(_eachListener); | ||
var _mapListeners2 = _interopRequireDefault(_mapListeners); | ||
@@ -48,3 +48,3 @@ var _getType = require("./util/getType"); | ||
const listeners = (0, _readListeners2.default)((0, _path.join)(__dirname, "listener")); | ||
const initializers = (0, _readListeners2.default)((0, _path.join)(__dirname, "listener")); | ||
@@ -78,10 +78,12 @@ const defaultOptions = { | ||
const fulfill = (err, entry) => void err ? reject(err) : entries.push(entry); | ||
const fulfill = (err, entry) => void (err ? reject(err) : entries.push(entry)); | ||
const listeners = (0, _mapListeners2.default)(initializers, fn => fn(options, fulfill)); | ||
// Set listeners before starting | ||
(0, _eachListener2.default)(listeners, (name, fn) => void busboy.on(name, fn(options, fulfill))); | ||
void (0, _mapListeners2.default)(listeners, (fn, name) => busboy.on(name, fn)); | ||
function onFinish() { | ||
// Cleanup listeners | ||
(0, _eachListener2.default)(listeners, (name, fn) => void busboy.removeListener(name, fn)); | ||
void (0, _mapListeners2.default)(listeners, (fn, name) => busboy.removeListener(name, fn)); | ||
@@ -88,0 +90,0 @@ try { |
@@ -20,5 +20,8 @@ "use strict"; | ||
for (const filename of dir) { | ||
const base = (0, _path.basename)(filename, (0, _path.extname)(filename)); | ||
const ext = (0, _path.extname)(filename); | ||
if (ext === ".js") { | ||
const base = (0, _path.basename)(filename, ext); | ||
res[base] = require((0, _path.join)(path, base)); | ||
res[base] = require((0, _path.join)(path, base)).default; | ||
} | ||
} | ||
@@ -25,0 +28,0 @@ |
{ | ||
"name": "then-busboy", | ||
"version": "2.0.0-beta.4", | ||
"version": "2.0.0-beta.5", | ||
"description": "Promise-based wrapper around Busboy, inspired by async-busboy", | ||
@@ -5,0 +5,0 @@ "repository": "octet-stream/then-busboy", |
@@ -31,4 +31,4 @@ # then-busboy | ||
* http.IncomingMessage **request** – HTTP request object | ||
* object **options** | ||
+ **http.IncomingMessage** request – HTTP request object | ||
+ **object** options | ||
- **boolean** restoreTypes – allow to restore type of each value (default – true) | ||
@@ -73,2 +73,4 @@ - more information about busboy options [here](https://github.com/mscdex/busboy#busboy-methods). | ||
File contents encoding | ||
##### `path` | ||
@@ -75,0 +77,0 @@ |
@@ -5,14 +5,13 @@ import getFieldPath from "lib/util/getFieldPath" | ||
const onField = (options, cb) => (fieldname, value) => { | ||
let path = null | ||
try { | ||
path = getFieldPath(fieldname) | ||
const path = getFieldPath(fieldname) | ||
cb(null, [ | ||
path, options.restoreTypes ? restoreType(value) : value | ||
]) | ||
} catch (err) { | ||
return cb(err) | ||
} | ||
cb(null, [ | ||
path, options.restoreTypes ? restoreType(value) : value | ||
]) | ||
} | ||
export default onField |
@@ -7,21 +7,23 @@ import clone from "cloneable-readable" | ||
const onFile = (options, cb) => (fieldname, stream, filename, enc, mime) => { | ||
let path = null | ||
try { | ||
path = getFieldPath(fieldname) | ||
} catch (err) { | ||
return cb(err) | ||
} | ||
const path = getFieldPath(fieldname) | ||
const contents = clone(stream) | ||
// We need to clone file Readable stream before creating a File instance. | ||
const contents = clone(stream) | ||
const file = new File({filename, contents, enc, mime}) | ||
const file = new File({filename, contents, enc, mime}) | ||
// Busboy will not fire "finish" event if I don't call this one. | ||
stream.emit("end") | ||
// Busboy will not fire "finish" event because of we're don't read data from | ||
// a file stream. So, here we just fire "end" manually to prevent | ||
// an inifinite Promise pending. | ||
stream.emit("end") | ||
cb(null, [ | ||
path, file | ||
]) | ||
cb(null, [ | ||
path, file | ||
]) | ||
} catch (err) { | ||
return cb(err) | ||
} | ||
} | ||
export default onFile |
@@ -9,3 +9,3 @@ import {IncomingMessage} from "http" | ||
import each from "lib/util/eachListener" | ||
import map from "lib/util/mapListeners" | ||
import getType from "lib/util/getType" | ||
@@ -15,3 +15,3 @@ import readListeners from "lib/util/readListeners" | ||
const listeners = readListeners(join(__dirname, "listener")) | ||
const initializers = readListeners(join(__dirname, "listener")) | ||
@@ -54,10 +54,12 @@ const defaultOptions = { | ||
const fulfill = (err, entry) => void err ? reject(err) : entries.push(entry) | ||
const fulfill = (err, entry) => void (err ? reject(err) : entries.push(entry)) | ||
const listeners = map(initializers, fn => fn(options, fulfill)) | ||
// Set listeners before starting | ||
each(listeners, (name, fn) => void busboy.on(name, fn(options, fulfill))) | ||
void map(listeners, (fn, name) => busboy.on(name, fn)) | ||
function onFinish() { | ||
// Cleanup listeners | ||
each(listeners, (name, fn) => void busboy.removeListener(name, fn)) | ||
void map(listeners, (fn, name) => busboy.removeListener(name, fn)) | ||
@@ -64,0 +66,0 @@ try { |
@@ -13,5 +13,8 @@ import {readdirSync} from "fs" | ||
for (const filename of dir) { | ||
const base = basename(filename, extname(filename)) | ||
const ext = extname(filename) | ||
if (ext === ".js") { | ||
const base = basename(filename, ext) | ||
res[base] = require(join(path, base)) | ||
res[base] = require(join(path, base)).default | ||
} | ||
} | ||
@@ -18,0 +21,0 @@ |
@@ -88,2 +88,49 @@ import test from "ava" | ||
test("Should restore field type by default", async t => { | ||
t.plan(1) | ||
const {body} = await request(mockServer(busboy)()) | ||
.post("/") | ||
.field("nullValue", "null") | ||
.field("falseValue", "false") | ||
.field("trueValue", "true") | ||
.field("numberValue", "42") | ||
.field("stringValue", "Some random string") | ||
const expected = { | ||
nullValue: null, | ||
falseValue: false, | ||
trueValue: true, | ||
numberValue: 42, | ||
stringValue: "Some random string" | ||
} | ||
t.deepEqual(body, expected) | ||
}) | ||
test( | ||
"Should not restore field type when options.restoreTypes turned to false", | ||
async t => { | ||
t.plan(1) | ||
const {body} = await request(mockServer(busboy)({restoreTypes: false})) | ||
.post("/") | ||
.field("nullValue", "null") | ||
.field("falseValue", "false") | ||
.field("trueValue", "true") | ||
.field("numberValue", "42") | ||
.field("stringValue", "Some random string") | ||
const expected = { | ||
nullValue: "null", | ||
falseValue: "false", | ||
trueValue: "true", | ||
numberValue: "42", | ||
stringValue: "Some random string" | ||
} | ||
t.deepEqual(body, expected) | ||
} | ||
) | ||
test("Should just receive file", async t => { | ||
@@ -141,1 +188,44 @@ t.plan(1) | ||
) | ||
test( | ||
"Should response with an error when assignin a property to primitive value", | ||
async t => { | ||
t.plan(1) | ||
const {error} = await request(mockServer(busboy)()) | ||
.post("/") | ||
.field("root[0]", "whatever") | ||
.field("root[0][nop]", "oops") | ||
t.is( | ||
error.text, | ||
"TypeError: Cannot create property 'nop' on string 'whatever'" | ||
) | ||
} | ||
) | ||
test("Should response an error on incorrect field name format", async t => { | ||
t.plan(1) | ||
const format = "some[totally[]][wrong]format[foo]" | ||
const {error} = await request(mockServer(busboy)({foo: "foo"})) | ||
.post("/") | ||
.field(format, "You shall not pass!") | ||
t.is(error.text, `Error: Unexpected name format of the field: ${format}`) | ||
}) | ||
test("Should response an error on incorrect field name format of given file", | ||
async t => { | ||
t.plan(1) | ||
const format = "some[totally[]][wrong]format[foo]" | ||
const {error} = await request(mockServer(busboy)({foo: "foo"})) | ||
.post("/") | ||
.attach(format, __filename) | ||
t.is(error.text, `Error: Unexpected name format of the field: ${format}`) | ||
} | ||
) |
133
8
5
49765
42
1478