Initial commit for OpenECOMP SDN-C OA&M
[sdnc/oam.git] / dgbuilder / dgeflows / node_modules / morgan / node_modules / depd / index.js
1 /*!
2  * depd
3  * Copyright(c) 2014 Douglas Christopher Wilson
4  * MIT Licensed
5  */
6
7 /**
8  * Module dependencies.
9  */
10
11 var callSiteToString = require('./lib/compat').callSiteToString
12 var EventEmitter = require('events').EventEmitter
13 var relative = require('path').relative
14
15 /**
16  * Module exports.
17  */
18
19 module.exports = depd
20
21 /**
22  * Get the path to base files on.
23  */
24
25 var basePath = process.cwd()
26
27 /**
28  * Get listener count on event emitter.
29  */
30
31 /*istanbul ignore next*/
32 var 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
39 function 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
60 function 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
82 function 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
96 function 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
114 function 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
144 function 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
161 function 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
178 function 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
259 function 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
280 function defaultMessage(site) {
281   var callSite = site.callSite
282   var funcName = site.name
283   var typeName = callSite.getTypeName()
284
285   // make useful anonymous name
286   if (!funcName) {
287     funcName = '<anonymous@' + formatLocation(site) + '>'
288   }
289
290   // make useful type name
291   if (typeName === 'Function') {
292     typeName = callSite.getThis().name || typeName
293   }
294
295   return callSite.getMethodName()
296     ? typeName + '.' + funcName
297     : funcName
298 }
299
300 /**
301  * Format deprecation message without color.
302  */
303
304 function formatPlain(msg, caller, stack) {
305   var timestamp = new Date().toUTCString()
306
307   var formatted = timestamp
308     + ' ' + this._namespace
309     + ' deprecated ' + msg
310
311   // add stack trace
312   if (this._traced) {
313     for (var i = 0; i < stack.length; i++) {
314       formatted += '\n    at ' + callSiteToString(stack[i])
315     }
316
317     return formatted
318   }
319
320   if (caller) {
321     formatted += ' at ' + formatLocation(caller)
322   }
323
324   return formatted
325 }
326
327 /**
328  * Format deprecation message with color.
329  */
330
331 function formatColor(msg, caller, stack) {
332   var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
333     + ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
334     + ' \x1b[0m' + msg + '\x1b[39m' // reset
335
336   // add stack trace
337   if (this._traced) {
338     for (var i = 0; i < stack.length; i++) {
339       formatted += '\n    \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan
340     }
341
342     return formatted
343   }
344
345   if (caller) {
346     formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
347   }
348
349   return formatted
350 }
351
352 /**
353  * Format call site location.
354  */
355
356 function formatLocation(callSite) {
357   return relative(basePath, callSite[0])
358     + ':' + callSite[1]
359     + ':' + callSite[2]
360 }
361
362 /**
363  * Get the stack as array of call sites.
364  */
365
366 function getStack() {
367   var limit = Error.stackTraceLimit
368   var obj = {}
369   var prep = Error.prepareStackTrace
370
371   Error.prepareStackTrace = prepareObjectStackTrace
372   Error.stackTraceLimit = Math.max(10, limit)
373
374   // capture the stack
375   Error.captureStackTrace(obj)
376
377   // slice this function off the top
378   var stack = obj.stack.slice(1)
379
380   Error.prepareStackTrace = prep
381   Error.stackTraceLimit = limit
382
383   return stack
384 }
385
386 /**
387  * Capture call site stack from v8.
388  */
389
390 function prepareObjectStackTrace(obj, stack) {
391   return stack
392 }
393
394 /**
395  * Return a wrapped function in a deprecation message.
396  */
397
398 function wrapfunction(fn, message) {
399   if (typeof fn !== 'function') {
400     throw new TypeError('argument fn must be a function')
401   }
402
403   var args = createArgumentsString(fn.length)
404   var deprecate = this
405   var stack = getStack()
406   var site = callSiteLocation(stack[1])
407
408   site.name = fn.name
409
410   var deprecatedfn = eval('(function (' + args + ') {\n'
411     + '"use strict"\n'
412     + 'log.call(deprecate, message, site)\n'
413     + 'return fn.apply(this, arguments)\n'
414     + '})')
415
416   return deprecatedfn
417 }
418
419 /**
420  * Wrap property in a deprecation message.
421  */
422
423 function wrapproperty(obj, prop, message) {
424   if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
425     throw new TypeError('argument obj must be object')
426   }
427
428   var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
429
430   if (!descriptor) {
431     throw new TypeError('must call property on owner object')
432   }
433
434   if (!descriptor.configurable) {
435     throw new TypeError('property must be configurable')
436   }
437
438   var deprecate = this
439   var stack = getStack()
440   var site = callSiteLocation(stack[1])
441
442   // set site name
443   site.name = prop
444
445   // convert data descriptor
446   if ('value' in descriptor) {
447     descriptor = convertDataDescriptorToAccessor(obj, prop, message)
448   }
449
450   var get = descriptor.get
451   var set = descriptor.set
452
453   // wrap getter
454   if (typeof get === 'function') {
455     descriptor.get = function getter() {
456       log.call(deprecate, message, site)
457       return get.apply(this, arguments)
458     }
459   }
460
461   // wrap setter
462   if (typeof set === 'function') {
463     descriptor.set = function setter() {
464       log.call(deprecate, message, site)
465       return set.apply(this, arguments)
466     }
467   }
468
469   Object.defineProperty(obj, prop, descriptor)
470 }
471
472 /**
473  * Create DeprecationError for deprecation
474  */
475
476 function DeprecationError(namespace, message, stack) {
477   var error = new Error()
478   var stackString
479
480   Object.defineProperty(error, 'constructor', {
481     value: DeprecationError
482   })
483
484   Object.defineProperty(error, 'message', {
485     configurable: true,
486     enumerable: false,
487     value: message,
488     writable: true
489   })
490
491   Object.defineProperty(error, 'name', {
492     enumerable: false,
493     configurable: true,
494     value: 'DeprecationError',
495     writable: true
496   })
497
498   Object.defineProperty(error, 'namespace', {
499     configurable: true,
500     enumerable: false,
501     value: namespace,
502     writable: true
503   })
504
505   Object.defineProperty(error, 'stack', {
506     configurable: true,
507     enumerable: false,
508     get: function () {
509       if (stackString !== undefined) {
510         return stackString
511       }
512
513       // prepare stack trace
514       return stackString = createStackString.call(this, stack)
515     },
516     set: function setter(val) {
517       stackString = val
518     }
519   })
520
521   return error
522 }