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