diff --git a/body-parser/body-parser.d.ts b/body-parser/body-parser.d.ts
new file mode 100644
index 0000000000..f16b2eefb5
--- /dev/null
+++ b/body-parser/body-parser.d.ts
@@ -0,0 +1,12 @@
+// Type definitions for body-parser
+// Project: http://expressjs.com
+// Definitions by: Santi Albo
+// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module "body-parser" {
+ import express = require('express');
+ function e(options?: any): express.RequestHandler;
+ export = e;
+}
\ No newline at end of file
diff --git a/compression/compression-tests.ts b/compression/compression-tests.ts
new file mode 100644
index 0000000000..ecfcab4320
--- /dev/null
+++ b/compression/compression-tests.ts
@@ -0,0 +1,10 @@
+///
+
+import express = require('express');
+import compress = require('compression');
+
+var app = express();
+app.use(compress());
+app.use(compress({
+ threshold: 512
+}));
diff --git a/compression/compression.d.ts b/compression/compression.d.ts
new file mode 100644
index 0000000000..9ef3a8cb75
--- /dev/null
+++ b/compression/compression.d.ts
@@ -0,0 +1,20 @@
+// Type definitions for compression
+// Project: https://github.com/expressjs/compression
+// Definitions by: Santi Albo
+// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module "compression" {
+ import express = require('express');
+
+ module e {
+ interface CompressionOptions {
+ threshold?: number;
+ filter?: Function;
+ }
+ }
+
+ function e(options?: e.CompressionOptions): express.RequestHandler;
+ export = e;
+}
\ No newline at end of file
diff --git a/cookie-parser/cookie-parser-tests.ts b/cookie-parser/cookie-parser-tests.ts
new file mode 100644
index 0000000000..94e8a9fdb2
--- /dev/null
+++ b/cookie-parser/cookie-parser-tests.ts
@@ -0,0 +1,7 @@
+///
+
+import express = require('express');
+import cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser('optional secret string'));
diff --git a/cookie-parser/cookie-parser.d.ts b/cookie-parser/cookie-parser.d.ts
new file mode 100644
index 0000000000..f43553b7c9
--- /dev/null
+++ b/cookie-parser/cookie-parser.d.ts
@@ -0,0 +1,12 @@
+// Type definitions for cookie-parser
+// Project: https://github.com/expressjs/cookie-parser
+// Definitions by: Santi Albo
+// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module "cookie-parser" {
+ import express = require('express');
+ function e(secret?: string, options?: any): express.RequestHandler;
+ export = e;
+}
\ No newline at end of file
diff --git a/errorhandler/errorhandler-tests.ts b/errorhandler/errorhandler-tests.ts
new file mode 100644
index 0000000000..02f788790e
--- /dev/null
+++ b/errorhandler/errorhandler-tests.ts
@@ -0,0 +1,7 @@
+///
+
+import express = require('express');
+import errorhandler = require('errorhandler');
+var app = express();
+
+app.use(errorhandler());
diff --git a/errorhandler/errorhandler.d.ts b/errorhandler/errorhandler.d.ts
new file mode 100644
index 0000000000..e6c3011a59
--- /dev/null
+++ b/errorhandler/errorhandler.d.ts
@@ -0,0 +1,12 @@
+// Type definitions for errorhandler
+// Project: https://github.com/expressjs/errorhandler
+// Definitions by: Santi Albo
+// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module "errorhandler" {
+ import express = require('express');
+ function e(): express.ErrorRequestHandler;
+ export = e;
+}
\ No newline at end of file
diff --git a/express/express-3.1.0-tests.ts b/express/express-3.1.0-tests.ts
new file mode 100644
index 0000000000..904f645115
--- /dev/null
+++ b/express/express-3.1.0-tests.ts
@@ -0,0 +1,1498 @@
+///
+
+import express = require('express');
+var app = express();
+
+//////////////////////////
+
+var hash: any;
+
+// config
+
+app.set('view engine', 'ejs');
+app.set('views', __dirname + '/views');
+
+// middleware
+
+app.use(express.bodyParser());
+app.use(express.cookieParser('shhhh, very secret'));
+app.use(express.session());
+
+// Session-persisted message middleware
+
+app.use((req: express.Request, res: express.Response, next) => {
+ var err = req.session.error
+ , msg = req.session.success;
+ delete req.session.error;
+ delete req.session.success;
+ res.locals.message = '';
+ if (err) res.locals.message = '
' + err + '
';
+ if (msg) res.locals.message = '' + msg + '
';
+ next();
+});
+
+// dummy database
+
+var users = {
+ tj: { name: 'tj' }
+};
+
+// when you create a user, generate a salt
+// and hash the password ('foobar' is the pass here)
+
+hash('foobar', (err, salt, hash) => {
+ if (err) throw err;
+ // store the salt & hash in the "db"
+ users.tj.salt = salt;
+ users.tj.hash = hash;
+});
+
+
+// Authenticate using our plain-object database of doom!
+
+function authenticate(name, pass, fn) {
+ if (!module.parent) console.log('authenticating %s:%s', name, pass);
+ var user = users[name];
+ // query the db for the given username
+ if (!user) return fn(new Error('cannot find user'));
+ // apply the same algorithm to the POSTed password, applying
+ // the hash against the pass / salt, if there is a match we
+ // found the user
+ hash(pass, user.salt, (err, hash) => {
+ if (err) return fn(err);
+ if (hash == user.hash) return fn(null, user);
+ fn(new Error('invalid password'));
+ });
+}
+
+function restrict(req: express.Request, res: express.Response, next?: Function) {
+ if (req.session.user) {
+ next();
+ } else {
+ req.session.error = 'Access denied!';
+ res.redirect('/login');
+ }
+}
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.redirect('login');
+});
+
+app.get('/restricted', restrict, (req: express.Request, res: express.Response) => {
+ res.send('Wahoo! restricted area, click to logout');
+});
+
+app.get('/logout', (req: express.Request, res: express.Response) => {
+ // destroy the user's session to log them out
+ // will be re-created next request
+ req.session.destroy(() => {
+ res.redirect('/');
+ });
+});
+
+app.get('/login', (req: express.Request, res: express.Response) => {
+ res.render('login');
+});
+
+app.post('/login', (req: express.Request, res: express.Response) => {
+ authenticate(req.body.username, req.body.password, (err, user) => {
+ if (user) {
+ // Regenerate session when signing in
+ // to prevent fixation
+ req.session.regenerate(() => {
+ // Store the user's primary key
+ // in the session store to be retrieved,
+ // or in this case the entire user object
+ req.session.user = user;
+ req.session.success = 'Authenticated as ' + user.name
+ + ' click to logout. '
+ + ' You may now access /restricted.';
+ res.redirect('back');
+ });
+ } else {
+ req.session.error = 'Authentication failed, please check your '
+ + ' username and password.'
+ + ' (use "tj" and "foobar")';
+ res.redirect('login');
+ }
+ });
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+//////////////
+
+app.set('views', __dirname);
+app.set('view engine', 'jade');
+
+var pets = [];
+
+var n = 1000;
+while (n--) {
+ pets.push({ name: 'Tobi', age: 2, species: 'ferret' });
+ pets.push({ name: 'Loki', age: 1, species: 'ferret' });
+ pets.push({ name: 'Jane', age: 6, species: 'ferret' });
+}
+
+app.use(express.logger('dev'));
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.render('pets', { pets: pets });
+});
+
+app.listen(3000);
+console.log('Express listening on port 3000');
+
+/////////////
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.format({
+ html: () => {
+ res.send('' + users.map(user => {
+ return '- ' + user.name + '
';
+ }).join('') + '
');
+ },
+
+ text: () => {
+ res.send(users.map(user => {
+ return ' - ' + user.name + '\n';
+ }).join(''));
+ },
+
+ json: () => {
+ res.json(users);
+ }
+ });
+});
+
+// or you could write a tiny middleware like
+// this to abstract make things a bit more declarative:
+
+function format(mod) {
+ var obj = require(mod);
+ return (req: express.Request, res: express.Response) => {
+ res.format(obj);
+ };
+}
+
+app.get('/users', format('./users'));
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('listening on port 3000');
+}
+
+/////////////////////////
+
+// add favicon() before logger() so
+// GET /favicon.ico requests are not
+// logged, because this middleware
+// reponds to /favicon.ico and does not
+// call next()
+app.use(express.favicon());
+
+// custom log format
+if ('test' != process.env.NODE_ENV)
+ app.use(express.logger(':method :url'));
+
+// parses request cookies, populating
+// req.cookies and req.signedCookies
+// when the secret is passed, used
+// for signing the cookies.
+app.use(express.cookieParser('my secret here'));
+
+// parses json, x-www-form-urlencoded, and multipart/form-data
+app.use(express.bodyParser());
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ if (req.cookies.remember) {
+ res.send('Remembered :). Click to forget!.');
+ } else {
+ res.send('');
+ }
+});
+
+app.get('/forget', (req: express.Request, res: express.Response) => {
+ res.clearCookie('remember');
+ res.redirect('back');
+});
+
+app.post('/', (req: express.Request, res: express.Response) => {
+ var minute = 60000;
+ if (req.body.remember) res.cookie('remember', 1, { maxAge: minute });
+ res.redirect('back');
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+///////////////////
+
+// ignore GET /favicon.ico
+app.use(express.favicon());
+
+// pass a secret to cookieParser() for signed cookies
+app.use(express.cookieParser('manny is cool'));
+
+// add req.session cookie support
+app.use(express.cookieSession());
+
+// do something with the session
+app.use(count);
+
+// custom middleware
+function count(req: express.Request, res: express.Response) {
+ req.session.count = req.session.count || 0;
+ var n = req.session.count++;
+ res.send('viewed ' + n + ' times\n');
+}
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express server listening on port 3000');
+}
+
+///////////////
+
+var api = app;
+
+app.use(express.static(__dirname + '/public'));
+
+// api middleware
+
+api.use(express.logger('dev'));
+api.use(express.bodyParser());
+
+/**
+ * CORS support.
+ */
+
+api.all('*', (req: express.Request, res: express.Response, next) => {
+ if (!req.get('Origin')) return next();
+ // use "*" here to accept any origin
+ res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
+ res.set('Access-Control-Allow-Methods', 'GET, POST');
+ res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
+ // res.set('Access-Control-Allow-Max-Age', 3600);
+ if ('OPTIONS' == req.method) return res.send(200);
+ next();
+});
+
+/**
+ * POST a user.
+ */
+
+api.post('/user', (req: express.Request, res: express.Response) => {
+ console.log(req.body);
+ res.send(201);
+});
+
+app.listen(3000);
+api.listen(3001);
+
+console.log('app listening on 3000');
+console.log('api listening on 3001');
+
+////////////////////
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.send('');
+});
+
+// /files/* is accessed via req.params[0]
+// but here we name it :file
+app.get('/files/:file(*)', (req: express.Request, res: express.Response) => {
+ var file = req.params.file
+ , path = __dirname + '/files/' + file;
+
+ res.download(path);
+});
+
+// error handling middleware. Because it's
+// below our routes, you will be able to
+// "intercept" errors, otherwise Connect
+// will respond with 500 "Internal Server Error".
+app.use((err, req, res: express.Response, next) => {
+ // special-case 404s,
+ // remember you could
+ // render a 404 template here
+ if (404 == err.status) {
+ res.statusCode = 404;
+ res.send('Cant find that file, sorry!');
+ } else {
+ next(err);
+ }
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+///////////////////
+
+// Register ejs as .html. If we did
+// not call this, we would need to
+// name our views foo.ejs instead
+// of foo.html. The __express method
+// is simply a function that engines
+// use to hook into the Express view
+// system by default, so if we want
+// to change "foo.ejs" to "foo.html"
+// we simply pass _any_ function, in this
+// case `ejs.__express`.
+
+app.engine('.html', require('ejs').__express);
+
+// Optional since express defaults to CWD/views
+
+app.set('views', __dirname + '/views');
+
+// Without this you would need to
+// supply the extension to res.render()
+// ex: res.render('users.html').
+app.set('view engine', 'html');
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.render('users', {
+ users: users,
+ title: "EJS example",
+ header: "Some users"
+ });
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express app started on port 3000');
+}
+
+////////////////////
+
+var test: any;
+
+if (!test) app.use(express.logger('dev'));
+app.use(app.router);
+
+// the error handler is strategically
+// placed *below* the app.router; if it
+// were above it would not receive errors
+// from app.get() etc
+app.use(error);
+
+// error handling middleware have an arity of 4
+// instead of the typical (req: express.Request, res: express.Response, next),
+// otherwise they behave exactly like regular
+// middleware, you may have several of them,
+// in different orders etc.
+
+function error(err, req, res: express.Response, next) {
+ // log it
+ if (!test) console.error(err.stack);
+
+ // respond with 500 "Internal Server Error".
+ res.send(500);
+}
+
+app.get('/', () => {
+ // Caught and passed down to the errorHandler middleware
+ throw new Error('something broke!');
+});
+
+app.get('/next', (req: express.Request, res: express.Response, next) => {
+ // We can also pass exceptions to next()
+ process.nextTick(() => {
+ next(new Error('oh no!'));
+ });
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+/////////////////////
+
+var silent: any;
+
+// general config
+app.set('views', __dirname + '/views');
+app.set('view engine', 'jade');
+
+// our custom "verbose errors" setting
+// which we can use in the templates
+// via settings['verbose errors']
+app.enable('verbose errors');
+
+// disable them in production
+// use $ NODE_ENV=production node examples/error-pages
+if ('production' == app.settings.env) {
+ app.disable('verbose errors');
+}
+
+app.use(express.favicon());
+
+silent || app.use(express.logger('dev'));
+
+// "app.router" positions our routes
+// above the middleware defined below,
+// this means that Express will attempt
+// to match & call routes _before_ continuing
+// on, at which point we assume it's a 404 because
+// no route has handled the request.
+
+app.use(app.router);
+
+// Since this is the last non-error-handling
+// middleware use()d, we assume 404, as nothing else
+// responded.
+
+// $ curl http://localhost:3000/notfound
+// $ curl http://localhost:3000/notfound -H "Accept: application/json"
+// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
+
+app.use((req: express.Request, res: express.Response) => {
+ res.status(404);
+
+ // respond with html page
+ if (req.accepts('html')) {
+ res.render('404', { url: req.url });
+ return;
+ }
+
+ // respond with json
+ if (req.accepts('json')) {
+ res.send({ error: 'Not found' });
+ return;
+ }
+
+ // default to plain-text. send()
+ res.type('txt').send('Not found');
+});
+
+// error-handling middleware, take the same form
+// as regular middleware, however they require an
+// arity of 4, aka the signature (err, req, res: express.Response, next).
+// when connect has an error, it will invoke ONLY error-handling
+// middleware.
+
+// If we were to next() here any remaining non-error-handling
+// middleware would then be executed, or if we next(err) to
+// continue passing the error, only error-handling middleware
+// would remain being executed, however here
+// we simply respond with an error page.
+
+app.use((err, req, res: express.Response) => {
+ // we may use properties of the error object
+ // here and next(err) appropriately, or if
+ // we possibly recovered from the error, simply next().
+ res.status(err.status || 500);
+ res.render('500', { error: err });
+});
+
+// Routes
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.render('index.jade');
+});
+
+app.get('/404', (req: express.Request, res: express.Response, next) => {
+ // trigger a 404 since no other middleware
+ // will match /404 after this one, and we're not
+ // responding here
+ next();
+});
+
+app.get('/403', (req: express.Request, res: express.Response, next) => {
+ // trigger a 403 error
+ var err = new Error('not allowed!');
+ err.status = 403;
+ next(err);
+});
+
+app.get('/500', (req: express.Request, res: express.Response, next) => {
+ // trigger a generic (500) error
+ next(new Error('keyboard cat!'));
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ //silent || console.log('Express started on port 3000');
+}
+
+///////////////
+
+var fs: any;
+var md: any;
+
+app.set('view engine', 'jade');
+app.set('views', __dirname + '/views');
+
+function User(name) {
+ this.private = 'heyyyy';
+ this.secret = 'something';
+ this.name = name;
+ this.id = 123;
+}
+
+// You'll probably want to do
+// something like this so you
+// dont expose "secret" data.
+
+User.prototype.toJSON = function () {
+ return {
+ id: this.id,
+ name: this.name
+ };
+};
+
+app.use(express.logger('dev'));
+
+// earlier on expose an object
+// that we can tack properties on.
+// all res.locals props are exposed
+// to the templates, so "expose" will
+// be present.
+
+app.use((req: express.Request, res: express.Response, next) => {
+ res.locals.expose = {};
+ // you could alias this as req or res.expose
+ // to make it shorter and less annoying
+ next();
+});
+
+// pretend we loaded a user
+
+app.use((req: express.Request, res: express.Response, next) => {
+ req.user = new User('Tobi');
+ next();
+});
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.redirect('/user');
+});
+
+app.get('/user', (req: express.Request, res: express.Response) => {
+ // we only want to expose the user
+ // to the client for this route:
+ res.locals.expose.user = req.user;
+ res.render('page');
+});
+
+app.listen(3000);
+console.log('app listening on port 3000');
+
+///////////////////////
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.send('Hello World');
+});
+
+app.listen(3000);
+console.log('Express started on port 3000');
+
+////////////////////
+
+// register .md as an engine in express view system
+
+app.engine('md', (path, options, fn) => {
+ fs.readFile(path, 'utf8', (err, str) => {
+ if (err) return fn(err);
+ try {
+ var html = md(str);
+ html = html.replace(/\{([^}]+)\}/g, (_, name) => {
+ return options[name] || '';
+ });
+ fn(null, html);
+ } catch (err) {
+ fn(err);
+ }
+ });
+});
+
+app.set('views', __dirname + '/views');
+
+// make it the default so we dont need .md
+app.set('view engine', 'md');
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.render('index', { title: 'Markdown Example' });
+});
+
+app.get('/fail', (req: express.Request, res: express.Response) => {
+ res.render('missing', { title: 'Markdown Example' });
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+///////////////////////
+
+var mformat: any;
+
+// bodyParser in connect 2.x uses node-formidable to parse
+// the multipart form data.
+app.use(express.bodyParser());
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.send('');
+});
+
+app.post('/', (req: express.Request, res: express.Response) => {
+ // the uploaded file can be found as `req.files.image` and the
+ // title field as `req.body.title`
+ res.send(mformat('\nuploaded %s (%d Kb) to %s as %s'
+ , req.files.image.name
+ , req.files.image.size / 1024 | 0
+ , req.files.image.path
+ , req.body.title));
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+//////////////////
+
+
+// first:
+// $ npm install redis online
+// $ redis-server
+
+/**
+ * Module dependencies.
+ */
+
+var online: any;
+var db: any;
+
+// online
+
+online = online(db);
+
+// activity tracking, in this case using
+// the UA string, you would use req.user.id etc
+
+app.use((req: express.Request, res: express.Response, next) => {
+ // fire-and-forget
+ online.add(req.headers['user-agent']);
+ next();
+});
+
+/**
+ * List helper.
+ */
+
+function list(ids) {
+ return '' + ids.map(id => {
+ return '- ' + id + '
';
+ }).join('') + '
';
+}
+
+/**
+ * GET users online.
+ */
+
+app.get('/', (req: express.Request, res: express.Response, next) => {
+ online.last(5, (err, ids) => {
+ if (err) return next(err);
+ res.send('Users online: ' + ids.length + '
' + list(ids));
+ });
+});
+
+app.listen(3000);
+console.log('listening on port 3000');
+
+///////////////////
+
+// Convert :to and :from to integers
+
+app.param(['to', 'from'], (req: express.Request, res: express.Response, next, num, name) => {
+ req.params[name] = num = parseInt(num, 10);
+ if (isNaN(num)) {
+ next(new Error('failed to parseInt ' + num));
+ } else {
+ next();
+ }
+});
+
+// Load user by id
+
+app.param('user', (req: express.Request, res: express.Response, next, id) => {
+ if (req.user = users[id]) {
+ next();
+ } else {
+ next(new Error('failed to find user'));
+ }
+});
+
+/**
+ * GET index.
+ */
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.send('Visit /user/0 or /users/0-2');
+});
+
+/**
+ * GET :user.
+ */
+
+app.get('/user/:user', (req: express.Request, res: express.Response) => {
+ res.send('user ' + req.user.name);
+});
+
+/**
+ * GET users :from - :to.
+ */
+
+app.get('/users/:from-:to', (req: express.Request, res: express.Response) => {
+ var from = req.params.from
+ , to = req.params.to
+ , names = users.map(user => { return user.name; });
+ res.send('users ' + names.slice(from, to).join(', '));
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+//////////////////
+
+// Ad-hoc example resource method
+
+app.resource = function (path, obj) {
+ this.get(path, obj.index);
+ this.get(path + '/:a..:b.:format?', (req: express.Request, res: express.Response) => {
+ var a = parseInt(req.params.a, 10)
+ , b = parseInt(req.params.b, 10)
+ , format = req.params.format;
+ obj.range(req, res, a, b, format);
+ });
+ this.get(path + '/:id', obj.show);
+ this.del(path + '/:id', obj.destroy);
+};
+
+// Fake controller.
+
+var FUser = {
+ index: (req: express.Request, res: express.Response) => {
+ res.send(users);
+ },
+ show: (req: express.Request, res: express.Response) => {
+ res.send(users[req.params.id] || { error: 'Cannot find user' });
+ },
+ destroy: (req: express.Request, res: express.Response) => {
+ var id = req.params.id;
+ var destroyed = id in users;
+ delete users[id];
+ res.send(destroyed ? 'destroyed' : 'Cannot find user');
+ },
+ range: (req: express.Request, res: express.Response, a, b, format) => {
+ var range = users.slice(a, b + 1);
+ switch (format) {
+ case 'json':
+ res.send(range);
+ break;
+ case 'html':
+ default:
+ var html = '' + range.map(user => {
+ return '- ' + user.name + '
';
+ }).join('\n') + '
';
+ res.send(html);
+ break;
+ }
+ }
+};
+
+// curl http://localhost:3000/users -- responds with all users
+// curl http://localhost:3000/users/1 -- responds with user 1
+// curl http://localhost:3000/users/4 -- responds with error
+// curl http://localhost:3000/users/1..3 -- responds with several users
+// curl -X DELETE http://localhost:3000/users/1 -- deletes the user
+
+app.resource('/users', FUser);
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.send([
+ 'Examples:
'
+ , '- GET /users
'
+ , '- GET /users/1
'
+ , '- GET /users/3
'
+ , '- GET /users/1..3
'
+ , '- GET /users/1..3.json
'
+ , '- DELETE /users/4
'
+ , '
'
+ ].join('\n'));
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express started on port 3000');
+}
+
+/////////////////////
+
+
+var verbose: any;
+
+app.map = (a, route) => {
+ route = route || '';
+ for (var key in a) {
+ switch (typeof a[key]) {
+ // { '/path': { ... }}
+ case 'object':
+ app.map(a[key], route + key);
+ break;
+ // get: function(){ ... }
+ case 'function':
+ if (verbose) console.log('%s %s', key, route);
+ app[key](route, a[key]);
+ break;
+ }
+ }
+};
+
+var users2 = {
+ list: (req: express.Request, res: express.Response) => {
+ res.send('user list');
+ },
+
+ get: (req: express.Request, res: express.Response) => {
+ res.send('user ' + req.params.uid);
+ },
+
+ del: (req: express.Request, res: express.Response) => {
+ res.send('delete users');
+ }
+};
+
+var pets2 = {
+ list: (req: express.Request, res: express.Response) => {
+ res.send('user ' + req.params.uid + '\'s pets');
+ },
+
+ del: (req: express.Request, res: express.Response) => {
+ res.send('delete ' + req.params.uid + '\'s pet ' + req.params.pid);
+ }
+};
+
+app.map({
+ '/users': {
+ get: users2.list,
+ del: users2.del,
+ '/:uid': {
+ get: users.get ,
+ '/pets': {
+ get: pets2.list,
+ '/:pid': {
+ del: pets2.del
+ }
+ }
+ }
+ }
+});
+
+app.listen(3000);
+
+///////////////////////////
+
+// Example requests:
+// curl http://localhost:3000/user/0
+// curl http://localhost:3000/user/0/edit
+// curl http://localhost:3000/user/1
+// curl http://localhost:3000/user/1/edit (unauthorized since this is not you)
+// curl -X DELETE http://localhost:3000/user/0 (unauthorized since you are not an admin)
+
+function loadUser(req: express.Request, res: express.Response, next) {
+ // You would fetch your user from the db
+ var user = users[req.params.id];
+ if (user) {
+ req.user = user;
+ next();
+ } else {
+ next(new Error('Failed to load user ' + req.params.id));
+ }
+}
+
+function andRestrictToSelf(req: express.Request, res: express.Response, next) {
+ // If our authenticated user is the user we are viewing
+ // then everything is fine :)
+ if (req.authenticatedUser.id == req.user.id) {
+ next();
+ } else {
+ // You may want to implement specific exceptions
+ // such as UnauthorizedError or similar so that you
+ // can handle these can be special-cased in an error handler
+ // (view ./examples/pages for this)
+ next(new Error('Unauthorized'));
+ }
+}
+
+function andRestrictTo(role) {
+ return (req: express.Request, res: express.Response, next) => {
+ if (req.authenticatedUser.role == role) {
+ next();
+ } else {
+ next(new Error('Unauthorized'));
+ }
+ };
+}
+
+// Middleware for faux authentication
+// you would of course implement something real,
+// but this illustrates how an authenticated user
+// may interact with middleware
+
+app.use((req: express.Request, res: express.Response, next) => {
+ req.authenticatedUser = users[0];
+ next();
+});
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.redirect('/user/0');
+});
+
+app.get('/user/:id', loadUser, (req: express.Request, res: express.Response) => {
+ res.send('Viewing user ' + req.user.name);
+});
+
+app.get('/user/:id/edit', loadUser, andRestrictToSelf, (req: express.Request, res: express.Response) => {
+ res.send('Editing user ' + req.user.name);
+});
+
+app.del('/user/:id', loadUser, andRestrictTo('admin'), (req: express.Request, res: express.Response) => {
+ res.send('Deleted user ' + req.user.name);
+});
+
+app.listen(3000);
+console.log('Express app started on port 3000');
+
+/////////////////////////
+
+app.set('view engine', 'jade');
+app.set('views', __dirname);
+
+// populate search
+
+db.sadd('ferret', 'tobi');
+db.sadd('ferret', 'loki');
+db.sadd('ferret', 'jane');
+db.sadd('cat', 'manny');
+db.sadd('cat', 'luna');
+
+/**
+ * GET the search page.
+ */
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ res.render('search');
+});
+
+/**
+ * GET search for :query.
+ */
+
+app.get('/search/:query?', (req: express.Request, res: express.Response) => {
+ var query = req.params.query;
+ db.smembers(query, (err, vals) => {
+ if (err) return res.send(500);
+ res.send(vals);
+ });
+});
+
+/**
+ * GET client javascript. Here we use sendfile()
+ * because serving __dirname with the static() middleware
+ * would also mean serving our server "index.js" and the "search.jade"
+ * template.
+ */
+
+app.get('/client.js', (req: express.Request, res: express.Response) => {
+ res.sendfile(__dirname + '/client.js');
+});
+
+app.listen(3000);
+console.log('app listening on port 3000');
+
+///////////////////
+
+app.use(express.logger('dev'));
+
+// Required by session() middleware
+// pass the secret for signed cookies
+// (required by session())
+app.use(express.cookieParser('keyboard cat'));
+
+// Populates req.session
+app.use(express.session());
+
+app.get('/', (req: express.Request, res: express.Response) => {
+ var body = '';
+ if (req.session.views) {
+ ++req.session.views;
+ } else {
+ req.session.views = 1;
+ body += 'First time visiting? view this page in several browsers :)
';
+ }
+ res.send(body + 'viewed ' + req.session.views + ' times.
');
+});
+
+app.listen(3000);
+console.log('Express app started on port 3000');
+
+////////////////////////
+
+// log requests
+app.use(express.logger('dev'));
+
+// express on its own has no notion
+// of a "file". The express.static()
+// middleware checks for a file matching
+// the `req.path` within the directory
+// that you pass it. In this case "GET /js/app.js"
+// will look for "./public/js/app.js".
+
+app.use(express.static(__dirname + '/public'));
+
+// if you wanted to "prefix" you may use
+// the mounting feature of Connect, for example
+// "GET /static/js/app.js" instead of "GET /js/app.js".
+// The mount-path "/static" is simply removed before
+// passing control to the express.static() middleware,
+// thus it serves the file correctly by ignoring "/static"
+app.use('/static', express.static(__dirname + '/public'));
+
+// if for some reason you want to serve files from
+// several directories, you can use express.static()
+// multiple times! Here we're passing "./public/css",
+// this will allow "GET /style.css" instead of "GET /css/style.css":
+app.use(express.static(__dirname + '/public/css'));
+
+// this examples does not have any routes, however
+// you may `app.use(app.router)` before or after these
+// static() middleware. If placed before them your routes
+// will be matched BEFORE file serving takes place. If placed
+// after as shown here then file serving is performed BEFORE
+// any routes are hit:
+app.use(app.router);
+
+app.listen(3000);
+console.log('listening on port 3000');
+console.log('try:');
+console.log(' GET /hello.txt');
+console.log(' GET /js/app.js');
+console.log(' GET /css/style.css');
+
+//////////////////
+
+/*
+edit /etc/vhosts:
+
+127.0.0.1 foo.example.com
+127.0.0.1 bar.example.com
+127.0.0.1 example.com
+*/
+
+// Main app
+
+var main = express();
+
+main.use(express.logger('dev'));
+
+main.get('/', (req: express.Request, res: express.Response) => {
+ res.send('Hello from main app!');
+});
+
+main.get('/:sub', (req: express.Request, res: express.Response) => {
+ res.send('requsted ' + req.params.sub);
+});
+
+// Redirect app
+
+var redirect = express();
+
+redirect.all('*', (req: express.Request, res: express.Response) => {
+ console.log(req.subdomains);
+ res.redirect('http://example.com:3000/' + req.subdomains[0]);
+});
+
+app.use(express.vhost('*.example.com', redirect));
+app.use(express.vhost('example.com', main));
+
+app.listen(3000);
+console.log('Express app started on port 3000');
+
+////////////////////
+
+// create an error with .status. we
+// can then use the property in our
+// custom error handler (Connect repects this prop as well)
+
+function merror(status, msg) {
+ var err = new Error(msg);
+ err.status = status;
+ return err;
+}
+
+// if we wanted to supply more than JSON, we could
+// use something similar to the content-negotiation
+// example.
+
+// here we validate the API key,
+// by mounting this middleware to /api
+// meaning only paths prefixed with "/api"
+// will cause this middleware to be invoked
+
+app.use('/api', (req, res: express.Response, next) => {
+ var key = req.query['api-key'];
+
+ // key isnt present
+ if (!key) return next(merror(400, 'api key required'));
+
+ // key is invalid
+ if (!~apiKeys.indexOf(key)) return next(merror(401, 'invalid api key'));
+
+ // all good, store req.key for route access
+ req.key = key;
+ next();
+});
+
+// position our routes above the error handling middleware,
+// and below our API middleware, since we want the API validation
+// to take place BEFORE our routes
+app.use(app.router);
+
+// middleware with an arity of 4 are considered
+// error handling middleware. When you next(err)
+// it will be passed through the defined middleware
+// in order, but ONLY those with an arity of 4, ignoring
+// regular middleware.
+app.use((err, req, res: express.Response) => {
+ // whatever you want here, feel free to populate
+ // properties on `err` to treat it differently in here.
+ res.send(err.status || 500, { error: err.message });
+});
+
+// our custom JSON 404 middleware. Since it's placed last
+// it will be the last middleware called, if all others
+// invoke next() and do not respond.
+app.use((req: express.Request, res: express.Response) => {
+ res.send(404, { error: "Lame, can't find that" });
+});
+
+// map of valid api keys, typically mapped to
+// account info with some sort of database like redis.
+// api keys do _not_ serve as authentication, merely to
+// track API usage or help prevent malicious behavior etc.
+
+var apiKeys = ['foo', 'bar', 'baz'];
+
+// these two objects will serve as our faux database
+
+var repos = [
+ { name: 'express', url: 'http://github.com/visionmedia/express' }
+ , { name: 'stylus', url: 'http://github.com/learnboost/stylus' }
+ , { name: 'cluster', url: 'http://github.com/learnboost/cluster' }
+];
+
+var userRepos = {
+ tobi: [repos[0], repos[1]]
+ , loki: [repos[1]]
+ , jane: [repos[2]]
+};
+
+// we now can assume the api key is valid,
+// and simply expose the data
+
+app.get('/api/users', (req: express.Request, res: express.Response) => {
+ res.send(users);
+});
+
+app.get('/api/repos', (req: express.Request, res: express.Response) => {
+ res.send(repos);
+});
+
+app.get('/api/user/:name/repos', (req: express.Request, res: express.Response, next) => {
+ var name = req.params.name
+ , user = userRepos[name];
+
+ if (user) res.send(user);
+ else next();
+});
+
+if (!module.parent) {
+ app.listen(3000);
+ console.log('Express server listening on port 3000');
+}
+
+//////
+
+var router = new express.Router();
+
+router.get('/', function (req, resp, next?) {
+ resp.send('response from router');
+ resp.end();
+ if (next) {
+ next();
+ }
+});
+
+function test_general() {
+
+ app.use((err, req, res: express.Response) => {
+ console.error(err.stack);
+ res.send(500, 'Something broke!');
+ });
+ app.use(express.bodyParser());
+ app.use(express.methodOverride());
+ app.use(app.router);
+ app.use(() => {});
+ app.use(express.bodyParser());
+ app.use(express.methodOverride());
+ app.use(app.router);
+
+ app.get('/', (req: express.Request, res: express.Response) => {
+ res.send('hello world');
+ });
+
+ app.listen(3000);
+
+ app.set('title', 'My Site');
+ app.get('title');
+
+ app.enable('trust proxy');
+ app.get('trust proxy');
+
+ app.disable('trust proxy');
+ app.get('trust proxy');
+
+ app.enabled('trust proxy');
+
+ app.configure(() => {
+ app.set('title', 'My Application');
+ });
+
+ app.configure('development', () => {
+ app.set('db uri', 'localhost/dev');
+ });
+
+ app.configure('stage', 'production', () => {});
+
+ app.configure('1', '2', '3', () => {});
+
+ app.use((req: express.Request, res: express.Response) => {
+ res.send('Hello World');
+ });
+
+ app.engine('jade', require('jade').__express);
+
+ var User;
+ app.param('user', (req: express.Request, res: express.Response, next, id) => {
+ User.find(id, (err, user) =>{
+ if (err) {
+ next(err);
+ } else if (user) {
+ req.user = user;
+ next();
+ } else {
+ next(new Error('failed to load user'));
+ }
+ });
+ });
+
+ app.get(/^\/commits\/(\d+)(?:\.\.(\d+))?$/, (req: express.Request, res: express.Response) => {
+ var from = req.params[0];
+ var to = req.params[1] || 'HEAD';
+ res.send('commit range ' + from + '..' + to);
+ });
+
+ app.locals.title = 'My App';
+ app.locals.strftime = require('strftime');
+
+ var requireAuthentication;
+ var loadUser = () => {};
+ app.all('*', requireAuthentication, loadUser);
+ app.all('*', loadUser);
+ app.all('*', loadUser, loadUser, loadUser);
+
+ app.locals.title = 'My App';
+ app.locals.strftime = require('strftime');
+ app.locals({
+ title: 'My App',
+ phone: '1-250-858-9990',
+ email: 'me@myapp.com'
+ });
+ app.render('email', () => {});
+
+ app.render('email', { name: 'Tobi' }, () => {});
+}
+
+function test_request() {
+ var req: express.Request;
+ req.params.name;
+ req.params[0];
+ req.query.q;
+ req.body.user.name;
+ app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/my/files' }));
+ req.param('name');
+ req.route;
+ req.cookies.name;
+ req.signedCookies;
+ req.get('Content-Type');
+ req.accepts('html');
+ req.accepts(['html', 'json']);
+ req.is('html');
+ req.ip;
+ req.path;
+ req.host;
+ req.fresh;
+ req.stale;
+ req.xhr;
+ req.protocol;
+ req.subdomains;
+ req.originalUrl;
+ req.acceptedLanguages;
+ req.acceptedCharsets;
+ var charset;
+ req.acceptsCharset(charset);
+ var lang;
+ req.acceptsLanguage(lang);
+ req.session = null;
+}
+
+function test_response() {
+ var res: express.Response;
+ res.status(404).sendfile('path/to/404.png');
+ res.set('Content-Type', 'text/plain');
+ res.set({
+ 'Content-Type': 'text/plain',
+ 'Content-Length': '123',
+ 'ETag': '12345'
+ });
+ res.get('Content-Type');
+ res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
+ res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
+ res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true });
+ res.cookie('cart', { items: [1, 2, 3] });
+ res.cookie('cart', { items: [1, 2, 3] }, { maxAge: 900000 });;
+ res.cookie('name', 'tobi', { signed: true });
+ res.cookie('name', 'tobi', { path: '/admin' });
+ res.clearCookie('name', { path: '/admin' });
+ res.redirect('/foo/bar');
+ res.redirect('http://example.com');
+ res.redirect(301, 'http://example.com');
+ res.charset = 'value';
+ res.send('some html');
+ res.send(new Buffer('whoop'));
+ res.send({ some: 'json' });
+ res.send('some html');
+ res.send(404, 'Sorry, we cannot find that!');
+ res.send(500, { error: 'something blew up' });
+ res.send(200);
+ res.set('Content-Type', 'text/html');
+ res.send(new Buffer('some html'));
+ res.send('some html');
+ res.send({ user: 'tobi' });
+ res.send([1, 2, 3]);
+ res.json(null);
+ res.json({ user: 'tobi' });
+ res.json(500, { error: 'message' });
+ res.jsonp(null);
+ res.jsonp({ user: 'tobi' });
+ res.jsonp(500, { error: 'message' });
+ res.jsonp({ user: 'tobi' });
+ res.type('application/json');
+
+ res.format({
+ 'text/plain': () => {
+ res.send('hey');
+ },
+ 'text/html': () => {
+ res.send('hey');
+ },
+ 'application/json': () => {
+ res.send({ message: 'hey' });
+ }
+ });
+
+ res.attachment();
+ res.attachment('path/to/logo.png');
+ app.get('/user/:uid/photos/:file', (req: express.Request, res: express.Response) => {
+ var uid = req.params.uid
+ , file = req.params.file;
+
+ req.user.mayViewFilesFrom(uid, yes => {
+ if (yes) {
+ res.sendfile('/uploads/' + uid + '/' + file);
+ } else {
+ res.send(403, 'Sorry! you cant see that.');
+ }
+ });
+ });
+
+ res.download('/report-12345.pdf');
+ res.download('/report-12345.pdf', 'report.pdf');
+ res.download('/report-12345.pdf', 'report.pdf', err => {
+ if (err) { } else { }
+ });
+
+ res.links({
+ next: 'http://api.example.com/users?page=2',
+ last: 'http://api.example.com/users?page=5'
+ });
+
+ app.use((req: express.Request, res: express.Response, next) => {
+ res.locals.user = req.user;
+ res.locals.authenticated = !req.user.anonymous;
+ next();
+ });
+ res.render('index', () => {});
+ res.render('user', { name: 'Tobi' }, () => {});
+
+}
+
+function test_middleware() {
+ app.use(express.basicAuth('username', 'password'));
+ app.use(express.basicAuth((user, pass) => {
+ return 'tj' == user && 'wahoo' == pass;
+ }));
+ app.use(express.bodyParser());
+ app.use(express.json());
+ app.use(express.urlencoded());
+ app.use(express.multipart());
+ app.use(express.logger());
+ app.use(express.compress());
+ app.use(express.methodOverride());
+ app.use(express.bodyParser());
+ app.use(express.cookieParser());
+ app.use(express.cookieParser('some secret'));
+ app.use(express.cookieSession());
+ app.use(express.directory('public'));
+ app.use(express.static('public'));
+ app.use(router.middleware);
+}
+
+////////////////////
+
+// make sure server can be shut down
+var testShutdownServer = app.listen(0);
+console.log('listening on port ' + testShutdownServer.address().port);
+testShutdownServer.close();
diff --git a/express/express-3.1.0-tests.ts.tscparams b/express/express-3.1.0-tests.ts.tscparams
new file mode 100644
index 0000000000..e16c76dff8
--- /dev/null
+++ b/express/express-3.1.0-tests.ts.tscparams
@@ -0,0 +1 @@
+""
diff --git a/express/express-3.1.0.d.ts b/express/express-3.1.0.d.ts
new file mode 100644
index 0000000000..d5865f418c
--- /dev/null
+++ b/express/express-3.1.0.d.ts
@@ -0,0 +1,1832 @@
+// Type definitions for Express 3.1
+// Project: http://expressjs.com
+// Definitions by: Boris Yankov
+// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
+
+/* =================== USAGE ===================
+
+ import express = require('express');
+ var app = express();
+
+ =============================================== */
+
+///
+
+
+declare module Express {
+
+ // These open interfaces may be extended in an application-specific manner via declaration merging.
+ // See for example passport.d.ts (https://github.com/borisyankov/DefinitelyTyped/blob/master/passport/passport.d.ts)
+ export interface Request { }
+ export interface Response { }
+ export interface Application { }
+}
+
+
+declare module "express" {
+ import http = require('http');
+
+ // Merged declaration, e is both a callable function and a namespace
+ function e(): e.Express;
+
+ module e {
+ interface IRoute {
+ path: string;
+
+ method: string;
+
+ callbacks: Function[];
+
+ regexp: any;
+
+ /**
+ * Check if this route matches `path`, if so
+ * populate `.params`.
+ */
+ match(path: string): boolean;
+ }
+
+ class Route implements IRoute {
+ path: string;
+
+ method: string;
+
+ callbacks: Function[];
+
+ regexp: any;
+ match(path: string): boolean;
+
+ /**
+ * Initialize `Route` with the given HTTP `method`, `path`,
+ * and an array of `callbacks` and `options`.
+ *
+ * Options:
+ *
+ * - `sensitive` enable case-sensitive routes
+ * - `strict` enable strict matching for trailing slashes
+ *
+ * @param method
+ * @param path
+ * @param callbacks
+ * @param options
+ */
+ new (method: string, path: string, callbacks: Function[], options: any): Route;
+ }
+
+ interface IRouter {
+ /**
+ * Map the given param placeholder `name`(s) to the given callback(s).
+ *
+ * Parameter mapping is used to provide pre-conditions to routes
+ * which use normalized placeholders. For example a _:user_id_ parameter
+ * could automatically load a user's information from the database without
+ * any additional code,
+ *
+ * The callback uses the samesignature as middleware, the only differencing
+ * being that the value of the placeholder is passed, in this case the _id_
+ * of the user. Once the `next()` function is invoked, just like middleware
+ * it will continue on to execute the route, or subsequent parameter functions.
+ *
+ * app.param('user_id', function(req, res, next, id){
+ * User.find(id, function(err, user){
+ * if (err) {
+ * next(err);
+ * } else if (user) {
+ * req.user = user;
+ * next();
+ * } else {
+ * next(new Error('failed to load user'));
+ * }
+ * });
+ * });
+ *
+ * @param name
+ * @param fn
+ */
+ param(name: string, fn: Function): T;
+
+ param(name: string[], fn: Function): T;
+
+ /**
+ * Special-cased "all" method, applying the given route `path`,
+ * middleware, and callback to _every_ HTTP method.
+ *
+ * @param path
+ * @param fn
+ */
+ all(path: string, fn?: (req: Request, res: Response, next: Function) => any): T;
+
+ all(path: string, ...callbacks: Function[]): void;
+
+ get(name: string, ...handlers: RequestFunction[]): T;
+
+ get(name: RegExp, ...handlers: RequestFunction[]): T;
+
+ post(name: string, ...handlers: RequestFunction[]): T;
+
+ post(name: RegExp, ...handlers: RequestFunction[]): T;
+
+ put(name: string, ...handlers: RequestFunction[]): T;
+
+ put(name: RegExp, ...handlers: RequestFunction[]): T;
+
+ del(name: string, ...handlers: RequestFunction[]): T;
+
+ del(name: RegExp, ...handlers: RequestFunction[]): T;
+
+ patch(name: string, ...handlers: RequestFunction[]): T;
+
+ patch(name: RegExp, ...handlers: RequestFunction[]): T;
+ }
+
+ export class Router implements IRouter {
+ new (options?: any): Router;
+
+ middleware (): any;
+
+ param(name: string, fn: Function): Router;
+
+ param(name: any[], fn: Function): Router;
+
+ all(path: string, fn?: (req: Request, res: Response, next: Function) => any): Router;
+
+ all(path: string, ...callbacks: Function[]): void;
+
+ get(name: string, ...handlers: RequestFunction[]): Router;
+
+ get(name: RegExp, ...handlers: RequestFunction[]): Router;
+
+ post(name: string, ...handlers: RequestFunction[]): Router;
+
+ post(name: RegExp, ...handlers: RequestFunction[]): Router;
+
+ put(name: string, ...handlers: RequestFunction[]): Router;
+
+ put(name: RegExp, ...handlers: RequestFunction[]): Router;
+
+ del(name: string, ...handlers: RequestFunction[]): Router;
+
+ del(name: RegExp, ...handlers: RequestFunction[]): Router;
+
+ patch(name: string, ...handlers: RequestFunction[]): Router;
+
+ patch(name: RegExp, ...handlers: RequestFunction[]): Router;
+ }
+
+ interface Handler {
+ (req: Request, res: Response, next?: Function): void;
+ }
+
+ interface CookieOptions {
+ maxAge?: number;
+ signed?: boolean;
+ expires?: Date;
+ httpOnly?: boolean;
+ path?: string;
+ domain?: string;
+ secure?: boolean;
+ }
+
+ interface Errback { (err: Error): void; }
+
+ interface Session {
+ /**
+ * Update reset `.cookie.maxAge` to prevent
+ * the cookie from expiring when the
+ * session is still active.
+ *
+ * @return {Session} for chaining
+ * @api public
+ */
+ touch(): Session;
+
+ /**
+ * Reset `.maxAge` to `.originalMaxAge`.
+ */
+ resetMaxAge(): Session;
+
+ /**
+ * Save the session data with optional callback `fn(err)`.
+ */
+ save(fn: Function): Session;
+
+ /**
+ * Re-loads the session data _without_ altering
+ * the maxAge properties. Invokes the callback `fn(err)`,
+ * after which time if no exception has occurred the
+ * `req.session` property will be a new `Session` object,
+ * although representing the same session.
+ */
+ reload(fn: Function): Session;
+
+ /**
+ * Destroy `this` session.
+ */
+ destroy(fn: Function): Session;
+
+ /**
+ * Regenerate this request's session.
+ */
+ regenerate(fn: Function): Session;
+
+ user: any;
+
+ error: string;
+
+ success: string;
+
+ views: any;
+
+ count: number;
+ }
+
+ interface Request extends http.ServerRequest, Express.Request {
+
+ session: Session;
+
+ /**
+ * Return request header.
+ *
+ * The `Referrer` header field is special-cased,
+ * both `Referrer` and `Referer` are interchangeable.
+ *
+ * Examples:
+ *
+ * req.get('Content-Type');
+ * // => "text/plain"
+ *
+ * req.get('content-type');
+ * // => "text/plain"
+ *
+ * req.get('Something');
+ * // => undefined
+ *
+ * Aliased as `req.header()`.
+ *
+ * @param name
+ */
+ get (name: string): string;
+
+ header(name: string): string;
+
+ headers: { [key: string]: string; };
+
+ /**
+ * Check if the given `type(s)` is acceptable, returning
+ * the best match when true, otherwise `undefined`, in which
+ * case you should respond with 406 "Not Acceptable".
+ *
+ * The `type` value may be a single mime type string
+ * such as "application/json", the extension name
+ * such as "json", a comma-delimted list such as "json, html, text/plain",
+ * or an array `["json", "html", "text/plain"]`. When a list
+ * or array is given the _best_ match, if any is returned.
+ *
+ * Examples:
+ *
+ * // Accept: text/html
+ * req.accepts('html');
+ * // => "html"
+ *
+ * // Accept: text/*, application/json
+ * req.accepts('html');
+ * // => "html"
+ * req.accepts('text/html');
+ * // => "text/html"
+ * req.accepts('json, text');
+ * // => "json"
+ * req.accepts('application/json');
+ * // => "application/json"
+ *
+ * // Accept: text/*, application/json
+ * req.accepts('image/png');
+ * req.accepts('png');
+ * // => undefined
+ *
+ * // Accept: text/*;q=.5, application/json
+ * req.accepts(['html', 'json']);
+ * req.accepts('html, json');
+ * // => "json"
+ */
+ accepts(type: string): string;
+
+ accepts(type: string[]): string;
+
+ /**
+ * Check if the given `charset` is acceptable,
+ * otherwise you should respond with 406 "Not Acceptable".
+ *
+ * @param charset
+ */
+ acceptsCharset(charset: string): boolean;
+
+ /**
+ * Check if the given `lang` is acceptable,
+ * otherwise you should respond with 406 "Not Acceptable".
+ *
+ * @param lang
+ */
+ acceptsLanguage(lang: string): boolean;
+
+ /**
+ * Parse Range header field,
+ * capping to the given `size`.
+ *
+ * Unspecified ranges such as "0-" require
+ * knowledge of your resource length. In
+ * the case of a byte range this is of course
+ * the total number of bytes. If the Range
+ * header field is not given `null` is returned,
+ * `-1` when unsatisfiable, `-2` when syntactically invalid.
+ *
+ * NOTE: remember that ranges are inclusive, so
+ * for example "Range: users=0-3" should respond
+ * with 4 users when available, not 3.
+ *
+ * @param size
+ */
+ range(size: number): any[];
+
+ /**
+ * Return an array of Accepted media types
+ * ordered from highest quality to lowest.
+ */
+ accepted: MediaType[];
+
+ /**
+ * Return an array of Accepted languages
+ * ordered from highest quality to lowest.
+ *
+ * Examples:
+ *
+ * Accept-Language: en;q=.5, en-us
+ * ['en-us', 'en']
+ */
+ acceptedLanguages: any[];
+
+ /**
+ * Return an array of Accepted charsets
+ * ordered from highest quality to lowest.
+ *
+ * Examples:
+ *
+ * Accept-Charset: iso-8859-5;q=.2, unicode-1-1;q=0.8
+ * ['unicode-1-1', 'iso-8859-5']
+ */
+ acceptedCharsets: any[];
+
+ /**
+ * Return the value of param `name` when present or `defaultValue`.
+ *
+ * - Checks route placeholders, ex: _/user/:id_
+ * - Checks body params, ex: id=12, {"id":12}
+ * - Checks query string params, ex: ?id=12
+ *
+ * To utilize request bodies, `req.body`
+ * should be an object. This can be done by using
+ * the `connect.bodyParser()` middleware.
+ *
+ * @param name
+ * @param defaultValue
+ */
+ param(name: string, defaultValue?: any): string;
+
+ /**
+ * Check if the incoming request contains the "Content-Type"
+ * header field, and it contains the give mime `type`.
+ *
+ * Examples:
+ *
+ * // With Content-Type: text/html; charset=utf-8
+ * req.is('html');
+ * req.is('text/html');
+ * req.is('text/*');
+ * // => true
+ *
+ * // When Content-Type is application/json
+ * req.is('json');
+ * req.is('application/json');
+ * req.is('application/*');
+ * // => true
+ *
+ * req.is('html');
+ * // => false
+ *
+ * @param type
+ */
+ is(type: string): boolean;
+
+ /**
+ * Return the protocol string "http" or "https"
+ * when requested with TLS. When the "trust proxy"
+ * setting is enabled the "X-Forwarded-Proto" header
+ * field will be trusted. If you're running behind
+ * a reverse proxy that supplies https for you this
+ * may be enabled.
+ */
+ protocol: string;
+
+ /**
+ * Short-hand for:
+ *
+ * req.protocol == 'https'
+ */
+ secure: boolean;
+
+ /**
+ * Return the remote address, or when
+ * "trust proxy" is `true` return
+ * the upstream addr.
+ */
+ ip: string;
+
+ /**
+ * When "trust proxy" is `true`, parse
+ * the "X-Forwarded-For" ip address list.
+ *
+ * For example if the value were "client, proxy1, proxy2"
+ * you would receive the array `["client", "proxy1", "proxy2"]`
+ * where "proxy2" is the furthest down-stream.
+ */
+ ips: string[];
+
+ /**
+ * Return basic auth credentials.
+ *
+ * Examples:
+ *
+ * // http://tobi:hello@example.com
+ * req.auth
+ * // => { username: 'tobi', password: 'hello' }
+ */
+ auth: any;
+
+ /**
+ * Return subdomains as an array.
+ *
+ * Subdomains are the dot-separated parts of the host before the main domain of
+ * the app. By default, the domain of the app is assumed to be the last two
+ * parts of the host. This can be changed by setting "subdomain offset".
+ *
+ * For example, if the domain is "tobi.ferrets.example.com":
+ * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.
+ * If "subdomain offset" is 3, req.subdomains is `["tobi"]`.
+ */
+ subdomains: string[];
+
+ /**
+ * Short-hand for `url.parse(req.url).pathname`.
+ */
+ path: string;
+
+ /**
+ * Parse the "Host" header field hostname.
+ */
+ host: string;
+
+ /**
+ * Check if the request is fresh, aka
+ * Last-Modified and/or the ETag
+ * still match.
+ */
+ fresh: boolean;
+
+ /**
+ * Check if the request is stale, aka
+ * "Last-Modified" and / or the "ETag" for the
+ * resource has changed.
+ */
+ stale: boolean;
+
+ /**
+ * Check if the request was an _XMLHttpRequest_.
+ */
+ xhr: boolean;
+
+ //body: { username: string; password: string; remember: boolean; title: string; };
+ body: any;
+
+ //cookies: { string; remember: boolean; };
+ cookies: any;
+
+ /**
+ * Used to generate an anti-CSRF token.
+ * Placed by the CSRF protection middleware.
+ */
+ csrfToken(): string;
+
+ method: string;
+
+ params: any;
+
+ user: any;
+
+ authenticatedUser: any;
+
+ files: any;
+
+ /**
+ * Clear cookie `name`.
+ *
+ * @param name
+ * @param options
+ */
+ clearCookie(name: string, options?: any): Response;
+
+ query: any;
+
+ route: any;
+
+ signedCookies: any;
+
+ originalUrl: string;
+
+ url: string;
+ }
+
+ interface MediaType {
+ value: string;
+ quality: number;
+ type: string;
+ subtype: string;
+ }
+
+ interface Send {
+ (status: number, body?: any): Response;
+ (body: any): Response;
+ }
+
+ interface Response extends http.ServerResponse, Express.Response {
+ /**
+ * Set status `code`.
+ *
+ * @param code
+ */
+ status(code: number): Response;
+
+ /**
+ * Set Link header field with the given `links`.
+ *
+ * Examples:
+ *
+ * res.links({
+ * next: 'http://api.example.com/users?page=2',
+ * last: 'http://api.example.com/users?page=5'
+ * });
+ *
+ * @param links
+ */
+ links(links: any): Response;
+
+ /**
+ * Send a response.
+ *
+ * Examples:
+ *
+ * res.send(new Buffer('wahoo'));
+ * res.send({ some: 'json' });
+ * res.send('some html
');
+ * res.send(404, 'Sorry, cant find that');
+ * res.send(404);
+ */
+ send: Send;
+
+ /**
+ * Send JSON response.
+ *
+ * Examples:
+ *
+ * res.json(null);
+ * res.json({ user: 'tj' });
+ * res.json(500, 'oh noes!');
+ * res.json(404, 'I dont have that');
+ */
+ json: Send;
+
+ /**
+ * Send JSON response with JSONP callback support.
+ *
+ * Examples:
+ *
+ * res.jsonp(null);
+ * res.jsonp({ user: 'tj' });
+ * res.jsonp(500, 'oh noes!');
+ * res.jsonp(404, 'I dont have that');
+ */
+ jsonp: Send;
+
+ /**
+ * Transfer the file at the given `path`.
+ *
+ * Automatically sets the _Content-Type_ response header field.
+ * The callback `fn(err)` is invoked when the transfer is complete
+ * or when an error occurs. Be sure to check `res.sentHeader`
+ * if you wish to attempt responding, as the header and some data
+ * may have already been transferred.
+ *
+ * Options:
+ *
+ * - `maxAge` defaulting to 0
+ * - `root` root directory for relative filenames
+ *
+ * Examples:
+ *
+ * The following example illustrates how `res.sendfile()` may
+ * be used as an alternative for the `static()` middleware for
+ * dynamic situations. The code backing `res.sendfile()` is actually
+ * the same code, so HTTP cache support etc is identical.
+ *
+ * app.get('/user/:uid/photos/:file', function(req, res){
+ * var uid = req.params.uid
+ * , file = req.params.file;
+ *
+ * req.user.mayViewFilesFrom(uid, function(yes){
+ * if (yes) {
+ * res.sendfile('/uploads/' + uid + '/' + file);
+ * } else {
+ * res.send(403, 'Sorry! you cant see that.');
+ * }
+ * });
+ * });
+ */
+ sendfile(path: string): void;
+
+ sendfile(path: string, options: any): void;
+
+ sendfile(path: string, fn: Errback): void;
+
+ sendfile(path: string, options: any, fn: Errback): void;
+
+ /**
+ * Transfer the file at the given `path` as an attachment.
+ *
+ * Optionally providing an alternate attachment `filename`,
+ * and optional callback `fn(err)`. The callback is invoked
+ * when the data transfer is complete, or when an error has
+ * ocurred. Be sure to check `res.headerSent` if you plan to respond.
+ *
+ * This method uses `res.sendfile()`.
+ */
+ download(path: string): void;
+
+ download(path: string, filename: string): void;
+
+ download(path: string, fn: Errback): void;
+
+ download(path: string, filename: string, fn: Errback): void;
+
+ /**
+ * Set _Content-Type_ response header with `type` through `mime.lookup()`
+ * when it does not contain "/", or set the Content-Type to `type` otherwise.
+ *
+ * Examples:
+ *
+ * res.type('.html');
+ * res.type('html');
+ * res.type('json');
+ * res.type('application/json');
+ * res.type('png');
+ *
+ * @param type
+ */
+ contentType(type: string): Response;
+
+ /**
+ * Set _Content-Type_ response header with `type` through `mime.lookup()`
+ * when it does not contain "/", or set the Content-Type to `type` otherwise.
+ *
+ * Examples:
+ *
+ * res.type('.html');
+ * res.type('html');
+ * res.type('json');
+ * res.type('application/json');
+ * res.type('png');
+ *
+ * @param type
+ */
+ type(type: string): Response;
+
+ /**
+ * Respond to the Acceptable formats using an `obj`
+ * of mime-type callbacks.
+ *
+ * This method uses `req.accepted`, an array of
+ * acceptable types ordered by their quality values.
+ * When "Accept" is not present the _first_ callback
+ * is invoked, otherwise the first match is used. When
+ * no match is performed the server responds with
+ * 406 "Not Acceptable".
+ *
+ * Content-Type is set for you, however if you choose
+ * you may alter this within the callback using `res.type()`
+ * or `res.set('Content-Type', ...)`.
+ *
+ * res.format({
+ * 'text/plain': function(){
+ * res.send('hey');
+ * },
+ *
+ * 'text/html': function(){
+ * res.send('hey
');
+ * },
+ *
+ * 'appliation/json': function(){
+ * res.send({ message: 'hey' });
+ * }
+ * });
+ *
+ * In addition to canonicalized MIME types you may
+ * also use extnames mapped to these types:
+ *
+ * res.format({
+ * text: function(){
+ * res.send('hey');
+ * },
+ *
+ * html: function(){
+ * res.send('hey
');
+ * },
+ *
+ * json: function(){
+ * res.send({ message: 'hey' });
+ * }
+ * });
+ *
+ * By default Express passes an `Error`
+ * with a `.status` of 406 to `next(err)`
+ * if a match is not made. If you provide
+ * a `.default` callback it will be invoked
+ * instead.
+ *
+ * @param obj
+ */
+ format(obj: any): Response;
+
+ /**
+ * Set _Content-Disposition_ header to _attachment_ with optional `filename`.
+ *
+ * @param filename
+ */
+ attachment(filename?: string): Response;
+
+ /**
+ * Set header `field` to `val`, or pass
+ * an object of header fields.
+ *
+ * Examples:
+ *
+ * res.set('Foo', ['bar', 'baz']);
+ * res.set('Accept', 'application/json');
+ * res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
+ *
+ * Aliased as `res.header()`.
+ */
+ set (field: any): Response;
+
+ set (field: string, value?: string): Response;
+
+ header(field: any): Response;
+
+ header(field: string, value?: string): Response;
+
+ /**
+ * Get value for header `field`.
+ *
+ * @param field
+ */
+ get (field: string): string;
+
+ /**
+ * Clear cookie `name`.
+ *
+ * @param name
+ * @param options
+ */
+ clearCookie(name: string, options?: any): Response;
+
+ /**
+ * Set cookie `name` to `val`, with the given `options`.
+ *
+ * Options:
+ *
+ * - `maxAge` max-age in milliseconds, converted to `expires`
+ * - `signed` sign the cookie
+ * - `path` defaults to "/"
+ *
+ * Examples:
+ *
+ * // "Remember Me" for 15 minutes
+ * res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
+ *
+ * // save as above
+ * res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
+ */
+ cookie(name: string, val: string, options: CookieOptions): Response;
+
+ cookie(name: string, val: any, options: CookieOptions): Response;
+
+ cookie(name: string, val: any): Response;
+
+ /**
+ * Set the location header to `url`.
+ *
+ * The given `url` can also be the name of a mapped url, for
+ * example by default express supports "back" which redirects
+ * to the _Referrer_ or _Referer_ headers or "/".
+ *
+ * Examples:
+ *
+ * res.location('/foo/bar').;
+ * res.location('http://example.com');
+ * res.location('../login'); // /blog/post/1 -> /blog/login
+ *
+ * Mounting:
+ *
+ * When an application is mounted and `res.location()`
+ * is given a path that does _not_ lead with "/" it becomes
+ * relative to the mount-point. For example if the application
+ * is mounted at "/blog", the following would become "/blog/login".
+ *
+ * res.location('login');
+ *
+ * While the leading slash would result in a location of "/login":
+ *
+ * res.location('/login');
+ *
+ * @param url
+ */
+ location(url: string): Response;
+
+ /**
+ * Redirect to the given `url` with optional response `status`
+ * defaulting to 302.
+ *
+ * The resulting `url` is determined by `res.location()`, so
+ * it will play nicely with mounted apps, relative paths,
+ * `"back"` etc.
+ *
+ * Examples:
+ *
+ * res.redirect('/foo/bar');
+ * res.redirect('http://example.com');
+ * res.redirect(301, 'http://example.com');
+ * res.redirect('http://example.com', 301);
+ * res.redirect('../login'); // /blog/post/1 -> /blog/login
+ */
+ redirect(url: string): void;
+
+ redirect(status: number, url: string): void;
+
+ redirect(url: string, status: number): void;
+
+ /**
+ * Render `view` with the given `options` and optional callback `fn`.
+ * When a callback function is given a response will _not_ be made
+ * automatically, otherwise a response of _200_ and _text/html_ is given.
+ *
+ * Options:
+ *
+ * - `cache` boolean hinting to the engine it should cache
+ * - `filename` filename of the view being rendered
+ */
+
+ render(view: string, options?: Object, callback?: (err: Error, html: string) => void ): void;
+
+ render(view: string, callback?: (err: Error, html: string) => void ): void;
+
+ locals: any;
+
+ charset: string;
+ }
+
+ interface RequestFunction {
+ (req: Request, res: Response, next: Function): any;
+ }
+
+ interface Application extends IRouter, Express.Application {
+ /**
+ * Initialize the server.
+ *
+ * - setup default configuration
+ * - setup default middleware
+ * - setup route reflection methods
+ */
+ init(): void;
+
+ /**
+ * Initialize application configuration.
+ */
+ defaultConfiguration(): void;
+
+ /**
+ * Proxy `connect#use()` to apply settings to
+ * mounted applications.
+ **/
+ use(route: string, callback?: Function): Application;
+
+ use(route: string, server: Application): Application;
+
+ use(callback: Function): Application;
+
+ use(server: Application): Application;
+
+ /**
+ * Register the given template engine callback `fn`
+ * as `ext`.
+ *
+ * By default will `require()` the engine based on the
+ * file extension. For example if you try to render
+ * a "foo.jade" file Express will invoke the following internally:
+ *
+ * app.engine('jade', require('jade').__express);
+ *
+ * For engines that do not provide `.__express` out of the box,
+ * or if you wish to "map" a different extension to the template engine
+ * you may use this method. For example mapping the EJS template engine to
+ * ".html" files:
+ *
+ * app.engine('html', require('ejs').renderFile);
+ *
+ * In this case EJS provides a `.renderFile()` method with
+ * the same signature that Express expects: `(path, options, callback)`,
+ * though note that it aliases this method as `ejs.__express` internally
+ * so if you're using ".ejs" extensions you dont need to do anything.
+ *
+ * Some template engines do not follow this convention, the
+ * [Consolidate.js](https://github.com/visionmedia/consolidate.js)
+ * library was created to map all of node's popular template
+ * engines to follow this convention, thus allowing them to
+ * work seamlessly within Express.
+ */
+ engine(ext: string, fn: Function): Application;
+
+ param(name: string, fn: Function): Application;
+
+ param(name: string[], fn: Function): Application;
+
+ /**
+ * Assign `setting` to `val`, or return `setting`'s value.
+ *
+ * app.set('foo', 'bar');
+ * app.get('foo');
+ * // => "bar"
+ *
+ * Mounted servers inherit their parent server's settings.
+ *
+ * @param setting
+ * @param val
+ */
+ set (setting: string, val: string): Application;
+
+ get(name: string): string;
+
+ get(name: string, ...handlers: RequestFunction[]): Application;
+
+ get(name: RegExp, ...handlers: RequestFunction[]): Application;
+
+ /**
+ * Return the app's absolute pathname
+ * based on the parent(s) that have
+ * mounted it.
+ *
+ * For example if the application was
+ * mounted as "/admin", which itself
+ * was mounted as "/blog" then the
+ * return value would be "/blog/admin".
+ */
+ path(): string;
+
+ /**
+ * Check if `setting` is enabled (truthy).
+ *
+ * app.enabled('foo')
+ * // => false
+ *
+ * app.enable('foo')
+ * app.enabled('foo')
+ * // => true
+ */
+ enabled(setting: string): boolean;
+
+ /**
+ * Check if `setting` is disabled.
+ *
+ * app.disabled('foo')
+ * // => true
+ *
+ * app.enable('foo')
+ * app.disabled('foo')
+ * // => false
+ *
+ * @param setting
+ */
+ disabled(setting: string): boolean;
+
+ /**
+ * Enable `setting`.
+ *
+ * @param setting
+ */
+ enable(setting: string): Application;
+
+ /**
+ * Disable `setting`.
+ *
+ * @param setting
+ */
+ disable(setting: string): Application;
+
+ /**
+ * Configure callback for zero or more envs,
+ * when no `env` is specified that callback will
+ * be invoked for all environments. Any combination
+ * can be used multiple times, in any order desired.
+ *
+ * Examples:
+ *
+ * app.configure(function(){
+ * // executed for all envs
+ * });
+ *
+ * app.configure('stage', function(){
+ * // executed staging env
+ * });
+ *
+ * app.configure('stage', 'production', function(){
+ * // executed for stage and production
+ * });
+ *
+ * Note:
+ *
+ * These callbacks are invoked immediately, and
+ * are effectively sugar for the following:
+ *
+ * var env = process.env.NODE_ENV || 'development';
+ *
+ * switch (env) {
+ * case 'development':
+ * ...
+ * break;
+ * case 'stage':
+ * ...
+ * break;
+ * case 'production':
+ * ...
+ * break;
+ * }
+ *
+ * @param env
+ * @param fn
+ */
+ configure(env: string, fn: Function): Application;
+
+ configure(env0: string, env1: string, fn: Function): Application;
+
+ configure(env0: string, env1: string, env2: string, fn: Function): Application;
+
+ configure(env0: string, env1: string, env2: string, env3: string, fn: Function): Application;
+
+ configure(env0: string, env1: string, env2: string, env3: string, env4: string, fn: Function): Application;
+
+ configure(fn: Function): Application;
+
+
+ /**
+ * Render the given view `name` name with `options`
+ * and a callback accepting an error and the
+ * rendered template string.
+ *
+ * Example:
+ *
+ * app.render('email', { name: 'Tobi' }, function(err, html){
+ * // ...
+ * })
+ *
+ * @param name
+ * @param options or fn
+ * @param fn
+ */
+ render(name: string, options?: Object, callback?: (err: Error, html: string) => void): void;
+
+ render(name: string, callback: (err: Error, html: string) => void): void;
+
+
+ /**
+ * Listen for connections.
+ *
+ * A node `http.Server` is returned, with this
+ * application (which is a `Function`) as its
+ * callback. If you wish to create both an HTTP
+ * and HTTPS server you may do so with the "http"
+ * and "https" modules as shown here:
+ *
+ * var http = require('http')
+ * , https = require('https')
+ * , express = require('express')
+ * , app = express();
+ *
+ * http.createServer(app).listen(80);
+ * https.createServer({ ... }, app).listen(443);
+ */
+ listen(port: number, hostname: string, backlog: number, callback?: Function): http.Server;
+
+ listen(port: number, hostname: string, callback?: Function): http.Server;
+
+ listen(port: number, callback?: Function): http.Server;
+
+ listen(path: string, callback?: Function): http.Server;
+
+ listen(handle: any, listeningListener?: Function): http.Server;
+
+ route: IRoute;
+
+ router: string;
+
+ settings: any;
+
+ resource: any;
+
+ map: any;
+
+ locals: any;
+
+ /**
+ * The app.routes object houses all of the routes defined mapped by the
+ * associated HTTP verb. This object may be used for introspection
+ * capabilities, for example Express uses this internally not only for
+ * routing but to provide default OPTIONS behaviour unless app.options()
+ * is used. Your application or framework may also remove routes by
+ * simply by removing them from this object.
+ */
+ routes: any;
+ }
+
+ interface Express extends Application {
+ /**
+ * Framework version.
+ */
+ version: string;
+
+ /**
+ * Expose mime.
+ */
+ mime: string;
+
+ (): Application;
+
+ /**
+ * Create an express application.
+ */
+ createApplication(): Application;
+
+ createServer(): Application;
+
+ application: any;
+
+ request: Request;
+
+ response: Response;
+ }
+
+ /**
+ * Body parser:
+ *
+ * Parse request bodies, supports _application/json_,
+ * _application/x-www-form-urlencoded_, and _multipart/form-data_.
+ *
+ * This is equivalent to:
+ *
+ * app.use(connect.json());
+ * app.use(connect.urlencoded());
+ * app.use(connect.multipart());
+ *
+ * Examples:
+ *
+ * connect()
+ * .use(connect.bodyParser())
+ * .use(function(req, res) {
+ * res.end('viewing user ' + req.body.user.name);
+ * });
+ *
+ * $ curl -d 'user[name]=tj' http://local/
+ * $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://local/
+ *
+ * View [json](json.html), [urlencoded](urlencoded.html), and [multipart](multipart.html) for more info.
+ *
+ * @param options
+ */
+ function bodyParser(options?: any): Handler;
+
+ /**
+ * Error handler:
+ *
+ * Development error handler, providing stack traces
+ * and error message responses for requests accepting text, html,
+ * or json.
+ *
+ * Text:
+ *
+ * By default, and when _text/plain_ is accepted a simple stack trace
+ * or error message will be returned.
+ *
+ * JSON:
+ *
+ * When _application/json_ is accepted, connect will respond with
+ * an object in the form of `{ "error": error }`.
+ *
+ * HTML:
+ *
+ * When accepted connect will output a nice html stack trace.
+ */
+ function errorHandler(opts?: any): Handler;
+
+ /**
+ * Method Override:
+ *
+ * Provides faux HTTP method support.
+ *
+ * Pass an optional `key` to use when checking for
+ * a method override, othewise defaults to _\_method_.
+ * The original method is available via `req.originalMethod`.
+ *
+ * @param key
+ */
+ function methodOverride(key?: string): Handler;
+
+ /**
+ * Cookie parser:
+ *
+ * Parse _Cookie_ header and populate `req.cookies`
+ * with an object keyed by the cookie names. Optionally
+ * you may enabled signed cookie support by passing
+ * a `secret` string, which assigns `req.secret` so
+ * it may be used by other middleware.
+ *
+ * Examples:
+ *
+ * connect()
+ * .use(connect.cookieParser('optional secret string'))
+ * .use(function(req, res, next){
+ * res.end(JSON.stringify(req.cookies));
+ * })
+ *
+ * @param secret
+ */
+ function cookieParser(secret?: string): Handler;
+
+ /**
+ * Session:
+ *
+ * Setup session store with the given `options`.
+ *
+ * Session data is _not_ saved in the cookie itself, however
+ * cookies are used, so we must use the [cookieParser()](cookieParser.html)
+ * middleware _before_ `session()`.
+ *
+ * Examples:
+ *
+ * connect()
+ * .use(connect.cookieParser())
+ * .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }}))
+ *
+ * Options:
+ *
+ * - `key` cookie name defaulting to `connect.sid`
+ * - `store` session store instance
+ * - `secret` session cookie is signed with this secret to prevent tampering
+ * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
+ * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
+ *
+ * Cookie option:
+ *
+ * By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set
+ * so the cookie becomes a browser-session cookie. When the user closes the
+ * browser the cookie (and session) will be removed.
+ *
+ * ## req.session
+ *
+ * To store or access session data, simply use the request property `req.session`,
+ * which is (generally) serialized as JSON by the store, so nested objects
+ * are typically fine. For example below is a user-specific view counter:
+ *
+ * connect()
+ * .use(connect.favicon())
+ * .use(connect.cookieParser())
+ * .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
+ * .use(function(req, res, next){
+ * var sess = req.session;
+ * if (sess.views) {
+ * res.setHeader('Content-Type', 'text/html');
+ * res.write('views: ' + sess.views + '
');
+ * res.write('expires in: ' + (sess.cookie.maxAge / 1000) + 's
');
+ * res.end();
+ * sess.views++;
+ * } else {
+ * sess.views = 1;
+ * res.end('welcome to the session demo. refresh!');
+ * }
+ * }
+ * )).listen(3000);
+ *
+ * ## Session#regenerate()
+ *
+ * To regenerate the session simply invoke the method, once complete
+ * a new SID and `Session` instance will be initialized at `req.session`.
+ *
+ * req.session.regenerate(function(err){
+ * // will have a new session here
+ * });
+ *
+ * ## Session#destroy()
+ *
+ * Destroys the session, removing `req.session`, will be re-generated next request.
+ *
+ * req.session.destroy(function(err){
+ * // cannot access session here
+ * });
+ *
+ * ## Session#reload()
+ *
+ * Reloads the session data.
+ *
+ * req.session.reload(function(err){
+ * // session updated
+ * });
+ *
+ * ## Session#save()
+ *
+ * Save the session.
+ *
+ * req.session.save(function(err){
+ * // session saved
+ * });
+ *
+ * ## Session#touch()
+ *
+ * Updates the `.maxAge` property. Typically this is
+ * not necessary to call, as the session middleware does this for you.
+ *
+ * ## Session#cookie
+ *
+ * Each session has a unique cookie object accompany it. This allows
+ * you to alter the session cookie per visitor. For example we can
+ * set `req.session.cookie.expires` to `false` to enable the cookie
+ * to remain for only the duration of the user-agent.
+ *
+ * ## Session#maxAge
+ *
+ * Alternatively `req.session.cookie.maxAge` will return the time
+ * remaining in milliseconds, which we may also re-assign a new value
+ * to adjust the `.expires` property appropriately. The following
+ * are essentially equivalent
+ *
+ * var hour = 3600000;
+ * req.session.cookie.expires = new Date(Date.now() + hour);
+ * req.session.cookie.maxAge = hour;
+ *
+ * For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+ * has elapsed it will return `30000` until the current request has completed,
+ * at which time `req.session.touch()` is called to reset `req.session.maxAge`
+ * to its original value.
+ *
+ * req.session.cookie.maxAge;
+ * // => 30000
+ *
+ * Session Store Implementation:
+ *
+ * Every session store _must_ implement the following methods
+ *
+ * - `.get(sid, callback)`
+ * - `.set(sid, session, callback)`
+ * - `.destroy(sid, callback)`
+ *
+ * Recommended methods include, but are not limited to:
+ *
+ * - `.length(callback)`
+ * - `.clear(callback)`
+ *
+ * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+ *
+ * @param options
+ */
+ function session(options?: any): Handler;
+
+ /**
+ * Hash the given `sess` object omitting changes
+ * to `.cookie`.
+ *
+ * @param sess
+ */
+ function hash(sess: string): string;
+
+ /**
+ * Static:
+ *
+ * Static file server with the given `root` path.
+ *
+ * Examples:
+ *
+ * var oneDay = 86400000;
+ *
+ * connect()
+ * .use(connect.static(__dirname + '/public'))
+ *
+ * connect()
+ * .use(connect.static(__dirname + '/public', { maxAge: oneDay }))
+ *
+ * Options:
+ *
+ * - `maxAge` Browser cache maxAge in milliseconds. defaults to 0
+ * - `hidden` Allow transfer of hidden files. defaults to false
+ * - `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to true
+ *
+ * @param root
+ * @param options
+ */
+ function static(root: string, options?: any): Handler;
+
+ /**
+ * Basic Auth:
+ *
+ * Enfore basic authentication by providing a `callback(user, pass)`,
+ * which must return `true` in order to gain access. Alternatively an async
+ * method is provided as well, invoking `callback(user, pass, callback)`. Populates
+ * `req.user`. The final alternative is simply passing username / password
+ * strings.
+ *
+ * Simple username and password
+ *
+ * connect(connect.basicAuth('username', 'password'));
+ *
+ * Callback verification
+ *
+ * connect()
+ * .use(connect.basicAuth(function(user, pass){
+ * return 'tj' == user & 'wahoo' == pass;
+ * }))
+ *
+ * Async callback verification, accepting `fn(err, user)`.
+ *
+ * connect()
+ * .use(connect.basicAuth(function(user, pass, fn){
+ * User.authenticate({ user: user, pass: pass }, fn);
+ * }))
+ *
+ * @param callback or username
+ * @param realm
+ */
+ export function basicAuth(callback: (user: string, pass: string, fn : Function) => void, realm?: string): Handler;
+
+ export function basicAuth(callback: (user: string, pass: string) => boolean, realm?: string): Handler;
+
+ export function basicAuth(user: string, pass: string, realm?: string): Handler;
+
+ /**
+ * Compress:
+ *
+ * Compress response data with gzip/deflate.
+ *
+ * Filter:
+ *
+ * A `filter` callback function may be passed to
+ * replace the default logic of:
+ *
+ * exports.filter = function(req, res){
+ * return /json|text|javascript/.test(res.getHeader('Content-Type'));
+ * };
+ *
+ * Options:
+ *
+ * All remaining options are passed to the gzip/deflate
+ * creation functions. Consult node's docs for additional details.
+ *
+ * - `chunkSize` (default: 16*1024)
+ * - `windowBits`
+ * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
+ * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
+ * - `strategy`: compression strategy
+ *
+ * @param options
+ */
+ function compress(options?: any): Handler;
+
+ /**
+ * Cookie Session:
+ *
+ * Cookie session middleware.
+ *
+ * var app = connect();
+ * app.use(connect.cookieParser());
+ * app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }}));
+ *
+ * Options:
+ *
+ * - `key` cookie name defaulting to `connect.sess`
+ * - `secret` prevents cookie tampering
+ * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
+ * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
+ *
+ * Clearing sessions:
+ *
+ * To clear the session simply set its value to `null`,
+ * `cookieSession()` will then respond with a 1970 Set-Cookie.
+ *
+ * req.session = null;
+ *
+ * @param options
+ */
+ function cookieSession(options?: any): Handler;
+
+ /**
+ * Anti CSRF:
+ *
+ * CSRF protection middleware.
+ *
+ * This middleware adds a `req.csrfToken()` function to make a token
+ * which should be added to requests which mutate
+ * state, within a hidden form field, query-string etc. This
+ * token is validated against the visitor's session.
+ *
+ * The default `value` function checks `req.body` generated
+ * by the `bodyParser()` middleware, `req.query` generated
+ * by `query()`, and the "X-CSRF-Token" header field.
+ *
+ * This middleware requires session support, thus should be added
+ * somewhere _below_ `session()` and `cookieParser()`.
+ *
+ * Options:
+ *
+ * - `value` a function accepting the request, returning the token
+ *
+ * @param options
+ */
+ export function csrf(options?: {value?: Function}): Handler;
+
+ /**
+ * Directory:
+ *
+ * Serve directory listings with the given `root` path.
+ *
+ * Options:
+ *
+ * - `hidden` display hidden (dot) files. Defaults to false.
+ * - `icons` display icons. Defaults to false.
+ * - `filter` Apply this filter function to files. Defaults to false.
+ *
+ * @param root
+ * @param options
+ */
+ function directory(root: string, options?: any): Handler;
+
+ /**
+ * Favicon:
+ *
+ * By default serves the connect favicon, or the favicon
+ * located by the given `path`.
+ *
+ * Options:
+ *
+ * - `maxAge` cache-control max-age directive, defaulting to 1 day
+ *
+ * Examples:
+ *
+ * Serve default favicon:
+ *
+ * connect()
+ * .use(connect.favicon())
+ *
+ * Serve favicon before logging for brevity:
+ *
+ * connect()
+ * .use(connect.favicon())
+ * .use(connect.logger('dev'))
+ *
+ * Serve custom favicon:
+ *
+ * connect()
+ * .use(connect.favicon('public/favicon.ico))
+ *
+ * @param path
+ * @param options
+ */
+ export function favicon(path?: string, options?: any): Handler;
+
+ /**
+ * JSON:
+ *
+ * Parse JSON request bodies, providing the
+ * parsed object as `req.body`.
+ *
+ * Options:
+ *
+ * - `strict` when `false` anything `JSON.parse()` accepts will be parsed
+ * - `reviver` used as the second "reviver" argument for JSON.parse
+ * - `limit` byte limit disabled by default
+ *
+ * @param options
+ */
+ function json(options?: any): Handler;
+
+ /**
+ * Limit:
+ *
+ * Limit request bodies to the given size in `bytes`.
+ *
+ * A string representation of the bytesize may also be passed,
+ * for example "5mb", "200kb", "1gb", etc.
+ *
+ * connect()
+ * .use(connect.limit('5.5mb'))
+ * .use(handleImageUpload)
+ */
+ function limit(bytes: number): Handler;
+
+ function limit(bytes: string): Handler;
+
+ /**
+ * Logger:
+ *
+ * Log requests with the given `options` or a `format` string.
+ *
+ * Options:
+ *
+ * - `format` Format string, see below for tokens
+ * - `stream` Output stream, defaults to _stdout_
+ * - `buffer` Buffer duration, defaults to 1000ms when _true_
+ * - `immediate` Write log line on request instead of response (for response times)
+ *
+ * Tokens:
+ *
+ * - `:req[header]` ex: `:req[Accept]`
+ * - `:res[header]` ex: `:res[Content-Length]`
+ * - `:http-version`
+ * - `:response-time`
+ * - `:remote-addr`
+ * - `:date`
+ * - `:method`
+ * - `:url`
+ * - `:referrer`
+ * - `:user-agent`
+ * - `:status`
+ *
+ * Formats:
+ *
+ * Pre-defined formats that ship with connect:
+ *
+ * - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
+ * - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
+ * - `tiny` ':method :url :status :res[content-length] - :response-time ms'
+ * - `dev` concise output colored by response status for development use
+ *
+ * Examples:
+ *
+ * connect.logger() // default
+ * connect.logger('short')
+ * connect.logger('tiny')
+ * connect.logger({ immediate: true, format: 'dev' })
+ * connect.logger(':method :url - :referrer')
+ * connect.logger(':req[content-type] -> :res[content-type]')
+ * connect.logger(function(tokens, req, res){ return 'some format string' })
+ *
+ * Defining Tokens:
+ *
+ * To define a token, simply invoke `connect.logger.token()` with the
+ * name and a callback function. The value returned is then available
+ * as ":type" in this case.
+ *
+ * connect.logger.token('type', function(req, res){ return req.headers['content-type']; })
+ *
+ * Defining Formats:
+ *
+ * All default formats are defined this way, however it's public API as well:
+ *
+ * connect.logger.format('name', 'string or function')
+ */
+ function logger(options: string): Handler;
+
+ function logger(options: Function): Handler;
+
+ function logger(options?: any): Handler;
+
+ /**
+ * Compile `fmt` into a function.
+ *
+ * @param fmt
+ */
+ function compile(fmt: string): Handler;
+
+ /**
+ * Define a token function with the given `name`,
+ * and callback `fn(req, res)`.
+ *
+ * @param name
+ * @param fn
+ */
+ function token(name: string, fn: Function): any;
+
+ /**
+ * Define a `fmt` with the given `name`.
+ */
+ function format(name: string, str: string): any;
+
+ function format(name: string, str: Function): any;
+
+ /**
+ * Query:
+ *
+ * Automatically parse the query-string when available,
+ * populating the `req.query` object.
+ *
+ * Examples:
+ *
+ * connect()
+ * .use(connect.query())
+ * .use(function(req, res){
+ * res.end(JSON.stringify(req.query));
+ * });
+ *
+ * The `options` passed are provided to qs.parse function.
+ */
+ function query(options: any): Handler;
+
+ /**
+ * Reponse time:
+ *
+ * Adds the `X-Response-Time` header displaying the response
+ * duration in milliseconds.
+ */
+ function responseTime(): Handler;
+
+ /**
+ * Static cache:
+ *
+ * Enables a memory cache layer on top of
+ * the `static()` middleware, serving popular
+ * static files.
+ *
+ * By default a maximum of 128 objects are
+ * held in cache, with a max of 256k each,
+ * totalling ~32mb.
+ *
+ * A Least-Recently-Used (LRU) cache algo
+ * is implemented through the `Cache` object,
+ * simply rotating cache objects as they are
+ * hit. This means that increasingly popular
+ * objects maintain their positions while
+ * others get shoved out of the stack and
+ * garbage collected.
+ *
+ * Benchmarks:
+ *
+ * static(): 2700 rps
+ * node-static: 5300 rps
+ * static() + staticCache(): 7500 rps
+ *
+ * Options:
+ *
+ * - `maxObjects` max cache objects [128]
+ * - `maxLength` max cache object length 256kb
+ */
+ function staticCache(options: any): Handler;
+
+ /**
+ * Timeout:
+ *
+ * Times out the request in `ms`, defaulting to `5000`. The
+ * method `req.clearTimeout()` is added to revert this behaviour
+ * programmatically within your application's middleware, routes, etc.
+ *
+ * The timeout error is passed to `next()` so that you may customize
+ * the response behaviour. This error has the `.timeout` property as
+ * well as `.status == 408`.
+ */
+ function timeout(ms: number): Handler;
+
+ /**
+ * Vhost:
+ *
+ * Setup vhost for the given `hostname` and `server`.
+ *
+ * connect()
+ * .use(connect.vhost('foo.com', fooApp))
+ * .use(connect.vhost('bar.com', barApp))
+ * .use(connect.vhost('*.com', mainApp))
+ *
+ * The `server` may be a Connect server or
+ * a regular Node `http.Server`.
+ *
+ * @param hostname
+ * @param server
+ */
+ function vhost(hostname: string, server: any): Handler;
+
+ function urlencoded(): any;
+
+ function multipart(): any;
+
+ }
+
+ export = e;
+}
+
diff --git a/express/express-tests.ts b/express/express-tests.ts
index 57d1d638c0..cda1e3e2e6 100644
--- a/express/express-tests.ts
+++ b/express/express-tests.ts
@@ -3,1496 +3,19 @@
import express = require('express');
var app = express();
-//////////////////////////
+app.engine('jade', require('jade').__express);
+app.engine('html', require('ejs').renderFile);
-var hash: any;
-
-// config
-
-app.set('view engine', 'ejs');
-app.set('views', __dirname + '/views');
-
-// middleware
-
-app.use(express.bodyParser());
-app.use(express.cookieParser('shhhh, very secret'));
-app.use(express.session());
-
-// Session-persisted message middleware
-
-app.use((req: express.Request, res: express.Response, next) => {
- var err = req.session.error
- , msg = req.session.success;
- delete req.session.error;
- delete req.session.success;
- res.locals.message = '';
- if (err) res.locals.message = '' + err + '
';
- if (msg) res.locals.message = '' + msg + '
';
- next();
-});
-
-// dummy database
-
-var users = {
- tj: { name: 'tj' }
-};
-
-// when you create a user, generate a salt
-// and hash the password ('foobar' is the pass here)
-
-hash('foobar', (err, salt, hash) => {
- if (err) throw err;
- // store the salt & hash in the "db"
- users.tj.salt = salt;
- users.tj.hash = hash;
-});
-
-
-// Authenticate using our plain-object database of doom!
-
-function authenticate(name, pass, fn) {
- if (!module.parent) console.log('authenticating %s:%s', name, pass);
- var user = users[name];
- // query the db for the given username
- if (!user) return fn(new Error('cannot find user'));
- // apply the same algorithm to the POSTed password, applying
- // the hash against the pass / salt, if there is a match we
- // found the user
- hash(pass, user.salt, (err, hash) => {
- if (err) return fn(err);
- if (hash == user.hash) return fn(null, user);
- fn(new Error('invalid password'));
- });
-}
-
-function restrict(req: express.Request, res: express.Response, next?: Function) {
- if (req.session.user) {
- next();
- } else {
- req.session.error = 'Access denied!';
- res.redirect('/login');
- }
-}
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.redirect('login');
-});
-
-app.get('/restricted', restrict, (req: express.Request, res: express.Response) => {
- res.send('Wahoo! restricted area, click to logout');
-});
-
-app.get('/logout', (req: express.Request, res: express.Response) => {
- // destroy the user's session to log them out
- // will be re-created next request
- req.session.destroy(() => {
- res.redirect('/');
- });
-});
-
-app.get('/login', (req: express.Request, res: express.Response) => {
- res.render('login');
-});
-
-app.post('/login', (req: express.Request, res: express.Response) => {
- authenticate(req.body.username, req.body.password, (err, user) => {
- if (user) {
- // Regenerate session when signing in
- // to prevent fixation
- req.session.regenerate(() => {
- // Store the user's primary key
- // in the session store to be retrieved,
- // or in this case the entire user object
- req.session.user = user;
- req.session.success = 'Authenticated as ' + user.name
- + ' click to logout. '
- + ' You may now access /restricted.';
- res.redirect('back');
- });
- } else {
- req.session.error = 'Authentication failed, please check your '
- + ' username and password.'
- + ' (use "tj" and "foobar")';
- res.redirect('login');
- }
- });
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-//////////////
-
-app.set('views', __dirname);
-app.set('view engine', 'jade');
-
-var pets = [];
-
-var n = 1000;
-while (n--) {
- pets.push({ name: 'Tobi', age: 2, species: 'ferret' });
- pets.push({ name: 'Loki', age: 1, species: 'ferret' });
- pets.push({ name: 'Jane', age: 6, species: 'ferret' });
-}
-
-app.use(express.logger('dev'));
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.render('pets', { pets: pets });
-});
-
-app.listen(3000);
-console.log('Express listening on port 3000');
-
-/////////////
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.format({
- html: () => {
- res.send('' + users.map(user => {
- return '- ' + user.name + '
';
- }).join('') + '
');
- },
-
- text: () => {
- res.send(users.map(user => {
- return ' - ' + user.name + '\n';
- }).join(''));
- },
-
- json: () => {
- res.json(users);
- }
- });
-});
-
-// or you could write a tiny middleware like
-// this to abstract make things a bit more declarative:
-
-function format(mod) {
- var obj = require(mod);
- return (req: express.Request, res: express.Response) => {
- res.format(obj);
- };
-}
-
-app.get('/users', format('./users'));
-
-if (!module.parent) {
- app.listen(3000);
- console.log('listening on port 3000');
-}
-
-/////////////////////////
-
-// add favicon() before logger() so
-// GET /favicon.ico requests are not
-// logged, because this middleware
-// reponds to /favicon.ico and does not
-// call next()
-app.use(express.favicon());
-
-// custom log format
-if ('test' != process.env.NODE_ENV)
- app.use(express.logger(':method :url'));
-
-// parses request cookies, populating
-// req.cookies and req.signedCookies
-// when the secret is passed, used
-// for signing the cookies.
-app.use(express.cookieParser('my secret here'));
-
-// parses json, x-www-form-urlencoded, and multipart/form-data
-app.use(express.bodyParser());
-
-app.get('/', (req: express.Request, res: express.Response) => {
- if (req.cookies.remember) {
- res.send('Remembered :). Click to forget!.');
- } else {
- res.send('');
- }
-});
-
-app.get('/forget', (req: express.Request, res: express.Response) => {
- res.clearCookie('remember');
- res.redirect('back');
-});
-
-app.post('/', (req: express.Request, res: express.Response) => {
- var minute = 60000;
- if (req.body.remember) res.cookie('remember', 1, { maxAge: minute });
- res.redirect('back');
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-///////////////////
-
-// ignore GET /favicon.ico
-app.use(express.favicon());
-
-// pass a secret to cookieParser() for signed cookies
-app.use(express.cookieParser('manny is cool'));
-
-// add req.session cookie support
-app.use(express.cookieSession());
-
-// do something with the session
-app.use(count);
-
-// custom middleware
-function count(req: express.Request, res: express.Response) {
- req.session.count = req.session.count || 0;
- var n = req.session.count++;
- res.send('viewed ' + n + ' times\n');
-}
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express server listening on port 3000');
-}
-
-///////////////
-
-var api = app;
-
-app.use(express.static(__dirname + '/public'));
-
-// api middleware
-
-api.use(express.logger('dev'));
-api.use(express.bodyParser());
-
-/**
- * CORS support.
- */
-
-api.all('*', (req: express.Request, res: express.Response, next) => {
- if (!req.get('Origin')) return next();
- // use "*" here to accept any origin
- res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
- res.set('Access-Control-Allow-Methods', 'GET, POST');
- res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
- // res.set('Access-Control-Allow-Max-Age', 3600);
- if ('OPTIONS' == req.method) return res.send(200);
- next();
-});
-
-/**
- * POST a user.
- */
-
-api.post('/user', (req: express.Request, res: express.Response) => {
- console.log(req.body);
- res.send(201);
-});
-
-app.listen(3000);
-api.listen(3001);
-
-console.log('app listening on 3000');
-console.log('api listening on 3001');
-
-////////////////////
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.send('');
-});
-
-// /files/* is accessed via req.params[0]
-// but here we name it :file
-app.get('/files/:file(*)', (req: express.Request, res: express.Response) => {
- var file = req.params.file
- , path = __dirname + '/files/' + file;
-
- res.download(path);
-});
-
-// error handling middleware. Because it's
-// below our routes, you will be able to
-// "intercept" errors, otherwise Connect
-// will respond with 500 "Internal Server Error".
-app.use((err, req, res: express.Response, next) => {
- // special-case 404s,
- // remember you could
- // render a 404 template here
- if (404 == err.status) {
- res.statusCode = 404;
- res.send('Cant find that file, sorry!');
- } else {
- next(err);
- }
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-///////////////////
-
-// Register ejs as .html. If we did
-// not call this, we would need to
-// name our views foo.ejs instead
-// of foo.html. The __express method
-// is simply a function that engines
-// use to hook into the Express view
-// system by default, so if we want
-// to change "foo.ejs" to "foo.html"
-// we simply pass _any_ function, in this
-// case `ejs.__express`.
-
-app.engine('.html', require('ejs').__express);
-
-// Optional since express defaults to CWD/views
-
-app.set('views', __dirname + '/views');
-
-// Without this you would need to
-// supply the extension to res.render()
-// ex: res.render('users.html').
-app.set('view engine', 'html');
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.render('users', {
- users: users,
- title: "EJS example",
- header: "Some users"
- });
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express app started on port 3000');
-}
-
-////////////////////
-
-var test: any;
-
-if (!test) app.use(express.logger('dev'));
-app.use(app.router);
-
-// the error handler is strategically
-// placed *below* the app.router; if it
-// were above it would not receive errors
-// from app.get() etc
-app.use(error);
-
-// error handling middleware have an arity of 4
-// instead of the typical (req: express.Request, res: express.Response, next),
-// otherwise they behave exactly like regular
-// middleware, you may have several of them,
-// in different orders etc.
-
-function error(err, req, res: express.Response, next) {
- // log it
- if (!test) console.error(err.stack);
-
- // respond with 500 "Internal Server Error".
- res.send(500);
-}
-
-app.get('/', () => {
- // Caught and passed down to the errorHandler middleware
- throw new Error('something broke!');
-});
-
-app.get('/next', (req: express.Request, res: express.Response, next) => {
- // We can also pass exceptions to next()
- process.nextTick(() => {
- next(new Error('oh no!'));
- });
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-/////////////////////
-
-var silent: any;
-
-// general config
-app.set('views', __dirname + '/views');
-app.set('view engine', 'jade');
-
-// our custom "verbose errors" setting
-// which we can use in the templates
-// via settings['verbose errors']
-app.enable('verbose errors');
-
-// disable them in production
-// use $ NODE_ENV=production node examples/error-pages
-if ('production' == app.settings.env) {
- app.disable('verbose errors');
-}
-
-app.use(express.favicon());
-
-silent || app.use(express.logger('dev'));
-
-// "app.router" positions our routes
-// above the middleware defined below,
-// this means that Express will attempt
-// to match & call routes _before_ continuing
-// on, at which point we assume it's a 404 because
-// no route has handled the request.
-
-app.use(app.router);
-
-// Since this is the last non-error-handling
-// middleware use()d, we assume 404, as nothing else
-// responded.
-
-// $ curl http://localhost:3000/notfound
-// $ curl http://localhost:3000/notfound -H "Accept: application/json"
-// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
-
-app.use((req: express.Request, res: express.Response) => {
- res.status(404);
-
- // respond with html page
- if (req.accepts('html')) {
- res.render('404', { url: req.url });
- return;
- }
-
- // respond with json
- if (req.accepts('json')) {
- res.send({ error: 'Not found' });
- return;
- }
-
- // default to plain-text. send()
- res.type('txt').send('Not found');
-});
-
-// error-handling middleware, take the same form
-// as regular middleware, however they require an
-// arity of 4, aka the signature (err, req, res: express.Response, next).
-// when connect has an error, it will invoke ONLY error-handling
-// middleware.
-
-// If we were to next() here any remaining non-error-handling
-// middleware would then be executed, or if we next(err) to
-// continue passing the error, only error-handling middleware
-// would remain being executed, however here
-// we simply respond with an error page.
-
-app.use((err, req, res: express.Response) => {
- // we may use properties of the error object
- // here and next(err) appropriately, or if
- // we possibly recovered from the error, simply next().
- res.status(err.status || 500);
- res.render('500', { error: err });
-});
-
-// Routes
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.render('index.jade');
-});
-
-app.get('/404', (req: express.Request, res: express.Response, next) => {
- // trigger a 404 since no other middleware
- // will match /404 after this one, and we're not
- // responding here
- next();
-});
-
-app.get('/403', (req: express.Request, res: express.Response, next) => {
- // trigger a 403 error
- var err = new Error('not allowed!');
- err.status = 403;
- next(err);
-});
-
-app.get('/500', (req: express.Request, res: express.Response, next) => {
- // trigger a generic (500) error
- next(new Error('keyboard cat!'));
-});
-
-if (!module.parent) {
- app.listen(3000);
- //silent || console.log('Express started on port 3000');
-}
-
-///////////////
-
-var fs: any;
-var md: any;
-
-app.set('view engine', 'jade');
-app.set('views', __dirname + '/views');
-
-function User(name) {
- this.private = 'heyyyy';
- this.secret = 'something';
- this.name = name;
- this.id = 123;
-}
-
-// You'll probably want to do
-// something like this so you
-// dont expose "secret" data.
-
-User.prototype.toJSON = function () {
- return {
- id: this.id,
- name: this.name
- };
-};
-
-app.use(express.logger('dev'));
-
-// earlier on expose an object
-// that we can tack properties on.
-// all res.locals props are exposed
-// to the templates, so "expose" will
-// be present.
-
-app.use((req: express.Request, res: express.Response, next) => {
- res.locals.expose = {};
- // you could alias this as req or res.expose
- // to make it shorter and less annoying
- next();
-});
-
-// pretend we loaded a user
-
-app.use((req: express.Request, res: express.Response, next) => {
- req.user = new User('Tobi');
- next();
-});
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.redirect('/user');
-});
-
-app.get('/user', (req: express.Request, res: express.Response) => {
- // we only want to expose the user
- // to the client for this route:
- res.locals.expose.user = req.user;
- res.render('page');
-});
-
-app.listen(3000);
-console.log('app listening on port 3000');
-
-///////////////////////
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.send('Hello World');
-});
-
-app.listen(3000);
-console.log('Express started on port 3000');
-
-////////////////////
-
-// register .md as an engine in express view system
-
-app.engine('md', (path, options, fn) => {
- fs.readFile(path, 'utf8', (err, str) => {
- if (err) return fn(err);
- try {
- var html = md(str);
- html = html.replace(/\{([^}]+)\}/g, (_, name) => {
- return options[name] || '';
- });
- fn(null, html);
- } catch (err) {
- fn(err);
- }
- });
-});
-
-app.set('views', __dirname + '/views');
-
-// make it the default so we dont need .md
-app.set('view engine', 'md');
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.render('index', { title: 'Markdown Example' });
-});
-
-app.get('/fail', (req: express.Request, res: express.Response) => {
- res.render('missing', { title: 'Markdown Example' });
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-///////////////////////
-
-var mformat: any;
-
-// bodyParser in connect 2.x uses node-formidable to parse
-// the multipart form data.
-app.use(express.bodyParser());
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.send('');
-});
-
-app.post('/', (req: express.Request, res: express.Response) => {
- // the uploaded file can be found as `req.files.image` and the
- // title field as `req.body.title`
- res.send(mformat('\nuploaded %s (%d Kb) to %s as %s'
- , req.files.image.name
- , req.files.image.size / 1024 | 0
- , req.files.image.path
- , req.body.title));
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-//////////////////
-
-
-// first:
-// $ npm install redis online
-// $ redis-server
-
-/**
- * Module dependencies.
- */
-
-var online: any;
-var db: any;
-
-// online
-
-online = online(db);
-
-// activity tracking, in this case using
-// the UA string, you would use req.user.id etc
-
-app.use((req: express.Request, res: express.Response, next) => {
- // fire-and-forget
- online.add(req.headers['user-agent']);
- next();
-});
-
-/**
- * List helper.
- */
-
-function list(ids) {
- return '' + ids.map(id => {
- return '- ' + id + '
';
- }).join('') + '
';
-}
-
-/**
- * GET users online.
- */
-
-app.get('/', (req: express.Request, res: express.Response, next) => {
- online.last(5, (err, ids) => {
- if (err) return next(err);
- res.send('Users online: ' + ids.length + '
' + list(ids));
- });
-});
-
-app.listen(3000);
-console.log('listening on port 3000');
-
-///////////////////
-
-// Convert :to and :from to integers
-
-app.param(['to', 'from'], (req: express.Request, res: express.Response, next, num, name) => {
- req.params[name] = num = parseInt(num, 10);
- if (isNaN(num)) {
- next(new Error('failed to parseInt ' + num));
- } else {
- next();
- }
-});
-
-// Load user by id
-
-app.param('user', (req: express.Request, res: express.Response, next, id) => {
- if (req.user = users[id]) {
- next();
- } else {
- next(new Error('failed to find user'));
- }
-});
-
-/**
- * GET index.
- */
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.send('Visit /user/0 or /users/0-2');
-});
-
-/**
- * GET :user.
- */
-
-app.get('/user/:user', (req: express.Request, res: express.Response) => {
- res.send('user ' + req.user.name);
-});
-
-/**
- * GET users :from - :to.
- */
-
-app.get('/users/:from-:to', (req: express.Request, res: express.Response) => {
- var from = req.params.from
- , to = req.params.to
- , names = users.map(user => { return user.name; });
- res.send('users ' + names.slice(from, to).join(', '));
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-//////////////////
-
-// Ad-hoc example resource method
-
-app.resource = function (path, obj) {
- this.get(path, obj.index);
- this.get(path + '/:a..:b.:format?', (req: express.Request, res: express.Response) => {
- var a = parseInt(req.params.a, 10)
- , b = parseInt(req.params.b, 10)
- , format = req.params.format;
- obj.range(req, res, a, b, format);
- });
- this.get(path + '/:id', obj.show);
- this.del(path + '/:id', obj.destroy);
-};
-
-// Fake controller.
-
-var FUser = {
- index: (req: express.Request, res: express.Response) => {
- res.send(users);
- },
- show: (req: express.Request, res: express.Response) => {
- res.send(users[req.params.id] || { error: 'Cannot find user' });
- },
- destroy: (req: express.Request, res: express.Response) => {
- var id = req.params.id;
- var destroyed = id in users;
- delete users[id];
- res.send(destroyed ? 'destroyed' : 'Cannot find user');
- },
- range: (req: express.Request, res: express.Response, a, b, format) => {
- var range = users.slice(a, b + 1);
- switch (format) {
- case 'json':
- res.send(range);
- break;
- case 'html':
- default:
- var html = '' + range.map(user => {
- return '- ' + user.name + '
';
- }).join('\n') + '
';
- res.send(html);
- break;
- }
- }
-};
-
-// curl http://localhost:3000/users -- responds with all users
-// curl http://localhost:3000/users/1 -- responds with user 1
-// curl http://localhost:3000/users/4 -- responds with error
-// curl http://localhost:3000/users/1..3 -- responds with several users
-// curl -X DELETE http://localhost:3000/users/1 -- deletes the user
-
-app.resource('/users', FUser);
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.send([
- 'Examples:
'
- , '- GET /users
'
- , '- GET /users/1
'
- , '- GET /users/3
'
- , '- GET /users/1..3
'
- , '- GET /users/1..3.json
'
- , '- DELETE /users/4
'
- , '
'
- ].join('\n'));
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express started on port 3000');
-}
-
-/////////////////////
-
-
-var verbose: any;
-
-app.map = (a, route) => {
- route = route || '';
- for (var key in a) {
- switch (typeof a[key]) {
- // { '/path': { ... }}
- case 'object':
- app.map(a[key], route + key);
- break;
- // get: function(){ ... }
- case 'function':
- if (verbose) console.log('%s %s', key, route);
- app[key](route, a[key]);
- break;
- }
- }
-};
-
-var users2 = {
- list: (req: express.Request, res: express.Response) => {
- res.send('user list');
- },
-
- get: (req: express.Request, res: express.Response) => {
- res.send('user ' + req.params.uid);
- },
-
- del: (req: express.Request, res: express.Response) => {
- res.send('delete users');
- }
-};
-
-var pets2 = {
- list: (req: express.Request, res: express.Response) => {
- res.send('user ' + req.params.uid + '\'s pets');
- },
-
- del: (req: express.Request, res: express.Response) => {
- res.send('delete ' + req.params.uid + '\'s pet ' + req.params.pid);
- }
-};
-
-app.map({
- '/users': {
- get: users2.list,
- del: users2.del,
- '/:uid': {
- get: users.get ,
- '/pets': {
- get: pets2.list,
- '/:pid': {
- del: pets2.del
- }
- }
- }
- }
-});
-
-app.listen(3000);
-
-///////////////////////////
-
-// Example requests:
-// curl http://localhost:3000/user/0
-// curl http://localhost:3000/user/0/edit
-// curl http://localhost:3000/user/1
-// curl http://localhost:3000/user/1/edit (unauthorized since this is not you)
-// curl -X DELETE http://localhost:3000/user/0 (unauthorized since you are not an admin)
-
-function loadUser(req: express.Request, res: express.Response, next) {
- // You would fetch your user from the db
- var user = users[req.params.id];
- if (user) {
- req.user = user;
- next();
- } else {
- next(new Error('Failed to load user ' + req.params.id));
- }
-}
-
-function andRestrictToSelf(req: express.Request, res: express.Response, next) {
- // If our authenticated user is the user we are viewing
- // then everything is fine :)
- if (req.authenticatedUser.id == req.user.id) {
- next();
- } else {
- // You may want to implement specific exceptions
- // such as UnauthorizedError or similar so that you
- // can handle these can be special-cased in an error handler
- // (view ./examples/pages for this)
- next(new Error('Unauthorized'));
- }
-}
-
-function andRestrictTo(role) {
- return (req: express.Request, res: express.Response, next) => {
- if (req.authenticatedUser.role == role) {
- next();
- } else {
- next(new Error('Unauthorized'));
- }
- };
-}
-
-// Middleware for faux authentication
-// you would of course implement something real,
-// but this illustrates how an authenticated user
-// may interact with middleware
-
-app.use((req: express.Request, res: express.Response, next) => {
- req.authenticatedUser = users[0];
- next();
-});
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.redirect('/user/0');
-});
-
-app.get('/user/:id', loadUser, (req: express.Request, res: express.Response) => {
- res.send('Viewing user ' + req.user.name);
-});
-
-app.get('/user/:id/edit', loadUser, andRestrictToSelf, (req: express.Request, res: express.Response) => {
- res.send('Editing user ' + req.user.name);
-});
-
-app.del('/user/:id', loadUser, andRestrictTo('admin'), (req: express.Request, res: express.Response) => {
- res.send('Deleted user ' + req.user.name);
-});
-
-app.listen(3000);
-console.log('Express app started on port 3000');
-
-/////////////////////////
-
-app.set('view engine', 'jade');
-app.set('views', __dirname);
-
-// populate search
-
-db.sadd('ferret', 'tobi');
-db.sadd('ferret', 'loki');
-db.sadd('ferret', 'jane');
-db.sadd('cat', 'manny');
-db.sadd('cat', 'luna');
-
-/**
- * GET the search page.
- */
-
-app.get('/', (req: express.Request, res: express.Response) => {
- res.render('search');
-});
-
-/**
- * GET search for :query.
- */
-
-app.get('/search/:query?', (req: express.Request, res: express.Response) => {
- var query = req.params.query;
- db.smembers(query, (err, vals) => {
- if (err) return res.send(500);
- res.send(vals);
- });
-});
-
-/**
- * GET client javascript. Here we use sendfile()
- * because serving __dirname with the static() middleware
- * would also mean serving our server "index.js" and the "search.jade"
- * template.
- */
-
-app.get('/client.js', (req: express.Request, res: express.Response) => {
- res.sendfile(__dirname + '/client.js');
-});
-
-app.listen(3000);
-console.log('app listening on port 3000');
-
-///////////////////
-
-app.use(express.logger('dev'));
-
-// Required by session() middleware
-// pass the secret for signed cookies
-// (required by session())
-app.use(express.cookieParser('keyboard cat'));
-
-// Populates req.session
-app.use(express.session());
-
-app.get('/', (req: express.Request, res: express.Response) => {
- var body = '';
- if (req.session.views) {
- ++req.session.views;
- } else {
- req.session.views = 1;
- body += 'First time visiting? view this page in several browsers :)
';
- }
- res.send(body + 'viewed ' + req.session.views + ' times.
');
-});
-
-app.listen(3000);
-console.log('Express app started on port 3000');
-
-////////////////////////
-
-// log requests
-app.use(express.logger('dev'));
-
-// express on its own has no notion
-// of a "file". The express.static()
-// middleware checks for a file matching
-// the `req.path` within the directory
-// that you pass it. In this case "GET /js/app.js"
-// will look for "./public/js/app.js".
-
-app.use(express.static(__dirname + '/public'));
-
-// if you wanted to "prefix" you may use
-// the mounting feature of Connect, for example
-// "GET /static/js/app.js" instead of "GET /js/app.js".
-// The mount-path "/static" is simply removed before
-// passing control to the express.static() middleware,
-// thus it serves the file correctly by ignoring "/static"
app.use('/static', express.static(__dirname + '/public'));
-// if for some reason you want to serve files from
-// several directories, you can use express.static()
-// multiple times! Here we're passing "./public/css",
-// this will allow "GET /style.css" instead of "GET /css/style.css":
-app.use(express.static(__dirname + '/public/css'));
-
-// this examples does not have any routes, however
-// you may `app.use(app.router)` before or after these
-// static() middleware. If placed before them your routes
-// will be matched BEFORE file serving takes place. If placed
-// after as shown here then file serving is performed BEFORE
-// any routes are hit:
-app.use(app.router);
-
-app.listen(3000);
-console.log('listening on port 3000');
-console.log('try:');
-console.log(' GET /hello.txt');
-console.log(' GET /js/app.js');
-console.log(' GET /css/style.css');
-
-//////////////////
-
-/*
-edit /etc/vhosts:
-
-127.0.0.1 foo.example.com
-127.0.0.1 bar.example.com
-127.0.0.1 example.com
-*/
-
-// Main app
-
-var main = express();
-
-main.use(express.logger('dev'));
-
-main.get('/', (req: express.Request, res: express.Response) => {
- res.send('Hello from main app!');
-});
-
-main.get('/:sub', (req: express.Request, res: express.Response) => {
- res.send('requsted ' + req.params.sub);
-});
-
-// Redirect app
-
-var redirect = express();
-
-redirect.all('*', (req: express.Request, res: express.Response) => {
- console.log(req.subdomains);
- res.redirect('http://example.com:3000/' + req.subdomains[0]);
-});
-
-app.use(express.vhost('*.example.com', redirect));
-app.use(express.vhost('example.com', main));
-
-app.listen(3000);
-console.log('Express app started on port 3000');
-
-////////////////////
-
-// create an error with .status. we
-// can then use the property in our
-// custom error handler (Connect repects this prop as well)
-
-function merror(status, msg) {
- var err = new Error(msg);
- err.status = status;
- return err;
-}
-
-// if we wanted to supply more than JSON, we could
-// use something similar to the content-negotiation
-// example.
-
-// here we validate the API key,
-// by mounting this middleware to /api
-// meaning only paths prefixed with "/api"
-// will cause this middleware to be invoked
-
-app.use('/api', (req, res: express.Response, next) => {
- var key = req.query['api-key'];
-
- // key isnt present
- if (!key) return next(merror(400, 'api key required'));
-
- // key is invalid
- if (!~apiKeys.indexOf(key)) return next(merror(401, 'invalid api key'));
-
- // all good, store req.key for route access
- req.key = key;
+// simple logger
+app.use(function(req, res, next){
+ console.log('%s %s', req.method, req.url);
next();
});
-// position our routes above the error handling middleware,
-// and below our API middleware, since we want the API validation
-// to take place BEFORE our routes
-app.use(app.router);
-
-// middleware with an arity of 4 are considered
-// error handling middleware. When you next(err)
-// it will be passed through the defined middleware
-// in order, but ONLY those with an arity of 4, ignoring
-// regular middleware.
-app.use((err, req, res: express.Response) => {
- // whatever you want here, feel free to populate
- // properties on `err` to treat it differently in here.
- res.send(err.status || 500, { error: err.message });
+app.get('/', function(req, res){
+ res.send('hello world');
});
-// our custom JSON 404 middleware. Since it's placed last
-// it will be the last middleware called, if all others
-// invoke next() and do not respond.
-app.use((req: express.Request, res: express.Response) => {
- res.send(404, { error: "Lame, can't find that" });
-});
-
-// map of valid api keys, typically mapped to
-// account info with some sort of database like redis.
-// api keys do _not_ serve as authentication, merely to
-// track API usage or help prevent malicious behavior etc.
-
-var apiKeys = ['foo', 'bar', 'baz'];
-
-// these two objects will serve as our faux database
-
-var repos = [
- { name: 'express', url: 'http://github.com/visionmedia/express' }
- , { name: 'stylus', url: 'http://github.com/learnboost/stylus' }
- , { name: 'cluster', url: 'http://github.com/learnboost/cluster' }
-];
-
-var userRepos = {
- tobi: [repos[0], repos[1]]
- , loki: [repos[1]]
- , jane: [repos[2]]
-};
-
-// we now can assume the api key is valid,
-// and simply expose the data
-
-app.get('/api/users', (req: express.Request, res: express.Response) => {
- res.send(users);
-});
-
-app.get('/api/repos', (req: express.Request, res: express.Response) => {
- res.send(repos);
-});
-
-app.get('/api/user/:name/repos', (req: express.Request, res: express.Response, next) => {
- var name = req.params.name
- , user = userRepos[name];
-
- if (user) res.send(user);
- else next();
-});
-
-if (!module.parent) {
- app.listen(3000);
- console.log('Express server listening on port 3000');
-}
-
-//////
-
-var router = new express.Router();
-
-router.get('/', function (req, resp, next?) {
- resp.send('response from router');
- resp.end();
- if (next) {
- next();
- }
-});
-
-function test_general() {
-
- app.use((err, req, res: express.Response) => {
- console.error(err.stack);
- res.send(500, 'Something broke!');
- });
- app.use(express.bodyParser());
- app.use(express.methodOverride());
- app.use(app.router);
- app.use(() => {});
- app.use(express.bodyParser());
- app.use(express.methodOverride());
- app.use(app.router);
-
- app.get('/', (req: express.Request, res: express.Response) => {
- res.send('hello world');
- });
-
- app.listen(3000);
-
- app.set('title', 'My Site');
- app.get('title');
-
- app.enable('trust proxy');
- app.get('trust proxy');
-
- app.disable('trust proxy');
- app.get('trust proxy');
-
- app.enabled('trust proxy');
-
- app.configure(() => {
- app.set('title', 'My Application');
- });
-
- app.configure('development', () => {
- app.set('db uri', 'localhost/dev');
- });
-
- app.configure('stage', 'production', () => {});
-
- app.configure('1', '2', '3', () => {});
-
- app.use((req: express.Request, res: express.Response) => {
- res.send('Hello World');
- });
-
- app.engine('jade', require('jade').__express);
-
- var User;
- app.param('user', (req: express.Request, res: express.Response, next, id) => {
- User.find(id, (err, user) =>{
- if (err) {
- next(err);
- } else if (user) {
- req.user = user;
- next();
- } else {
- next(new Error('failed to load user'));
- }
- });
- });
-
- app.get(/^\/commits\/(\d+)(?:\.\.(\d+))?$/, (req: express.Request, res: express.Response) => {
- var from = req.params[0];
- var to = req.params[1] || 'HEAD';
- res.send('commit range ' + from + '..' + to);
- });
-
- app.locals.title = 'My App';
- app.locals.strftime = require('strftime');
-
- var requireAuthentication;
- var loadUser = () => {};
- app.all('*', requireAuthentication, loadUser);
- app.all('*', loadUser);
- app.all('*', loadUser, loadUser, loadUser);
-
- app.locals.title = 'My App';
- app.locals.strftime = require('strftime');
- app.locals({
- title: 'My App',
- phone: '1-250-858-9990',
- email: 'me@myapp.com'
- });
- app.render('email', () => {});
-
- app.render('email', { name: 'Tobi' }, () => {});
-}
-
-function test_request() {
- var req: express.Request;
- req.params.name;
- req.params[0];
- req.query.q;
- req.body.user.name;
- app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/my/files' }));
- req.param('name');
- req.route;
- req.cookies.name;
- req.signedCookies;
- req.get('Content-Type');
- req.accepts('html');
- req.accepts(['html', 'json']);
- req.is('html');
- req.ip;
- req.path;
- req.host;
- req.fresh;
- req.stale;
- req.xhr;
- req.protocol;
- req.subdomains;
- req.originalUrl;
- req.acceptedLanguages;
- req.acceptedCharsets;
- var charset;
- req.acceptsCharset(charset);
- var lang;
- req.acceptsLanguage(lang);
- req.session = null;
-}
-
-function test_response() {
- var res: express.Response;
- res.status(404).sendfile('path/to/404.png');
- res.set('Content-Type', 'text/plain');
- res.set({
- 'Content-Type': 'text/plain',
- 'Content-Length': '123',
- 'ETag': '12345'
- });
- res.get('Content-Type');
- res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
- res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
- res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true });
- res.cookie('cart', { items: [1, 2, 3] });
- res.cookie('cart', { items: [1, 2, 3] }, { maxAge: 900000 });;
- res.cookie('name', 'tobi', { signed: true });
- res.cookie('name', 'tobi', { path: '/admin' });
- res.clearCookie('name', { path: '/admin' });
- res.redirect('/foo/bar');
- res.redirect('http://example.com');
- res.redirect(301, 'http://example.com');
- res.charset = 'value';
- res.send('some html');
- res.send(new Buffer('whoop'));
- res.send({ some: 'json' });
- res.send('some html');
- res.send(404, 'Sorry, we cannot find that!');
- res.send(500, { error: 'something blew up' });
- res.send(200);
- res.set('Content-Type', 'text/html');
- res.send(new Buffer('some html'));
- res.send('some html');
- res.send({ user: 'tobi' });
- res.send([1, 2, 3]);
- res.json(null);
- res.json({ user: 'tobi' });
- res.json(500, { error: 'message' });
- res.jsonp(null);
- res.jsonp({ user: 'tobi' });
- res.jsonp(500, { error: 'message' });
- res.jsonp({ user: 'tobi' });
- res.type('application/json');
-
- res.format({
- 'text/plain': () => {
- res.send('hey');
- },
- 'text/html': () => {
- res.send('hey');
- },
- 'application/json': () => {
- res.send({ message: 'hey' });
- }
- });
-
- res.attachment();
- res.attachment('path/to/logo.png');
- app.get('/user/:uid/photos/:file', (req: express.Request, res: express.Response) => {
- var uid = req.params.uid
- , file = req.params.file;
-
- req.user.mayViewFilesFrom(uid, yes => {
- if (yes) {
- res.sendfile('/uploads/' + uid + '/' + file);
- } else {
- res.send(403, 'Sorry! you cant see that.');
- }
- });
- });
-
- res.download('/report-12345.pdf');
- res.download('/report-12345.pdf', 'report.pdf');
- res.download('/report-12345.pdf', 'report.pdf', err => {
- if (err) { } else { }
- });
-
- res.links({
- next: 'http://api.example.com/users?page=2',
- last: 'http://api.example.com/users?page=5'
- });
-
- app.use((req: express.Request, res: express.Response, next) => {
- res.locals.user = req.user;
- res.locals.authenticated = !req.user.anonymous;
- next();
- });
- res.render('index', () => {});
- res.render('user', { name: 'Tobi' }, () => {});
-
-}
-
-function test_middleware() {
- app.use(express.basicAuth('username', 'password'));
- app.use(express.basicAuth((user, pass) => {
- return 'tj' == user && 'wahoo' == pass;
- }));
- app.use(express.bodyParser());
- app.use(express.json());
- app.use(express.urlencoded());
- app.use(express.multipart());
- app.use(express.logger());
- app.use(express.compress());
- app.use(express.methodOverride());
- app.use(express.bodyParser());
- app.use(express.cookieParser());
- app.use(express.cookieParser('some secret'));
- app.use(express.cookieSession());
- app.use(express.directory('public'));
- app.use(express.static('public'));
- app.use(router.middleware);
-}
-
-////////////////////
-
-// make sure server can be shut down
-var testShutdownServer = app.listen(0);
-console.log('listening on port ' + testShutdownServer.address().port);
-testShutdownServer.close();
+app.listen(3000);
diff --git a/express/express.d.ts b/express/express.d.ts
index eafc4c5966..052173c831 100644
--- a/express/express.d.ts
+++ b/express/express.d.ts
@@ -1,22 +1,14 @@
-// Type definitions for Express 3.1
+// Type definitions for Express 4.x
// Project: http://expressjs.com
// Definitions by: Boris Yankov
// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
-/* =================== USAGE ===================
-
- import express = require('express');
- var app = express();
-
- =============================================== */
-
///
-
declare module Express {
// These open interfaces may be extended in an application-specific manner via declaration merging.
- // See for example passport.d.ts (https://github.com/borisyankov/DefinitelyTyped/blob/master/passport/passport.d.ts)
+ // See for example method-override.d.ts (https://github.com/borisyankov/DefinitelyTyped/blob/master/method-override/method-override.d.ts)
export interface Request { }
export interface Response { }
export interface Application { }
@@ -26,51 +18,24 @@ declare module Express {
declare module "express" {
import http = require('http');
- // Merged declaration, e is both a callable function and a namespace
function e(): e.Express;
module e {
interface IRoute {
path: string;
-
- method: string;
-
- callbacks: Function[];
-
- regexp: any;
-
- /**
- * Check if this route matches `path`, if so
- * populate `.params`.
- */
- match(path: string): boolean;
+ stack: any;
+ all(...handler: RequestHandler[]): IRoute;
+ get(...handler: RequestHandler[]): IRoute;
+ post(...handler: RequestHandler[]): IRoute;
+ put(...handler: RequestHandler[]): IRoute;
+ delete(...handler: RequestHandler[]): IRoute;
+ patch(...handler: RequestHandler[]): IRoute;
+ options(...handler: RequestHandler[]): IRoute;
}
- class Route implements IRoute {
- path: string;
-
- method: string;
-
- callbacks: Function[];
-
- regexp: any;
- match(path: string): boolean;
-
- /**
- * Initialize `Route` with the given HTTP `method`, `path`,
- * and an array of `callbacks` and `options`.
- *
- * Options:
- *
- * - `sensitive` enable case-sensitive routes
- * - `strict` enable strict matching for trailing slashes
- *
- * @param method
- * @param path
- * @param callbacks
- * @param options
- */
- new (method: string, path: string, callbacks: Function[], options: any): Route;
+ interface IRouterMatcher {
+ (name: string, ...handlers: RequestHandler[]): T;
+ (name: RegExp, ...handlers: RequestHandler[]): T;
}
interface IRouter {
@@ -103,9 +68,9 @@ declare module "express" {
* @param name
* @param fn
*/
- param(name: string, fn: Function): T;
-
- param(name: string[], fn: Function): T;
+ param(name: string, handler: RequestParamHandler): T;
+ param(name: string, matcher: RegExp): T;
+ param(name: string, mapper: (param: any) => any): T;
/**
* Special-cased "all" method, applying the given route `path`,
@@ -114,68 +79,27 @@ declare module "express" {
* @param path
* @param fn
*/
- all(path: string, fn?: (req: Request, res: Response, next: Function) => any): T;
+ all: IRouterMatcher;
+ get: IRouterMatcher;
+ post: IRouterMatcher;
+ put: IRouterMatcher;
+ delete: IRouterMatcher;
+ patch: IRouterMatcher;
+ options: IRouterMatcher;
- all(path: string, ...callbacks: Function[]): void;
+ route(path: string): IRoute;
- get(name: string, ...handlers: RequestFunction[]): T;
-
- get(name: RegExp, ...handlers: RequestFunction[]): T;
-
- post(name: string, ...handlers: RequestFunction[]): T;
-
- post(name: RegExp, ...handlers: RequestFunction[]): T;
-
- put(name: string, ...handlers: RequestFunction[]): T;
-
- put(name: RegExp, ...handlers: RequestFunction[]): T;
-
- del(name: string, ...handlers: RequestFunction[]): T;
-
- del(name: RegExp, ...handlers: RequestFunction[]): T;
-
- patch(name: string, ...handlers: RequestFunction[]): T;
-
- patch(name: RegExp, ...handlers: RequestFunction[]): T;
+ use(server: Application): Application;
+ use(handler: RequestHandler): Application;
+ use(handler: ErrorRequestHandler): Application;
+ use(path: string, server: Application): Application;
+ use(path: string, handler: RequestHandler): Application;
+ use(path: string, handler: ErrorRequestHandler): Application;
}
- export class Router implements IRouter {
- new (options?: any): Router;
+ export function Router(options?: any): Router;
- middleware (): any;
-
- param(name: string, fn: Function): Router;
-
- param(name: any[], fn: Function): Router;
-
- all(path: string, fn?: (req: Request, res: Response, next: Function) => any): Router;
-
- all(path: string, ...callbacks: Function[]): void;
-
- get(name: string, ...handlers: RequestFunction[]): Router;
-
- get(name: RegExp, ...handlers: RequestFunction[]): Router;
-
- post(name: string, ...handlers: RequestFunction[]): Router;
-
- post(name: RegExp, ...handlers: RequestFunction[]): Router;
-
- put(name: string, ...handlers: RequestFunction[]): Router;
-
- put(name: RegExp, ...handlers: RequestFunction[]): Router;
-
- del(name: string, ...handlers: RequestFunction[]): Router;
-
- del(name: RegExp, ...handlers: RequestFunction[]): Router;
-
- patch(name: string, ...handlers: RequestFunction[]): Router;
-
- patch(name: RegExp, ...handlers: RequestFunction[]): Router;
- }
-
- interface Handler {
- (req: Request, res: Response, next?: Function): void;
- }
+ export interface Router extends IRouter {}
interface CookieOptions {
maxAge?: number;
@@ -189,61 +113,8 @@ declare module "express" {
interface Errback { (err: Error): void; }
- interface Session {
- /**
- * Update reset `.cookie.maxAge` to prevent
- * the cookie from expiring when the
- * session is still active.
- *
- * @return {Session} for chaining
- * @api public
- */
- touch(): Session;
-
- /**
- * Reset `.maxAge` to `.originalMaxAge`.
- */
- resetMaxAge(): Session;
-
- /**
- * Save the session data with optional callback `fn(err)`.
- */
- save(fn: Function): Session;
-
- /**
- * Re-loads the session data _without_ altering
- * the maxAge properties. Invokes the callback `fn(err)`,
- * after which time if no exception has occurred the
- * `req.session` property will be a new `Session` object,
- * although representing the same session.
- */
- reload(fn: Function): Session;
-
- /**
- * Destroy `this` session.
- */
- destroy(fn: Function): Session;
-
- /**
- * Regenerate this request's session.
- */
- regenerate(fn: Function): Session;
-
- user: any;
-
- error: string;
-
- success: string;
-
- views: any;
-
- count: number;
- }
-
interface Request extends http.ServerRequest, Express.Request {
- session: Session;
-
/**
* Return request header.
*
@@ -450,17 +321,6 @@ declare module "express" {
*/
ips: string[];
- /**
- * Return basic auth credentials.
- *
- * Examples:
- *
- * // http://tobi:hello@example.com
- * req.auth
- * // => { username: 'tobi', password: 'hello' }
- */
- auth: any;
-
/**
* Return subdomains as an array.
*
@@ -509,12 +369,6 @@ declare module "express" {
//cookies: { string; remember: boolean; };
cookies: any;
- /**
- * Used to generate an anti-CSRF token.
- * Placed by the CSRF protection middleware.
- */
- csrfToken(): string;
-
method: string;
params: any;
@@ -650,11 +504,8 @@ declare module "express" {
* });
*/
sendfile(path: string): void;
-
sendfile(path: string, options: any): void;
-
sendfile(path: string, fn: Errback): void;
-
sendfile(path: string, options: any, fn: Errback): void;
/**
@@ -668,11 +519,8 @@ declare module "express" {
* This method uses `res.sendfile()`.
*/
download(path: string): void;
-
download(path: string, filename: string): void;
-
download(path: string, fn: Errback): void;
-
download(path: string, filename: string, fn: Errback): void;
/**
@@ -782,12 +630,10 @@ declare module "express" {
*
* Aliased as `res.header()`.
*/
- set (field: any): Response;
-
- set (field: string, value?: string): Response;
+ set(field: any): Response;
+ set(field: string, value?: string): Response;
header(field: any): Response;
-
header(field: string, value?: string): Response;
/**
@@ -823,9 +669,7 @@ declare module "express" {
* res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
*/
cookie(name: string, val: string, options: CookieOptions): Response;
-
cookie(name: string, val: any, options: CookieOptions): Response;
-
cookie(name: string, val: any): Response;
/**
@@ -875,9 +719,7 @@ declare module "express" {
* res.redirect('../login'); // /blog/post/1 -> /blog/login
*/
redirect(url: string): void;
-
redirect(status: number, url: string): void;
-
redirect(url: string, status: number): void;
/**
@@ -890,9 +732,7 @@ declare module "express" {
* - `cache` boolean hinting to the engine it should cache
* - `filename` filename of the view being rendered
*/
-
render(view: string, options?: Object, callback?: (err: Error, html: string) => void ): void;
-
render(view: string, callback?: (err: Error, html: string) => void ): void;
locals: any;
@@ -900,10 +740,18 @@ declare module "express" {
charset: string;
}
- interface RequestFunction {
+ interface ErrorRequestHandler {
+ (err: any, req: Request, res: Response, next: Function): any;
+ }
+
+ interface RequestHandler {
(req: Request, res: Response, next: Function): any;
}
+ interface RequestParamHandler {
+ (req: Request, res: Response, next: Function, param: any): any;
+ }
+
interface Application extends IRouter, Express.Application {
/**
* Initialize the server.
@@ -919,18 +767,6 @@ declare module "express" {
*/
defaultConfiguration(): void;
- /**
- * Proxy `connect#use()` to apply settings to
- * mounted applications.
- **/
- use(route: string, callback?: Function): Application;
-
- use(route: string, server: Application): Application;
-
- use(callback: Function): Application;
-
- use(server: Application): Application;
-
/**
* Register the given template engine callback `fn`
* as `ext`.
@@ -961,10 +797,6 @@ declare module "express" {
*/
engine(ext: string, fn: Function): Application;
- param(name: string, fn: Function): Application;
-
- param(name: string[], fn: Function): Application;
-
/**
* Assign `setting` to `val`, or return `setting`'s value.
*
@@ -977,13 +809,12 @@ declare module "express" {
* @param setting
* @param val
*/
- set (setting: string, val: string): Application;
-
- get(name: string): string;
-
- get(name: string, ...handlers: RequestFunction[]): Application;
-
- get(name: RegExp, ...handlers: RequestFunction[]): Application;
+ set(setting: string, val: string): Application;
+ get: {
+ (name: string): string; // Getter
+ (name: string, ...handlers: RequestHandler[]): Application;
+ (name: RegExp, ...handlers: RequestHandler[]): Application;
+ }
/**
* Return the app's absolute pathname
@@ -1079,18 +910,12 @@ declare module "express" {
* @param env
* @param fn
*/
- configure(env: string, fn: Function): Application;
-
- configure(env0: string, env1: string, fn: Function): Application;
-
- configure(env0: string, env1: string, env2: string, fn: Function): Application;
-
- configure(env0: string, env1: string, env2: string, env3: string, fn: Function): Application;
-
- configure(env0: string, env1: string, env2: string, env3: string, env4: string, fn: Function): Application;
-
configure(fn: Function): Application;
-
+ configure(env0: string, fn: Function): Application;
+ configure(env0: string, env1: string, fn: Function): Application;
+ configure(env0: string, env1: string, env2: string, fn: Function): Application;
+ configure(env0: string, env1: string, env2: string, env3: string, fn: Function): Application;
+ configure(env0: string, env1: string, env2: string, env3: string, env4: string, fn: Function): Application;
/**
* Render the given view `name` name with `options`
@@ -1108,7 +933,6 @@ declare module "express" {
* @param fn
*/
render(name: string, options?: Object, callback?: (err: Error, html: string) => void): void;
-
render(name: string, callback: (err: Error, html: string) => void): void;
@@ -1130,16 +954,12 @@ declare module "express" {
* https.createServer({ ... }, app).listen(443);
*/
listen(port: number, hostname: string, backlog: number, callback?: Function): http.Server;
-
listen(port: number, hostname: string, callback?: Function): http.Server;
-
listen(port: number, callback?: Function): http.Server;
-
listen(path: string, callback?: Function): http.Server;
-
listen(handle: any, listeningListener?: Function): http.Server;
- route: IRoute;
+ route(path: string): IRoute;
router: string;
@@ -1189,237 +1009,6 @@ declare module "express" {
response: Response;
}
- /**
- * Body parser:
- *
- * Parse request bodies, supports _application/json_,
- * _application/x-www-form-urlencoded_, and _multipart/form-data_.
- *
- * This is equivalent to:
- *
- * app.use(connect.json());
- * app.use(connect.urlencoded());
- * app.use(connect.multipart());
- *
- * Examples:
- *
- * connect()
- * .use(connect.bodyParser())
- * .use(function(req, res) {
- * res.end('viewing user ' + req.body.user.name);
- * });
- *
- * $ curl -d 'user[name]=tj' http://local/
- * $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://local/
- *
- * View [json](json.html), [urlencoded](urlencoded.html), and [multipart](multipart.html) for more info.
- *
- * @param options
- */
- function bodyParser(options?: any): Handler;
-
- /**
- * Error handler:
- *
- * Development error handler, providing stack traces
- * and error message responses for requests accepting text, html,
- * or json.
- *
- * Text:
- *
- * By default, and when _text/plain_ is accepted a simple stack trace
- * or error message will be returned.
- *
- * JSON:
- *
- * When _application/json_ is accepted, connect will respond with
- * an object in the form of `{ "error": error }`.
- *
- * HTML:
- *
- * When accepted connect will output a nice html stack trace.
- */
- function errorHandler(opts?: any): Handler;
-
- /**
- * Method Override:
- *
- * Provides faux HTTP method support.
- *
- * Pass an optional `key` to use when checking for
- * a method override, othewise defaults to _\_method_.
- * The original method is available via `req.originalMethod`.
- *
- * @param key
- */
- function methodOverride(key?: string): Handler;
-
- /**
- * Cookie parser:
- *
- * Parse _Cookie_ header and populate `req.cookies`
- * with an object keyed by the cookie names. Optionally
- * you may enabled signed cookie support by passing
- * a `secret` string, which assigns `req.secret` so
- * it may be used by other middleware.
- *
- * Examples:
- *
- * connect()
- * .use(connect.cookieParser('optional secret string'))
- * .use(function(req, res, next){
- * res.end(JSON.stringify(req.cookies));
- * })
- *
- * @param secret
- */
- function cookieParser(secret?: string): Handler;
-
- /**
- * Session:
- *
- * Setup session store with the given `options`.
- *
- * Session data is _not_ saved in the cookie itself, however
- * cookies are used, so we must use the [cookieParser()](cookieParser.html)
- * middleware _before_ `session()`.
- *
- * Examples:
- *
- * connect()
- * .use(connect.cookieParser())
- * .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }}))
- *
- * Options:
- *
- * - `key` cookie name defaulting to `connect.sid`
- * - `store` session store instance
- * - `secret` session cookie is signed with this secret to prevent tampering
- * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
- * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
- *
- * Cookie option:
- *
- * By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set
- * so the cookie becomes a browser-session cookie. When the user closes the
- * browser the cookie (and session) will be removed.
- *
- * ## req.session
- *
- * To store or access session data, simply use the request property `req.session`,
- * which is (generally) serialized as JSON by the store, so nested objects
- * are typically fine. For example below is a user-specific view counter:
- *
- * connect()
- * .use(connect.favicon())
- * .use(connect.cookieParser())
- * .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
- * .use(function(req, res, next){
- * var sess = req.session;
- * if (sess.views) {
- * res.setHeader('Content-Type', 'text/html');
- * res.write('views: ' + sess.views + '
');
- * res.write('expires in: ' + (sess.cookie.maxAge / 1000) + 's
');
- * res.end();
- * sess.views++;
- * } else {
- * sess.views = 1;
- * res.end('welcome to the session demo. refresh!');
- * }
- * }
- * )).listen(3000);
- *
- * ## Session#regenerate()
- *
- * To regenerate the session simply invoke the method, once complete
- * a new SID and `Session` instance will be initialized at `req.session`.
- *
- * req.session.regenerate(function(err){
- * // will have a new session here
- * });
- *
- * ## Session#destroy()
- *
- * Destroys the session, removing `req.session`, will be re-generated next request.
- *
- * req.session.destroy(function(err){
- * // cannot access session here
- * });
- *
- * ## Session#reload()
- *
- * Reloads the session data.
- *
- * req.session.reload(function(err){
- * // session updated
- * });
- *
- * ## Session#save()
- *
- * Save the session.
- *
- * req.session.save(function(err){
- * // session saved
- * });
- *
- * ## Session#touch()
- *
- * Updates the `.maxAge` property. Typically this is
- * not necessary to call, as the session middleware does this for you.
- *
- * ## Session#cookie
- *
- * Each session has a unique cookie object accompany it. This allows
- * you to alter the session cookie per visitor. For example we can
- * set `req.session.cookie.expires` to `false` to enable the cookie
- * to remain for only the duration of the user-agent.
- *
- * ## Session#maxAge
- *
- * Alternatively `req.session.cookie.maxAge` will return the time
- * remaining in milliseconds, which we may also re-assign a new value
- * to adjust the `.expires` property appropriately. The following
- * are essentially equivalent
- *
- * var hour = 3600000;
- * req.session.cookie.expires = new Date(Date.now() + hour);
- * req.session.cookie.maxAge = hour;
- *
- * For example when `maxAge` is set to `60000` (one minute), and 30 seconds
- * has elapsed it will return `30000` until the current request has completed,
- * at which time `req.session.touch()` is called to reset `req.session.maxAge`
- * to its original value.
- *
- * req.session.cookie.maxAge;
- * // => 30000
- *
- * Session Store Implementation:
- *
- * Every session store _must_ implement the following methods
- *
- * - `.get(sid, callback)`
- * - `.set(sid, session, callback)`
- * - `.destroy(sid, callback)`
- *
- * Recommended methods include, but are not limited to:
- *
- * - `.length(callback)`
- * - `.clear(callback)`
- *
- * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
- *
- * @param options
- */
- function session(options?: any): Handler;
-
- /**
- * Hash the given `sess` object omitting changes
- * to `.cookie`.
- *
- * @param sess
- */
- function hash(sess: string): string;
-
/**
* Static:
*
@@ -1444,387 +1033,7 @@ declare module "express" {
* @param root
* @param options
*/
- function static(root: string, options?: any): Handler;
-
- /**
- * Basic Auth:
- *
- * Enfore basic authentication by providing a `callback(user, pass)`,
- * which must return `true` in order to gain access. Alternatively an async
- * method is provided as well, invoking `callback(user, pass, callback)`. Populates
- * `req.user`. The final alternative is simply passing username / password
- * strings.
- *
- * Simple username and password
- *
- * connect(connect.basicAuth('username', 'password'));
- *
- * Callback verification
- *
- * connect()
- * .use(connect.basicAuth(function(user, pass){
- * return 'tj' == user & 'wahoo' == pass;
- * }))
- *
- * Async callback verification, accepting `fn(err, user)`.
- *
- * connect()
- * .use(connect.basicAuth(function(user, pass, fn){
- * User.authenticate({ user: user, pass: pass }, fn);
- * }))
- *
- * @param callback or username
- * @param realm
- */
- export function basicAuth(callback: (user: string, pass: string, fn : Function) => void, realm?: string): Handler;
-
- export function basicAuth(callback: (user: string, pass: string) => boolean, realm?: string): Handler;
-
- export function basicAuth(user: string, pass: string, realm?: string): Handler;
-
- /**
- * Compress:
- *
- * Compress response data with gzip/deflate.
- *
- * Filter:
- *
- * A `filter` callback function may be passed to
- * replace the default logic of:
- *
- * exports.filter = function(req, res){
- * return /json|text|javascript/.test(res.getHeader('Content-Type'));
- * };
- *
- * Options:
- *
- * All remaining options are passed to the gzip/deflate
- * creation functions. Consult node's docs for additional details.
- *
- * - `chunkSize` (default: 16*1024)
- * - `windowBits`
- * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
- * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
- * - `strategy`: compression strategy
- *
- * @param options
- */
- function compress(options?: any): Handler;
-
- /**
- * Cookie Session:
- *
- * Cookie session middleware.
- *
- * var app = connect();
- * app.use(connect.cookieParser());
- * app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }}));
- *
- * Options:
- *
- * - `key` cookie name defaulting to `connect.sess`
- * - `secret` prevents cookie tampering
- * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
- * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
- *
- * Clearing sessions:
- *
- * To clear the session simply set its value to `null`,
- * `cookieSession()` will then respond with a 1970 Set-Cookie.
- *
- * req.session = null;
- *
- * @param options
- */
- function cookieSession(options?: any): Handler;
-
- /**
- * Anti CSRF:
- *
- * CSRF protection middleware.
- *
- * This middleware adds a `req.csrfToken()` function to make a token
- * which should be added to requests which mutate
- * state, within a hidden form field, query-string etc. This
- * token is validated against the visitor's session.
- *
- * The default `value` function checks `req.body` generated
- * by the `bodyParser()` middleware, `req.query` generated
- * by `query()`, and the "X-CSRF-Token" header field.
- *
- * This middleware requires session support, thus should be added
- * somewhere _below_ `session()` and `cookieParser()`.
- *
- * Options:
- *
- * - `value` a function accepting the request, returning the token
- *
- * @param options
- */
- export function csrf(options?: {value?: Function}): Handler;
-
- /**
- * Directory:
- *
- * Serve directory listings with the given `root` path.
- *
- * Options:
- *
- * - `hidden` display hidden (dot) files. Defaults to false.
- * - `icons` display icons. Defaults to false.
- * - `filter` Apply this filter function to files. Defaults to false.
- *
- * @param root
- * @param options
- */
- function directory(root: string, options?: any): Handler;
-
- /**
- * Favicon:
- *
- * By default serves the connect favicon, or the favicon
- * located by the given `path`.
- *
- * Options:
- *
- * - `maxAge` cache-control max-age directive, defaulting to 1 day
- *
- * Examples:
- *
- * Serve default favicon:
- *
- * connect()
- * .use(connect.favicon())
- *
- * Serve favicon before logging for brevity:
- *
- * connect()
- * .use(connect.favicon())
- * .use(connect.logger('dev'))
- *
- * Serve custom favicon:
- *
- * connect()
- * .use(connect.favicon('public/favicon.ico))
- *
- * @param path
- * @param options
- */
- export function favicon(path?: string, options?: any): Handler;
-
- /**
- * JSON:
- *
- * Parse JSON request bodies, providing the
- * parsed object as `req.body`.
- *
- * Options:
- *
- * - `strict` when `false` anything `JSON.parse()` accepts will be parsed
- * - `reviver` used as the second "reviver" argument for JSON.parse
- * - `limit` byte limit disabled by default
- *
- * @param options
- */
- function json(options?: any): Handler;
-
- /**
- * Limit:
- *
- * Limit request bodies to the given size in `bytes`.
- *
- * A string representation of the bytesize may also be passed,
- * for example "5mb", "200kb", "1gb", etc.
- *
- * connect()
- * .use(connect.limit('5.5mb'))
- * .use(handleImageUpload)
- */
- function limit(bytes: number): Handler;
-
- function limit(bytes: string): Handler;
-
- /**
- * Logger:
- *
- * Log requests with the given `options` or a `format` string.
- *
- * Options:
- *
- * - `format` Format string, see below for tokens
- * - `stream` Output stream, defaults to _stdout_
- * - `buffer` Buffer duration, defaults to 1000ms when _true_
- * - `immediate` Write log line on request instead of response (for response times)
- *
- * Tokens:
- *
- * - `:req[header]` ex: `:req[Accept]`
- * - `:res[header]` ex: `:res[Content-Length]`
- * - `:http-version`
- * - `:response-time`
- * - `:remote-addr`
- * - `:date`
- * - `:method`
- * - `:url`
- * - `:referrer`
- * - `:user-agent`
- * - `:status`
- *
- * Formats:
- *
- * Pre-defined formats that ship with connect:
- *
- * - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
- * - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
- * - `tiny` ':method :url :status :res[content-length] - :response-time ms'
- * - `dev` concise output colored by response status for development use
- *
- * Examples:
- *
- * connect.logger() // default
- * connect.logger('short')
- * connect.logger('tiny')
- * connect.logger({ immediate: true, format: 'dev' })
- * connect.logger(':method :url - :referrer')
- * connect.logger(':req[content-type] -> :res[content-type]')
- * connect.logger(function(tokens, req, res){ return 'some format string' })
- *
- * Defining Tokens:
- *
- * To define a token, simply invoke `connect.logger.token()` with the
- * name and a callback function. The value returned is then available
- * as ":type" in this case.
- *
- * connect.logger.token('type', function(req, res){ return req.headers['content-type']; })
- *
- * Defining Formats:
- *
- * All default formats are defined this way, however it's public API as well:
- *
- * connect.logger.format('name', 'string or function')
- */
- function logger(options: string): Handler;
-
- function logger(options: Function): Handler;
-
- function logger(options?: any): Handler;
-
- /**
- * Compile `fmt` into a function.
- *
- * @param fmt
- */
- function compile(fmt: string): Handler;
-
- /**
- * Define a token function with the given `name`,
- * and callback `fn(req, res)`.
- *
- * @param name
- * @param fn
- */
- function token(name: string, fn: Function): any;
-
- /**
- * Define a `fmt` with the given `name`.
- */
- function format(name: string, str: string): any;
-
- function format(name: string, str: Function): any;
-
- /**
- * Query:
- *
- * Automatically parse the query-string when available,
- * populating the `req.query` object.
- *
- * Examples:
- *
- * connect()
- * .use(connect.query())
- * .use(function(req, res){
- * res.end(JSON.stringify(req.query));
- * });
- *
- * The `options` passed are provided to qs.parse function.
- */
- function query(options: any): Handler;
-
- /**
- * Reponse time:
- *
- * Adds the `X-Response-Time` header displaying the response
- * duration in milliseconds.
- */
- function responseTime(): Handler;
-
- /**
- * Static cache:
- *
- * Enables a memory cache layer on top of
- * the `static()` middleware, serving popular
- * static files.
- *
- * By default a maximum of 128 objects are
- * held in cache, with a max of 256k each,
- * totalling ~32mb.
- *
- * A Least-Recently-Used (LRU) cache algo
- * is implemented through the `Cache` object,
- * simply rotating cache objects as they are
- * hit. This means that increasingly popular
- * objects maintain their positions while
- * others get shoved out of the stack and
- * garbage collected.
- *
- * Benchmarks:
- *
- * static(): 2700 rps
- * node-static: 5300 rps
- * static() + staticCache(): 7500 rps
- *
- * Options:
- *
- * - `maxObjects` max cache objects [128]
- * - `maxLength` max cache object length 256kb
- */
- function staticCache(options: any): Handler;
-
- /**
- * Timeout:
- *
- * Times out the request in `ms`, defaulting to `5000`. The
- * method `req.clearTimeout()` is added to revert this behaviour
- * programmatically within your application's middleware, routes, etc.
- *
- * The timeout error is passed to `next()` so that you may customize
- * the response behaviour. This error has the `.timeout` property as
- * well as `.status == 408`.
- */
- function timeout(ms: number): Handler;
-
- /**
- * Vhost:
- *
- * Setup vhost for the given `hostname` and `server`.
- *
- * connect()
- * .use(connect.vhost('foo.com', fooApp))
- * .use(connect.vhost('bar.com', barApp))
- * .use(connect.vhost('*.com', mainApp))
- *
- * The `server` may be a Connect server or
- * a regular Node `http.Server`.
- *
- * @param hostname
- * @param server
- */
- function vhost(hostname: string, server: any): Handler;
-
- function urlencoded(): any;
-
- function multipart(): any;
-
+ function static(root: string, options?: any): RequestHandler;
}
export = e;
diff --git a/method-override/method-override-tests.ts b/method-override/method-override-tests.ts
new file mode 100644
index 0000000000..84b4e966e0
--- /dev/null
+++ b/method-override/method-override-tests.ts
@@ -0,0 +1,15 @@
+///
+
+import express = require('express');
+import methodOverride = require('method-override');
+var app = express();
+
+app.use(methodOverride('X-HTTP-Method-Override'));
+app.use(methodOverride((req: express.Request, res: express.Response) => {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ var method = req.body._method
+ delete req.body._method
+ return method
+ }
+}));
diff --git a/method-override/method-override.d.ts b/method-override/method-override.d.ts
new file mode 100644
index 0000000000..51b62f521f
--- /dev/null
+++ b/method-override/method-override.d.ts
@@ -0,0 +1,24 @@
+// Type definitions for method-override
+// Project: https://github.com/expressjs/method-override
+// Definitions by: Santi Albo
+// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module Express {
+ export interface Request {
+ originalMethod?: string;
+ }
+}
+
+declare module "method-override" {
+ import express = require('express');
+ module e {
+ interface MethodOverrideOptions {
+ methods: string[];
+ }
+ }
+ function e(getter: string, options?: any): express.RequestHandler;
+ function e(getter: (req: express.Request, res: express.Response) => string, options?: any): express.RequestHandler;
+ export = e;
+}
\ No newline at end of file