Use let or const to avoid scope issues and hoisting
var { METHODS } = require('node:http');
1/*!2 * express3 * Copyright(c) 2009-2013 TJ Holowaychuk4 * Copyright(c) 2014-2015 Douglas Christopher Wilson5 * MIT Licensed6 */78'use strict';910/**11 * Module dependencies.12 * @api private13 */1415var { METHODS } = require('node:http');16var contentType = require('content-type');17var etag = require('etag');18var mime = require('mime-types')19var proxyaddr = require('proxy-addr');20var qs = require('qs');21var querystring = require('node:querystring');22const { Buffer } = require('node:buffer');232425/**26 * A list of lowercased HTTP methods that are supported by Node.js.27 * @api private28 */29exports.methods = METHODS.map((method) => method.toLowerCase());3031/**32 * Return strong ETag for `body`.33 *34 * @param {String|Buffer} body35 * @param {String} [encoding]36 * @return {String}37 * @api private38 */3940exports.etag = createETagGenerator({ weak: false })4142/**43 * Return weak ETag for `body`.44 *45 * @param {String|Buffer} body46 * @param {String} [encoding]47 * @return {String}48 * @api private49 */5051exports.wetag = createETagGenerator({ weak: true })5253/**54 * Normalize the given `type`, for example "html" becomes "text/html".55 *56 * @param {String} type57 * @return {Object}58 * @api private59 */6061exports.normalizeType = function(type){62 return ~type.indexOf('/')63 ? acceptParams(type)64 : { value: (mime.lookup(type) || 'application/octet-stream'), params: {} }65};6667/**68 * Normalize `types`, for example "html" becomes "text/html".69 *70 * @param {Array} types71 * @return {Array}72 * @api private73 */7475exports.normalizeTypes = function(types) {76 return types.map(exports.normalizeType);77};787980/**81 * Parse accept params `str` returning an82 * object with `.value`, `.quality` and `.params`.83 *84 * @param {String} str85 * @return {Object}86 * @api private87 */8889function acceptParams (str) {90 var length = str.length;91 var colonIndex = str.indexOf(';');92 var index = colonIndex === -1 ? length : colonIndex;93 var ret = { value: str.slice(0, index).trim(), quality: 1, params: {} };9495 while (index < length) {96 var splitIndex = str.indexOf('=', index);97 if (splitIndex === -1) break;9899 var colonIndex = str.indexOf(';', index);100 var endIndex = colonIndex === -1 ? length : colonIndex;101102 if (splitIndex > endIndex) {103 index = str.lastIndexOf(';', splitIndex - 1) + 1;104 continue;105 }106107 var key = str.slice(index, splitIndex).trim();108 var value = str.slice(splitIndex + 1, endIndex).trim();109110 if (key === 'q') {111 ret.quality = parseFloat(value);112 } else {113 ret.params[key] = value;114 }115116 index = endIndex + 1;117 }118119 return ret;120}121122/**123 * Compile "etag" value to function.124 *125 * @param {Boolean|String|Function} val126 * @return {Function}127 * @api private128 */129130exports.compileETag = function(val) {131 var fn;132133 if (typeof val === 'function') {134 return val;135 }136137 switch (val) {138 case true:139 case 'weak':140 fn = exports.wetag;141 break;142 case false:143 break;144 case 'strong':145 fn = exports.etag;146 break;147 default:148 throw new TypeError('unknown value for etag function: ' + val);149 }150151 return fn;152}153154/**155 * Compile "query parser" value to function.156 *157 * @param {String|Function} val158 * @return {Function}159 * @api private160 */161162exports.compileQueryParser = function compileQueryParser(val) {163 var fn;164165 if (typeof val === 'function') {166 return val;167 }168169 switch (val) {170 case true:171 case 'simple':172 fn = querystring.parse;173 break;174 case false:175 break;176 case 'extended':177 fn = parseExtendedQueryString;178 break;179 default:180 throw new TypeError('unknown value for query parser function: ' + val);181 }182183 return fn;184}185186/**187 * Compile "proxy trust" value to function.188 *189 * @param {Boolean|String|Number|Array|Function} val190 * @return {Function}191 * @api private192 */193194exports.compileTrust = function(val) {195 if (typeof val === 'function') return val;196197 if (val === true) {198 // Support plain true/false199 return function(){ return true };200 }201202 if (typeof val === 'number') {203 // Support trusting hop count204 return function(a, i){ return i < val };205 }206207 if (typeof val === 'string') {208 // Support comma-separated values209 val = val.split(',')210 .map(function (v) { return v.trim() })211 }212213 return proxyaddr.compile(val || []);214}215216/**217 * Set the charset in a given Content-Type string.218 *219 * @param {String} type220 * @param {String} charset221 * @return {String}222 * @api private223 */224225exports.setCharset = function setCharset(type, charset) {226 if (!type || !charset) {227 return type;228 }229230 // parse type231 var parsed = contentType.parse(type);232233 // set charset234 parsed.parameters.charset = charset;235236 // format type237 return contentType.format(parsed);238};239240/**241 * Create an ETag generator function, generating ETags with242 * the given options.243 *244 * @param {object} options245 * @return {function}246 * @private247 */248249function createETagGenerator (options) {250 return function generateETag (body, encoding) {251 var buf = !Buffer.isBuffer(body)252 ? Buffer.from(body, encoding)253 : body254255 return etag(buf, options)256 }257}258259/**260 * Parse an extended query string with qs.261 *262 * @param {String} str263 * @return {Object}264 * @private265 */266267function parseExtendedQueryString(str) {268 return qs.parse(str, {269 allowPrototypes: true270 });271}
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.