arnaucube
arnaucube/socketioMEANseedPublic Self-hosted repository
socketioMEANseed/server/node_modules/depd/index.js
server/node_modules/depd/index.jsRaw
  1/*!
  2 * depd
  3 * Copyright(c) 2014 Douglas Christopher Wilson
  4 * MIT Licensed
  5 */
  6
  7/**
  8 * Module dependencies.
  9 */
 10
 11var callSiteToString = require('./lib/compat').callSiteToString
 12var EventEmitter = require('events').EventEmitter
 13var relative = require('path').relative
 14
 15/**
 16 * Module exports.
 17 */
 18
 19module.exports = depd
 20
 21/**
 22 * Get the path to base files on.
 23 */
 24
 25var basePath = process.cwd()
 26
 27/**
 28 * Get listener count on event emitter.
 29 */
 30
 31/*istanbul ignore next*/
 32var eventListenerCount = EventEmitter.listenerCount
 33  || function (emitter, type) { return emitter.listeners(type).length }
 34
 35/**
 36 * Determine if namespace is contained in the string.
 37 */
 38
 39function containsNamespace(str, namespace) {
 40  var val = str.split(/[ ,]+/)
 41
 42  namespace = String(namespace).toLowerCase()
 43
 44  for (var i = 0 ; i < val.length; i++) {
 45    if (!(str = val[i])) continue;
 46
 47    // namespace contained
 48    if (str === '*' || str.toLowerCase() === namespace) {
 49      return true
 50    }
 51  }
 52
 53  return false
 54}
 55
 56/**
 57 * Convert a data descriptor to accessor descriptor.
 58 */
 59
 60function convertDataDescriptorToAccessor(obj, prop, message) {
 61  var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
 62  var value = descriptor.value
 63
 64  descriptor.get = function getter() { return value }
 65
 66  if (descriptor.writable) {
 67    descriptor.set = function setter(val) { return value = val }
 68  }
 69
 70  delete descriptor.value
 71  delete descriptor.writable
 72
 73  Object.defineProperty(obj, prop, descriptor)
 74
 75  return descriptor
 76}
 77
 78/**
 79 * Create arguments string to keep arity.
 80 */
 81
 82function createArgumentsString(arity) {
 83  var str = ''
 84
 85  for (var i = 0; i < arity; i++) {
 86    str += ', arg' + i
 87  }
 88
 89  return str.substr(2)
 90}
 91
 92/**
 93 * Create stack string from stack.
 94 */
 95
 96function createStackString(stack) {
 97  var str = this.name + ': ' + this.namespace
 98
 99  if (this.message) {
100    str += ' deprecated ' + this.message
101  }
102
103  for (var i = 0; i < stack.length; i++) {
104    str += '\n    at ' + callSiteToString(stack[i])
105  }
106
107  return str
108}
109
110/**
111 * Create deprecate for namespace in caller.
112 */
113
114function depd(namespace) {
115  if (!namespace) {
116    throw new TypeError('argument namespace is required')
117  }
118
119  var stack = getStack()
120  var site = callSiteLocation(stack[1])
121  var file = site[0]
122
123  function deprecate(message) {
124    // call to self as log
125    log.call(deprecate, message)
126  }
127
128  deprecate._file = file
129  deprecate._ignored = isignored(namespace)
130  deprecate._namespace = namespace
131  deprecate._traced = istraced(namespace)
132  deprecate._warned = Object.create(null)
133
134  deprecate.function = wrapfunction
135  deprecate.property = wrapproperty
136
137  return deprecate
138}
139
140/**
141 * Determine if namespace is ignored.
142 */
143
144function isignored(namespace) {
145  /* istanbul ignore next: tested in a child processs */
146  if (process.noDeprecation) {
147    // --no-deprecation support
148    return true
149  }
150
151  var str = process.env.NO_DEPRECATION || ''
152
153  // namespace ignored
154  return containsNamespace(str, namespace)
155}
156
157/**
158 * Determine if namespace is traced.
159 */
160
161function istraced(namespace) {
162  /* istanbul ignore next: tested in a child processs */
163  if (process.traceDeprecation) {
164    // --trace-deprecation support
165    return true
166  }
167
168  var str = process.env.TRACE_DEPRECATION || ''
169
170  // namespace traced
171  return containsNamespace(str, namespace)
172}
173
174/**
175 * Display deprecation message.
176 */
177
178function log(message, site) {
179  var haslisteners = eventListenerCount(process, 'deprecation') !== 0
180
181  // abort early if no destination
182  if (!haslisteners && this._ignored) {
183    return
184  }
185
186  var caller
187  var callFile
188  var callSite
189  var i = 0
190  var seen = false
191  var stack = getStack()
192  var file = this._file
193
194  if (site) {
195    // provided site
196    callSite = callSiteLocation(stack[1])
197    callSite.name = site.name
198    file = callSite[0]
199  } else {
200    // get call site
201    i = 2
202    site = callSiteLocation(stack[i])
203    callSite = site
204  }
205
206  // get caller of deprecated thing in relation to file
207  for (; i < stack.length; i++) {
208    caller = callSiteLocation(stack[i])
209    callFile = caller[0]
210
211    if (callFile === file) {
212      seen = true
213    } else if (callFile === this._file) {
214      file = this._file
215    } else if (seen) {
216      break
217    }
218  }
219
220  var key = caller
221    ? site.join(':') + '__' + caller.join(':')
222    : undefined
223
224  if (key !== undefined && key in this._warned) {
225    // already warned
226    return
227  }
228
229  this._warned[key] = true
230
231  // generate automatic message from call site
232  if (!message) {
233    message = callSite === site || !callSite.name
234      ? defaultMessage(site)
235      : defaultMessage(callSite)
236  }
237
238  // emit deprecation if listeners exist
239  if (haslisteners) {
240    var err = DeprecationError(this._namespace, message, stack.slice(i))
241    process.emit('deprecation', err)
242    return
243  }
244
245  // format and write message
246  var format = process.stderr.isTTY
247    ? formatColor
248    : formatPlain
249  var msg = format.call(this, message, caller, stack.slice(i))
250  process.stderr.write(msg + '\n', 'utf8')
251
252  return
253}
254
255/**
256 * Get call site location as array.
257 */
258
259function callSiteLocation(callSite) {
260  var file = callSite.getFileName() || '<anonymous>'
261  var line = callSite.getLineNumber()
262  var colm = callSite.getColumnNumber()
263
264  if (callSite.isEval()) {
265    file = callSite.getEvalOrigin() + ', ' + file
266  }
267
268  var site = [file, line, colm]
269
270  site.callSite = callSite
271  site.name = callSite.getFunctionName()
272
273  return site
274}
275
276/**
277 * Generate a default message from the site.
278 */
279
280function defaultMessage(site) {
281  var callSite = site.callSite
282  var funcName = site.name
283
284  // make useful anonymous name
285  if (!funcName) {
286    funcName = '<anonymous@' + formatLocation(site) + '>'
287  }
288
289  var context = callSite.getThis()
290  var typeName = context && callSite.getTypeName()
291
292  // ignore useless type name
293  if (typeName === 'Object') {
294    typeName = undefined
295  }
296
297  // make useful type name
298  if (typeName === 'Function') {
299    typeName = context.name || typeName
300  }
301
302  return typeName && callSite.getMethodName()
303    ? typeName + '.' + funcName
304    : funcName
305}
306
307/**
308 * Format deprecation message without color.
309 */
310
311function formatPlain(msg, caller, stack) {
312  var timestamp = new Date().toUTCString()
313
314  var formatted = timestamp
315    + ' ' + this._namespace
316    + ' deprecated ' + msg
317
318  // add stack trace
319  if (this._traced) {
320    for (var i = 0; i < stack.length; i++) {
321      formatted += '\n    at ' + callSiteToString(stack[i])
322    }
323
324    return formatted
325  }
326
327  if (caller) {
328    formatted += ' at ' + formatLocation(caller)
329  }
330
331  return formatted
332}
333
334/**
335 * Format deprecation message with color.
336 */
337
338function formatColor(msg, caller, stack) {
339  var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
340    + ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
341    + ' \x1b[0m' + msg + '\x1b[39m' // reset
342
343  // add stack trace
344  if (this._traced) {
345    for (var i = 0; i < stack.length; i++) {
346      formatted += '\n    \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan
347    }
348
349    return formatted
350  }
351
352  if (caller) {
353    formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
354  }
355
356  return formatted
357}
358
359/**
360 * Format call site location.
361 */
362
363function formatLocation(callSite) {
364  return relative(basePath, callSite[0])
365    + ':' + callSite[1]
366    + ':' + callSite[2]
367}
368
369/**
370 * Get the stack as array of call sites.
371 */
372
373function getStack() {
374  var limit = Error.stackTraceLimit
375  var obj = {}
376  var prep = Error.prepareStackTrace
377
378  Error.prepareStackTrace = prepareObjectStackTrace
379  Error.stackTraceLimit = Math.max(10, limit)
380
381  // capture the stack
382  Error.captureStackTrace(obj)
383
384  // slice this function off the top
385  var stack = obj.stack.slice(1)
386
387  Error.prepareStackTrace = prep
388  Error.stackTraceLimit = limit
389
390  return stack
391}
392
393/**
394 * Capture call site stack from v8.
395 */
396
397function prepareObjectStackTrace(obj, stack) {
398  return stack
399}
400
401/**
402 * Return a wrapped function in a deprecation message.
403 */
404
405function wrapfunction(fn, message) {
406  if (typeof fn !== 'function') {
407    throw new TypeError('argument fn must be a function')
408  }
409
410  var args = createArgumentsString(fn.length)
411  var deprecate = this
412  var stack = getStack()
413  var site = callSiteLocation(stack[1])
414
415  site.name = fn.name
416
417  var deprecatedfn = eval('(function (' + args + ') {\n'
418    + '"use strict"\n'
419    + 'log.call(deprecate, message, site)\n'
420    + 'return fn.apply(this, arguments)\n'
421    + '})')
422
423  return deprecatedfn
424}
425
426/**
427 * Wrap property in a deprecation message.
428 */
429
430function wrapproperty(obj, prop, message) {
431  if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
432    throw new TypeError('argument obj must be object')
433  }
434
435  var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
436
437  if (!descriptor) {
438    throw new TypeError('must call property on owner object')
439  }
440
441  if (!descriptor.configurable) {
442    throw new TypeError('property must be configurable')
443  }
444
445  var deprecate = this
446  var stack = getStack()
447  var site = callSiteLocation(stack[1])
448
449  // set site name
450  site.name = prop
451
452  // convert data descriptor
453  if ('value' in descriptor) {
454    descriptor = convertDataDescriptorToAccessor(obj, prop, message)
455  }
456
457  var get = descriptor.get
458  var set = descriptor.set
459
460  // wrap getter
461  if (typeof get === 'function') {
462    descriptor.get = function getter() {
463      log.call(deprecate, message, site)
464      return get.apply(this, arguments)
465    }
466  }
467
468  // wrap setter
469  if (typeof set === 'function') {
470    descriptor.set = function setter() {
471      log.call(deprecate, message, site)
472      return set.apply(this, arguments)
473    }
474  }
475
476  Object.defineProperty(obj, prop, descriptor)
477}
478
479/**
480 * Create DeprecationError for deprecation
481 */
482
483function DeprecationError(namespace, message, stack) {
484  var error = new Error()
485  var stackString
486
487  Object.defineProperty(error, 'constructor', {
488    value: DeprecationError
489  })
490
491  Object.defineProperty(error, 'message', {
492    configurable: true,
493    enumerable: false,
494    value: message,
495    writable: true
496  })
497
498  Object.defineProperty(error, 'name', {
499    enumerable: false,
500    configurable: true,
501    value: 'DeprecationError',
502    writable: true
503  })
504
505  Object.defineProperty(error, 'namespace', {
506    configurable: true,
507    enumerable: false,
508    value: namespace,
509    writable: true
510  })
511
512  Object.defineProperty(error, 'stack', {
513    configurable: true,
514    enumerable: false,
515    get: function () {
516      if (stackString !== undefined) {
517        return stackString
518      }
519
520      // prepare stack trace
521      return stackString = createStackString.call(this, stack)
522    },
523    set: function setter(val) {
524      stackString = val
525    }
526  })
527
528  return error
529}