newrelic 8.3.0 → 8.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/NEWS.md +76 -0
  2. package/README.md +7 -6
  3. package/THIRD_PARTY_NOTICES.md +95 -35
  4. package/api.js +74 -68
  5. package/bin/test-naming-rules.js +22 -22
  6. package/lib/agent.js +4 -4
  7. package/lib/attributes.js +2 -2
  8. package/lib/collector/api.js +12 -12
  9. package/lib/collector/facts.js +1 -1
  10. package/lib/collector/http-agents.js +12 -11
  11. package/lib/collector/key-parser.js +1 -1
  12. package/lib/collector/remote-method.js +27 -26
  13. package/lib/config/attribute-filter.js +23 -23
  14. package/lib/config/default.js +12 -10
  15. package/lib/config/hsm.js +1 -1
  16. package/lib/config/index.js +82 -66
  17. package/lib/config/lasp.js +3 -3
  18. package/lib/config/merge-server-config.js +1 -1
  19. package/lib/db/parse-sql.js +8 -8
  20. package/lib/db/parsed-statement.js +9 -8
  21. package/lib/db/query-parsers/sql.js +7 -7
  22. package/lib/db/query-sample.js +9 -9
  23. package/lib/db/query-trace-aggregator.js +4 -4
  24. package/lib/db/statement-matcher.js +5 -5
  25. package/lib/db/utils.js +1 -1
  26. package/lib/environment.js +43 -43
  27. package/lib/errors/error-collector.js +2 -2
  28. package/lib/errors/error-trace-aggregator.js +1 -1
  29. package/lib/errors/helper.js +3 -3
  30. package/lib/errors/index.js +17 -17
  31. package/lib/feature_flags.js +7 -5
  32. package/lib/header-attributes.js +6 -6
  33. package/lib/header-processing.js +1 -1
  34. package/lib/instrumentation/amqplib.js +26 -26
  35. package/lib/instrumentation/bluebird.js +3 -3
  36. package/lib/instrumentation/cassandra-driver.js +7 -3
  37. package/lib/instrumentation/connect.js +4 -4
  38. package/lib/instrumentation/core/async_hooks.js +6 -6
  39. package/lib/instrumentation/core/domain.js +2 -2
  40. package/lib/instrumentation/core/globals.js +1 -1
  41. package/lib/instrumentation/core/http-outbound.js +15 -84
  42. package/lib/instrumentation/core/http.js +34 -67
  43. package/lib/instrumentation/core/inspector.js +2 -2
  44. package/lib/instrumentation/core/timers.js +7 -7
  45. package/lib/instrumentation/core/zlib.js +2 -2
  46. package/lib/instrumentation/director.js +4 -4
  47. package/lib/instrumentation/express.js +8 -8
  48. package/lib/instrumentation/fastify/spec-builders.js +57 -47
  49. package/lib/instrumentation/fastify.js +85 -24
  50. package/lib/instrumentation/generic-pool.js +1 -1
  51. package/lib/instrumentation/hapi/hapi-17.js +11 -11
  52. package/lib/instrumentation/hapi/shared.js +1 -1
  53. package/lib/instrumentation/hapi.js +22 -22
  54. package/lib/instrumentation/ioredis.js +7 -7
  55. package/lib/instrumentation/memcached.js +7 -7
  56. package/lib/instrumentation/mongodb/common.js +16 -5
  57. package/lib/instrumentation/mysql.js +19 -19
  58. package/lib/instrumentation/oracle.js +15 -15
  59. package/lib/instrumentation/pg.js +4 -4
  60. package/lib/instrumentation/promise.js +46 -46
  61. package/lib/instrumentation/q.js +2 -2
  62. package/lib/instrumentation/redis.js +11 -11
  63. package/lib/instrumentation/restify.js +1 -1
  64. package/lib/instrumentation/undici.js +242 -0
  65. package/lib/instrumentation/vision.js +4 -4
  66. package/lib/instrumentation/when.js +3 -3
  67. package/lib/instrumentations.js +2 -1
  68. package/lib/logger.js +5 -5
  69. package/lib/metrics/index.js +15 -15
  70. package/lib/metrics/mapper.js +7 -7
  71. package/lib/metrics/normalizer/rule.js +9 -9
  72. package/lib/metrics/normalizer/tx_segment.js +17 -17
  73. package/lib/metrics/normalizer.js +22 -22
  74. package/lib/metrics/recorders/custom.js +5 -5
  75. package/lib/metrics/recorders/generic.js +3 -3
  76. package/lib/metrics/recorders/http.js +7 -7
  77. package/lib/metrics/recorders/http_external.js +7 -7
  78. package/lib/metrics/recorders/message-transaction.js +5 -6
  79. package/lib/metrics/recorders/other.js +5 -5
  80. package/lib/parse-proc-cpuinfo.js +25 -19
  81. package/lib/parse-proc-meminfo.js +8 -2
  82. package/lib/prioritized-attributes.js +2 -2
  83. package/lib/priority-queue.js +10 -10
  84. package/lib/reservoir.js +3 -3
  85. package/lib/sampler.js +26 -26
  86. package/lib/serverless/aws-lambda.js +8 -2
  87. package/lib/shim/datastore-shim.js +35 -32
  88. package/lib/shim/index.js +2 -2
  89. package/lib/shim/message-shim.js +47 -47
  90. package/lib/shim/promise-shim.js +1 -1
  91. package/lib/shim/shim.js +61 -61
  92. package/lib/shim/specs/index.js +3 -3
  93. package/lib/shim/transaction-shim.js +44 -192
  94. package/lib/shim/webframework-shim.js +52 -52
  95. package/lib/spans/span-event.js +1 -1
  96. package/lib/spans/streaming-span-attributes.js +1 -1
  97. package/lib/stats/apdex.js +2 -2
  98. package/lib/stats/index.js +2 -2
  99. package/lib/system-info.js +23 -23
  100. package/lib/timer.js +5 -5
  101. package/lib/transaction/dt-payload.js +1 -1
  102. package/lib/transaction/index.js +40 -40
  103. package/lib/transaction/name-state.js +14 -14
  104. package/lib/transaction/trace/exclusive-time-calculator.js +6 -6
  105. package/lib/transaction/trace/index.js +14 -14
  106. package/lib/transaction/trace/segment.js +18 -18
  107. package/lib/transaction/tracecontext.js +1 -1
  108. package/lib/transaction/tracer/index.js +53 -49
  109. package/lib/uninstrumented.js +7 -7
  110. package/lib/util/arity.js +2 -2
  111. package/lib/util/byte-limit.js +4 -4
  112. package/lib/util/cat.js +269 -24
  113. package/lib/util/codec.js +2 -2
  114. package/lib/util/copy.js +2 -2
  115. package/lib/util/deep-equal.js +10 -10
  116. package/lib/util/flatten.js +4 -4
  117. package/lib/util/hashes.js +14 -14
  118. package/lib/util/label-parser.js +17 -17
  119. package/lib/util/logger.js +24 -24
  120. package/lib/util/process-version.js +2 -2
  121. package/lib/util/properties.js +4 -4
  122. package/lib/util/sql/obfuscate.js +15 -15
  123. package/lib/util/stream-sink.js +3 -3
  124. package/lib/util/unwrapped-core.js +2 -2
  125. package/lib/util/urltils.js +16 -16
  126. package/lib/utilization/aws-info.js +7 -7
  127. package/lib/utilization/azure-info.js +6 -6
  128. package/lib/utilization/common.js +13 -13
  129. package/lib/utilization/docker-info.js +11 -11
  130. package/lib/utilization/gcp-info.js +4 -4
  131. package/lib/utilization/index.js +5 -5
  132. package/lib/utilization/pcf-info.js +9 -9
  133. package/package.json +13 -6
  134. package/stub_api.js +8 -8
package/lib/util/cat.js CHANGED
@@ -5,51 +5,296 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ const cat = module.exports
8
9
  const hashes = require('./hashes')
9
10
  const logger = require('../logger').child({ component: 'cat' })
11
+ const NAMES = require('../metrics/names')
10
12
 
11
- module.exports.handleCatHeaders = handleCatHeaders
12
- module.exports.parsedHeadersToTrans = parsedHeadersToTrans
13
+ const HTTP_CAT_ID_HEADER = 'X-NewRelic-Id'
14
+ const MQ_CAT_ID_HEADER = 'NewRelicID'
15
+ const MATCH_CAT_ID_HEADER = new RegExp(
16
+ '^(?:' + HTTP_CAT_ID_HEADER + '|' + MQ_CAT_ID_HEADER + ')$',
17
+ 'i'
18
+ )
19
+ const HTTP_CAT_TRANSACTION_HEADER = 'X-NewRelic-Transaction'
20
+ const MQ_CAT_TRANSACTION_HEADER = 'NewRelicTransaction'
21
+ const MATCH_CAT_TRANSACTION_HEADER = new RegExp(
22
+ '^(?:' + HTTP_CAT_TRANSACTION_HEADER + '|' + MQ_CAT_TRANSACTION_HEADER + ')$',
23
+ 'i'
24
+ )
25
+ const HTTP_CAT_APP_DATA_HEADER = 'X-NewRelic-App-Data'
26
+ const MQ_CAT_APP_DATA_HEADER = 'NewRelicAppData'
27
+ const MATCH_CAT_APP_DATA_HEADER = new RegExp(
28
+ '^(?:' + HTTP_CAT_APP_DATA_HEADER + '|' + MQ_CAT_APP_DATA_HEADER + ')$',
29
+ 'i'
30
+ )
13
31
 
14
- function handleCatHeaders(incomingCatId, obfTransaction, encKey, transaction) {
15
- var parsedCatId = null
16
- if (incomingCatId) {
17
- parsedCatId = hashes.deobfuscateNameUsingKey(incomingCatId, encKey)
32
+ /**
33
+ * Decodes the CAT id and transaction headers from incoming request
34
+ *
35
+ * @param {Object} headers incoming headers
36
+ * @param {string} encKey config.encoding_key used to decode CAT headers
37
+ * @param {Object} { externalId, externalTransaction }
38
+ */
39
+ cat.parseCatData = function parseCatData(id, transactionId, encKey) {
40
+ if (!encKey) {
41
+ logger.warn('Missing encoding key, not extract CAT headers!')
42
+ return {}
43
+ }
44
+
45
+ let externalId = null
46
+
47
+ if (id) {
48
+ externalId = hashes.deobfuscateNameUsingKey(id, encKey)
18
49
  }
19
50
 
20
- var externalTrans = null
21
- if (obfTransaction) {
51
+ let externalTransaction = null
52
+ if (transactionId) {
22
53
  try {
23
- externalTrans = JSON.parse(hashes.deobfuscateNameUsingKey(obfTransaction, encKey))
54
+ externalTransaction = JSON.parse(hashes.deobfuscateNameUsingKey(transactionId, encKey))
24
55
  } catch (e) {
25
- logger.trace('Got an unparsable CAT header x-newrelic-transaction: %s', obfTransaction)
56
+ logger.trace(`Got an unparsable CAT header ${HTTP_CAT_ID_HEADER} %s`, transactionId)
26
57
  }
27
58
  }
28
59
 
29
- parsedHeadersToTrans(parsedCatId, externalTrans, transaction)
60
+ return { externalId, externalTransaction }
30
61
  }
31
62
 
32
- function parsedHeadersToTrans(parsedCatId, externalTrans, transaction) {
33
- if (typeof parsedCatId === 'string') {
34
- transaction.incomingCatId = parsedCatId
63
+ /**
64
+ * Adds the appropriate keys to transaction based on the incoming parsed CAT data
65
+ *
66
+ * @param {string} externalId decoded CAT id
67
+ * @param {Array} externalTransaction CAT transaction
68
+ * @param {Transaction} transaction active transaction
69
+ */
70
+ cat.assignCatToTransaction = function assignCatToTransaction(
71
+ externalId,
72
+ externalTransaction,
73
+ transaction
74
+ ) {
75
+ if (typeof externalId === 'string') {
76
+ transaction.incomingCatId = externalId
35
77
  }
36
78
 
37
- if (Array.isArray(externalTrans)) {
38
- transaction.referringTransactionGuid = externalTrans[0]
39
- if (typeof externalTrans[2] === 'string') {
40
- transaction.tripId = externalTrans[2]
41
- } else if (externalTrans[2]) {
79
+ if (Array.isArray(externalTransaction)) {
80
+ const [referringGuid, , tripId, referringPathHash] = externalTransaction
81
+ transaction.referringTransactionGuid = referringGuid
82
+
83
+ if (typeof tripId === 'string') {
84
+ transaction.tripId = tripId
85
+ } else if (tripId) {
42
86
  transaction.invalidIncomingExternalTransaction = true
43
87
  }
44
88
 
45
- if (_isValidReferringHash(externalTrans[3])) {
46
- transaction.referringPathHash = externalTrans[3]
47
- } else if (externalTrans[3]) {
89
+ if (typeof referringPathHash === 'string') {
90
+ transaction.referringPathHash = referringPathHash
91
+ } else if (referringPathHash) {
48
92
  transaction.invalidIncomingExternalTransaction = true
49
93
  }
50
94
  }
95
+
96
+ if (transaction.incomingCatId) {
97
+ logger.trace(
98
+ 'Got inbound CAT headers in transaction %s from %s',
99
+ transaction.id,
100
+ transaction.incomingCatId
101
+ )
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Encodes the data to be set on the CAT app data header
107
+ * for incoming requests
108
+ *
109
+ * @param {Object} config agent config
110
+ * @param {Transaction} transaction
111
+ * @param {string} contentLength
112
+ * @param {Boolean} useMqHeaders flag to return proper headers for MQ compliance
113
+ * @return {Object} { key, data} to add as header
114
+ */
115
+ cat.encodeAppData = function encodeAppData(config, transaction, contentLength, useMqHeaders) {
116
+ let appData = null
117
+ const transactionName = transaction.getFullName() || ''
118
+
119
+ try {
120
+ appData = JSON.stringify([
121
+ config.cross_process_id, // cross_process_id
122
+ transactionName, // transaction name
123
+ transaction.queueTime / 1000, // queue time (s)
124
+ transaction.catResponseTime / 1000, // response time (s)
125
+ contentLength, // content length (if content-length header is also being sent)
126
+ transaction.id, // TransactionGuid
127
+ false // force a transaction trace to be recorded
128
+ ])
129
+ } catch (err) {
130
+ logger.trace(
131
+ err,
132
+ 'Failed to serialize transaction: %s - not adding CAT response headers',
133
+ transactionName
134
+ )
135
+ return
136
+ }
137
+
138
+ const encKey = config.encoding_key
139
+ const obfAppData = hashes.obfuscateNameUsingKey(appData, encKey)
140
+ const key = useMqHeaders ? MQ_CAT_APP_DATA_HEADER : HTTP_CAT_APP_DATA_HEADER
141
+ return { key, data: obfAppData }
142
+ }
143
+
144
+ /**
145
+ * Adds CAT headers to outbound request.
146
+ *
147
+ * @param {Object} config agent config
148
+ * @param {Transaction} transaction
149
+ * @param {Object} headers object that contains headers the agent is adding to client request
150
+ * @param {Boolean} useMqHeaders flag to return proper headers for MQ compliance
151
+ */
152
+ cat.addCatHeaders = function addCatHeaders(config, transaction, headers, useMqHeaders) {
153
+ if (!config.encoding_key) {
154
+ logger.warn('Missing encoding key, not adding CAT headers!')
155
+ return
156
+ }
157
+
158
+ const idHeader = useMqHeaders ? MQ_CAT_ID_HEADER : HTTP_CAT_ID_HEADER
159
+ const transactionHeader = useMqHeaders ? MQ_CAT_TRANSACTION_HEADER : HTTP_CAT_TRANSACTION_HEADER
160
+
161
+ // Add in the application ID
162
+ if (config.obfuscatedId) {
163
+ headers[idHeader] = config.obfuscatedId
164
+ }
165
+
166
+ const transactionName = transaction.getFullName() || ''
167
+
168
+ const pathHash = hashes.calculatePathHash(
169
+ config.applications()[0],
170
+ transactionName,
171
+ transaction.referringPathHash
172
+ )
173
+ transaction.pushPathHash(pathHash)
174
+
175
+ try {
176
+ const transactionData = hashes.obfuscateNameUsingKey(
177
+ JSON.stringify([transaction.id, false, transaction.tripId || transaction.id, pathHash]),
178
+ config.encoding_key
179
+ )
180
+ headers[transactionHeader] = transactionData
181
+
182
+ logger.trace('Added outbound request CAT headers in transaction %s', transaction.id)
183
+ } catch (err) {
184
+ logger.trace(err, 'Failed to create CAT payload')
185
+ }
51
186
  }
52
187
 
53
- function _isValidReferringHash(hash) {
54
- return typeof hash === 'string'
188
+ /**
189
+ * Find the CAT id, transaction, app data headers
190
+ * from the headers of either HTTP or MQ request
191
+ *
192
+ * @param {Object} headers
193
+ * @return {Object} { id, transactionId, appData }
194
+ */
195
+ cat.extractCatHeaders = function extractCatHeaders(headers) {
196
+ // Hunt down the CAT headers.
197
+ let id = null
198
+ let transactionId = null
199
+ let appData = null
200
+ // eslint-disable-next-line guard-for-in
201
+ for (const key in headers) {
202
+ if (MATCH_CAT_ID_HEADER.test(key)) {
203
+ id = headers[key]
204
+ } else if (MATCH_CAT_TRANSACTION_HEADER.test(key)) {
205
+ transactionId = headers[key]
206
+ } else if (MATCH_CAT_APP_DATA_HEADER.test(key)) {
207
+ appData = headers[key]
208
+ }
209
+ if (id && transactionId && appData) {
210
+ break
211
+ }
212
+ }
213
+
214
+ return { id, transactionId, appData }
215
+ }
216
+
217
+ /**
218
+ * Extracts the account Id from CAT data and verifies if it is
219
+ * a trusted account id
220
+ *
221
+ * @param {Object} CAT data
222
+ * @param {Array} trustedAccounts from config
223
+ * @return {Boolean}
224
+ */
225
+ cat.isTrustedAccountId = function isTrustedAccountId(data, trustedAccounts) {
226
+ const accountId = parseInt(data.split('#')[0], 10)
227
+ const trusted = trustedAccounts.includes(accountId)
228
+ if (!trusted) {
229
+ logger.trace('Response from untrusted CAT header account id: %s', accountId)
230
+ }
231
+ return trusted
232
+ }
233
+
234
+ /**
235
+ * Decodes the CAT App Data header and extracts the downstream
236
+ * CAT id, transaction id
237
+ *
238
+ * @param {Object} config agent config
239
+ * @param {string} obfAppData encoded app data to parse and use
240
+ * @param {Array} decoded app data header
241
+ */
242
+ cat.parseAppData = function parseAppData(config, obfAppData) {
243
+ if (!config.encoding_key) {
244
+ logger.trace('config.encoding_key is not set - not parsing response CAT headers')
245
+ return
246
+ }
247
+
248
+ if (!config.trusted_account_ids) {
249
+ logger.trace('config.trusted_account_ids is not set - not parsing response CAT headers')
250
+ return
251
+ }
252
+
253
+ let appData = null
254
+ try {
255
+ appData = JSON.parse(hashes.deobfuscateNameUsingKey(obfAppData, config.encoding_key))
256
+ } catch (e) {
257
+ logger.warn(`Got an unparsable CAT header ${HTTP_CAT_APP_DATA_HEADER}: %s`, obfAppData)
258
+ return
259
+ }
260
+
261
+ // Make sure it is a trusted account
262
+ if (!cat.isTrustedAccountId(appData && appData[0], config.trusted_account_ids)) {
263
+ return
264
+ }
265
+
266
+ return appData
267
+ }
268
+
269
+ /**
270
+ * Assigns the CAT id, transaction to segment and adds `transaction_guid` when it exists.
271
+ * It also renames the segment name based on the newly decoded app data when host is present
272
+ *
273
+ * @param {Array} appData decodes CAT app data
274
+ * @param {TraceSegment} segment
275
+ * @param {string} [host] if host is present it will rename segment with app data and host
276
+ */
277
+ cat.assignCatToSegment = function assignCatToSegment(appData, segment, host) {
278
+ if (!Array.isArray(appData) || typeof appData[0] !== 'string') {
279
+ logger.trace(`Unknown format for CAT header ${HTTP_CAT_APP_DATA_HEADER}.`)
280
+ return
281
+ }
282
+
283
+ segment.catId = appData[0]
284
+ segment.catTransaction = appData[1]
285
+
286
+ if (host) {
287
+ segment.name = `${NAMES.EXTERNAL.TRANSACTION}${host}/${segment.catId}/${segment.catTransaction}`
288
+ }
289
+
290
+ let transactionGuid
291
+ if (appData.length >= 6) {
292
+ transactionGuid = appData[5]
293
+ segment.addAttribute('transaction_guid', transactionGuid)
294
+ }
295
+ logger.trace(
296
+ 'Got inbound response CAT headers in transaction %s from %s',
297
+ segment.transaction.id,
298
+ transactionGuid
299
+ )
55
300
  }
package/lib/util/codec.js CHANGED
@@ -5,8 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var stringify = require('json-stringify-safe')
9
- var zlib = require('zlib')
8
+ const stringify = require('json-stringify-safe')
9
+ const zlib = require('zlib')
10
10
 
11
11
  module.exports = {
12
12
  /**
package/lib/util/copy.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var hasOwnProperty = require('./properties').hasOwn
8
+ const hasOwnProperty = require('./properties').hasOwn
9
9
 
10
10
  exports.shallow = shallowCopy
11
11
 
@@ -19,7 +19,7 @@ exports.shallow = shallowCopy
19
19
  */
20
20
  function shallowCopy(source, dest) {
21
21
  dest = dest || Object.create(null)
22
- for (var k in source) {
22
+ for (const k in source) {
23
23
  if (hasOwnProperty(source, k)) {
24
24
  dest[k] = source[k]
25
25
  }
@@ -11,9 +11,9 @@ function isArguments(object) {
11
11
 
12
12
  function slice(args) {
13
13
  // Array.prototype.slice on arguments array-like is expensive
14
- var l = args.length
15
- var a = []
16
- var i
14
+ const l = args.length
15
+ const a = []
16
+ let i
17
17
  for (i = 0; i < l; i++) {
18
18
  a[i] = args[i]
19
19
  }
@@ -78,7 +78,7 @@ function deeper(a, b, ca, cb) {
78
78
  }
79
79
 
80
80
  // potentially incredibly expensive
81
- for (var i = 0; i < a.length; i++) {
81
+ for (let i = 0; i < a.length; i++) {
82
82
  if (a[i] !== b[i]) {
83
83
  return false
84
84
  }
@@ -107,13 +107,13 @@ function deeper(a, b, ca, cb) {
107
107
  return false
108
108
  }
109
109
 
110
- var ka = Object.keys(a)
111
- var kb = Object.keys(b)
110
+ const ka = Object.keys(a)
111
+ const kb = Object.keys(b)
112
112
  if (ka.length !== kb.length) {
113
113
  return false
114
114
  }
115
115
 
116
- var cal = ca.length
116
+ let cal = ca.length
117
117
  while (cal--) {
118
118
  if (ca[cal] === a) {
119
119
  return cb[cal] === b
@@ -124,14 +124,14 @@ function deeper(a, b, ca, cb) {
124
124
 
125
125
  ka.sort()
126
126
  kb.sort()
127
- for (var j = ka.length - 1; j >= 0; j--) {
127
+ for (let j = ka.length - 1; j >= 0; j--) {
128
128
  if (ka[j] !== kb[j]) {
129
129
  return false
130
130
  }
131
131
  }
132
132
 
133
- var key
134
- for (var k = ka.length - 1; k >= 0; k--) {
133
+ let key
134
+ for (let k = ka.length - 1; k >= 0; k--) {
135
135
  key = ka[k]
136
136
  if (!deeper(a[key], b[key], ca, cb)) {
137
137
  return false
@@ -25,7 +25,7 @@ function flatten(result, prefix, obj, seen) {
25
25
  seen = seen || []
26
26
  seen.push(obj)
27
27
 
28
- for (var key in obj) {
28
+ for (const key in obj) {
29
29
  if (seen.indexOf(obj[key]) > -1) {
30
30
  continue
31
31
  }
@@ -52,15 +52,15 @@ function flatten(result, prefix, obj, seen) {
52
52
  * @return {array.<string>} An array of keys names.
53
53
  */
54
54
  function flatKeys(obj, prefix, arrayIdxs) {
55
- var keys = []
56
- var seen = []
55
+ const keys = []
56
+ const seen = []
57
57
  recurse(prefix || '', obj)
58
58
  return keys
59
59
 
60
60
  function recurse(p, o) {
61
61
  seen.push(o)
62
62
 
63
- for (var key in o) {
63
+ for (const key in o) {
64
64
  if (seen.indexOf(o[key]) !== -1) {
65
65
  continue
66
66
  }
@@ -8,7 +8,7 @@
8
8
  const crypto = require('crypto')
9
9
 
10
10
  function encode(bytes, keyBytes) {
11
- for (var i = 0; i < bytes.length; i++) {
11
+ for (let i = 0; i < bytes.length; i++) {
12
12
  // This is really dense but happens commonly so I'm in-lining some of what
13
13
  // could be tossed into variables. It takes the current byte of bytes, then
14
14
  // XORs it with the current byte of the key (which uses modulo to make sure
@@ -19,14 +19,14 @@ function encode(bytes, keyBytes) {
19
19
  }
20
20
 
21
21
  function obfuscateNameUsingKey(name, key) {
22
- var encodedBytes = Buffer.from(name, 'utf-8')
23
- var keyBytes = Buffer.from(key)
22
+ const encodedBytes = Buffer.from(name, 'utf-8')
23
+ const keyBytes = Buffer.from(key)
24
24
  return encode(encodedBytes, keyBytes).toString('base64')
25
25
  }
26
26
 
27
27
  function deobfuscateNameUsingKey(name, key) {
28
- var bytes = Buffer.from(name, 'base64')
29
- var keyBytes = Buffer.from(key)
28
+ const bytes = Buffer.from(name, 'base64')
29
+ const keyBytes = Buffer.from(key)
30
30
 
31
31
  return encode(bytes, keyBytes).toString('utf-8')
32
32
  }
@@ -35,21 +35,21 @@ function calculatePathHash(appName, pathName, referingPathHash) {
35
35
  if (typeof referingPathHash === 'string') {
36
36
  referingPathHash = parseInt(referingPathHash, 16)
37
37
  }
38
- var rotated = ((referingPathHash << 1) | (referingPathHash >>> 31)) >>> 0
39
- var hash = getHash(appName, pathName)
38
+ const rotated = ((referingPathHash << 1) | (referingPathHash >>> 31)) >>> 0
39
+ const hash = getHash(appName, pathName)
40
40
 
41
- var result = (rotated ^ hash) >>> 0
41
+ const result = (rotated ^ hash) >>> 0
42
42
 
43
43
  // This is a trick to pad it out to 8 chars regardless of length.
44
- var retval = ('00000000' + result.toString(16)).substr(-8)
44
+ const retval = ('00000000' + result.toString(16)).substr(-8)
45
45
 
46
46
  return retval
47
47
  }
48
48
 
49
49
  function getHash(appName, txName) {
50
- var md5sum = crypto.createHash('md5')
50
+ const md5sum = crypto.createHash('md5')
51
51
  md5sum.update(appName + ';' + txName, 'utf8')
52
- var buf = md5sum.digest()
52
+ let buf = md5sum.digest()
53
53
  if (!(buf instanceof Buffer)) {
54
54
  buf = Buffer.from(buf)
55
55
  }
@@ -66,10 +66,10 @@ function randInt32() {
66
66
 
67
67
  function int32ToByteArray(int32) {
68
68
  // we want to represent the input as a 4-bytes array
69
- let byteArray = new Uint8Array(4)
69
+ const byteArray = new Uint8Array(4)
70
70
 
71
71
  for (let i = 0; i < byteArray.length; i++) {
72
- let byte = int32 & 0xff
72
+ const byte = int32 & 0xff
73
73
  byteArray[i] = byte
74
74
  int32 = (int32 - byte) / 256
75
75
  }
@@ -87,7 +87,7 @@ function makeId(length = 16) {
87
87
  // length is number of hex characters, which multiplied by 4 is the number of
88
88
  // bits, then divided by 8 is number of bytes. Or just divide by 2
89
89
  const numBytes = Math.ceil(length / 2)
90
- let randBytes = new Uint8Array(numBytes)
90
+ const randBytes = new Uint8Array(numBytes)
91
91
 
92
92
  // Generate random bytes one 32-bit integer at a time
93
93
  const numInts = Math.ceil(numBytes / 4) // 32 bit integers are 4 bytes
@@ -10,12 +10,12 @@ module.exports.fromString = fromString
10
10
  module.exports.fromMap = fromMap
11
11
 
12
12
  // this creates a copy of trim that can be used with map
13
- var trim = Function.prototype.call.bind(String.prototype.trim)
14
- var logger = require('../logger').child({ component: 'label-parser' })
15
- var stringify = require('json-stringify-safe')
13
+ const trim = Function.prototype.call.bind(String.prototype.trim)
14
+ const logger = require('../logger').child({ component: 'label-parser' })
15
+ const stringify = require('json-stringify-safe')
16
16
 
17
17
  function parse(labels) {
18
- var results
18
+ let results
19
19
 
20
20
  if (!labels) {
21
21
  return []
@@ -33,14 +33,14 @@ function parse(labels) {
33
33
  }
34
34
 
35
35
  function fromString(raw) {
36
- var map = Object.create(null)
36
+ const map = Object.create(null)
37
37
 
38
38
  if (!raw) {
39
39
  return { labels: [], warnings: [] }
40
40
  }
41
41
 
42
- var pairs = raw.split(';').map(trim)
43
- var parts
42
+ const pairs = raw.split(';').map(trim)
43
+ let parts
44
44
 
45
45
  while (!pairs[pairs.length - 1]) {
46
46
  pairs.pop()
@@ -50,7 +50,7 @@ function fromString(raw) {
50
50
  pairs.shift()
51
51
  }
52
52
 
53
- for (var i = 0, l = pairs.length; i < l; ++i) {
53
+ for (let i = 0, l = pairs.length; i < l; ++i) {
54
54
  parts = pairs[i].split(':').map(trim)
55
55
 
56
56
  if (parts.length !== 2) {
@@ -72,11 +72,11 @@ function fromString(raw) {
72
72
  }
73
73
 
74
74
  function fromMap(map) {
75
- var warnings = []
76
- var labels = []
75
+ const warnings = []
76
+ let labels = []
77
77
 
78
78
  Object.keys(map).forEach(function processKeys(key) {
79
- var type = truncate(key, 255)
79
+ const type = truncate(key, 255)
80
80
 
81
81
  if (!map[key] || typeof map[key] !== 'string') {
82
82
  return warnings.push(
@@ -84,7 +84,7 @@ function fromMap(map) {
84
84
  )
85
85
  }
86
86
 
87
- var value = truncate(map[key], 255)
87
+ const value = truncate(map[key], 255)
88
88
 
89
89
  if (type !== key) {
90
90
  warnings.push('Label key too long: ' + type)
@@ -114,11 +114,11 @@ function fromMap(map) {
114
114
  }
115
115
 
116
116
  function truncate(str, max) {
117
- var len = 0
118
- var chr
119
- for (var i = 0, l = str.length; i < l; ++i) {
120
- chr = str.charCodeAt(i)
121
- if (chr >= 0xd800 && chr <= 0xdbff && i !== l) {
117
+ let len = 0
118
+ let i
119
+ for (i = 0; i < str.length; ++i) {
120
+ const chr = str.charCodeAt(i)
121
+ if (chr >= 0xd800 && chr <= 0xdbff && i !== str.length) {
122
122
  i += 1
123
123
  }
124
124