' + err + '
'; + if (msg) res.locals.message = '' + msg + '
'; + next(); +}); + +// dummy database + +var users =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'], function (req, res, 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', function (req, res, next, id) { + if (req.user = users[id]) { + next(); + } else { + next(new Error('failed to find user')); + } +}); + +/** + * GET index. + */ + +app.get('/', function (req, res) { + res.send('Visit /user/0 or /users/0-2'); +}); + +/** + * GET :user. + */ + +app.get('/user/:user', function (req, res, next) { + res.send('user ' + req.user.name); +}); + +/** + * GET users :from - :to. + */ + +app.get('/users/:from-:to', function (req, res, next) { + var from = req.params.from + , to = req.params.to + , names = users.map(function (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?', function (req, res) { + 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: function (req, res) { + res.send(users); + }, + show: function (req, res) { + res.send(users[req.params.id] || { error: 'Cannot find user' }); + }, + destroy: function (req, res) { + var id = req.params.id; + var destroyed = id in users; + delete users[id]; + res.send(destroyed ? 'destroyed' : 'Cannot find user'); + }, + range: function (req, res, a, b, format) { + var range = users.slice(a, b + 1); + switch (format) { + case 'json': + res.send(range); + break; + case 'html': + default: + var html = '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('/', function (req, res) { + res.send('Hello from main app!') +}); + +main.get('/:sub', function (req, res) { + res.send('requsted ' + req.params.sub); +}); + +// Redirect app + +var redirect = express(); + +redirect.all('*', function (req, res) { + 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 =some html
'); + * res.send(404, 'Sorry, cant find that'); + * res.send(404); + */ + send(status: number): ExpressServerResponse; + + send(bodyOrStatus: any): ExpressServerResponse; + + send(status: number, body: any): ExpressServerResponse; + + + /** + * Send JSON response. + * + * Examples: + * + * res.json(null); + * res.json({ user: 'tj' }); + * res.json(500, 'oh noes!'); + * res.json(404, 'I dont have that'); + */ + json(status: number): ExpressServerResponse; + + json(bodyOrStatus: any): ExpressServerResponse; + + json(status: number, body: any): ExpressServerResponse; + + /** + * 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(status: number): ExpressServerResponse; + + jsonp(bodyOrStatus: any): ExpressServerResponse; + + jsonp(status: number, body: any): ExpressServerResponse; + + /** + * 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): ExpressServerResponse; + + /** + * 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): ExpressServerResponse; + + /** + * 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): ExpressServerResponse; + + /** + * Set _Content-Disposition_ header to _attachment_ with optional `filename`. + * + * @param filename + */ + attachment(filename: string): ExpressServerResponse; + + /** + * 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): void; + + set (field: string, value?: string): void; + + header(field: any): void; + + header(field: string, value?: string): void; + + /** + * Get value for header `field`. + * + * @param field + */ + get (field: string): string; + + /** + * Clear cookie `name`. + * + * @param name + * @param options + */ + clearCookie(name: string, options?: any): ExpressServerResponse; + + /** + * 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); + + cookie(name: string, val: any, options: CookieOptions); + + /** + * 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); + + /** + * 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): void; + + render(view: string, options: any): void; + + render(view: string, callback: (err: Error, html: any) => void ): void; + + render(view: string, options: any, callback: (err: Error, html: any) => void ): void; + + locals: any; +} + +interface ImportConnect { + /** + * 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 + */ + 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. + */ + 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 + */ + 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 + */ + 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 + */ + session(options?: any): Handler; + + /** + * Hash the given `sess` object omitting changes + * to `.cookie`. + * + * @param sess + */ + 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 + */ + 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 + */ + basicAuth(callback: Function, realm: string); + + basicAuth(callback: string, realm: string); + + /** + * 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 + */ + 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 + */ + cookieSession(options?: any): Handler; + + /** + * Anti CSRF: + * + * CRSF protection middleware. + * + * By default this middleware generates a token named "_csrf" + * 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 `req.session._csrf` + * property. + * + * 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 + */ + csrf(options: any); + + /** + * 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 + */ + 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 + */ + favicon(path?: string, options?: any); + + /** + * 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 + */ + 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) + */ + limit(bytes: number): Handler; + + 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') + */ + logger(options: string): Handler; + + logger(options: Function): Handler; + + logger(options: any): Handler; + + /** + * Compile `fmt` into a function. + * + * @param fmt + */ + compile(fmt: string): Handler; + + /** + * Define a token function with the given `name`, + * and callback `fn(req, res)`. + * + * @param name + * @param fn + */ + token(name: string, fn: Function): any; + + /** + * Define a `fmt` with the given `name`. + */ + format(name: string, str: string): any; + + 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. + */ + query(options: any): Handler; + + /** + * Reponse time: + * + * Adds the `X-Response-Time` header displaying the response + * duration in milliseconds. + */ + 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 + */ + 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`. + */ + 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 + */ + vhost(hostname: string, server: any): Handler; +} + +interface ExpressApplication extends ImportConnect { + /** + * Initialize the server. + * + * - setup default configuration + * - setup default middleware + * - setup route reflection methods + */ + init(); + + /** + * Initialize application configuration. + */ + defaultConfiguration(); + + /** + * Proxy `connect#use()` to apply settings to + * mounted applications. + **/ + use(route: string, callback?: Function): ExpressApplication; + + use(route: string, server: ExpressApplication): ExpressApplication; + + use(callback: Function): ExpressApplication; + + use(server: ExpressApplication): ExpressApplication; + + /** + * 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): ExpressApplication; + + /** + * 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): ExpressApplication; + + param(name: Array, fn: Function): ExpressApplication; + + /** + * 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): ExpressApplication; + + /** + * 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): bool; + + /** + * Check if `setting` is disabled. + * + * app.disabled('foo') + * // => true + * + * app.enable('foo') + * app.disabled('foo') + * // => false + * + * @param setting + */ + disabled(setting: string): bool; + + /** + * Enable `setting`. + * + * @param setting + */ + enable(setting: string): ExpressApplication; + + /** + * Disable `setting`. + * + * @param setting + */ + disable(setting: string): ExpressApplication; + + /** + * 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): ExpressApplication; + + /** + * 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: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): ExpressApplication; + + /** + * 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: string, fn: Function); + + render(name: string, fn: Function); + + get (name: string): any; + + get (name: string, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + get (name: RegExp): any; + + get (name: RegExp, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + get (name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + post(name: string): any; + + post(name: string, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + post(name: RegExp): any; + + post(name: RegExp, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + post(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + put(name: string): any; + + put(name: string, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + put(name: RegExp): any; + + put(name: RegExp, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + put(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + del(name: string): any; + + del(name: string, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: string, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + del(name: RegExp): any; + + del(name: RegExp, handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any): any; + + del(name: RegExp, + handler: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler2: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler3: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler4: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + handler5: (req: ExpressServerRequest, res: ExpressServerResponse, next: Function) => any, + ...handlers: any[]): any; + + /** + * 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): void; + + listen(port: number, callback: Function): void; + + listen(path: string, callback?: Function): void; + + listen(handle: any, listeningListener?: Function): void; + + render(view: string, callback: (err: Error, html) => void ): void; + + render(view: string, optionss: any, callback: (err: Error, html) => void ): void; + + route: Route; + + router: string; + + settings: any; + + resource: any; + + map: any; +} + +interface Express extends ExpressApplication { + /** + * Framework version. + */ + version: string; + + /** + * Expose mime. + */ + mime: string; + + (): ExpressApplication; + + /** + * Create an express application. + */ + createApplication(): ExpressApplication; + + createServer(): ExpressApplication; + + application: any; + + request: ExpressServerRequest; + + response: ExpressServerResponse; +}