The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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