spirit-body
Version:
Body parser for spirit.
120 lines (102 loc) • 3.16 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
var _rawBody = require('raw-body');
var _rawBody2 = _interopRequireDefault(_rawBody);
var _contentType = require('content-type');
var _contentType2 = _interopRequireDefault(_contentType);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var httpError = function httpError(error) {
return {
status: 400,
body: JSON.stringify({
error: error
}, null, '\t'),
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
};
var bodyPromise = function bodyPromise(req, options) {
return new Promise(function (resolve, reject) {
(0, _rawBody2.default)(req, options, function (error, data) {
return error ? reject(error) : resolve(data);
});
});
};
/**
* @description Body-parsing middleware
* This is a curried function with options, so you have to
* call it once before passing it to spirit
* @param {Object} options The parsing components to be used.
* @return {function} Middleware to be used.
* @example const body = spiritBody({json: true, urlEncoded: true})
*/
exports.default = function () {
var _options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return function (handler) {
return async function (request) {
var options = Object.assign({
json: false,
form: false,
text: false,
limit: 4 * 1024 * 1024,
error: true,
allowEmptyBody: true
}, _options);
if (options.allowEmptyBody && (!request.headers['content-length'] || request.headers['content-length'] === '0')) return handler(request
// detect encoding
);
var _contentType$parse = _contentType2.default.parse(request.headers['content-type']
// retrieve raw body
),
type = _contentType$parse.type,
encoding = _contentType$parse.parameters.charset;
var body = await bodyPromise(request.req(), {
lenght: request.headers['content-length'],
limit: options.limit,
encoding: encoding
});
if (!request.headers['content-type']) {
if (options.error) return httpError('No Content-Type.');
return request;
}
if (options.json && type === 'application/json') {
try {
request.body = JSON.parse(body);
} catch (error) {
request.invalidBody = true;
if (options.error) return httpError('Invalid JSON.');
}
} else if (options.form && type === 'application/x-www-form-urlencoded') {
try {
// request.body = await promisify(formBody, request.req(), {
// limit: options.limit
// })
} catch (error) {
request.invalidBody = true;
if (options.error) return httpError('Invalid form.');
}
} else if (options.text) {
try {
request.body = body;
} catch (error) {
request.invalidBody = true;
if (options.error) return httpError('Invalid body.');
}
} else {
if (options.error) return {
status: 415,
body: JSON.stringify({
error: 'Unsupported Media Type'
}, null, '\t'),
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
}
return handler(request);
};
};
};
;