newrelic 8.0.0 → 8.4.0

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 (173) hide show
  1. package/NEWS.md +5023 -4922
  2. package/THIRD_PARTY_NOTICES.md +618 -209
  3. package/api.js +156 -219
  4. package/bin/test-naming-rules.js +57 -51
  5. package/bin/tracetractor +0 -1
  6. package/index.js +7 -14
  7. package/lib/agent.js +111 -114
  8. package/lib/aggregators/base-aggregator.js +1 -1
  9. package/lib/aggregators/event-aggregator.js +6 -6
  10. package/lib/attributes.js +13 -14
  11. package/lib/collector/api.js +44 -54
  12. package/lib/collector/facts.js +68 -66
  13. package/lib/collector/http-agents.js +36 -32
  14. package/lib/collector/key-parser.js +1 -1
  15. package/lib/collector/parse-response.js +1 -2
  16. package/lib/collector/remote-method.js +69 -61
  17. package/lib/collector/serverless.js +13 -18
  18. package/lib/collector/ssl/certificates.js +1056 -1056
  19. package/lib/config/attribute-filter.js +109 -101
  20. package/lib/config/default.js +35 -21
  21. package/lib/config/env.js +17 -12
  22. package/lib/config/harvest-config-validator.js +1 -1
  23. package/lib/config/hsm.js +1 -1
  24. package/lib/config/index.js +240 -234
  25. package/lib/config/lasp.js +3 -3
  26. package/lib/config/merge-server-config.js +8 -6
  27. package/lib/custom-events/custom-event-aggregator.js +1 -1
  28. package/lib/db/parse-sql.js +13 -16
  29. package/lib/db/parsed-statement.js +13 -19
  30. package/lib/db/query-parsers/sql.js +12 -15
  31. package/lib/db/query-sample.js +16 -12
  32. package/lib/db/query-trace-aggregator.js +16 -16
  33. package/lib/db/statement-matcher.js +5 -5
  34. package/lib/db/utils.js +2 -2
  35. package/lib/environment.js +210 -175
  36. package/lib/errors/error-collector.js +20 -33
  37. package/lib/errors/error-event-aggregator.js +1 -1
  38. package/lib/errors/error-trace-aggregator.js +3 -4
  39. package/lib/errors/helper.js +23 -32
  40. package/lib/errors/index.js +31 -43
  41. package/lib/feature_flags.js +3 -4
  42. package/lib/grpc/connection/states.js +6 -6
  43. package/lib/grpc/connection.js +35 -46
  44. package/lib/header-attributes.js +55 -59
  45. package/lib/header-processing.js +1 -1
  46. package/lib/instrumentation/amqplib.js +34 -43
  47. package/lib/instrumentation/bluebird.js +63 -22
  48. package/lib/instrumentation/cassandra-driver.js +8 -4
  49. package/lib/instrumentation/connect.js +7 -6
  50. package/lib/instrumentation/core/async_hooks.js +16 -9
  51. package/lib/instrumentation/core/child_process.js +20 -28
  52. package/lib/instrumentation/core/crypto.js +1 -7
  53. package/lib/instrumentation/core/dns.js +3 -7
  54. package/lib/instrumentation/core/domain.js +4 -10
  55. package/lib/instrumentation/core/fs.js +22 -37
  56. package/lib/instrumentation/core/globals.js +4 -8
  57. package/lib/instrumentation/core/http-outbound.js +20 -114
  58. package/lib/instrumentation/core/http.js +61 -128
  59. package/lib/instrumentation/core/inspector.js +7 -11
  60. package/lib/instrumentation/core/net.js +3 -1
  61. package/lib/instrumentation/core/timers.js +21 -28
  62. package/lib/instrumentation/core/zlib.js +3 -11
  63. package/lib/instrumentation/director.js +4 -4
  64. package/lib/instrumentation/express.js +12 -10
  65. package/lib/instrumentation/fastify/spec-builders.js +5 -0
  66. package/lib/instrumentation/fastify.js +37 -10
  67. package/lib/instrumentation/generic-pool.js +1 -1
  68. package/lib/instrumentation/hapi/hapi-17.js +20 -21
  69. package/lib/instrumentation/hapi/shared.js +1 -1
  70. package/lib/instrumentation/hapi.js +37 -37
  71. package/lib/instrumentation/ioredis.js +8 -9
  72. package/lib/instrumentation/memcached.js +41 -45
  73. package/lib/instrumentation/mongodb/common.js +221 -0
  74. package/lib/instrumentation/mongodb/constants.js +87 -0
  75. package/lib/instrumentation/mongodb/v2-mongo.js +110 -0
  76. package/lib/instrumentation/mongodb/v3-mongo.js +80 -0
  77. package/lib/instrumentation/mongodb/v4-mongo.js +90 -0
  78. package/lib/instrumentation/mongodb.js +20 -312
  79. package/lib/instrumentation/mysql.js +51 -44
  80. package/lib/instrumentation/oracle.js +24 -28
  81. package/lib/instrumentation/pg.js +34 -25
  82. package/lib/instrumentation/promise.js +65 -62
  83. package/lib/instrumentation/q.js +2 -2
  84. package/lib/instrumentation/redis.js +38 -38
  85. package/lib/instrumentation/restify.js +1 -1
  86. package/lib/instrumentation/vision.js +4 -4
  87. package/lib/instrumentation/when.js +12 -4
  88. package/lib/instrumentations.js +25 -25
  89. package/lib/logger.js +6 -6
  90. package/lib/metrics/index.js +50 -30
  91. package/lib/metrics/mapper.js +15 -15
  92. package/lib/metrics/metric-aggregator.js +5 -10
  93. package/lib/metrics/names.js +8 -7
  94. package/lib/metrics/normalizer/rule.js +14 -15
  95. package/lib/metrics/normalizer/tx_segment.js +33 -29
  96. package/lib/metrics/normalizer.js +51 -54
  97. package/lib/metrics/recorders/custom.js +8 -6
  98. package/lib/metrics/recorders/distributed-trace.js +3 -18
  99. package/lib/metrics/recorders/generic.js +6 -5
  100. package/lib/metrics/recorders/http.js +11 -13
  101. package/lib/metrics/recorders/http_external.js +8 -10
  102. package/lib/metrics/recorders/message-transaction.js +7 -18
  103. package/lib/metrics/recorders/other.js +7 -17
  104. package/lib/parse-proc-cpuinfo.js +26 -31
  105. package/lib/parse-proc-meminfo.js +5 -3
  106. package/lib/prioritized-attributes.js +14 -19
  107. package/lib/priority-queue.js +11 -11
  108. package/lib/proxy/grpc.js +1 -1
  109. package/lib/reservoir.js +12 -6
  110. package/lib/sampler.js +33 -34
  111. package/lib/serverless/api-gateway.js +3 -3
  112. package/lib/serverless/aws-lambda.js +28 -37
  113. package/lib/shim/conglomerate-shim.js +4 -4
  114. package/lib/shim/datastore-shim.js +61 -67
  115. package/lib/shim/index.js +10 -11
  116. package/lib/shim/message-shim.js +149 -151
  117. package/lib/shim/promise-shim.js +19 -14
  118. package/lib/shim/shim.js +131 -125
  119. package/lib/shim/specs/index.js +21 -22
  120. package/lib/shim/transaction-shim.js +52 -210
  121. package/lib/shim/webframework-shim.js +75 -85
  122. package/lib/shimmer.js +184 -166
  123. package/lib/spans/create-span-event-aggregator.js +11 -8
  124. package/lib/spans/span-context.js +4 -10
  125. package/lib/spans/span-event-aggregator.js +68 -13
  126. package/lib/spans/span-event.js +6 -8
  127. package/lib/spans/span-streamer.js +10 -18
  128. package/lib/spans/streaming-span-attributes.js +1 -1
  129. package/lib/spans/streaming-span-event-aggregator.js +1 -1
  130. package/lib/spans/streaming-span-event.js +4 -4
  131. package/lib/stats/apdex.js +7 -13
  132. package/lib/stats/index.js +14 -19
  133. package/lib/system-info.js +29 -25
  134. package/lib/timer.js +35 -21
  135. package/lib/transaction/dt-payload.js +1 -1
  136. package/lib/transaction/handle.js +19 -19
  137. package/lib/transaction/index.js +133 -151
  138. package/lib/transaction/name-state.js +18 -19
  139. package/lib/transaction/trace/aggregator.js +78 -73
  140. package/lib/transaction/trace/exclusive-time-calculator.js +9 -13
  141. package/lib/transaction/trace/index.js +37 -35
  142. package/lib/transaction/trace/segment.js +56 -73
  143. package/lib/transaction/tracecontext.js +38 -46
  144. package/lib/transaction/tracer/index.js +130 -91
  145. package/lib/transaction/transaction-event-aggregator.js +29 -31
  146. package/lib/uninstrumented.js +11 -12
  147. package/lib/util/arity.js +2 -2
  148. package/lib/util/attribute-types.js +1 -5
  149. package/lib/util/byte-limit.js +4 -5
  150. package/lib/util/cat.js +270 -33
  151. package/lib/util/codec.js +10 -6
  152. package/lib/util/copy.js +2 -2
  153. package/lib/util/deep-equal.js +51 -21
  154. package/lib/util/flatten.js +9 -6
  155. package/lib/util/hashes.js +16 -16
  156. package/lib/util/label-parser.js +22 -28
  157. package/lib/util/logger.js +53 -35
  158. package/lib/util/process-version.js +3 -3
  159. package/lib/util/properties.js +5 -5
  160. package/lib/util/sql/obfuscate.js +21 -31
  161. package/lib/util/stream-sink.js +5 -6
  162. package/lib/util/unwrapped-core.js +2 -2
  163. package/lib/util/urltils.js +26 -30
  164. package/lib/utilization/aws-info.js +8 -9
  165. package/lib/utilization/azure-info.js +37 -35
  166. package/lib/utilization/common.js +17 -16
  167. package/lib/utilization/docker-info.js +14 -16
  168. package/lib/utilization/gcp-info.js +38 -37
  169. package/lib/utilization/index.js +5 -5
  170. package/lib/utilization/kubernetes-info.js +2 -2
  171. package/lib/utilization/pcf-info.js +12 -12
  172. package/package.json +23 -6
  173. package/stub_api.js +16 -14
package/lib/util/cat.js CHANGED
@@ -5,59 +5,296 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ const cat = module.exports
8
9
  const hashes = require('./hashes')
9
- const logger = require('../logger').child({component: 'cat'})
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(
18
- incomingCatId,
19
- encKey
20
- )
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)
21
49
  }
22
50
 
23
- var externalTrans = null
24
- if (obfTransaction) {
51
+ let externalTransaction = null
52
+ if (transactionId) {
25
53
  try {
26
- externalTrans = JSON.parse(
27
- hashes.deobfuscateNameUsingKey(obfTransaction, encKey)
28
- )
54
+ externalTransaction = JSON.parse(hashes.deobfuscateNameUsingKey(transactionId, encKey))
29
55
  } catch (e) {
30
- logger.trace(
31
- 'Got an unparsable CAT header x-newrelic-transaction: %s',
32
- obfTransaction
33
- )
56
+ logger.trace(`Got an unparsable CAT header ${HTTP_CAT_ID_HEADER} %s`, transactionId)
34
57
  }
35
58
  }
36
59
 
37
- parsedHeadersToTrans(parsedCatId, externalTrans, transaction)
60
+ return { externalId, externalTransaction }
38
61
  }
39
62
 
40
- function parsedHeadersToTrans(parsedCatId, externalTrans, transaction) {
41
- if (typeof parsedCatId === 'string') {
42
- 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
43
77
  }
44
78
 
45
- if (Array.isArray(externalTrans)) {
46
- transaction.referringTransactionGuid = externalTrans[0]
47
- if (typeof externalTrans[2] === 'string') {
48
- transaction.tripId = externalTrans[2]
49
- } 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) {
50
86
  transaction.invalidIncomingExternalTransaction = true
51
87
  }
52
88
 
53
- if (_isValidReferringHash(externalTrans[3])) {
54
- transaction.referringPathHash = externalTrans[3]
55
- } else if (externalTrans[3]) {
89
+ if (typeof referringPathHash === 'string') {
90
+ transaction.referringPathHash = referringPathHash
91
+ } else if (referringPathHash) {
56
92
  transaction.invalidIncomingExternalTransaction = true
57
93
  }
58
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
+ }
59
186
  }
60
187
 
61
- function _isValidReferringHash(hash) {
62
- 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
+ )
63
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
  /**
@@ -23,8 +23,10 @@ module.exports = {
23
23
  */
24
24
  encode: function encode(data, callback) {
25
25
  try {
26
- zlib.deflate(stringify(data), function cb_deflate(err, raw) {
27
- if (err) return callback(err)
26
+ zlib.deflate(stringify(data), function cbDeflate(err, raw) {
27
+ if (err) {
28
+ return callback(err)
29
+ }
28
30
 
29
31
  return callback(null, raw.toString('base64'))
30
32
  })
@@ -47,8 +49,10 @@ module.exports = {
47
49
  * decoding, and the second parameter is the decoded data object.
48
50
  */
49
51
  decode: function decode(encoded, callback) {
50
- zlib.inflate(Buffer.from(encoded, 'base64'), function cb_inflate(err, raw) {
51
- if (err) return callback(err)
52
+ zlib.inflate(Buffer.from(encoded, 'base64'), function cbInflate(err, raw) {
53
+ if (err) {
54
+ return callback(err)
55
+ }
52
56
 
53
57
  let json
54
58
  try {
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,7 +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, a = [], i
14
+ const l = args.length
15
+ const a = []
16
+ let i
15
17
  for (i = 0; i < l; i++) {
16
18
  a[i] = args[i]
17
19
  }
@@ -71,45 +73,73 @@ function deeper(a, b, ca, cb) {
71
73
  } else if (a === null || b === null) {
72
74
  return false
73
75
  } else if (Buffer.isBuffer(a) && Buffer.isBuffer(b)) {
74
- if (a.length !== b.length) return false
76
+ if (a.length !== b.length) {
77
+ return false
78
+ }
75
79
 
76
80
  // potentially incredibly expensive
77
- for (var i = 0; i < a.length; i++) if (a[i] !== b[i]) return false
81
+ for (let i = 0; i < a.length; i++) {
82
+ if (a[i] !== b[i]) {
83
+ return false
84
+ }
85
+ }
78
86
 
79
87
  return true
80
88
  } else if (a instanceof Date && b instanceof Date) {
81
89
  return a.getTime() === b.getTime()
82
90
  } else if (a instanceof RegExp && b instanceof RegExp) {
83
- return a.source === b.source &&
84
- a.global === b.global &&
85
- a.multiline === b.multiline &&
86
- a.lastIndex === b.lastIndex &&
87
- a.ignoreCase === b.ignoreCase
91
+ return (
92
+ a.source === b.source &&
93
+ a.global === b.global &&
94
+ a.multiline === b.multiline &&
95
+ a.lastIndex === b.lastIndex &&
96
+ a.ignoreCase === b.ignoreCase
97
+ )
88
98
  } else if (isArguments(a) || isArguments(b)) {
89
- if (!(isArguments(a) && isArguments(b))) return false
99
+ if (!(isArguments(a) && isArguments(b))) {
100
+ return false
101
+ }
90
102
 
91
103
  return deeper(slice(a), slice(b), ca, cb)
92
104
  }
93
105
 
94
- if (a.constructor !== b.constructor) return false
106
+ if (a.constructor !== b.constructor) {
107
+ return false
108
+ }
95
109
 
96
- var ka = Object.keys(a), kb = Object.keys(b)
97
- if (ka.length !== kb.length) return false
110
+ const ka = Object.keys(a)
111
+ const kb = Object.keys(b)
112
+ if (ka.length !== kb.length) {
113
+ return false
114
+ }
98
115
 
99
- var cal = ca.length
100
- while (cal--) if (ca[cal] === a) return cb[cal] === b
101
- ca.push(a); cb.push(b)
116
+ let cal = ca.length
117
+ while (cal--) {
118
+ if (ca[cal] === a) {
119
+ return cb[cal] === b
120
+ }
121
+ }
122
+ ca.push(a)
123
+ cb.push(b)
102
124
 
103
- ka.sort(); kb.sort()
104
- for (var j = ka.length - 1; j >= 0; j--) if (ka[j] !== kb[j]) return false
125
+ ka.sort()
126
+ kb.sort()
127
+ for (let j = ka.length - 1; j >= 0; j--) {
128
+ if (ka[j] !== kb[j]) {
129
+ return false
130
+ }
131
+ }
105
132
 
106
- var key
107
- for (var k = ka.length - 1; k >= 0; k--) {
133
+ let key
134
+ for (let k = ka.length - 1; k >= 0; k--) {
108
135
  key = ka[k]
109
- if (!deeper(a[key], b[key], ca, cb)) return false
136
+ if (!deeper(a[key], b[key], ca, cb)) {
137
+ return false
138
+ }
110
139
  }
111
140
 
112
- ca.pop(); cb.pop()
141
+ ca.pop()
142
+ cb.pop()
113
143
 
114
144
  return true
115
145
  }
@@ -25,13 +25,16 @@ 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
  }
32
32
 
33
- if (obj[key] instanceof Object) flatten(result, prefix + key + '.', obj[key], seen)
34
- else result[prefix + key] = obj[key]
33
+ if (obj[key] instanceof Object) {
34
+ flatten(result, prefix + key + '.', obj[key], seen)
35
+ } else {
36
+ result[prefix + key] = obj[key]
37
+ }
35
38
  }
36
39
 
37
40
  return result
@@ -49,15 +52,15 @@ function flatten(result, prefix, obj, seen) {
49
52
  * @return {array.<string>} An array of keys names.
50
53
  */
51
54
  function flatKeys(obj, prefix, arrayIdxs) {
52
- var keys = []
53
- var seen = []
55
+ const keys = []
56
+ const seen = []
54
57
  recurse(prefix || '', obj)
55
58
  return keys
56
59
 
57
60
  function recurse(p, o) {
58
61
  seen.push(o)
59
62
 
60
- for (var key in o) {
63
+ for (const key in o) {
61
64
  if (seen.indexOf(o[key]) !== -1) {
62
65
  continue
63
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,37 +19,37 @@ 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
- return encode(bytes, keyBytes).toString("utf-8")
31
+ return encode(bytes, keyBytes).toString('utf-8')
32
32
  }
33
33
 
34
34
  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
@@ -98,7 +98,7 @@ function makeId(length = 16) {
98
98
  // This could "overflow" since we're iterating over the number of ints, which could
99
99
  // be more data than needed. But out-of-bound index assignment on typed arrays are
100
100
  // discarded
101
- randBytes[(i * 4) + j] = bytes[j]
101
+ randBytes[i * 4 + j] = bytes[j]
102
102
  }
103
103
  }
104
104