Compare commits

...

9 Commits

Author SHA1 Message Date
Antoine WEBER ca00dcd224 version app + node.exe + nw.exe 2015-10-13 21:47:32 +02:00
WEBER Antoine 858c5bd713 si la conf n'existe pas on l'ouvre 2015-10-12 19:16:48 +02:00
WEBER Antoine 36838263a3 modification pour build 2015-10-12 19:03:28 +02:00
WEBER Antoine 7f52b8b8a4 modif du chargement 2015-10-12 09:44:48 +02:00
WEBER Antoine 38759dc9d4 modif du chargement 2015-10-11 22:21:01 +02:00
WEBER Antoine 83c11eaa96 mode application clusterisé 2015-10-11 22:15:49 +02:00
WEBER Antoine a9205daf7e mode application clusterisé 2015-10-11 22:13:49 +02:00
WEBER Antoine b3e2fe85bc creation du menu avec tray icon 2015-10-09 21:12:23 +02:00
Antoine WEBER 9e01dd3724 modification de la TODOLIST 2015-10-08 12:19:05 +02:00
2649 changed files with 389373 additions and 170 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
config.js
database
database/*
nodes_modules
nodes_modules/*

BIN
PLEX_WD.lnk Normal file

Binary file not shown.

View File

@ -7,11 +7,18 @@ Ce projet permet de créer une liste de vos fichiers vidéo plex et de les parta
INSTALLATION
--------------------
il existe des version packagé pour window et mac, où vous n'avez plus qu'à éditer votre configuration avant de lancer le serveur
voir ici:
INSTALLATION MANUELLE
--------------------
**Sur Windows**
pré requis, installer git ( https://git-scm.com/download/win )
pré requis, installer nodejs 0.12.x ( https://nodejs.org/dist/v0.12.7/ )
pré requis, installer nodewebkit (http://dl.nwjs.io/v0.12.3/nwjs-v0.12.3-win-ia32.zip)
ouvrir l'invite de commande 'cmb', puis se deplacer dans un repertoire où vous voulez installer
@ -32,15 +39,7 @@ INSTALLATION
**Sous MacOS**
pré requis, nodejs
sinon installer homebrew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
et :
brew install node
pré requis, nodewebkit ( http://dl.nwjs.io/v0.12.3/nwjs-v0.12.3-osx-ia32.zip )
git clone https://github.com/TwanoO67/plex-web-downloader.git
@ -57,29 +56,7 @@ INSTALLATION
puis ouvrir dans votre navigateur l'adresse http://localhost:3000
**Sous Ubuntu**
pré requis nodejs, ou
apt-get install nodejs
ln -s /usr/bin/nodejs /usr/local/bin/node
puis, se déplacer dans votre repertoire pour l'install et :
git clone https://github.com/TwanoO67/plex-web-downloader.git
cd plex-web-downloader
npm install
modifier le fichier config.js, pour y mettre le chemin de la base de données plex
exemple: /home/yourUsername/plex-config/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db
npm start
puis ouvrir dans votre navigateur l'adresse http://localhost:3000
@ -115,19 +92,21 @@ DEVELOPPEMENT
puis configurer vos chaines sur: http://localhost:32400/web/index.html
COMPILATION
PACKAGING
--------------------
voir ici: https://github.com/nwjs/nw.js/wiki/Using-Node-modules
npm install enclose -g
sudo npm install
enclose -o bin/mac_bin --loglevel info -c enclose_config.js -v 0.12.7 ./bin/www
sudo npm install nw-gyp -g
sudo nw-gyp rebuild --target=0.12.3
TODO Liste
--------------------
* Ajouter une présentation sur l'index, configurable dans config.js
* Gérer les images des vignettes
* Faire une page spéciales pour les séries
* Mutualisé les sources avec un mirroir centralisé
* Gérer les téléchargements multi-source en proposant un lien aria2 (voir aria2.sourceforge.net)
* Intégré web ui: http://ziahamza.github.io/webui-aria2/
* Mettre en place une limite d'upload activable à la demande

BIN
bin/node.exe Normal file

Binary file not shown.

114
bin/www
View File

@ -1,114 +0,0 @@
#!/usr/bin/env node
//On commence par la mise en cluster
var cluster = require('cluster');
// Code to run if we're in the master process
if (cluster.isMaster) {
// Count the machine's CPUs
var cpuCount = require('os').cpus().length;
// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) {
console.log('Création du fork ' + i);
cluster.fork();
}
// Listen for dying workers
cluster.on('exit', function (worker) {
// Replace the dead worker, we're not sentimental
console.log('Worker ' + worker.id + ' died :(');
cluster.fork();
console.log('Remplacement du worker ');
});
// Code to run if we're in a worker process
} else {
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('plex_webdown:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
}
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

17093
credits.html Normal file

File diff suppressed because it is too large Load Diff

BIN
d3dcompiler_47.dll Normal file

Binary file not shown.

BIN
ffmpegsumo.dll Normal file

Binary file not shown.

BIN
icudtl.dat Normal file

Binary file not shown.

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title>PLEX Web Downloader</title>
<script src="./js/startup.js"></script>
</head>
<body>
<section>
Chargement en cours...
</section>
</body>
</html>

View File

@ -4,17 +4,17 @@ var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var config = require('./config');
var config = require('../config');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'jade');
//protection par mot de passe
if( typeof config.auth_user !== 'undefined' && typeof config.auth_password !== 'undefined' ){
console.log("SAFE MODE: votre serveur est protégé par mot de passe.");
//console.log("SAFE MODE: votre serveur est protégé par mot de passe.");
var basicAuth = require('basic-auth');
app.use(function(req, res, next) {
var user = basicAuth(req);
@ -27,9 +27,9 @@ if( typeof config.auth_user !== 'undefined' && typeof config.auth_password !== '
}
});
}
else{
/*else{
console.log("UNSAFE MODE: configurez un auth_user et auth_password dans le fichier config.js");
}
}*/
//envoyer config a tout le monde
app.use(function(req, res, next) {
@ -37,22 +37,22 @@ app.use(function(req, res, next) {
next();
});
app.use(favicon(path.join(__dirname, 'public', 'iconarchive_plex.ico')));
app.use(favicon(path.join(__dirname, '../public', 'iconarchive_plex.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, '../public')));
app.use('/', require('./routes/index'));
app.use('/users', require('./routes/users'));
app.use('/file', require('./routes/file'));
app.use('/channel', require('./routes/channel'));
app.use('/movie', require('./routes/movie'));
app.use('/show_list', require('./routes/show_list'));
app.use('/show', require('./routes/show'));
app.use('/divers', require('./routes/divers'));
app.use('/', require('../routes/index'));
app.use('/users', require('../routes/users'));
app.use('/file', require('../routes/file'));
app.use('/channel', require('../routes/channel'));
app.use('/movie', require('../routes/movie'));
app.use('/show_list', require('../routes/show_list'));
app.use('/show', require('../routes/show'));
app.use('/divers', require('../routes/divers'));
// catch 404 and forward to error handler
app.use(function(req, res, next) {

113
js/clustering.js Normal file
View File

@ -0,0 +1,113 @@
//On commence par la mise en cluster
var cluster = require('cluster');
// Code to run if we're in the master process
if (cluster.isMaster) {
// Count the machine's CPUs
var cpuCount = require('os').cpus().length;
// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) {
//console.log('Création du fork ' + i);
cluster.fork();
}
console.log('Création de '+cpuCount+' thread');
// Listen for dying workers
cluster.on('exit', function (worker) {
// Replace the dead worker, we're not sentimental
cluster.fork();
console.log('Remplacement du worker ' + worker.id);
});
// Code to run if we're in a worker process
} else {
/**
* Module dependencies.
*/
var app = require('./build_server');
var debug = require('debug')('plex_webdown:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
}
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

110
js/custom-tray-menu.js Normal file
View File

@ -0,0 +1,110 @@
"use strict";
var gui = global.window.nwDispatcher.requireNwGui();
var util = require('util');
class CustomTrayMenu {
constructor(windowPath, trayIcon, windowOptions) {
this.shown = false;
this.iconWidth = 12;
//valeur par défaut
this.trayIcon = trayIcon || 'tray2.png';
this.menuWindowPath = windowPath || 'custom-tray-menu.html';
this.menuWndowOptions = windowOptions || {
width: 185,
height: 143
};
this._initTray();
this._initMenuWindow();
this.tray.on('click', this.toggleTrayMenuAt.bind(this));
}
// remove tray, cose custom menu window
remove() {
this.tray.remove();
this.tray = null;
this.trayMenu.close();
}
_initTray() {
this.tray = new gui.Tray({
title: '',
icon: this.trayIcon,
alticon: '',
tooltip: window.document.title,
iconsAreTemplates: false
});
}
_initMenuWindow() {
var windowOptions = util._extend({
width: 200,
height: 100,
frame: false,
transparent: true,
resizable: false,
toolbar: false,
show: false,
'show_in_taskbar': process.platform == "darwin"
}, this.menuWndowOptions);
this.trayMenu = gui.Window.open(this.menuWindowPath, windowOptions);
// add class to new window's body to apply platform specific css
this.trayMenu.on('document-end', function() {
this.trayMenu.window.document.body.className += ' ' + process.platform;
//console.log("Adding class " + process.platform);
}.bind(this));
this.trayMenu.on('blur', function () {
this.trayMenu.hide();
this.shown = false;
//console.log('Hide custom menu');
}.bind(this));
}
// called when user click on tray icon
toggleTrayMenuAt(position) {
/*if (this.shown) {
this.trayMenu.hide(); // this will trigger listener added above
this.shown = false;
} else {*/
this.translate(position);
this.trayMenu.moveTo(position.x, position.y);
//global.main_win.show();
//global.main_win.focus();
this.trayMenu.show();
this.trayMenu.focus();
this.shown = true;
//console.log('Show custom menu');
//}
}
// calculdate position for window to appear
translate(pos) {
//console.log("Click position: " + util.inspect(pos));
if (process.platform == 'darwin') {
pos.x -= Math.floor(this.trayMenu.width / 2 - this.iconWidth);
} else {
pos.x -= Math.floor(this.trayMenu.width / 2);
// for windows can not make exac position, because we have position of click. Just move it 5px up
pos.y -= this._trayAreaIsTop(pos) ? 0 : this.trayMenu.height + this.iconWidth / 2 + 5;
}
}
_trayAreaIsTop(pos) {
var screen;
if (gui.Screen.Init) gui.Screen.Init();
function posInBounds(s) {
return pos.y > s.bounds.y && pos.y < (s.bounds.y + s.bounds.height) &&
pos.x > s.bounds.x && pos.x < (s.bounds.x + s.bounds.width);
}
screen = gui.Screen.screens.filter(posInBounds)[0];
return pos.y < (screen.bounds.y + screen.bounds.height) / 2;
}
}
module.exports = CustomTrayMenu;

99
js/startup.js Normal file
View File

@ -0,0 +1,99 @@

//sur le master on cree l'interface
"use strict";
var gui = require('nw.gui');
var CustomTrayMenu = require('./js/custom-tray-menu');
var win = gui.Window.get();
global.main_win = win;
//Test la presence du fichier de config
var fs = require('fs.extra');
fs.exists('config.js', function(exists) {
if (!exists) {
console.log('Config.js a été ré-initialisé');
fs.copy('config.js_example','config.js');
var child_process = require('child_process');
// exec: spawns a shell.
var cp = child_process.exec('start notepad "config.js"', function(error, stdout, stderr){
//var gui = require('nw.gui');
//gui.App.closeAllWindows();
//global.main_server.kill();
//gui.App.quit();
});
cp.on('exit',function(stream){
var gui = require('nw.gui');
gui.App.closeAllWindows();
//global.main_server.kill();
gui.App.quit();
});
}
else{
//lancement normal
var config = require('./config');
//Prevenir des informations de config
if( typeof config.auth_user !== 'undefined' && typeof config.auth_password !== 'undefined' ){
console.log("SAFE MODE: votre serveur est protégé par mot de passe.");
}
else{
console.log("UNSAFE MODE: configurez un auth_user et auth_password dans le fichier config.js");
}
if( typeof config.database !== undefined){
fs.exists(config.database, function(exists) {
if (!exists) {
console.log("La base plex n'existe pas. Mettez à jour le champ DATABASE du fichier config.js");
}
else{
console.log("La base plex a bien été trouvée.");
}
});
}
else{
console.log("La base plex n'est pas définie. Mettez à jour le champ DATABASE du fichier config.js");
}
// Extend application menu for Mac OS
if (process.platform == "darwin") {
var menu = new gui.Menu({type: "menubar"});
menu.createMacBuiltin && menu.createMacBuiltin(window.document.title);
win.menu = menu;
}
var $ = function (selector) {
return document.querySelector(selector);
}
var customTray;
customTray = new CustomTrayMenu('views/custom-tray-menu.html', 'public/icon.png', {
width: 200,
height: 180
});
//lancement du serveur
var child_process = require('child_process');
global.main_server = child_process.exec('serveur.bat',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
//on tue le serveur quand on quite l'interface
process.on('exit', function (exitCode) {
child_process.kill();
});
}
});
win.hide();

BIN
libEGL.dll Normal file

Binary file not shown.

BIN
libGLESv2.dll Normal file

Binary file not shown.

BIN
locales/am.pak Normal file

Binary file not shown.

BIN
locales/ar.pak Normal file

Binary file not shown.

BIN
locales/bg.pak Normal file

Binary file not shown.

BIN
locales/bn.pak Normal file

Binary file not shown.

BIN
locales/ca.pak Normal file

Binary file not shown.

BIN
locales/cs.pak Normal file

Binary file not shown.

BIN
locales/da.pak Normal file

Binary file not shown.

BIN
locales/de.pak Normal file

Binary file not shown.

BIN
locales/el.pak Normal file

Binary file not shown.

BIN
locales/en-GB.pak Normal file

Binary file not shown.

BIN
locales/en-US.pak Normal file

Binary file not shown.

BIN
locales/es-419.pak Normal file

Binary file not shown.

BIN
locales/es.pak Normal file

Binary file not shown.

BIN
locales/et.pak Normal file

Binary file not shown.

BIN
locales/fa.pak Normal file

Binary file not shown.

BIN
locales/fi.pak Normal file

Binary file not shown.

BIN
locales/fil.pak Normal file

Binary file not shown.

BIN
locales/fr.pak Normal file

Binary file not shown.

BIN
locales/gu.pak Normal file

Binary file not shown.

BIN
locales/hi.pak Normal file

Binary file not shown.

BIN
locales/hr.pak Normal file

Binary file not shown.

BIN
locales/hu.pak Normal file

Binary file not shown.

BIN
locales/id.pak Normal file

Binary file not shown.

BIN
locales/it.pak Normal file

Binary file not shown.

BIN
locales/iw.pak Normal file

Binary file not shown.

BIN
locales/ja.pak Normal file

Binary file not shown.

BIN
locales/kn.pak Normal file

Binary file not shown.

BIN
locales/ko.pak Normal file

Binary file not shown.

BIN
locales/lt.pak Normal file

Binary file not shown.

BIN
locales/lv.pak Normal file

Binary file not shown.

BIN
locales/ml.pak Normal file

Binary file not shown.

BIN
locales/mr.pak Normal file

Binary file not shown.

BIN
locales/ms.pak Normal file

Binary file not shown.

BIN
locales/nl.pak Normal file

Binary file not shown.

BIN
locales/no.pak Normal file

Binary file not shown.

BIN
locales/pl.pak Normal file

Binary file not shown.

BIN
locales/pt-BR.pak Normal file

Binary file not shown.

BIN
locales/pt-PT.pak Normal file

Binary file not shown.

BIN
locales/ro.pak Normal file

Binary file not shown.

BIN
locales/ru.pak Normal file

Binary file not shown.

BIN
locales/sk.pak Normal file

Binary file not shown.

BIN
locales/sl.pak Normal file

Binary file not shown.

BIN
locales/sr.pak Normal file

Binary file not shown.

BIN
locales/sv.pak Normal file

Binary file not shown.

BIN
locales/sw.pak Normal file

Binary file not shown.

BIN
locales/ta.pak Normal file

Binary file not shown.

BIN
locales/te.pak Normal file

Binary file not shown.

BIN
locales/th.pak Normal file

Binary file not shown.

BIN
locales/tr.pak Normal file

Binary file not shown.

BIN
locales/uk.pak Normal file

Binary file not shown.

BIN
locales/vi.pak Normal file

Binary file not shown.

BIN
locales/zh-CN.pak Normal file

Binary file not shown.

BIN
locales/zh-TW.pak Normal file

Binary file not shown.

15
node_modules/.bin/jade generated vendored Normal file
View File

@ -0,0 +1,15 @@
#!/bin/sh
basedir=`dirname "$0"`
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../jade/bin/jade.js" "$@"
ret=$?
else
node "$basedir/../jade/bin/jade.js" "$@"
ret=$?
fi
exit $ret

7
node_modules/.bin/jade.cmd generated vendored Normal file
View File

@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\jade\bin\jade.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\jade\bin\jade.js" %*
)

29
node_modules/basic-auth/HISTORY.md generated vendored Normal file
View File

@ -0,0 +1,29 @@
1.0.3 / 2015-07-01
==================
* Fix regression accepting a Koa context
1.0.2 / 2015-06-12
==================
* Improve error message when `req` argument missing
* perf: enable strict mode
* perf: hoist regular expression
* perf: parse with regular expressions
* perf: remove argument reassignment
1.0.1 / 2015-05-04
==================
* Update readme
1.0.0 / 2014-07-01
==================
* Support empty password
* Support empty username
0.0.1 / 2013-11-30
==================
* Initial release

24
node_modules/basic-auth/LICENSE generated vendored Normal file
View File

@ -0,0 +1,24 @@
(The MIT License)
Copyright (c) 2013 TJ Holowaychuk
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

78
node_modules/basic-auth/README.md generated vendored Normal file
View File

@ -0,0 +1,78 @@
# basic-auth
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Generic basic auth Authorization header field parser for whatever.
## Installation
```
$ npm install basic-auth
```
## API
```js
var auth = require('basic-auth')
```
### auth(req)
Get the basic auth credentials from the given request. The `Authorization`
header is parsed and if the header is invalid, `undefined` is returned,
otherwise an object with `name` and `pass` properties.
## Example
Pass a node request or koa Context object to the module exported. If
parsing fails `undefined` is returned, otherwise an object with
`.name` and `.pass`.
```js
var auth = require('basic-auth');
var user = auth(req);
// => { name: 'something', pass: 'whatever' }
```
### With vanilla node.js http server
```js
var http = require('http')
var auth = require('basic-auth')
// Create server
var server = http.createServer(function (req, res) {
var credentials = auth(req)
if (!credentials || credentials.name !== 'john' || credentials.pass !== 'secret') {
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="example"')
res.end('Access denied')
} else {
res.end('Access granted')
}
})
// Listen
server.listen(3000)
```
# License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/basic-auth.svg
[npm-url]: https://npmjs.org/package/basic-auth
[node-version-image]: https://img.shields.io/node/v/basic-auth.svg
[node-version-url]: http://nodejs.org/download/
[travis-image]: https://img.shields.io/travis/jshttp/basic-auth/master.svg
[travis-url]: https://travis-ci.org/jshttp/basic-auth
[coveralls-image]: https://img.shields.io/coveralls/jshttp/basic-auth/master.svg
[coveralls-url]: https://coveralls.io/r/jshttp/basic-auth?branch=master
[downloads-image]: https://img.shields.io/npm/dm/basic-auth.svg
[downloads-url]: https://npmjs.org/package/basic-auth

91
node_modules/basic-auth/index.js generated vendored Normal file
View File

@ -0,0 +1,91 @@
/*!
* basic-auth
* Copyright(c) 2013 TJ Holowaychuk
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = auth
/**
* RegExp for basic auth credentials
*
* credentials = auth-scheme 1*SP token68
* auth-scheme = "Basic" ; case insensitive
* token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
* @private
*/
var credentialsRegExp = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9\-\._~\+\/]+=*) *$/
/**
* RegExp for basic auth user/pass
*
* user-pass = userid ":" password
* userid = *<TEXT excluding ":">
* password = *TEXT
* @private
*/
var userPassRegExp = /^([^:]*):(.*)$/
/**
* Parse the Authorization header field of a request.
*
* @param {object} req
* @return {object} with .name and .pass
* @public
*/
function auth(req) {
if (!req) {
throw new TypeError('argument req is required')
}
// get header
var header = (req.req || req).headers.authorization
// parse header
var match = credentialsRegExp.exec(header || '')
if (!match) {
return
}
// decode user pass
var userPass = userPassRegExp.exec(decodeBase64(match[1]))
if (!userPass) {
return
}
// return credentials object
return new Credentials(userPass[1], userPass[2])
}
/**
* Decode base64 string.
* @private
*/
function decodeBase64(str) {
return new Buffer(str, 'base64').toString()
}
/**
* Object to represent user credentials.
* @private
*/
function Credentials(name, pass) {
this.name = name
this.pass = pass
}

71
node_modules/basic-auth/package.json generated vendored Normal file
View File

@ -0,0 +1,71 @@
{
"name": "basic-auth",
"description": "node.js basic auth parser",
"version": "1.0.3",
"license": "MIT",
"keywords": [
"basic",
"auth",
"authorization",
"basicauth"
],
"repository": {
"type": "git",
"url": "git+https://github.com/jshttp/basic-auth.git"
},
"devDependencies": {
"istanbul": "0.3.17",
"mocha": "1.21.5"
},
"files": [
"HISTORY.md",
"LICENSE",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"test": "mocha --check-leaks --reporter spec --bail",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
},
"gitHead": "eec1944e5a54c907676822096d40bc7c52c0aff3",
"bugs": {
"url": "https://github.com/jshttp/basic-auth/issues"
},
"homepage": "https://github.com/jshttp/basic-auth",
"_id": "basic-auth@1.0.3",
"_shasum": "41f55523e589405038ee3567958c62a5ed70551a",
"_from": "basic-auth@>=1.0.3 <2.0.0",
"_npmVersion": "1.4.28",
"_npmUser": {
"name": "dougwilson",
"email": "doug@somethingdoug.com"
},
"maintainers": [
{
"name": "tjholowaychuk",
"email": "tj@vision-media.ca"
},
{
"name": "jonathanong",
"email": "jonathanrichardong@gmail.com"
},
{
"name": "dougwilson",
"email": "doug@somethingdoug.com"
},
{
"name": "jongleberry",
"email": "jonathanrichardong@gmail.com"
}
],
"dist": {
"shasum": "41f55523e589405038ee3567958c62a5ed70551a",
"tarball": "http://registry.npmjs.org/basic-auth/-/basic-auth-1.0.3.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.3.tgz",
"readme": "ERROR: No README data found!"
}

387
node_modules/body-parser/HISTORY.md generated vendored Normal file
View File

@ -0,0 +1,387 @@
1.13.3 / 2015-07-31
===================
* deps: type-is@~1.6.6
- deps: mime-types@~2.1.4
1.13.2 / 2015-07-05
===================
* deps: iconv-lite@0.4.11
* deps: qs@4.0.0
- Fix dropping parameters like `hasOwnProperty`
- Fix user-visible incompatibilities from 3.1.0
- Fix various parsing edge cases
* deps: raw-body@~2.1.2
- Fix error stack traces to skip `makeError`
- deps: iconv-lite@0.4.11
* deps: type-is@~1.6.4
- deps: mime-types@~2.1.2
- perf: enable strict mode
- perf: remove argument reassignment
1.13.1 / 2015-06-16
===================
* deps: qs@2.4.2
- Downgraded from 3.1.0 because of user-visible incompatibilities
1.13.0 / 2015-06-14
===================
* Add `statusCode` property on `Error`s, in addition to `status`
* Change `type` default to `application/json` for JSON parser
* Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser
* Provide static `require` analysis
* Use the `http-errors` module to generate errors
* deps: bytes@2.1.0
- Slight optimizations
* deps: iconv-lite@0.4.10
- The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails
- Leading BOM is now removed when decoding
* deps: on-finished@~2.3.0
- Add defined behavior for HTTP `CONNECT` requests
- Add defined behavior for HTTP `Upgrade` requests
- deps: ee-first@1.1.1
* deps: qs@3.1.0
- Fix dropping parameters like `hasOwnProperty`
- Fix various parsing edge cases
- Parsed object now has `null` prototype
* deps: raw-body@~2.1.1
- Use `unpipe` module for unpiping requests
- deps: iconv-lite@0.4.10
* deps: type-is@~1.6.3
- deps: mime-types@~2.1.1
- perf: reduce try block size
- perf: remove bitwise operations
* perf: enable strict mode
* perf: remove argument reassignment
* perf: remove delete call
1.12.4 / 2015-05-10
===================
* deps: debug@~2.2.0
* deps: qs@2.4.2
- Fix allowing parameters like `constructor`
* deps: on-finished@~2.2.1
* deps: raw-body@~2.0.1
- Fix a false-positive when unpiping in Node.js 0.8
- deps: bytes@2.0.1
* deps: type-is@~1.6.2
- deps: mime-types@~2.0.11
1.12.3 / 2015-04-15
===================
* Slight efficiency improvement when not debugging
* deps: depd@~1.0.1
* deps: iconv-lite@0.4.8
- Add encoding alias UNICODE-1-1-UTF-7
* deps: raw-body@1.3.4
- Fix hanging callback if request aborts during read
- deps: iconv-lite@0.4.8
1.12.2 / 2015-03-16
===================
* deps: qs@2.4.1
- Fix error when parameter `hasOwnProperty` is present
1.12.1 / 2015-03-15
===================
* deps: debug@~2.1.3
- Fix high intensity foreground color for bold
- deps: ms@0.7.0
* deps: type-is@~1.6.1
- deps: mime-types@~2.0.10
1.12.0 / 2015-02-13
===================
* add `debug` messages
* accept a function for the `type` option
* use `content-type` to parse `Content-Type` headers
* deps: iconv-lite@0.4.7
- Gracefully support enumerables on `Object.prototype`
* deps: raw-body@1.3.3
- deps: iconv-lite@0.4.7
* deps: type-is@~1.6.0
- fix argument reassignment
- fix false-positives in `hasBody` `Transfer-Encoding` check
- support wildcard for both type and subtype (`*/*`)
- deps: mime-types@~2.0.9
1.11.0 / 2015-01-30
===================
* make internal `extended: true` depth limit infinity
* deps: type-is@~1.5.6
- deps: mime-types@~2.0.8
1.10.2 / 2015-01-20
===================
* deps: iconv-lite@0.4.6
- Fix rare aliases of single-byte encodings
* deps: raw-body@1.3.2
- deps: iconv-lite@0.4.6
1.10.1 / 2015-01-01
===================
* deps: on-finished@~2.2.0
* deps: type-is@~1.5.5
- deps: mime-types@~2.0.7
1.10.0 / 2014-12-02
===================
* make internal `extended: true` array limit dynamic
1.9.3 / 2014-11-21
==================
* deps: iconv-lite@0.4.5
- Fix Windows-31J and X-SJIS encoding support
* deps: qs@2.3.3
- Fix `arrayLimit` behavior
* deps: raw-body@1.3.1
- deps: iconv-lite@0.4.5
* deps: type-is@~1.5.3
- deps: mime-types@~2.0.3
1.9.2 / 2014-10-27
==================
* deps: qs@2.3.2
- Fix parsing of mixed objects and values
1.9.1 / 2014-10-22
==================
* deps: on-finished@~2.1.1
- Fix handling of pipelined requests
* deps: qs@2.3.0
- Fix parsing of mixed implicit and explicit arrays
* deps: type-is@~1.5.2
- deps: mime-types@~2.0.2
1.9.0 / 2014-09-24
==================
* include the charset in "unsupported charset" error message
* include the encoding in "unsupported content encoding" error message
* deps: depd@~1.0.0
1.8.4 / 2014-09-23
==================
* fix content encoding to be case-insensitive
1.8.3 / 2014-09-19
==================
* deps: qs@2.2.4
- Fix issue with object keys starting with numbers truncated
1.8.2 / 2014-09-15
==================
* deps: depd@0.4.5
1.8.1 / 2014-09-07
==================
* deps: media-typer@0.3.0
* deps: type-is@~1.5.1
1.8.0 / 2014-09-05
==================
* make empty-body-handling consistent between chunked requests
- empty `json` produces `{}`
- empty `raw` produces `new Buffer(0)`
- empty `text` produces `''`
- empty `urlencoded` produces `{}`
* deps: qs@2.2.3
- Fix issue where first empty value in array is discarded
* deps: type-is@~1.5.0
- fix `hasbody` to be true for `content-length: 0`
1.7.0 / 2014-09-01
==================
* add `parameterLimit` option to `urlencoded` parser
* change `urlencoded` extended array limit to 100
* respond with 413 when over `parameterLimit` in `urlencoded`
1.6.7 / 2014-08-29
==================
* deps: qs@2.2.2
- Remove unnecessary cloning
1.6.6 / 2014-08-27
==================
* deps: qs@2.2.0
- Array parsing fix
- Performance improvements
1.6.5 / 2014-08-16
==================
* deps: on-finished@2.1.0
1.6.4 / 2014-08-14
==================
* deps: qs@1.2.2
1.6.3 / 2014-08-10
==================
* deps: qs@1.2.1
1.6.2 / 2014-08-07
==================
* deps: qs@1.2.0
- Fix parsing array of objects
1.6.1 / 2014-08-06
==================
* deps: qs@1.1.0
- Accept urlencoded square brackets
- Accept empty values in implicit array notation
1.6.0 / 2014-08-05
==================
* deps: qs@1.0.2
- Complete rewrite
- Limits array length to 20
- Limits object depth to 5
- Limits parameters to 1,000
1.5.2 / 2014-07-27
==================
* deps: depd@0.4.4
- Work-around v8 generating empty stack traces
1.5.1 / 2014-07-26
==================
* deps: depd@0.4.3
- Fix exception when global `Error.stackTraceLimit` is too low
1.5.0 / 2014-07-20
==================
* deps: depd@0.4.2
- Add `TRACE_DEPRECATION` environment variable
- Remove non-standard grey color from color output
- Support `--no-deprecation` argument
- Support `--trace-deprecation` argument
* deps: iconv-lite@0.4.4
- Added encoding UTF-7
* deps: raw-body@1.3.0
- deps: iconv-lite@0.4.4
- Added encoding UTF-7
- Fix `Cannot switch to old mode now` error on Node.js 0.10+
* deps: type-is@~1.3.2
1.4.3 / 2014-06-19
==================
* deps: type-is@1.3.1
- fix global variable leak
1.4.2 / 2014-06-19
==================
* deps: type-is@1.3.0
- improve type parsing
1.4.1 / 2014-06-19
==================
* fix urlencoded extended deprecation message
1.4.0 / 2014-06-19
==================
* add `text` parser
* add `raw` parser
* check accepted charset in content-type (accepts utf-8)
* check accepted encoding in content-encoding (accepts identity)
* deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed
* deprecate `urlencoded()` without provided `extended` option
* lazy-load urlencoded parsers
* parsers split into files for reduced mem usage
* support gzip and deflate bodies
- set `inflate: false` to turn off
* deps: raw-body@1.2.2
- Support all encodings from `iconv-lite`
1.3.1 / 2014-06-11
==================
* deps: type-is@1.2.1
- Switch dependency from mime to mime-types@1.0.0
1.3.0 / 2014-05-31
==================
* add `extended` option to urlencoded parser
1.2.2 / 2014-05-27
==================
* deps: raw-body@1.1.6
- assert stream encoding on node.js 0.8
- assert stream encoding on node.js < 0.10.6
- deps: bytes@1
1.2.1 / 2014-05-26
==================
* invoke `next(err)` after request fully read
- prevents hung responses and socket hang ups
1.2.0 / 2014-05-11
==================
* add `verify` option
* deps: type-is@1.2.0
- support suffix matching
1.1.2 / 2014-05-11
==================
* improve json parser speed
1.1.1 / 2014-05-11
==================
* fix repeated limit parsing with every request
1.1.0 / 2014-05-10
==================
* add `type` option
* deps: pin for safety and consistency
1.0.2 / 2014-04-14
==================
* use `type-is` module
1.0.1 / 2014-03-20
==================
* lower default limits to 100kb

23
node_modules/body-parser/LICENSE generated vendored Normal file
View File

@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

401
node_modules/body-parser/README.md generated vendored Normal file
View File

@ -0,0 +1,401 @@
# body-parser
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Node.js body parsing middleware.
_This does not handle multipart bodies_, due to their complex and typically
large nature. For multipart bodies, you may be interested in the following
modules:
* [busboy](https://www.npmjs.org/package/busboy#readme) and
[connect-busboy](https://www.npmjs.org/package/connect-busboy#readme)
* [multiparty](https://www.npmjs.org/package/multiparty#readme) and
[connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme)
* [formidable](https://www.npmjs.org/package/formidable#readme)
* [multer](https://www.npmjs.org/package/multer#readme)
This module provides the following parsers:
* [JSON body parser](#bodyparserjsonoptions)
* [Raw body parser](#bodyparserrawoptions)
* [Text body parser](#bodyparsertextoptions)
* [URL-encoded form body parser](#bodyparserurlencodedoptions)
Other body parsers you might be interested in:
- [body](https://www.npmjs.org/package/body#readme)
- [co-body](https://www.npmjs.org/package/co-body#readme)
## Installation
```sh
$ npm install body-parser
```
## API
```js
var bodyParser = require('body-parser')
```
The `bodyParser` object exposes various factories to create middlewares. All
middlewares will populate the `req.body` property with the parsed body or
provide an error to the callback. The various errors are described in the
[errors section](#errors).
### bodyParser.json(options)
Returns middleware that only parses `json`. This parser accepts any Unicode
encoding of the body and supports automatic inflation of `gzip` and `deflate`
encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`).
#### Options
The `json` function takes an option `options` object that may contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### reviver
The `reviver` option is passed directly to `JSON.parse` as the second
argument. You can find more information on this argument
[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
##### strict
When set to `true`, will only accept arrays and objects; when `false` will
accept anything `JSON.parse` accepts. Defaults to `true`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `json`), a mime type (like
`application/json`), or a mime type with a wildcard (like `*/*` or `*/json`).
If a function, the `type` option is called as `fn(req)` and the request is
parsed if it returns a truthy value. Defaults to `application/json`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.raw(options)
Returns middleware that parses all bodies as a `Buffer`. This parser
supports automatic inflation of `gzip` and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a `Buffer` object
of the body.
#### Options
The `raw` function takes an option `options` object that may contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `bin`), a mime type (like
`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
`application/*`). If a function, the `type` option is called as `fn(req)`
and the request is parsed if it returns a truthy value. Defaults to
`application/octet-stream`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.text(options)
Returns middleware that parses all bodies as a string. This parser supports
automatic inflation of `gzip` and `deflate` encodings.
A new `body` string containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a string of the
body.
#### Options
The `text` function takes an option `options` object that may contain any of
the following keys:
##### defaultCharset
Specify the default character set for the text content if the charset is not
specified in the `Content-Type` header of the request. Defaults to `utf-8`.
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `txt`), a mime type (like
`text/plain`), or a mime type with a wildcard (like `*/*` or `text/*`).
If a function, the `type` option is called as `fn(req)` and the request is
parsed if it returns a truthy value. Defaults to `text/plain`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.urlencoded(options)
Returns middleware that only parses `urlencoded` bodies. This parser accepts
only UTF-8 encoding of the body and supports automatic inflation of `gzip`
and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This object will contain
key-value pairs, where the value can be a string or array (when `extended` is
`false`), or any type (when `extended` is `true`).
#### Options
The `urlencoded` function takes an option `options` object that may contain
any of the following keys:
##### extended
The `extended` option allows to choose between parsing the URL-encoded data
with the `querystring` library (when `false`) or the `qs` library (when
`true`). The "extended" syntax allows for rich objects and arrays to be
encoded into the URL-encoded format, allowing for a JSON-like experience
with URL-encoded. For more information, please
[see the qs library](https://www.npmjs.org/package/qs#readme).
Defaults to `true`, but using the default has been deprecated. Please
research into the difference between `qs` and `querystring` and choose the
appropriate setting.
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### parameterLimit
The `parameterLimit` option controls the maximum number of parameters that
are allowed in the URL-encoded data. If a request contains more parameters
than this value, a 413 will be returned to the client. Defaults to `1000`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `urlencoded`), a mime type (like
`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
`*/x-www-form-urlencoded`). If a function, the `type` option is called as
`fn(req)` and the request is parsed if it returns a truthy value. Defaults
to `application/x-www-form-urlencoded`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
## Errors
The middlewares provided by this module create errors depending on the error
condition during parsing. The errors will typically have a `status` property
that contains the suggested HTTP response code.
The following are the common errors emitted, though any error can come through
for various reasons.
### content encoding unsupported
This error will occur when the request had a `Content-Encoding` header that
contained an encoding but the "inflation" option was set to `false`. The
`status` property is set to `415`.
### request aborted
This error will occur when the request is aborted by the client before reading
the body has finished. The `received` property will be set to the number of
bytes received before the request was aborted and the `expected` property is
set to the number of expected bytes. The `status` property is set to `400`.
### request entity too large
This error will occur when the request body's size is larger than the "limit"
option. The `limit` property will be set to the byte limit and the `length`
property will be set to the request body's length. The `status` property is
set to `413`.
### request size did not match content length
This error will occur when the request's length did not match the length from
the `Content-Length` header. This typically occurs when the requst is malformed,
typically when the `Content-Length` header was calculated based on characters
instead of bytes. The `status` property is set to `400`.
### stream encoding should not be set
This error will occur when something called the `req.setEncoding` method prior
to this middleware. This module operates directly on bytes only and you cannot
call `req.setEncoding` when using this module. The `status` property is set to
`500`.
### unsupported charset "BOGUS"
This error will occur when the request had a charset parameter in the
`Content-Type` header, but the `iconv-lite` module does not support it OR the
parser does not support it. The charset is contained in the message as well
as in the `charset` property. The `status` property is set to `415`.
### unsupported content encoding "bogus"
This error will occur when the request had a `Content-Encoding` header that
contained an unsupported encoding. The encoding is contained in the message
as well as in the `encoding` property. The `status` property is set to `415`.
## Examples
### express/connect top-level generic
This example demonstrates adding a generic JSON and URL-encoded parser as a
top-level middleware, which will parse the bodies of all incoming requests.
This is the simplest setup.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})
```
### express route-specific
This example demonstrates adding body parsers specifically to the routes that
need them. In general, this is the most recommend way to use body-parser with
express.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// create application/json parser
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
// create user in req.body
})
```
### change content-type for parsers
All the parsers accept a `type` option which allows you to change the
`Content-Type` that the middleware will parse.
```js
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }))
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }))
```
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/body-parser.svg
[npm-url]: https://npmjs.org/package/body-parser
[travis-image]: https://img.shields.io/travis/expressjs/body-parser/master.svg
[travis-url]: https://travis-ci.org/expressjs/body-parser
[coveralls-image]: https://img.shields.io/coveralls/expressjs/body-parser/master.svg
[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
[downloads-image]: https://img.shields.io/npm/dm/body-parser.svg
[downloads-url]: https://npmjs.org/package/body-parser
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/

157
node_modules/body-parser/index.js generated vendored Normal file
View File

@ -0,0 +1,157 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var deprecate = require('depd')('body-parser')
/**
* Cache of loaded parsers.
* @private
*/
var parsers = Object.create(null)
/**
* @typedef Parsers
* @type {function}
* @property {function} json
* @property {function} raw
* @property {function} text
* @property {function} urlencoded
*/
/**
* Module exports.
* @type {Parsers}
*/
exports = module.exports = deprecate.function(bodyParser,
'bodyParser: use individual json/urlencoded middlewares')
/**
* JSON parser.
* @public
*/
Object.defineProperty(exports, 'json', {
configurable: true,
enumerable: true,
get: createParserGetter('json')
})
/**
* Raw parser.
* @public
*/
Object.defineProperty(exports, 'raw', {
configurable: true,
enumerable: true,
get: createParserGetter('raw')
})
/**
* Text parser.
* @public
*/
Object.defineProperty(exports, 'text', {
configurable: true,
enumerable: true,
get: createParserGetter('text')
})
/**
* URL-encoded parser.
* @public
*/
Object.defineProperty(exports, 'urlencoded', {
configurable: true,
enumerable: true,
get: createParserGetter('urlencoded')
})
/**
* Create a middleware to parse json and urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @deprecated
* @public
*/
function bodyParser(options){
var opts = {}
// exclude type option
if (options) {
for (var prop in options) {
if ('type' !== prop) {
opts[prop] = options[prop]
}
}
}
var _urlencoded = exports.urlencoded(opts)
var _json = exports.json(opts)
return function bodyParser(req, res, next) {
_json(req, res, function(err){
if (err) return next(err);
_urlencoded(req, res, next);
});
}
}
/**
* Create a getter for loading a parser.
* @private
*/
function createParserGetter(name) {
return function get() {
return loadParser(name)
}
}
/**
* Load a parser module.
* @private
*/
function loadParser(parserName) {
var parser = parsers[parserName]
if (parser !== undefined) {
return parser
}
// this uses a switch for static require analysis
switch (parserName) {
case 'json':
parser = require('./lib/types/json')
break
case 'raw':
parser = require('./lib/types/raw')
break
case 'text':
parser = require('./lib/types/text')
break
case 'urlencoded':
parser = require('./lib/types/urlencoded')
break
}
// store to prevent invoking require()
return parsers[parserName] = parser
}

180
node_modules/body-parser/lib/read.js generated vendored Normal file
View File

@ -0,0 +1,180 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var createError = require('http-errors')
var getBody = require('raw-body')
var iconv = require('iconv-lite')
var onFinished = require('on-finished')
var zlib = require('zlib')
/**
* Module exports.
*/
module.exports = read
/**
* Read a request into a buffer and parse.
*
* @param {object} req
* @param {object} res
* @param {function} next
* @param {function} parse
* @param {function} debug
* @param {object} [options]
* @api private
*/
function read(req, res, next, parse, debug, options) {
var length
var stream
// flag as parsed
req._body = true
var opts = options || {}
try {
stream = contentstream(req, debug, opts.inflate)
length = stream.length
stream.length = undefined
} catch (err) {
return next(err)
}
opts.length = length
var encoding = opts.encoding !== null
? opts.encoding || 'utf-8'
: null
var verify = opts.verify
opts.encoding = verify
? null
: encoding
// read body
debug('read body')
getBody(stream, opts, function (err, body) {
if (err) {
// default to 400
setErrorStatus(err, 400)
// echo back charset
if (err.type === 'encoding.unsupported') {
err = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
charset: encoding.toLowerCase()
})
}
// read off entire request
stream.resume()
onFinished(req, function onfinished() {
next(err)
})
return
}
// verify
if (verify) {
try {
debug('verify body')
verify(req, res, body, encoding)
} catch (err) {
// default to 403
setErrorStatus(err, 403)
next(err)
return
}
}
// parse
var str
try {
debug('parse body')
str = typeof body !== 'string' && encoding !== null
? iconv.decode(body, encoding)
: body
req.body = parse(str)
} catch (err) {
err.body = str === undefined
? body
: str
// default to 400
setErrorStatus(err, 400)
next(err)
return
}
next()
})
}
/**
* Get the content stream of the request.
*
* @param {object} req
* @param {function} debug
* @param {boolean} [inflate=true]
* @return {object}
* @api private
*/
function contentstream(req, debug, inflate) {
var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
var length = req.headers['content-length']
var stream
debug('content-encoding "%s"', encoding)
if (inflate === false && encoding !== 'identity') {
throw createError(415, 'content encoding unsupported')
}
switch (encoding) {
case 'deflate':
stream = zlib.createInflate()
debug('inflate body')
req.pipe(stream)
break
case 'gzip':
stream = zlib.createGunzip()
debug('gunzip body')
req.pipe(stream)
break
case 'identity':
stream = req
stream.length = length
break
default:
throw createError(415, 'unsupported content encoding "' + encoding + '"', {
encoding: encoding
})
}
return stream
}
/**
* Set a status on an error object, if ones does not exist
* @private
*/
function setErrorStatus(error, status) {
if (!error.status && !error.statusCode) {
error.status = status
error.statusCode = status
}
}

170
node_modules/body-parser/lib/types/json.js generated vendored Normal file
View File

@ -0,0 +1,170 @@
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:json')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = json
/**
* RegExp to match the first non-space in a string.
*
* Allowed whitespace is defined in RFC 7159:
*
* ws = *(
* %x20 / ; Space
* %x09 / ; Horizontal tab
* %x0A / ; Line feed or New line
* %x0D ) ; Carriage return
*/
var firstcharRegExp = /^[\x20\x09\x0a\x0d]*(.)/
/**
* Create a middleware to parse JSON bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function json(options) {
var opts = options || {}
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var inflate = opts.inflate !== false
var reviver = opts.reviver
var strict = opts.strict !== false
var type = opts.type || 'application/json'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse(body) {
if (body.length === 0) {
// special-case empty json body, as it's a common client-side mistake
// TODO: maybe make this configurable or part of "strict" option
return {}
}
if (strict) {
var first = firstchar(body)
if (first !== '{' && first !== '[') {
debug('strict violation')
throw new Error('invalid json')
}
}
debug('parse json')
return JSON.parse(body, reviver)
}
return function jsonParser(req, res, next) {
if (req._body) {
return debug('body already parsed'), next()
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
return debug('skip empty body'), next()
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
return debug('skip parsing'), next()
}
// assert charset per RFC 7159 sec 8.1
var charset = getCharset(req) || 'utf-8'
if (charset.substr(0, 4) !== 'utf-') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset
}))
return
}
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the first non-whitespace character in a string.
*
* @param {string} str
* @return {function}
* @api public
*/
function firstchar(str) {
var match = firstcharRegExp.exec(str)
return match ? match[1] : ''
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset(req) {
try {
return contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker(type) {
return function checkType(req) {
return Boolean(typeis(req, type))
}
}

95
node_modules/body-parser/lib/types/raw.js generated vendored Normal file
View File

@ -0,0 +1,95 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var debug = require('debug')('body-parser:raw')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = raw
/**
* Create a middleware to parse raw bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function raw(options) {
var opts = options || {};
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/octet-stream'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse(buf) {
return buf
}
return function rawParser(req, res, next) {
if (req._body) {
return debug('body already parsed'), next()
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
return debug('skip empty body'), next()
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
return debug('skip parsing'), next()
}
// read
read(req, res, next, parse, debug, {
encoding: null,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker(type) {
return function checkType(req) {
return Boolean(typeis(req, type))
}
}

115
node_modules/body-parser/lib/types/text.js generated vendored Normal file
View File

@ -0,0 +1,115 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var contentType = require('content-type')
var debug = require('debug')('body-parser:text')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = text
/**
* Create a middleware to parse text bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function text(options) {
var opts = options || {}
var defaultCharset = opts.defaultCharset || 'utf-8'
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'text/plain'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse(buf) {
return buf
}
return function textParser(req, res, next) {
if (req._body) {
return debug('body already parsed'), next()
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
return debug('skip empty body'), next()
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
return debug('skip parsing'), next()
}
// get charset
var charset = getCharset(req) || defaultCharset
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset(req) {
try {
return contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker(type) {
return function checkType(req) {
return Boolean(typeis(req, type))
}
}

264
node_modules/body-parser/lib/types/urlencoded.js generated vendored Normal file
View File

@ -0,0 +1,264 @@
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:urlencoded')
var deprecate = require('depd')('body-parser')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = urlencoded
/**
* Cache of parser modules.
*/
var parsers = Object.create(null)
/**
* Create a middleware to parse urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function urlencoded(options) {
var opts = options || {}
// notice because option default will flip in next major
if (opts.extended === undefined) {
deprecate('undefined extended: provide extended option')
}
var extended = opts.extended !== false
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/x-www-form-urlencoded'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate query parser
var queryparse = extended
? extendedparser(opts)
: simpleparser(opts)
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse(body) {
return body.length
? queryparse(body)
: {}
}
return function urlencodedParser(req, res, next) {
if (req._body) {
return debug('body already parsed'), next()
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
return debug('skip empty body'), next()
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
return debug('skip parsing'), next()
}
// assert charset
var charset = getCharset(req) || 'utf-8'
if (charset !== 'utf-8') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset
}))
return
}
// read
read(req, res, next, parse, debug, {
debug: debug,
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the extended query parser.
*
* @param {object} options
*/
function extendedparser(options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('qs')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse(body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters')
}
var arrayLimit = Math.max(100, paramCount)
debug('parse extended urlencoding')
return parse(body, {
allowDots: false,
allowPrototypes: true,
arrayLimit: arrayLimit,
depth: Infinity,
parameterLimit: parameterLimit
})
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset(req) {
try {
return contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Count the number of parameters, stopping once limit reached
*
* @param {string} body
* @param {number} limit
* @api private
*/
function parameterCount(body, limit) {
var count = 0
var index = 0
while ((index = body.indexOf('&', index)) !== -1) {
count++
index++
if (count === limit) {
return undefined
}
}
return count
}
/**
* Get parser for module name dynamically.
*
* @param {string} name
* @return {function}
* @api private
*/
function parser(name) {
var mod = parsers[name]
if (mod) {
return mod.parse
}
// load module
mod = parsers[name] = require(name)
return mod.parse
}
/**
* Get the simple query parser.
*
* @param {object} options
*/
function simpleparser(options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('querystring')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse(body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters')
}
debug('parse urlencoding')
return parse(body, undefined, undefined, {maxKeys: parameterLimit})
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker(type) {
return function checkType(req) {
return Boolean(typeis(req, type))
}
}

51
node_modules/body-parser/node_modules/bytes/History.md generated vendored Normal file
View File

@ -0,0 +1,51 @@
2.1.0 / 2015-05-21
==================
* add `.format` export
* add `.parse` export
2.0.2 / 2015-05-20
==================
* remove map recreation
* remove unnecessary object construction
2.0.1 / 2015-05-07
==================
* fix browserify require
* remove node.extend dependency
2.0.0 / 2015-04-12
==================
* add option "case"
* add option "thousandsSeparator"
* return "null" on invalid parse input
* support proper round-trip: bytes(bytes(num)) === num
* units no longer case sensitive when parsing
1.0.0 / 2014-05-05
==================
* add negative support. fixes #6
0.3.0 / 2014-03-19
==================
* added terabyte support
0.2.1 / 2013-04-01
==================
* add .component
0.2.0 / 2012-10-28
==================
* bytes(200).should.eql('200b')
0.1.0 / 2012-07-04
==================
* add bytes to string conversion [yields]

83
node_modules/body-parser/node_modules/bytes/Readme.md generated vendored Normal file
View File

@ -0,0 +1,83 @@
# Bytes utility
Utility to parse a string bytes (ex: `1TB`) to bytes (`1099511627776`) and vice-versa.
## Usage
```js
var bytes = require('bytes');
```
#### bytes.format(number value, [options]): string|null
Format the given value in bytes into a string. If the value is negative, it is kept as such. If it is a float, it is
rounded.
**Arguments**
| Name | Type | Description |
|---------|--------|--------------------|
| value | `number` | Value in bytes |
| options | `Object` | Conversion options |
**Options**
| Property | Type | Description |
|-------------------|--------|-----------------------------------------------------------------------------------------|
| thousandsSeparator | `string`&#124;`null` | Example of values: `' '`, `','` and `.`... Default value to `' '`. |
**Returns**
| Name | Type | Description |
|---------|-------------|-------------------------|
| results | `string`&#124;`null` | Return null upon error. String value otherwise. |
**Example**
```js
bytes(1024);
// output: '1kB'
bytes(1000);
// output: '1000B'
bytes(1000, {thousandsSeparator: ' '});
// output: '1 000B'
```
#### bytes.parse(string value): number|null
Parse the string value into an integer in bytes. If no unit is given, it is assumed the value is in bytes.
**Arguments**
| Name | Type | Description |
|---------------|--------|--------------------|
| value | `string` | String to parse. |
**Returns**
| Name | Type | Description |
|---------|-------------|-------------------------|
| results | `number`&#124;`null` | Return null upon error. Value in bytes otherwise. |
**Example**
```js
bytes('1kB');
// output: 1024
bytes('1024');
// output: 1024
```
## Installation
```bash
npm install bytes --save
component install visionmedia/bytes.js
```
## License
[![npm](https://img.shields.io/npm/l/express.svg)](https://github.com/visionmedia/bytes.js/blob/master/LICENSE)

133
node_modules/body-parser/node_modules/bytes/index.js generated vendored Normal file
View File

@ -0,0 +1,133 @@
/*!
* bytes
* Copyright(c) 2012-2014 TJ Holowaychuk
* Copyright(c) 2015 Jed Watson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = bytes;
module.exports.format = format;
module.exports.parse = parse;
/**
* Module variables.
* @private
*/
var map = {
b: 1,
kb: 1 << 10,
mb: 1 << 20,
gb: 1 << 30,
tb: ((1 << 30) * 1024)
};
/**
*Convert the given value in bytes into a string or parse to string to an integer in bytes.
*
* @param {string|number} value
* @param {{
* case: [string],
* thousandsSeparator: [string]
* }} [options] bytes options.
*
* @returns {string|number|null}
*/
function bytes(value, options) {
if (typeof value === 'string') {
return parse(value);
}
if (typeof value === 'number') {
return format(value, options);
}
return null;
}
/**
* Format the given value in bytes into a string.
*
* If the value is negative, it is kept as such. If it is a float,
* it is rounded.
*
* @param {number} value
* @param {object} [options]
* @param {string} [options.thousandsSeparator=]
* @public
*/
function format(val, options) {
if (typeof val !== 'number') {
return null;
}
var mag = Math.abs(val);
var thousandsSeparator = (options && options.thousandsSeparator) || '';
var unit = 'B';
var value = val;
if (mag >= map.tb) {
value = Math.round(value / map.tb * 100) / 100;
unit = 'TB';
} else if (mag >= map.gb) {
value = Math.round(value / map.gb * 100) / 100;
unit = 'GB';
} else if (mag >= map.mb) {
value = Math.round(value / map.mb * 100) / 100;
unit = 'MB';
} else if (mag >= map.kb) {
value = Math.round(value / map.kb * 100) / 100;
unit = 'kB';
}
if (thousandsSeparator) {
value = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
}
return value + unit;
}
/**
* Parse the string value into an integer in bytes.
*
* If no unit is given, it is assumed the value is in bytes.
*
* @param {number|string} val
* @public
*/
function parse(val) {
if (typeof val === 'number' && !isNaN(val)) {
return val;
}
if (typeof val !== 'string') {
return null;
}
// Test if the string passed is valid
var results = val.match(/^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i);
var floatValue;
var unit = 'b';
if (!results) {
// Nothing could be extracted from the given string
floatValue = parseInt(val);
unit = 'b'
} else {
// Retrieve the value and the unit
floatValue = parseFloat(results[1]);
unit = results[4].toLowerCase();
}
return map[unit] * floatValue;
}

View File

@ -0,0 +1,77 @@
{
"name": "bytes",
"description": "Utility to parse a string bytes to bytes and vice-versa",
"version": "2.1.0",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca",
"url": "http://tjholowaychuk.com"
},
"contributors": [
{
"name": "Jed Watson",
"email": "jed.watson@me.com"
}
],
"license": "MIT",
"keywords": [
"byte",
"bytes",
"utility",
"parse",
"parser",
"convert",
"converter"
],
"repository": {
"type": "git",
"url": "git+https://github.com/visionmedia/bytes.js.git"
},
"component": {
"scripts": {
"bytes/index.js": "index.js"
}
},
"devDependencies": {
"mocha": "*"
},
"files": [
"History.md",
"LICENSE",
"Readme.md",
"index.js"
],
"scripts": {
"test": "mocha --check-leaks --reporter spec"
},
"gitHead": "86e4520cc369b34866154a53344ca50b2bb5ddcd",
"bugs": {
"url": "https://github.com/visionmedia/bytes.js/issues"
},
"homepage": "https://github.com/visionmedia/bytes.js",
"_id": "bytes@2.1.0",
"_shasum": "ac93c410e2ffc9cc7cf4b464b38289067f5e47b4",
"_from": "bytes@2.1.0",
"_npmVersion": "1.4.28",
"_npmUser": {
"name": "dougwilson",
"email": "doug@somethingdoug.com"
},
"maintainers": [
{
"name": "tjholowaychuk",
"email": "tj@vision-media.ca"
},
{
"name": "dougwilson",
"email": "doug@somethingdoug.com"
}
],
"dist": {
"shasum": "ac93c410e2ffc9cc7cf4b464b38289067f5e47b4",
"tarball": "http://registry.npmjs.org/bytes/-/bytes-2.1.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/bytes/-/bytes-2.1.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,9 @@
1.0.1 / 2015-02-13
==================
* Improve missing `Content-Type` header error message
1.0.0 / 2015-02-01
==================
* Initial implementation, derived from `media-typer@0.3.0`

View File

@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Douglas Christopher Wilson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,92 @@
# content-type
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Create and parse HTTP Content-Type header according to RFC 7231
## Installation
```sh
$ npm install content-type
```
## API
```js
var contentType = require('content-type')
```
### contentType.parse(string)
```js
var obj = contentType.parse('image/svg+xml; charset=utf-8')
```
Parse a content type string. This will return an object with the following
properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type (the type and subtype, always lower case).
Example: `'image/svg+xml'`
- `parameters`: An object of the parameters in the media type (name of parameter
always lower case). Example: `{charset: 'utf-8'}`
Throws a `TypeError` if the string is missing or invalid.
### contentType.parse(req)
```js
var obj = contentType.parse(req)
```
Parse the `content-type` header from the given `req`. Short-cut for
`contentType.parse(req.headers['content-type'])`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.parse(res)
```js
var obj = contentType.parse(res)
```
Parse the `content-type` header set on the given `res`. Short-cut for
`contentType.parse(res.getHeader('content-type'))`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.format(obj)
```js
var str = contentType.format({type: 'image/svg+xml'})
```
Format an object into a content type string. This will return a string of the
content type for the given object with the following properties (examples are
shown that produce the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type (will be lower-cased). Example: `'image/svg+xml'`
- `parameters`: An object of the parameters in the media type (name of the
parameter will be lower-cased). Example: `{charset: 'utf-8'}`
Throws a `TypeError` if the object contains an invalid type or parameter names.
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/content-type.svg
[npm-url]: https://npmjs.org/package/content-type
[node-version-image]: https://img.shields.io/node/v/content-type.svg
[node-version-url]: http://nodejs.org/download/
[travis-image]: https://img.shields.io/travis/jshttp/content-type/master.svg
[travis-url]: https://travis-ci.org/jshttp/content-type
[coveralls-image]: https://img.shields.io/coveralls/jshttp/content-type/master.svg
[coveralls-url]: https://coveralls.io/r/jshttp/content-type
[downloads-image]: https://img.shields.io/npm/dm/content-type.svg
[downloads-url]: https://npmjs.org/package/content-type

View File

@ -0,0 +1,214 @@
/*!
* content-type
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1
*
* parameter = token "=" ( token / quoted-string )
* token = 1*tchar
* tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
* / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
* / DIGIT / ALPHA
* ; any VCHAR, except delimiters
* quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
* qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
* obs-text = %x80-FF
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
*/
var paramRegExp = /; *([!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) */g
var textRegExp = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/
var tokenRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/
/**
* RegExp to match quoted-pair in RFC 7230 sec 3.2.6
*
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
* obs-text = %x80-FF
*/
var qescRegExp = /\\([\u000b\u0020-\u00ff])/g
/**
* RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6
*/
var quoteRegExp = /([\\"])/g
/**
* RegExp to match type in RFC 6838
*
* media-type = type "/" subtype
* type = token
* subtype = token
*/
var typeRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+\/[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/
/**
* Module exports.
* @public
*/
exports.format = format
exports.parse = parse
/**
* Format object to media type.
*
* @param {object} obj
* @return {string}
* @public
*/
function format(obj) {
if (!obj || typeof obj !== 'object') {
throw new TypeError('argument obj is required')
}
var parameters = obj.parameters
var type = obj.type
if (!type || !typeRegExp.test(type)) {
throw new TypeError('invalid type')
}
var string = type
// append parameters
if (parameters && typeof parameters === 'object') {
var param
var params = Object.keys(parameters).sort()
for (var i = 0; i < params.length; i++) {
param = params[i]
if (!tokenRegExp.test(param)) {
throw new TypeError('invalid parameter name')
}
string += '; ' + param + '=' + qstring(parameters[param])
}
}
return string
}
/**
* Parse media type to object.
*
* @param {string|object} string
* @return {Object}
* @public
*/
function parse(string) {
if (!string) {
throw new TypeError('argument string is required')
}
if (typeof string === 'object') {
// support req/res-like objects as argument
string = getcontenttype(string)
if (typeof string !== 'string') {
throw new TypeError('content-type header is missing from object');
}
}
if (typeof string !== 'string') {
throw new TypeError('argument string is required to be a string')
}
var index = string.indexOf(';')
var type = index !== -1
? string.substr(0, index).trim()
: string.trim()
if (!typeRegExp.test(type)) {
throw new TypeError('invalid media type')
}
var key
var match
var obj = new ContentType(type.toLowerCase())
var value
paramRegExp.lastIndex = index
while (match = paramRegExp.exec(string)) {
if (match.index !== index) {
throw new TypeError('invalid parameter format')
}
index += match[0].length
key = match[1].toLowerCase()
value = match[2]
if (value[0] === '"') {
// remove quotes and escapes
value = value
.substr(1, value.length - 2)
.replace(qescRegExp, '$1')
}
obj.parameters[key] = value
}
if (index !== -1 && index !== string.length) {
throw new TypeError('invalid parameter format')
}
return obj
}
/**
* Get content-type from req/res objects.
*
* @param {object}
* @return {Object}
* @private
*/
function getcontenttype(obj) {
if (typeof obj.getHeader === 'function') {
// res-like
return obj.getHeader('content-type')
}
if (typeof obj.headers === 'object') {
// req-like
return obj.headers && obj.headers['content-type']
}
}
/**
* Quote a string if necessary.
*
* @param {string} val
* @return {string}
* @private
*/
function qstring(val) {
var str = String(val)
// no need to quote tokens
if (tokenRegExp.test(str)) {
return str
}
if (str.length > 0 && !textRegExp.test(str)) {
throw new TypeError('invalid parameter value')
}
return '"' + str.replace(quoteRegExp, '\\$1') + '"'
}
/**
* Class to represent a content type.
* @private
*/
function ContentType(type) {
this.parameters = Object.create(null)
this.type = type
}

View File

@ -0,0 +1,65 @@
{
"name": "content-type",
"description": "Create and parse HTTP Content-Type header",
"version": "1.0.1",
"author": {
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
"license": "MIT",
"keywords": [
"content-type",
"http",
"req",
"res",
"rfc7231"
],
"repository": {
"type": "git",
"url": "git+https://github.com/jshttp/content-type.git"
},
"devDependencies": {
"istanbul": "0.3.5",
"mocha": "~1.21.5"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/"
},
"gitHead": "3aa58f9c5a358a3634b8601602177888b4a477d8",
"bugs": {
"url": "https://github.com/jshttp/content-type/issues"
},
"homepage": "https://github.com/jshttp/content-type",
"_id": "content-type@1.0.1",
"_shasum": "a19d2247327dc038050ce622b7a154ec59c5e600",
"_from": "content-type@>=1.0.1 <1.1.0",
"_npmVersion": "1.4.28",
"_npmUser": {
"name": "dougwilson",
"email": "doug@somethingdoug.com"
},
"maintainers": [
{
"name": "dougwilson",
"email": "doug@somethingdoug.com"
}
],
"dist": {
"shasum": "a19d2247327dc038050ce622b7a154ec59c5e600",
"tarball": "http://registry.npmjs.org/content-type/-/content-type-1.0.1.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.1.tgz",
"readme": "ERROR: No README data found!"
}

75
node_modules/body-parser/node_modules/depd/History.md generated vendored Normal file
View File

@ -0,0 +1,75 @@
1.0.1 / 2015-04-07
==================
* Fix `TypeError`s when under `'use strict'` code
* Fix useless type name on auto-generated messages
* Support io.js 1.x
* Support Node.js 0.12
1.0.0 / 2014-09-17
==================
* No changes
0.4.5 / 2014-09-09
==================
* Improve call speed to functions using the function wrapper
* Support Node.js 0.6
0.4.4 / 2014-07-27
==================
* Work-around v8 generating empty stack traces
0.4.3 / 2014-07-26
==================
* Fix exception when global `Error.stackTraceLimit` is too low
0.4.2 / 2014-07-19
==================
* Correct call site for wrapped functions and properties
0.4.1 / 2014-07-19
==================
* Improve automatic message generation for function properties
0.4.0 / 2014-07-19
==================
* Add `TRACE_DEPRECATION` environment variable
* Remove non-standard grey color from color output
* Support `--no-deprecation` argument
* Support `--trace-deprecation` argument
* Support `deprecate.property(fn, prop, message)`
0.3.0 / 2014-06-16
==================
* Add `NO_DEPRECATION` environment variable
0.2.0 / 2014-06-15
==================
* Add `deprecate.property(obj, prop, message)`
* Remove `supports-color` dependency for node.js 0.8
0.1.0 / 2014-06-15
==================
* Add `deprecate.function(fn, message)`
* Add `process.on('deprecation', fn)` emitter
* Automatically generate message when omitted from `deprecate()`
0.0.1 / 2014-06-15
==================
* Fix warning for dynamic calls at singe call site
0.0.0 / 2014-06-15
==================
* Initial implementation

22
node_modules/body-parser/node_modules/depd/LICENSE generated vendored Normal file
View File

@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014 Douglas Christopher Wilson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

274
node_modules/body-parser/node_modules/depd/Readme.md generated vendored Normal file
View File

@ -0,0 +1,274 @@
# depd
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Linux Build][travis-image]][travis-url]
[![Windows Build][appveyor-image]][appveyor-url]
[![Coverage Status][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Deprecate all the things
> With great modules comes great responsibility; mark things deprecated!
## Install
```sh
$ npm install depd
```
## API
```js
var deprecate = require('depd')('my-module')
```
This library allows you to display deprecation messages to your users.
This library goes above and beyond with deprecation warnings by
introspection of the call stack (but only the bits that it is interested
in).
Instead of just warning on the first invocation of a deprecated
function and never again, this module will warn on the first invocation
of a deprecated function per unique call site, making it ideal to alert
users of all deprecated uses across the code base, rather than just
whatever happens to execute first.
The deprecation warnings from this module also include the file and line
information for the call into the module that the deprecated function was
in.
**NOTE** this library has a similar interface to the `debug` module, and
this module uses the calling file to get the boundary for the call stacks,
so you should always create a new `deprecate` object in each file and not
within some central file.
### depd(namespace)
Create a new deprecate function that uses the given namespace name in the
messages and will display the call site prior to the stack entering the
file this function was called from. It is highly suggested you use the
name of your module as the namespace.
### deprecate(message)
Call this function from deprecated code to display a deprecation message.
This message will appear once per unique caller site. Caller site is the
first call site in the stack in a different file from the caller of this
function.
If the message is omitted, a message is generated for you based on the site
of the `deprecate()` call and will display the name of the function called,
similar to the name displayed in a stack trace.
### deprecate.function(fn, message)
Call this function to wrap a given function in a deprecation message on any
call to the function. An optional message can be supplied to provide a custom
message.
### deprecate.property(obj, prop, message)
Call this function to wrap a given property on object in a deprecation message
on any accessing or setting of the property. An optional message can be supplied
to provide a custom message.
The method must be called on the object where the property belongs (not
inherited from the prototype).
If the property is a data descriptor, it will be converted to an accessor
descriptor in order to display the deprecation message.
### process.on('deprecation', fn)
This module will allow easy capturing of deprecation errors by emitting the
errors as the type "deprecation" on the global `process`. If there are no
listeners for this type, the errors are written to STDERR as normal, but if
there are any listeners, nothing will be written to STDERR and instead only
emitted. From there, you can write the errors in a different format or to a
logging source.
The error represents the deprecation and is emitted only once with the same
rules as writing to STDERR. The error has the following properties:
- `message` - This is the message given by the library
- `name` - This is always `'DeprecationError'`
- `namespace` - This is the namespace the deprecation came from
- `stack` - This is the stack of the call to the deprecated thing
Example `error.stack` output:
```
DeprecationError: my-cool-module deprecated oldfunction
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (module.js:456:26)
at evalScript (node.js:532:25)
at startup (node.js:80:7)
at node.js:902:3
```
### process.env.NO_DEPRECATION
As a user of modules that are deprecated, the environment variable `NO_DEPRECATION`
is provided as a quick solution to silencing deprecation warnings from being
output. The format of this is similar to that of `DEBUG`:
```sh
$ NO_DEPRECATION=my-module,othermod node app.js
```
This will suppress deprecations from being output for "my-module" and "othermod".
The value is a list of comma-separated namespaces. To suppress every warning
across all namespaces, use the value `*` for a namespace.
Providing the argument `--no-deprecation` to the `node` executable will suppress
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not suppress the deperecations given to any "deprecation"
event listeners, just the output to STDERR.
### process.env.TRACE_DEPRECATION
As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`
is provided as a solution to getting more detailed location information in deprecation
warnings by including the entire stack trace. The format of this is the same as
`NO_DEPRECATION`:
```sh
$ TRACE_DEPRECATION=my-module,othermod node app.js
```
This will include stack traces for deprecations being output for "my-module" and
"othermod". The value is a list of comma-separated namespaces. To trace every
warning across all namespaces, use the value `*` for a namespace.
Providing the argument `--trace-deprecation` to the `node` executable will trace
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.
## Display
![message](files/message.png)
When a user calls a function in your library that you mark deprecated, they
will see the following written to STDERR (in the given colors, similar colors
and layout to the `debug` module):
```
bright cyan bright yellow
| | reset cyan
| | | |
▼ ▼ ▼ ▼
my-cool-module deprecated oldfunction [eval]-wrapper:6:22
▲ ▲ ▲ ▲
| | | |
namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
If the user redirects their STDERR to a file or somewhere that does not support
colors, they see (similar layout to the `debug` module):
```
Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22
▲ ▲ ▲ ▲ ▲
| | | | |
timestamp of message namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
## Examples
### Deprecating all calls to a function
This will display a deprecated message about "oldfunction" being deprecated
from "my-module" on STDERR.
```js
var deprecate = require('depd')('my-cool-module')
// message automatically derived from function name
// Object.oldfunction
exports.oldfunction = deprecate.function(function oldfunction() {
// all calls to function are deprecated
})
// specific message
exports.oldfunction = deprecate.function(function () {
// all calls to function are deprecated
}, 'oldfunction')
```
### Conditionally deprecating a function call
This will display a deprecated message about "weirdfunction" being deprecated
from "my-module" on STDERR when called with less than 2 arguments.
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
}
}
```
When calling `deprecate` as a function, the warning is counted per call site
within your own module, so you can display different deprecations depending
on different situations and the users will still get all the warnings:
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
} else if (typeof arguments[0] !== 'string') {
// calls with non-string first argument are deprecated
deprecate('weirdfunction non-string first arg')
}
}
```
### Deprecating property access
This will display a deprecated message about "oldprop" being deprecated
from "my-module" on STDERR when accessed. A deprecation will be displayed
when setting the value and when getting the value.
```js
var deprecate = require('depd')('my-cool-module')
exports.oldprop = 'something'
// message automatically derives from property name
deprecate.property(exports, 'oldprop')
// explicit message
deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
```
## License
[MIT](LICENSE)
[npm-version-image]: https://img.shields.io/npm/v/depd.svg
[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg
[npm-url]: https://npmjs.org/package/depd
[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd/master.svg?label=linux
[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/nodejs-depd/master.svg?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd
[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd/master.svg
[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
[node-image]: https://img.shields.io/node/v/depd.svg
[node-url]: http://nodejs.org/download/
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/

529
node_modules/body-parser/node_modules/depd/index.js generated vendored Normal file
View File

@ -0,0 +1,529 @@
/*!
* depd
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module dependencies.
*/
var callSiteToString = require('./lib/compat').callSiteToString
var EventEmitter = require('events').EventEmitter
var relative = require('path').relative
/**
* Module exports.
*/
module.exports = depd
/**
* Get the path to base files on.
*/
var basePath = process.cwd()
/**
* Get listener count on event emitter.
*/
/*istanbul ignore next*/
var eventListenerCount = EventEmitter.listenerCount
|| function (emitter, type) { return emitter.listeners(type).length }
/**
* Determine if namespace is contained in the string.
*/
function containsNamespace(str, namespace) {
var val = str.split(/[ ,]+/)
namespace = String(namespace).toLowerCase()
for (var i = 0 ; i < val.length; i++) {
if (!(str = val[i])) continue;
// namespace contained
if (str === '*' || str.toLowerCase() === namespace) {
return true
}
}
return false
}
/**
* Convert a data descriptor to accessor descriptor.
*/
function convertDataDescriptorToAccessor(obj, prop, message) {
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
var value = descriptor.value
descriptor.get = function getter() { return value }
if (descriptor.writable) {
descriptor.set = function setter(val) { return value = val }
}
delete descriptor.value
delete descriptor.writable
Object.defineProperty(obj, prop, descriptor)
return descriptor
}
/**
* Create arguments string to keep arity.
*/
function createArgumentsString(arity) {
var str = ''
for (var i = 0; i < arity; i++) {
str += ', arg' + i
}
return str.substr(2)
}
/**
* Create stack string from stack.
*/
function createStackString(stack) {
var str = this.name + ': ' + this.namespace
if (this.message) {
str += ' deprecated ' + this.message
}
for (var i = 0; i < stack.length; i++) {
str += '\n at ' + callSiteToString(stack[i])
}
return str
}
/**
* Create deprecate for namespace in caller.
*/
function depd(namespace) {
if (!namespace) {
throw new TypeError('argument namespace is required')
}
var stack = getStack()
var site = callSiteLocation(stack[1])
var file = site[0]
function deprecate(message) {
// call to self as log
log.call(deprecate, message)
}
deprecate._file = file
deprecate._ignored = isignored(namespace)
deprecate._namespace = namespace
deprecate._traced = istraced(namespace)
deprecate._warned = Object.create(null)
deprecate.function = wrapfunction
deprecate.property = wrapproperty
return deprecate
}
/**
* Determine if namespace is ignored.
*/
function isignored(namespace) {
/* istanbul ignore next: tested in a child processs */
if (process.noDeprecation) {
// --no-deprecation support
return true
}
var str = process.env.NO_DEPRECATION || ''
// namespace ignored
return containsNamespace(str, namespace)
}
/**
* Determine if namespace is traced.
*/
function istraced(namespace) {
/* istanbul ignore next: tested in a child processs */
if (process.traceDeprecation) {
// --trace-deprecation support
return true
}
var str = process.env.TRACE_DEPRECATION || ''
// namespace traced
return containsNamespace(str, namespace)
}
/**
* Display deprecation message.
*/
function log(message, site) {
var haslisteners = eventListenerCount(process, 'deprecation') !== 0
// abort early if no destination
if (!haslisteners && this._ignored) {
return
}
var caller
var callFile
var callSite
var i = 0
var seen = false
var stack = getStack()
var file = this._file
if (site) {
// provided site
callSite = callSiteLocation(stack[1])
callSite.name = site.name
file = callSite[0]
} else {
// get call site
i = 2
site = callSiteLocation(stack[i])
callSite = site
}
// get caller of deprecated thing in relation to file
for (; i < stack.length; i++) {
caller = callSiteLocation(stack[i])
callFile = caller[0]
if (callFile === file) {
seen = true
} else if (callFile === this._file) {
file = this._file
} else if (seen) {
break
}
}
var key = caller
? site.join(':') + '__' + caller.join(':')
: undefined
if (key !== undefined && key in this._warned) {
// already warned
return
}
this._warned[key] = true
// generate automatic message from call site
if (!message) {
message = callSite === site || !callSite.name
? defaultMessage(site)
: defaultMessage(callSite)
}
// emit deprecation if listeners exist
if (haslisteners) {
var err = DeprecationError(this._namespace, message, stack.slice(i))
process.emit('deprecation', err)
return
}
// format and write message
var format = process.stderr.isTTY
? formatColor
: formatPlain
var msg = format.call(this, message, caller, stack.slice(i))
process.stderr.write(msg + '\n', 'utf8')
return
}
/**
* Get call site location as array.
*/
function callSiteLocation(callSite) {
var file = callSite.getFileName() || '<anonymous>'
var line = callSite.getLineNumber()
var colm = callSite.getColumnNumber()
if (callSite.isEval()) {
file = callSite.getEvalOrigin() + ', ' + file
}
var site = [file, line, colm]
site.callSite = callSite
site.name = callSite.getFunctionName()
return site
}
/**
* Generate a default message from the site.
*/
function defaultMessage(site) {
var callSite = site.callSite
var funcName = site.name
// make useful anonymous name
if (!funcName) {
funcName = '<anonymous@' + formatLocation(site) + '>'
}
var context = callSite.getThis()
var typeName = context && callSite.getTypeName()
// ignore useless type name
if (typeName === 'Object') {
typeName = undefined
}
// make useful type name
if (typeName === 'Function') {
typeName = context.name || typeName
}
return typeName && callSite.getMethodName()
? typeName + '.' + funcName
: funcName
}
/**
* Format deprecation message without color.
*/
function formatPlain(msg, caller, stack) {
var timestamp = new Date().toUTCString()
var formatted = timestamp
+ ' ' + this._namespace
+ ' deprecated ' + msg
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n at ' + callSiteToString(stack[i])
}
return formatted
}
if (caller) {
formatted += ' at ' + formatLocation(caller)
}
return formatted
}
/**
* Format deprecation message with color.
*/
function formatColor(msg, caller, stack) {
var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
+ ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
+ ' \x1b[0m' + msg + '\x1b[39m' // reset
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan
}
return formatted
}
if (caller) {
formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
}
return formatted
}
/**
* Format call site location.
*/
function formatLocation(callSite) {
return relative(basePath, callSite[0])
+ ':' + callSite[1]
+ ':' + callSite[2]
}
/**
* Get the stack as array of call sites.
*/
function getStack() {
var limit = Error.stackTraceLimit
var obj = {}
var prep = Error.prepareStackTrace
Error.prepareStackTrace = prepareObjectStackTrace
Error.stackTraceLimit = Math.max(10, limit)
// capture the stack
Error.captureStackTrace(obj)
// slice this function off the top
var stack = obj.stack.slice(1)
Error.prepareStackTrace = prep
Error.stackTraceLimit = limit
return stack
}
/**
* Capture call site stack from v8.
*/
function prepareObjectStackTrace(obj, stack) {
return stack
}
/**
* Return a wrapped function in a deprecation message.
*/
function wrapfunction(fn, message) {
if (typeof fn !== 'function') {
throw new TypeError('argument fn must be a function')
}
var args = createArgumentsString(fn.length)
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])
site.name = fn.name
var deprecatedfn = eval('(function (' + args + ') {\n'
+ '"use strict"\n'
+ 'log.call(deprecate, message, site)\n'
+ 'return fn.apply(this, arguments)\n'
+ '})')
return deprecatedfn
}
/**
* Wrap property in a deprecation message.
*/
function wrapproperty(obj, prop, message) {
if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
if (!descriptor) {
throw new TypeError('must call property on owner object')
}
if (!descriptor.configurable) {
throw new TypeError('property must be configurable')
}
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])
// set site name
site.name = prop
// convert data descriptor
if ('value' in descriptor) {
descriptor = convertDataDescriptorToAccessor(obj, prop, message)
}
var get = descriptor.get
var set = descriptor.set
// wrap getter
if (typeof get === 'function') {
descriptor.get = function getter() {
log.call(deprecate, message, site)
return get.apply(this, arguments)
}
}
// wrap setter
if (typeof set === 'function') {
descriptor.set = function setter() {
log.call(deprecate, message, site)
return set.apply(this, arguments)
}
}
Object.defineProperty(obj, prop, descriptor)
}
/**
* Create DeprecationError for deprecation
*/
function DeprecationError(namespace, message, stack) {
var error = new Error()
var stackString
Object.defineProperty(error, 'constructor', {
value: DeprecationError
})
Object.defineProperty(error, 'message', {
configurable: true,
enumerable: false,
value: message,
writable: true
})
Object.defineProperty(error, 'name', {
enumerable: false,
configurable: true,
value: 'DeprecationError',
writable: true
})
Object.defineProperty(error, 'namespace', {
configurable: true,
enumerable: false,
value: namespace,
writable: true
})
Object.defineProperty(error, 'stack', {
configurable: true,
enumerable: false,
get: function () {
if (stackString !== undefined) {
return stackString
}
// prepare stack trace
return stackString = createStackString.call(this, stack)
},
set: function setter(val) {
stackString = val
}
})
return error
}

View File

@ -0,0 +1,33 @@
/*!
* depd
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module exports.
*/
module.exports = bufferConcat
/**
* Concatenate an array of Buffers.
*/
function bufferConcat(bufs) {
var length = 0
for (var i = 0, len = bufs.length; i < len; i++) {
length += bufs[i].length
}
var buf = new Buffer(length)
var pos = 0
for (var i = 0, len = bufs.length; i < len; i++) {
bufs[i].copy(buf, pos)
pos += bufs[i].length
}
return buf
}

View File

@ -0,0 +1,101 @@
/*!
* depd
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module exports.
*/
module.exports = callSiteToString
/**
* Format a CallSite file location to a string.
*/
function callSiteFileLocation(callSite) {
var fileName
var fileLocation = ''
if (callSite.isNative()) {
fileLocation = 'native'
} else if (callSite.isEval()) {
fileName = callSite.getScriptNameOrSourceURL()
if (!fileName) {
fileLocation = callSite.getEvalOrigin()
}
} else {
fileName = callSite.getFileName()
}
if (fileName) {
fileLocation += fileName
var lineNumber = callSite.getLineNumber()
if (lineNumber != null) {
fileLocation += ':' + lineNumber
var columnNumber = callSite.getColumnNumber()
if (columnNumber) {
fileLocation += ':' + columnNumber
}
}
}
return fileLocation || 'unknown source'
}
/**
* Format a CallSite to a string.
*/
function callSiteToString(callSite) {
var addSuffix = true
var fileLocation = callSiteFileLocation(callSite)
var functionName = callSite.getFunctionName()
var isConstructor = callSite.isConstructor()
var isMethodCall = !(callSite.isToplevel() || isConstructor)
var line = ''
if (isMethodCall) {
var methodName = callSite.getMethodName()
var typeName = getConstructorName(callSite)
if (functionName) {
if (typeName && functionName.indexOf(typeName) !== 0) {
line += typeName + '.'
}
line += functionName
if (methodName && functionName.lastIndexOf('.' + methodName) !== functionName.length - methodName.length - 1) {
line += ' [as ' + methodName + ']'
}
} else {
line += typeName + '.' + (methodName || '<anonymous>')
}
} else if (isConstructor) {
line += 'new ' + (functionName || '<anonymous>')
} else if (functionName) {
line += functionName
} else {
addSuffix = false
line += fileLocation
}
if (addSuffix) {
line += ' (' + fileLocation + ')'
}
return line
}
/**
* Get constructor name of reviver.
*/
function getConstructorName(obj) {
var receiver = obj.receiver
return (receiver.constructor && receiver.constructor.name) || null
}

Some files were not shown because too many files have changed in this diff Show More