| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 | /*! * depd * Copyright(c) 2014-2018 Douglas Christopher Wilson * MIT Licensed *//** * Module dependencies. */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 ' + stack[i].toString()  }  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 event emitter has listeners of a given type. * * The way to do this check is done three different ways in Node.js >= 0.8 * so this consolidates them into a minimal set using instance methods. * * @param {EventEmitter} emitter * @param {string} type * @returns {boolean} * @private */function eehaslisteners (emitter, type) {  var count = typeof emitter.listenerCount !== 'function'    ? emitter.listeners(type).length    : emitter.listenerCount(type)  return count > 0}/** * Determine if namespace is ignored. */function isignored (namespace) {  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) {  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 = eehaslisteners(process, 'deprecation')  // 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 ' + stack[i].toString()    }    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 ' + stack[i].toString() + '\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 stack = getStack()  var site = callSiteLocation(stack[1])  site.name = fn.name  // eslint-disable-next-line no-new-func  var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',    '"use strict"\n' +    'return function (' + args + ') {' +    'log.call(deprecate, message, site)\n' +    'return fn.apply(this, arguments)\n' +    '}')(fn, log, this, message, site)  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}
 |