mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	main
This commit is contained in:
		
							
								
								
									
										673
									
								
								node_modules/express/lib/router/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										673
									
								
								node_modules/express/lib/router/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,673 @@ | ||||
| /*! | ||||
|  * express | ||||
|  * Copyright(c) 2009-2013 TJ Holowaychuk | ||||
|  * Copyright(c) 2013 Roman Shtylman | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| var Route = require('./route'); | ||||
| var Layer = require('./layer'); | ||||
| var methods = require('methods'); | ||||
| var mixin = require('utils-merge'); | ||||
| var debug = require('debug')('express:router'); | ||||
| var deprecate = require('depd')('express'); | ||||
| var flatten = require('array-flatten'); | ||||
| var parseUrl = require('parseurl'); | ||||
| var setPrototypeOf = require('setprototypeof') | ||||
|  | ||||
| /** | ||||
|  * Module variables. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| var objectRegExp = /^\[object (\S+)\]$/; | ||||
| var slice = Array.prototype.slice; | ||||
| var toString = Object.prototype.toString; | ||||
|  | ||||
| /** | ||||
|  * Initialize a new `Router` with the given `options`. | ||||
|  * | ||||
|  * @param {Object} [options] | ||||
|  * @return {Router} which is an callable function | ||||
|  * @public | ||||
|  */ | ||||
|  | ||||
| var proto = module.exports = function(options) { | ||||
|   var opts = options || {}; | ||||
|  | ||||
|   function router(req, res, next) { | ||||
|     router.handle(req, res, next); | ||||
|   } | ||||
|  | ||||
|   // mixin Router class functions | ||||
|   setPrototypeOf(router, proto) | ||||
|  | ||||
|   router.params = {}; | ||||
|   router._params = []; | ||||
|   router.caseSensitive = opts.caseSensitive; | ||||
|   router.mergeParams = opts.mergeParams; | ||||
|   router.strict = opts.strict; | ||||
|   router.stack = []; | ||||
|  | ||||
|   return router; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Map the given param placeholder `name`(s) to the given callback. | ||||
|  * | ||||
|  * 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 same signature as middleware, the only difference | ||||
|  * 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. | ||||
|  * | ||||
|  * Just like in middleware, you must either respond to the request or call next | ||||
|  * to avoid stalling the request. | ||||
|  * | ||||
|  *  app.param('user_id', function(req, res, next, id){ | ||||
|  *    User.find(id, function(err, user){ | ||||
|  *      if (err) { | ||||
|  *        return next(err); | ||||
|  *      } else if (!user) { | ||||
|  *        return next(new Error('failed to load user')); | ||||
|  *      } | ||||
|  *      req.user = user; | ||||
|  *      next(); | ||||
|  *    }); | ||||
|  *  }); | ||||
|  * | ||||
|  * @param {String} name | ||||
|  * @param {Function} fn | ||||
|  * @return {app} for chaining | ||||
|  * @public | ||||
|  */ | ||||
|  | ||||
| proto.param = function param(name, fn) { | ||||
|   // param logic | ||||
|   if (typeof name === 'function') { | ||||
|     deprecate('router.param(fn): Refactor to use path params'); | ||||
|     this._params.push(name); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // apply param functions | ||||
|   var params = this._params; | ||||
|   var len = params.length; | ||||
|   var ret; | ||||
|  | ||||
|   if (name[0] === ':') { | ||||
|     deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.slice(1)) + ', fn) instead') | ||||
|     name = name.slice(1) | ||||
|   } | ||||
|  | ||||
|   for (var i = 0; i < len; ++i) { | ||||
|     if (ret = params[i](name, fn)) { | ||||
|       fn = ret; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // ensure we end up with a | ||||
|   // middleware function | ||||
|   if ('function' !== typeof fn) { | ||||
|     throw new Error('invalid param() call for ' + name + ', got ' + fn); | ||||
|   } | ||||
|  | ||||
|   (this.params[name] = this.params[name] || []).push(fn); | ||||
|   return this; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Dispatch a req, res into the router. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| proto.handle = function handle(req, res, out) { | ||||
|   var self = this; | ||||
|  | ||||
|   debug('dispatching %s %s', req.method, req.url); | ||||
|  | ||||
|   var idx = 0; | ||||
|   var protohost = getProtohost(req.url) || '' | ||||
|   var removed = ''; | ||||
|   var slashAdded = false; | ||||
|   var sync = 0 | ||||
|   var paramcalled = {}; | ||||
|  | ||||
|   // store options for OPTIONS request | ||||
|   // only used if OPTIONS request | ||||
|   var options = []; | ||||
|  | ||||
|   // middleware and routes | ||||
|   var stack = self.stack; | ||||
|  | ||||
|   // manage inter-router variables | ||||
|   var parentParams = req.params; | ||||
|   var parentUrl = req.baseUrl || ''; | ||||
|   var done = restore(out, req, 'baseUrl', 'next', 'params'); | ||||
|  | ||||
|   // setup next layer | ||||
|   req.next = next; | ||||
|  | ||||
|   // for options requests, respond with a default if nothing else responds | ||||
|   if (req.method === 'OPTIONS') { | ||||
|     done = wrap(done, function(old, err) { | ||||
|       if (err || options.length === 0) return old(err); | ||||
|       sendOptionsResponse(res, options, old); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   // setup basic req values | ||||
|   req.baseUrl = parentUrl; | ||||
|   req.originalUrl = req.originalUrl || req.url; | ||||
|  | ||||
|   next(); | ||||
|  | ||||
|   function next(err) { | ||||
|     var layerError = err === 'route' | ||||
|       ? null | ||||
|       : err; | ||||
|  | ||||
|     // remove added slash | ||||
|     if (slashAdded) { | ||||
|       req.url = req.url.slice(1) | ||||
|       slashAdded = false; | ||||
|     } | ||||
|  | ||||
|     // restore altered req.url | ||||
|     if (removed.length !== 0) { | ||||
|       req.baseUrl = parentUrl; | ||||
|       req.url = protohost + removed + req.url.slice(protohost.length) | ||||
|       removed = ''; | ||||
|     } | ||||
|  | ||||
|     // signal to exit router | ||||
|     if (layerError === 'router') { | ||||
|       setImmediate(done, null) | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // no more matching layers | ||||
|     if (idx >= stack.length) { | ||||
|       setImmediate(done, layerError); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     // max sync stack | ||||
|     if (++sync > 100) { | ||||
|       return setImmediate(next, err) | ||||
|     } | ||||
|  | ||||
|     // get pathname of request | ||||
|     var path = getPathname(req); | ||||
|  | ||||
|     if (path == null) { | ||||
|       return done(layerError); | ||||
|     } | ||||
|  | ||||
|     // find next matching layer | ||||
|     var layer; | ||||
|     var match; | ||||
|     var route; | ||||
|  | ||||
|     while (match !== true && idx < stack.length) { | ||||
|       layer = stack[idx++]; | ||||
|       match = matchLayer(layer, path); | ||||
|       route = layer.route; | ||||
|  | ||||
|       if (typeof match !== 'boolean') { | ||||
|         // hold on to layerError | ||||
|         layerError = layerError || match; | ||||
|       } | ||||
|  | ||||
|       if (match !== true) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       if (!route) { | ||||
|         // process non-route handlers normally | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       if (layerError) { | ||||
|         // routes do not match with a pending error | ||||
|         match = false; | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       var method = req.method; | ||||
|       var has_method = route._handles_method(method); | ||||
|  | ||||
|       // build up automatic options response | ||||
|       if (!has_method && method === 'OPTIONS') { | ||||
|         appendMethods(options, route._options()); | ||||
|       } | ||||
|  | ||||
|       // don't even bother matching route | ||||
|       if (!has_method && method !== 'HEAD') { | ||||
|         match = false; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // no match | ||||
|     if (match !== true) { | ||||
|       return done(layerError); | ||||
|     } | ||||
|  | ||||
|     // store route for dispatch on change | ||||
|     if (route) { | ||||
|       req.route = route; | ||||
|     } | ||||
|  | ||||
|     // Capture one-time layer values | ||||
|     req.params = self.mergeParams | ||||
|       ? mergeParams(layer.params, parentParams) | ||||
|       : layer.params; | ||||
|     var layerPath = layer.path; | ||||
|  | ||||
|     // this should be done for the layer | ||||
|     self.process_params(layer, paramcalled, req, res, function (err) { | ||||
|       if (err) { | ||||
|         next(layerError || err) | ||||
|       } else if (route) { | ||||
|         layer.handle_request(req, res, next) | ||||
|       } else { | ||||
|         trim_prefix(layer, layerError, layerPath, path) | ||||
|       } | ||||
|  | ||||
|       sync = 0 | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   function trim_prefix(layer, layerError, layerPath, path) { | ||||
|     if (layerPath.length !== 0) { | ||||
|       // Validate path is a prefix match | ||||
|       if (layerPath !== path.slice(0, layerPath.length)) { | ||||
|         next(layerError) | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       // Validate path breaks on a path separator | ||||
|       var c = path[layerPath.length] | ||||
|       if (c && c !== '/' && c !== '.') return next(layerError) | ||||
|  | ||||
|       // Trim off the part of the url that matches the route | ||||
|       // middleware (.use stuff) needs to have the path stripped | ||||
|       debug('trim prefix (%s) from url %s', layerPath, req.url); | ||||
|       removed = layerPath; | ||||
|       req.url = protohost + req.url.slice(protohost.length + removed.length) | ||||
|  | ||||
|       // Ensure leading slash | ||||
|       if (!protohost && req.url[0] !== '/') { | ||||
|         req.url = '/' + req.url; | ||||
|         slashAdded = true; | ||||
|       } | ||||
|  | ||||
|       // Setup base URL (no trailing slash) | ||||
|       req.baseUrl = parentUrl + (removed[removed.length - 1] === '/' | ||||
|         ? removed.substring(0, removed.length - 1) | ||||
|         : removed); | ||||
|     } | ||||
|  | ||||
|     debug('%s %s : %s', layer.name, layerPath, req.originalUrl); | ||||
|  | ||||
|     if (layerError) { | ||||
|       layer.handle_error(layerError, req, res, next); | ||||
|     } else { | ||||
|       layer.handle_request(req, res, next); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Process any parameters for the layer. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| proto.process_params = function process_params(layer, called, req, res, done) { | ||||
|   var params = this.params; | ||||
|  | ||||
|   // captured parameters from the layer, keys and values | ||||
|   var keys = layer.keys; | ||||
|  | ||||
|   // fast track | ||||
|   if (!keys || keys.length === 0) { | ||||
|     return done(); | ||||
|   } | ||||
|  | ||||
|   var i = 0; | ||||
|   var name; | ||||
|   var paramIndex = 0; | ||||
|   var key; | ||||
|   var paramVal; | ||||
|   var paramCallbacks; | ||||
|   var paramCalled; | ||||
|  | ||||
|   // process params in order | ||||
|   // param callbacks can be async | ||||
|   function param(err) { | ||||
|     if (err) { | ||||
|       return done(err); | ||||
|     } | ||||
|  | ||||
|     if (i >= keys.length ) { | ||||
|       return done(); | ||||
|     } | ||||
|  | ||||
|     paramIndex = 0; | ||||
|     key = keys[i++]; | ||||
|     name = key.name; | ||||
|     paramVal = req.params[name]; | ||||
|     paramCallbacks = params[name]; | ||||
|     paramCalled = called[name]; | ||||
|  | ||||
|     if (paramVal === undefined || !paramCallbacks) { | ||||
|       return param(); | ||||
|     } | ||||
|  | ||||
|     // param previously called with same value or error occurred | ||||
|     if (paramCalled && (paramCalled.match === paramVal | ||||
|       || (paramCalled.error && paramCalled.error !== 'route'))) { | ||||
|       // restore value | ||||
|       req.params[name] = paramCalled.value; | ||||
|  | ||||
|       // next param | ||||
|       return param(paramCalled.error); | ||||
|     } | ||||
|  | ||||
|     called[name] = paramCalled = { | ||||
|       error: null, | ||||
|       match: paramVal, | ||||
|       value: paramVal | ||||
|     }; | ||||
|  | ||||
|     paramCallback(); | ||||
|   } | ||||
|  | ||||
|   // single param callbacks | ||||
|   function paramCallback(err) { | ||||
|     var fn = paramCallbacks[paramIndex++]; | ||||
|  | ||||
|     // store updated value | ||||
|     paramCalled.value = req.params[key.name]; | ||||
|  | ||||
|     if (err) { | ||||
|       // store error | ||||
|       paramCalled.error = err; | ||||
|       param(err); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     if (!fn) return param(); | ||||
|  | ||||
|     try { | ||||
|       fn(req, res, paramCallback, paramVal, key.name); | ||||
|     } catch (e) { | ||||
|       paramCallback(e); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   param(); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Use the given middleware function, with optional path, defaulting to "/". | ||||
|  * | ||||
|  * Use (like `.all`) will run for any http METHOD, but it will not add | ||||
|  * handlers for those methods so OPTIONS requests will not consider `.use` | ||||
|  * functions even if they could respond. | ||||
|  * | ||||
|  * The other difference is that _route_ path is stripped and not visible | ||||
|  * to the handler function. The main effect of this feature is that mounted | ||||
|  * handlers can operate without any code changes regardless of the "prefix" | ||||
|  * pathname. | ||||
|  * | ||||
|  * @public | ||||
|  */ | ||||
|  | ||||
| proto.use = function use(fn) { | ||||
|   var offset = 0; | ||||
|   var path = '/'; | ||||
|  | ||||
|   // default path to '/' | ||||
|   // disambiguate router.use([fn]) | ||||
|   if (typeof fn !== 'function') { | ||||
|     var arg = fn; | ||||
|  | ||||
|     while (Array.isArray(arg) && arg.length !== 0) { | ||||
|       arg = arg[0]; | ||||
|     } | ||||
|  | ||||
|     // first arg is the path | ||||
|     if (typeof arg !== 'function') { | ||||
|       offset = 1; | ||||
|       path = fn; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   var callbacks = flatten(slice.call(arguments, offset)); | ||||
|  | ||||
|   if (callbacks.length === 0) { | ||||
|     throw new TypeError('Router.use() requires a middleware function') | ||||
|   } | ||||
|  | ||||
|   for (var i = 0; i < callbacks.length; i++) { | ||||
|     var fn = callbacks[i]; | ||||
|  | ||||
|     if (typeof fn !== 'function') { | ||||
|       throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn)) | ||||
|     } | ||||
|  | ||||
|     // add the middleware | ||||
|     debug('use %o %s', path, fn.name || '<anonymous>') | ||||
|  | ||||
|     var layer = new Layer(path, { | ||||
|       sensitive: this.caseSensitive, | ||||
|       strict: false, | ||||
|       end: false | ||||
|     }, fn); | ||||
|  | ||||
|     layer.route = undefined; | ||||
|  | ||||
|     this.stack.push(layer); | ||||
|   } | ||||
|  | ||||
|   return this; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Create a new Route for the given path. | ||||
|  * | ||||
|  * Each route contains a separate middleware stack and VERB handlers. | ||||
|  * | ||||
|  * See the Route api documentation for details on adding handlers | ||||
|  * and middleware to routes. | ||||
|  * | ||||
|  * @param {String} path | ||||
|  * @return {Route} | ||||
|  * @public | ||||
|  */ | ||||
|  | ||||
| proto.route = function route(path) { | ||||
|   var route = new Route(path); | ||||
|  | ||||
|   var layer = new Layer(path, { | ||||
|     sensitive: this.caseSensitive, | ||||
|     strict: this.strict, | ||||
|     end: true | ||||
|   }, route.dispatch.bind(route)); | ||||
|  | ||||
|   layer.route = route; | ||||
|  | ||||
|   this.stack.push(layer); | ||||
|   return route; | ||||
| }; | ||||
|  | ||||
| // create Router#VERB functions | ||||
| methods.concat('all').forEach(function(method){ | ||||
|   proto[method] = function(path){ | ||||
|     var route = this.route(path) | ||||
|     route[method].apply(route, slice.call(arguments, 1)); | ||||
|     return this; | ||||
|   }; | ||||
| }); | ||||
|  | ||||
| // append methods to a list of methods | ||||
| function appendMethods(list, addition) { | ||||
|   for (var i = 0; i < addition.length; i++) { | ||||
|     var method = addition[i]; | ||||
|     if (list.indexOf(method) === -1) { | ||||
|       list.push(method); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| // get pathname of request | ||||
| function getPathname(req) { | ||||
|   try { | ||||
|     return parseUrl(req).pathname; | ||||
|   } catch (err) { | ||||
|     return undefined; | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Get get protocol + host for a URL | ||||
| function getProtohost(url) { | ||||
|   if (typeof url !== 'string' || url.length === 0 || url[0] === '/') { | ||||
|     return undefined | ||||
|   } | ||||
|  | ||||
|   var searchIndex = url.indexOf('?') | ||||
|   var pathLength = searchIndex !== -1 | ||||
|     ? searchIndex | ||||
|     : url.length | ||||
|   var fqdnIndex = url.slice(0, pathLength).indexOf('://') | ||||
|  | ||||
|   return fqdnIndex !== -1 | ||||
|     ? url.substring(0, url.indexOf('/', 3 + fqdnIndex)) | ||||
|     : undefined | ||||
| } | ||||
|  | ||||
| // get type for error message | ||||
| function gettype(obj) { | ||||
|   var type = typeof obj; | ||||
|  | ||||
|   if (type !== 'object') { | ||||
|     return type; | ||||
|   } | ||||
|  | ||||
|   // inspect [[Class]] for objects | ||||
|   return toString.call(obj) | ||||
|     .replace(objectRegExp, '$1'); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Match path to a layer. | ||||
|  * | ||||
|  * @param {Layer} layer | ||||
|  * @param {string} path | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| function matchLayer(layer, path) { | ||||
|   try { | ||||
|     return layer.match(path); | ||||
|   } catch (err) { | ||||
|     return err; | ||||
|   } | ||||
| } | ||||
|  | ||||
| // merge params with parent params | ||||
| function mergeParams(params, parent) { | ||||
|   if (typeof parent !== 'object' || !parent) { | ||||
|     return params; | ||||
|   } | ||||
|  | ||||
|   // make copy of parent for base | ||||
|   var obj = mixin({}, parent); | ||||
|  | ||||
|   // simple non-numeric merging | ||||
|   if (!(0 in params) || !(0 in parent)) { | ||||
|     return mixin(obj, params); | ||||
|   } | ||||
|  | ||||
|   var i = 0; | ||||
|   var o = 0; | ||||
|  | ||||
|   // determine numeric gaps | ||||
|   while (i in params) { | ||||
|     i++; | ||||
|   } | ||||
|  | ||||
|   while (o in parent) { | ||||
|     o++; | ||||
|   } | ||||
|  | ||||
|   // offset numeric indices in params before merge | ||||
|   for (i--; i >= 0; i--) { | ||||
|     params[i + o] = params[i]; | ||||
|  | ||||
|     // create holes for the merge when necessary | ||||
|     if (i < o) { | ||||
|       delete params[i]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return mixin(obj, params); | ||||
| } | ||||
|  | ||||
| // restore obj props after function | ||||
| function restore(fn, obj) { | ||||
|   var props = new Array(arguments.length - 2); | ||||
|   var vals = new Array(arguments.length - 2); | ||||
|  | ||||
|   for (var i = 0; i < props.length; i++) { | ||||
|     props[i] = arguments[i + 2]; | ||||
|     vals[i] = obj[props[i]]; | ||||
|   } | ||||
|  | ||||
|   return function () { | ||||
|     // restore vals | ||||
|     for (var i = 0; i < props.length; i++) { | ||||
|       obj[props[i]] = vals[i]; | ||||
|     } | ||||
|  | ||||
|     return fn.apply(this, arguments); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| // send an OPTIONS response | ||||
| function sendOptionsResponse(res, options, next) { | ||||
|   try { | ||||
|     var body = options.join(','); | ||||
|     res.set('Allow', body); | ||||
|     res.send(body); | ||||
|   } catch (err) { | ||||
|     next(err); | ||||
|   } | ||||
| } | ||||
|  | ||||
| // wrap a function | ||||
| function wrap(old, fn) { | ||||
|   return function proxy() { | ||||
|     var args = new Array(arguments.length + 1); | ||||
|  | ||||
|     args[0] = old; | ||||
|     for (var i = 0, len = arguments.length; i < len; i++) { | ||||
|       args[i + 1] = arguments[i]; | ||||
|     } | ||||
|  | ||||
|     fn.apply(this, args); | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										181
									
								
								node_modules/express/lib/router/layer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								node_modules/express/lib/router/layer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | ||||
| /*! | ||||
|  * express | ||||
|  * Copyright(c) 2009-2013 TJ Holowaychuk | ||||
|  * Copyright(c) 2013 Roman Shtylman | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| var pathRegexp = require('path-to-regexp'); | ||||
| var debug = require('debug')('express:router:layer'); | ||||
|  | ||||
| /** | ||||
|  * Module variables. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| var hasOwnProperty = Object.prototype.hasOwnProperty; | ||||
|  | ||||
| /** | ||||
|  * Module exports. | ||||
|  * @public | ||||
|  */ | ||||
|  | ||||
| module.exports = Layer; | ||||
|  | ||||
| function Layer(path, options, fn) { | ||||
|   if (!(this instanceof Layer)) { | ||||
|     return new Layer(path, options, fn); | ||||
|   } | ||||
|  | ||||
|   debug('new %o', path) | ||||
|   var opts = options || {}; | ||||
|  | ||||
|   this.handle = fn; | ||||
|   this.name = fn.name || '<anonymous>'; | ||||
|   this.params = undefined; | ||||
|   this.path = undefined; | ||||
|   this.regexp = pathRegexp(path, this.keys = [], opts); | ||||
|  | ||||
|   // set fast path flags | ||||
|   this.regexp.fast_star = path === '*' | ||||
|   this.regexp.fast_slash = path === '/' && opts.end === false | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Handle the error for the layer. | ||||
|  * | ||||
|  * @param {Error} error | ||||
|  * @param {Request} req | ||||
|  * @param {Response} res | ||||
|  * @param {function} next | ||||
|  * @api private | ||||
|  */ | ||||
|  | ||||
| Layer.prototype.handle_error = function handle_error(error, req, res, next) { | ||||
|   var fn = this.handle; | ||||
|  | ||||
|   if (fn.length !== 4) { | ||||
|     // not a standard error handler | ||||
|     return next(error); | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     fn(error, req, res, next); | ||||
|   } catch (err) { | ||||
|     next(err); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Handle the request for the layer. | ||||
|  * | ||||
|  * @param {Request} req | ||||
|  * @param {Response} res | ||||
|  * @param {function} next | ||||
|  * @api private | ||||
|  */ | ||||
|  | ||||
| Layer.prototype.handle_request = function handle(req, res, next) { | ||||
|   var fn = this.handle; | ||||
|  | ||||
|   if (fn.length > 3) { | ||||
|     // not a standard request handler | ||||
|     return next(); | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     fn(req, res, next); | ||||
|   } catch (err) { | ||||
|     next(err); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Check if this route matches `path`, if so | ||||
|  * populate `.params`. | ||||
|  * | ||||
|  * @param {String} path | ||||
|  * @return {Boolean} | ||||
|  * @api private | ||||
|  */ | ||||
|  | ||||
| Layer.prototype.match = function match(path) { | ||||
|   var match | ||||
|  | ||||
|   if (path != null) { | ||||
|     // fast path non-ending match for / (any path matches) | ||||
|     if (this.regexp.fast_slash) { | ||||
|       this.params = {} | ||||
|       this.path = '' | ||||
|       return true | ||||
|     } | ||||
|  | ||||
|     // fast path for * (everything matched in a param) | ||||
|     if (this.regexp.fast_star) { | ||||
|       this.params = {'0': decode_param(path)} | ||||
|       this.path = path | ||||
|       return true | ||||
|     } | ||||
|  | ||||
|     // match the path | ||||
|     match = this.regexp.exec(path) | ||||
|   } | ||||
|  | ||||
|   if (!match) { | ||||
|     this.params = undefined; | ||||
|     this.path = undefined; | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // store values | ||||
|   this.params = {}; | ||||
|   this.path = match[0] | ||||
|  | ||||
|   var keys = this.keys; | ||||
|   var params = this.params; | ||||
|  | ||||
|   for (var i = 1; i < match.length; i++) { | ||||
|     var key = keys[i - 1]; | ||||
|     var prop = key.name; | ||||
|     var val = decode_param(match[i]) | ||||
|  | ||||
|     if (val !== undefined || !(hasOwnProperty.call(params, prop))) { | ||||
|       params[prop] = val; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Decode param value. | ||||
|  * | ||||
|  * @param {string} val | ||||
|  * @return {string} | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| function decode_param(val) { | ||||
|   if (typeof val !== 'string' || val.length === 0) { | ||||
|     return val; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     return decodeURIComponent(val); | ||||
|   } catch (err) { | ||||
|     if (err instanceof URIError) { | ||||
|       err.message = 'Failed to decode param \'' + val + '\''; | ||||
|       err.status = err.statusCode = 400; | ||||
|     } | ||||
|  | ||||
|     throw err; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										225
									
								
								node_modules/express/lib/router/route.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								node_modules/express/lib/router/route.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,225 @@ | ||||
| /*! | ||||
|  * express | ||||
|  * Copyright(c) 2009-2013 TJ Holowaychuk | ||||
|  * Copyright(c) 2013 Roman Shtylman | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| var debug = require('debug')('express:router:route'); | ||||
| var flatten = require('array-flatten'); | ||||
| var Layer = require('./layer'); | ||||
| var methods = require('methods'); | ||||
|  | ||||
| /** | ||||
|  * Module variables. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| var slice = Array.prototype.slice; | ||||
| var toString = Object.prototype.toString; | ||||
|  | ||||
| /** | ||||
|  * Module exports. | ||||
|  * @public | ||||
|  */ | ||||
|  | ||||
| module.exports = Route; | ||||
|  | ||||
| /** | ||||
|  * Initialize `Route` with the given `path`, | ||||
|  * | ||||
|  * @param {String} path | ||||
|  * @public | ||||
|  */ | ||||
|  | ||||
| function Route(path) { | ||||
|   this.path = path; | ||||
|   this.stack = []; | ||||
|  | ||||
|   debug('new %o', path) | ||||
|  | ||||
|   // route handlers for various http methods | ||||
|   this.methods = {}; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Determine if the route handles a given method. | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| Route.prototype._handles_method = function _handles_method(method) { | ||||
|   if (this.methods._all) { | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   var name = method.toLowerCase(); | ||||
|  | ||||
|   if (name === 'head' && !this.methods['head']) { | ||||
|     name = 'get'; | ||||
|   } | ||||
|  | ||||
|   return Boolean(this.methods[name]); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * @return {Array} supported HTTP methods | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| Route.prototype._options = function _options() { | ||||
|   var methods = Object.keys(this.methods); | ||||
|  | ||||
|   // append automatic head | ||||
|   if (this.methods.get && !this.methods.head) { | ||||
|     methods.push('head'); | ||||
|   } | ||||
|  | ||||
|   for (var i = 0; i < methods.length; i++) { | ||||
|     // make upper case | ||||
|     methods[i] = methods[i].toUpperCase(); | ||||
|   } | ||||
|  | ||||
|   return methods; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * dispatch req, res into this route | ||||
|  * @private | ||||
|  */ | ||||
|  | ||||
| Route.prototype.dispatch = function dispatch(req, res, done) { | ||||
|   var idx = 0; | ||||
|   var stack = this.stack; | ||||
|   var sync = 0 | ||||
|  | ||||
|   if (stack.length === 0) { | ||||
|     return done(); | ||||
|   } | ||||
|  | ||||
|   var method = req.method.toLowerCase(); | ||||
|   if (method === 'head' && !this.methods['head']) { | ||||
|     method = 'get'; | ||||
|   } | ||||
|  | ||||
|   req.route = this; | ||||
|  | ||||
|   next(); | ||||
|  | ||||
|   function next(err) { | ||||
|     // signal to exit route | ||||
|     if (err && err === 'route') { | ||||
|       return done(); | ||||
|     } | ||||
|  | ||||
|     // signal to exit router | ||||
|     if (err && err === 'router') { | ||||
|       return done(err) | ||||
|     } | ||||
|  | ||||
|     // max sync stack | ||||
|     if (++sync > 100) { | ||||
|       return setImmediate(next, err) | ||||
|     } | ||||
|  | ||||
|     var layer = stack[idx++] | ||||
|  | ||||
|     // end of layers | ||||
|     if (!layer) { | ||||
|       return done(err) | ||||
|     } | ||||
|  | ||||
|     if (layer.method && layer.method !== method) { | ||||
|       next(err) | ||||
|     } else if (err) { | ||||
|       layer.handle_error(err, req, res, next); | ||||
|     } else { | ||||
|       layer.handle_request(req, res, next); | ||||
|     } | ||||
|  | ||||
|     sync = 0 | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Add a handler for all HTTP verbs to this route. | ||||
|  * | ||||
|  * Behaves just like middleware and can respond or call `next` | ||||
|  * to continue processing. | ||||
|  * | ||||
|  * You can use multiple `.all` call to add multiple handlers. | ||||
|  * | ||||
|  *   function check_something(req, res, next){ | ||||
|  *     next(); | ||||
|  *   }; | ||||
|  * | ||||
|  *   function validate_user(req, res, next){ | ||||
|  *     next(); | ||||
|  *   }; | ||||
|  * | ||||
|  *   route | ||||
|  *   .all(validate_user) | ||||
|  *   .all(check_something) | ||||
|  *   .get(function(req, res, next){ | ||||
|  *     res.send('hello world'); | ||||
|  *   }); | ||||
|  * | ||||
|  * @param {function} handler | ||||
|  * @return {Route} for chaining | ||||
|  * @api public | ||||
|  */ | ||||
|  | ||||
| Route.prototype.all = function all() { | ||||
|   var handles = flatten(slice.call(arguments)); | ||||
|  | ||||
|   for (var i = 0; i < handles.length; i++) { | ||||
|     var handle = handles[i]; | ||||
|  | ||||
|     if (typeof handle !== 'function') { | ||||
|       var type = toString.call(handle); | ||||
|       var msg = 'Route.all() requires a callback function but got a ' + type | ||||
|       throw new TypeError(msg); | ||||
|     } | ||||
|  | ||||
|     var layer = Layer('/', {}, handle); | ||||
|     layer.method = undefined; | ||||
|  | ||||
|     this.methods._all = true; | ||||
|     this.stack.push(layer); | ||||
|   } | ||||
|  | ||||
|   return this; | ||||
| }; | ||||
|  | ||||
| methods.forEach(function(method){ | ||||
|   Route.prototype[method] = function(){ | ||||
|     var handles = flatten(slice.call(arguments)); | ||||
|  | ||||
|     for (var i = 0; i < handles.length; i++) { | ||||
|       var handle = handles[i]; | ||||
|  | ||||
|       if (typeof handle !== 'function') { | ||||
|         var type = toString.call(handle); | ||||
|         var msg = 'Route.' + method + '() requires a callback function but got a ' + type | ||||
|         throw new Error(msg); | ||||
|       } | ||||
|  | ||||
|       debug('%s %o', method, this.path) | ||||
|  | ||||
|       var layer = Layer('/', {}, handle); | ||||
|       layer.method = method; | ||||
|  | ||||
|       this.methods[method] = true; | ||||
|       this.stack.push(layer); | ||||
|     } | ||||
|  | ||||
|     return this; | ||||
|   }; | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user