newrelic 9.5.0 → 9.7.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 (104) hide show
  1. package/NEWS.md +14 -0
  2. package/api.js +2 -0
  3. package/bin/test-naming-rules.js +1 -1
  4. package/esm-loader.mjs +1 -3
  5. package/index.js +6 -5
  6. package/lib/adaptive-sampler.js +1 -2
  7. package/lib/agent.js +2 -0
  8. package/lib/aggregators/event-aggregator.js +2 -2
  9. package/lib/attributes.js +2 -4
  10. package/lib/collector/api.js +20 -12
  11. package/lib/collector/facts.js +1 -3
  12. package/lib/collector/parse-response.js +3 -1
  13. package/lib/collector/remote-method.js +10 -10
  14. package/lib/config/attribute-filter.js +14 -16
  15. package/lib/config/default.js +544 -286
  16. package/lib/config/formatters.js +108 -0
  17. package/lib/config/harvest-config-validator.js +3 -5
  18. package/lib/config/index.js +74 -93
  19. package/lib/environment.js +6 -5
  20. package/lib/errors/error-collector.js +6 -3
  21. package/lib/errors/helper.js +10 -18
  22. package/lib/errors/index.js +12 -6
  23. package/lib/grpc/connection.js +12 -5
  24. package/lib/header-attributes.js +4 -2
  25. package/lib/header-processing.js +2 -2
  26. package/lib/instrumentation/@hapi/hapi.js +231 -1
  27. package/lib/instrumentation/{vision.js → @hapi/vision.js} +0 -0
  28. package/lib/instrumentation/@node-redis/client.js +2 -0
  29. package/lib/instrumentation/amqplib.js +2 -0
  30. package/lib/instrumentation/core/async_hooks.js +3 -4
  31. package/lib/instrumentation/core/globals.js +12 -10
  32. package/lib/instrumentation/core/http-outbound.js +17 -17
  33. package/lib/instrumentation/core/http.js +16 -27
  34. package/lib/instrumentation/core/timers.js +5 -1
  35. package/lib/instrumentation/fastify.js +1 -3
  36. package/lib/instrumentation/grpc-js/grpc.js +14 -3
  37. package/lib/instrumentation/memcached.js +5 -0
  38. package/lib/instrumentation/mongodb/common.js +3 -0
  39. package/lib/instrumentation/mongodb/v2-mongo.js +6 -3
  40. package/lib/instrumentation/mongodb.js +1 -1
  41. package/lib/instrumentation/mysql/mysql.js +6 -5
  42. package/lib/instrumentation/nr-winston-transport.js +3 -4
  43. package/lib/instrumentation/promise.js +22 -18
  44. package/lib/instrumentation/redis.js +2 -0
  45. package/lib/instrumentation/undici.js +12 -15
  46. package/lib/instrumentations.js +1 -1
  47. package/lib/metrics/mapper.js +2 -3
  48. package/lib/metrics/metric-aggregator.js +1 -3
  49. package/lib/metrics/names.js +19 -15
  50. package/lib/metrics/normalizer/rule.js +6 -7
  51. package/lib/metrics/normalizer/tx_segment.js +3 -2
  52. package/lib/metrics/normalizer.js +5 -3
  53. package/lib/parse-proc-cpuinfo.js +11 -6
  54. package/lib/serverless/api-gateway.js +3 -4
  55. package/lib/serverless/aws-lambda.js +3 -3
  56. package/lib/shim/conglomerate-shim.js +2 -3
  57. package/lib/shim/constants.js +1 -16
  58. package/lib/shim/datastore-shim.js +24 -105
  59. package/lib/shim/index.js +7 -0
  60. package/lib/shim/message-shim.js +2 -0
  61. package/lib/shim/promise-shim.js +66 -59
  62. package/lib/shim/shim.js +44 -89
  63. package/lib/shim/transaction-shim.js +1 -1
  64. package/lib/shim/webframework-shim.js +4 -8
  65. package/lib/shimmer.js +29 -23
  66. package/lib/spans/map-to-streaming-type.js +0 -2
  67. package/lib/spans/span-context.js +2 -0
  68. package/lib/spans/span-event-aggregator.js +2 -2
  69. package/lib/spans/span-event.js +2 -2
  70. package/lib/spans/span-streamer.js +4 -0
  71. package/lib/spans/streaming-span-event-aggregator.js +2 -4
  72. package/lib/spans/streaming-span-event.js +3 -2
  73. package/lib/symbols.js +26 -0
  74. package/lib/system-info.js +4 -7
  75. package/lib/timer.js +8 -6
  76. package/lib/transaction/dt-payload.js +4 -3
  77. package/lib/transaction/handle.js +12 -2
  78. package/lib/transaction/index.js +19 -18
  79. package/lib/transaction/name-state.js +17 -2
  80. package/lib/transaction/trace/aggregator.js +4 -12
  81. package/lib/transaction/trace/index.js +7 -5
  82. package/lib/transaction/trace/segment.js +6 -11
  83. package/lib/transaction/tracecontext.js +10 -6
  84. package/lib/transaction/tracer/index.js +35 -43
  85. package/lib/transaction/transaction-event-aggregator.js +1 -3
  86. package/lib/util/arity.js +4 -9
  87. package/lib/util/attribute-types.js +1 -2
  88. package/lib/util/byte-limit.js +1 -3
  89. package/lib/util/cat.js +16 -13
  90. package/lib/util/codec.js +0 -2
  91. package/lib/util/copy.js +1 -2
  92. package/lib/util/deep-equal.js +7 -0
  93. package/lib/util/flatten.js +4 -6
  94. package/lib/util/hashes.js +1 -3
  95. package/lib/util/process-version.js +2 -3
  96. package/lib/util/properties.js +2 -51
  97. package/lib/util/stream-sink.js +2 -0
  98. package/lib/util/urltils.js +4 -10
  99. package/newrelic.js +1 -1
  100. package/package.json +2 -1
  101. package/lib/config/env.js +0 -294
  102. package/lib/instrumentation/hapi/hapi.js +0 -207
  103. package/lib/instrumentation/hapi/shared.js +0 -28
  104. package/lib/instrumentation/hapi.js +0 -254
package/NEWS.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### v9.7.0 (2022-11-14)
2
+
3
+ * Added new configuration option, `grpc.ignore_status_codes`, which can be used to select nonzero gRPC status codes to ignore and not report as errors.
4
+
5
+ ### v9.6.0 (2022-11-09)
6
+
7
+ * Dropped support for `vision`, and instead only instrument `@hapi/vision`.
8
+
9
+ * Updated configuration system to automatically create an environment variable mapping for a new config value.
10
+ * It will follow a convention of `NEW_RELIC_PATH_TO_CONFIG_KEY`.
11
+ * For example if there is a new configuration option of `config.nested.object_path.enabled` the env var would be `NEW_RELIC_NESTED_OBJECT_PATH.ENABLED`.
12
+
13
+ * Removed `transaction_tracer.hide_internals` configuration. All of the internal configuration is now handled by Javascript symbols instead of non-enumerable properties, so there is no longer a performance penalty, as symbols are already hidden by default.
14
+
1
15
  ### v9.5.0 (2022-10-26)
2
16
 
3
17
  * Increased the default limit of custom events from 1,000 events per minute to 3,000 events per minute. In the scenario that custom events were being limited, this change will allow more custom events to be sent to New Relic. There is also a new configurable maximum limit of 100,000 events per minute. To change the limits, see the documentation for [custom_insights_events](https://docs.newrelic.com/docs/apm/agents/nodejs-agent/installation-configuration/nodejs-agent-configuration#custom_events_max_samples_stored). To learn more about the change and how to determine if custom events are being dropped, see our Explorers Hub [post](https://discuss.newrelic.com/t/send-more-custom-events-with-the-latest-apm-agents/190497).
package/api.js CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ /* eslint sonarjs/cognitive-complexity: ["error", 21] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
9
+
8
10
  const util = require('util')
9
11
  const logger = require('./lib/logger').child({ component: 'api' })
10
12
  const recordWeb = require('./lib/metrics/recorders/http')
@@ -64,7 +64,7 @@ function run(opts) {
64
64
  let appliedRules = []
65
65
 
66
66
  // responsible for handling default rules provided by the server
67
- const defaultNormalizer = loadDefaultNormalizer(config, runtimeRules)
67
+ const defaultNormalizer = loadDefaultNormalizer(config)
68
68
 
69
69
  // rules defined by user in local configuration file
70
70
  const userNormalizer = loadUserNormalizer(config, runtimeRules)
package/esm-loader.mjs CHANGED
@@ -197,11 +197,9 @@ async function wrapEsmSource(url, specifier) {
197
197
  const _wrappedModule = wrapModule(_originalModule, '${specifier}', '${trimmedUrl}')
198
198
  ${props
199
199
  .map((propName) => {
200
- const propertyExportSource = `
200
+ return `
201
201
  let _${propName} = _wrappedModule.${propName}
202
202
  export { _${propName} as ${propName} }`
203
-
204
- return propertyExportSource
205
203
  })
206
204
  .join('\n')}
207
205
  `
package/index.js CHANGED
@@ -14,6 +14,7 @@ require('./lib/util/unwrapped-core')
14
14
 
15
15
  const featureFlags = require('./lib/feature_flags').prerelease
16
16
  const psemver = require('./lib/util/process-version')
17
+ const symbols = require('./lib/symbols')
17
18
  let logger = require('./lib/logger') // Gets re-loaded after initialization.
18
19
 
19
20
  const pkgJSON = require('./package.json')
@@ -23,15 +24,15 @@ logger.info(
23
24
  process.version
24
25
  )
25
26
 
26
- if (require.cache.__NR_cache) {
27
+ if (require.cache[symbols.cache]) {
27
28
  logger.warn(
28
29
  'Attempting to load a second copy of newrelic from %s, using cache instead',
29
30
  __dirname
30
31
  )
31
- if (require.cache.__NR_cache.agent) {
32
- require.cache.__NR_cache.agent.recordSupportability('Agent/DoubleLoad')
32
+ if (require.cache[symbols.cache].agent) {
33
+ require.cache[symbols.cache].agent.recordSupportability('Agent/DoubleLoad')
33
34
  }
34
- module.exports = require.cache.__NR_cache
35
+ module.exports = require.cache[symbols.cache]
35
36
  } else {
36
37
  initialize()
37
38
  }
@@ -98,7 +99,7 @@ function initialize() {
98
99
  API = require('./stub_api')
99
100
  }
100
101
 
101
- require.cache.__NR_cache = module.exports = new API(agent)
102
+ require.cache[symbols.cache] = module.exports = new API(agent)
102
103
 
103
104
  // If we loaded an agent, record a startup time for the agent.
104
105
  // NOTE: Metrics are recorded in seconds, so divide the value by 1000.
@@ -79,8 +79,7 @@ class AdaptiveSampler {
79
79
  * the number of objects sampled in this window.
80
80
  *
81
81
  * @param {number} roll - The number to compare against the threshold
82
- *
83
- * @return {bool} True if the object should be sampled.
82
+ * @returns {bool} True if the object should be sampled.
84
83
  */
85
84
  shouldSample(roll) {
86
85
  ++this._seen
package/lib/agent.js CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ /* eslint sonarjs/cognitive-complexity: ["error", 23] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
9
+
8
10
  const AdaptiveSampler = require('./adaptive-sampler')
9
11
  const CollectorAPI = require('./collector/api')
10
12
  const ServerlessCollector = require('./collector/serverless')
@@ -76,7 +76,7 @@ class EventAggregator extends Aggregator {
76
76
  /**
77
77
  * Fetches all the span events aggregated.
78
78
  *
79
- * @return {array.<Event>} An array of span events from the aggregator.
79
+ * @returns {Array.<Event>} An array of span events from the aggregator.
80
80
  */
81
81
  getEvents() {
82
82
  return this._items.toArray()
@@ -85,7 +85,7 @@ class EventAggregator extends Aggregator {
85
85
  /**
86
86
  * Resets the contents of the aggregator and all counters.
87
87
  *
88
- * @return {PriorityQueue} The old collection of aggregated events.
88
+ * @returns {PriorityQueue} The old collection of aggregated events.
89
89
  */
90
90
  clearEvents() {
91
91
  // ???: might be more efficient to clear here and come up with an efficient way to
package/lib/attributes.js CHANGED
@@ -22,7 +22,6 @@ class Attributes {
22
22
  * @param {string} scope
23
23
  * The scope of the attributes this will collect. Must be `transaction` or
24
24
  * `segment`.
25
- *
26
25
  * @param {number} [limit=Infinity]
27
26
  * The maximum number of attributes to retrieve for each destination.
28
27
  */
@@ -61,7 +60,7 @@ class Attributes {
61
60
  * attributes allowed, no more than that number will be included in the result.
62
61
  *
63
62
  * @param {AttributeFilter.DESTINATIONS} dest
64
- * @return {object}
63
+ * @returns {object}
65
64
  */
66
65
  get(dest) {
67
66
  const attrs = Object.create(null)
@@ -168,8 +167,7 @@ class Attributes {
168
167
  * Creates a filter function for the given scope.
169
168
  *
170
169
  * @param {string} scope - The scope of the filter to make.
171
- *
172
- * @return {function} A function that performs attribute filtering for the given
170
+ * @returns {Function} A function that performs attribute filtering for the given
173
171
  * scope.
174
172
  */
175
173
  function makeFilter(scope) {
@@ -5,6 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ /* eslint sonarjs/cognitive-complexity: ["error", 16] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
9
+
8
10
  const CollectorResponse = require('./response')
9
11
  const facts = require('./facts')
10
12
  const logger = require('../logger').child({ component: 'collector_api' })
@@ -89,6 +91,10 @@ function CollectorAPI(agent) {
89
91
  }
90
92
  }
91
93
 
94
+ CollectorAPI.prototype._throwCallbackError = function _throwCallbackError() {
95
+ throw new TypeError('callback is required')
96
+ }
97
+
92
98
  /**
93
99
  * Updates all methods except preconnect w/ new host/port pairs sent down from server
94
100
  * during preconnect (via redirect_host). Preconnect does not update.
@@ -107,7 +113,7 @@ CollectorAPI.prototype._updateEndpoints = function _updateEndpoints(endpoint) {
107
113
 
108
114
  CollectorAPI.prototype.connect = function connect(callback) {
109
115
  if (!callback) {
110
- throw new TypeError('callback is required')
116
+ this._throwCallbackError()
111
117
  }
112
118
 
113
119
  logger.trace('Starting collector.')
@@ -376,7 +382,7 @@ CollectorAPI.prototype.reportSettings = function reportSettings(callback) {
376
382
  */
377
383
  CollectorAPI.prototype.error_data = function errorData(errors, callback) {
378
384
  if (!callback) {
379
- throw new TypeError('callback is required')
385
+ this._throwCallbackError()
380
386
  }
381
387
  if (!errors) {
382
388
  return callback(new TypeError('must pass errors to send'))
@@ -387,7 +393,7 @@ CollectorAPI.prototype.error_data = function errorData(errors, callback) {
387
393
 
388
394
  CollectorAPI.prototype.error_event_data = function errorEvents(events, callback) {
389
395
  if (!callback) {
390
- throw new TypeError('callback is required')
396
+ this._throwCallbackError()
391
397
  }
392
398
  if (!events) {
393
399
  return callback(new TypeError('must pass errors to send'))
@@ -403,7 +409,7 @@ CollectorAPI.prototype.analytic_event_data = transactionEvents
403
409
  */
404
410
  function transactionEvents(events, callback) {
405
411
  if (!callback) {
406
- throw new TypeError('callback is required')
412
+ this._throwCallbackError()
407
413
  }
408
414
  if (!events) {
409
415
  return callback(new TypeError('must pass events to send'))
@@ -414,7 +420,7 @@ function transactionEvents(events, callback) {
414
420
 
415
421
  CollectorAPI.prototype.custom_event_data = function customEvents(events, callback) {
416
422
  if (!callback) {
417
- throw new TypeError('callback is required')
423
+ this._throwCallbackError()
418
424
  }
419
425
  if (!events) {
420
426
  return callback(new TypeError('must pass events to send'))
@@ -441,7 +447,7 @@ CollectorAPI.prototype.custom_event_data = function customEvents(events, callbac
441
447
  */
442
448
  CollectorAPI.prototype.metric_data = function metricData(metrics, callback) {
443
449
  if (!callback) {
444
- throw new TypeError('callback is required')
450
+ this._throwCallbackError()
445
451
  }
446
452
  if (!metrics) {
447
453
  return callback(new TypeError('must pass metrics to send'))
@@ -464,7 +470,7 @@ CollectorAPI.prototype.metric_data = function metricData(metrics, callback) {
464
470
  */
465
471
  CollectorAPI.prototype.sql_trace_data = function queryData(queries, callback) {
466
472
  if (!callback) {
467
- throw new TypeError('callback is required')
473
+ this._throwCallbackError()
468
474
  }
469
475
  if (!queries) {
470
476
  return callback(new TypeError('must pass queries to send'))
@@ -474,7 +480,7 @@ CollectorAPI.prototype.sql_trace_data = function queryData(queries, callback) {
474
480
 
475
481
  CollectorAPI.prototype.span_event_data = function spanEvents(events, callback) {
476
482
  if (!callback) {
477
- throw new TypeError('callback is required')
483
+ this._throwCallbackError()
478
484
  }
479
485
  if (!events) {
480
486
  return callback(new TypeError('must pass spans to send'))
@@ -503,7 +509,7 @@ CollectorAPI.prototype.transaction_sample_data = transactionSampleData
503
509
  */
504
510
  function transactionSampleData(traces, callback) {
505
511
  if (!callback) {
506
- throw new TypeError('callback is required')
512
+ this._throwCallbackError()
507
513
  }
508
514
  if (!traces) {
509
515
  return callback(new TypeError('must pass traces to send'))
@@ -527,7 +533,7 @@ function transactionSampleData(traces, callback) {
527
533
  */
528
534
  CollectorAPI.prototype.log_event_data = function logEventData(logRecords, callback) {
529
535
  if (!callback) {
530
- throw new TypeError('callback is required')
536
+ this._throwCallbackError()
531
537
  }
532
538
  if (!logRecords) {
533
539
  return callback(new TypeError('must pass logRecords to send'))
@@ -545,7 +551,7 @@ CollectorAPI.prototype.log_event_data = function logEventData(logRecords, callba
545
551
  */
546
552
  CollectorAPI.prototype.shutdown = function shutdown(callback) {
547
553
  if (!callback) {
548
- throw new TypeError('callback is required')
554
+ this._throwCallbackError()
549
555
  }
550
556
 
551
557
  logger.info('Shutting down collector.')
@@ -620,6 +626,7 @@ CollectorAPI.prototype._sendData = function _sendData(method, data, callback) {
620
626
 
621
627
  // TODO: log the payload if exists?
622
628
 
629
+ /*
623
630
  if (response.agentRun === AGENT_RUN_BEHAVIOR.SHUTDOWN) {
624
631
  // TODO: for now, shut handled in _handleResponseCode for consistency
625
632
  // either find way to safely change while side-by-side or move
@@ -635,7 +642,8 @@ CollectorAPI.prototype._sendData = function _sendData(method, data, callback) {
635
642
  // })
636
643
 
637
644
  callback(null, { retainData: response.retainData })
638
- } else if (response.agentRun === AGENT_RUN_BEHAVIOR.RESTART) {
645
+ */
646
+ if (response.agentRun === AGENT_RUN_BEHAVIOR.RESTART) {
639
647
  // TODO: almost seems better to leg aggregator finish (cb) then restart?
640
648
 
641
649
  // TODO: ensure harvesting stopped for all other endpoints. same for shutdown.
@@ -142,13 +142,11 @@ function getAllIPAddresses() {
142
142
  * @param appNames
143
143
  */
144
144
  function getIdentifierOverride(appNames) {
145
- const identifier = [
145
+ return [
146
146
  'nodejs',
147
147
  // NOTE: The concat is necessary to prevent sort from happening in-place.
148
148
  appNames.concat([]).sort().join(',')
149
149
  ].join(':')
150
-
151
- return identifier
152
150
  }
153
151
 
154
152
  /**
@@ -22,7 +22,9 @@ const logger = require('../logger').child({ component: 'new_relic_response' })
22
22
  * error, the value returned by the server
23
23
  * (if any), and the raw JSON of the
24
24
  * server's response.
25
- *
25
+ * @param name
26
+ * @param response
27
+ * @param callback
26
28
  * @returns Function Another callback that is meant to be invoked with
27
29
  * any errors from reading the response stream, as
28
30
  * well as a string containing the full response.
@@ -16,6 +16,7 @@ const Sink = require('../util/stream-sink')
16
16
  const agents = require('./http-agents')
17
17
  const isValidLength = require('../util/byte-limit').isValidLength
18
18
  const { DATA_USAGE } = require('../metrics/names')
19
+ const symbols = require('../symbols')
19
20
 
20
21
  function getMetricName(name) {
21
22
  return `${DATA_USAGE.PREFIX}/${name}/${DATA_USAGE.SUFFIX}`
@@ -249,12 +250,13 @@ RemoteMethod.prototype._safeRequest = function _safeRequest(options) {
249
250
 
250
251
  // If trace level is not explicitly enabled check to see if the audit log is
251
252
  // enabled.
252
- if (logConfig != null && logConfig.level !== 'trace' && auditLog.enabled) {
253
- // If the filter property is empty, then always log the event otherwise
254
- // check to see if the filter includes this method.
255
- if (auditLog.endpoints.length === 0 || auditLog.endpoints.indexOf(this.name) > -1) {
256
- level = 'info'
257
- }
253
+ if (
254
+ logConfig != null &&
255
+ logConfig.level !== 'trace' &&
256
+ auditLog.enabled &&
257
+ (auditLog.endpoints.length === 0 || auditLog.endpoints.indexOf(this.name) > -1)
258
+ ) {
259
+ level = 'info'
258
260
  }
259
261
 
260
262
  const logBody = Buffer.isBuffer(options.body) ? 'Buffer ' + options.body.length : options.body
@@ -295,7 +297,7 @@ RemoteMethod.prototype._request = function _request(options) {
295
297
  path: options.path,
296
298
  headers: this._headers(options),
297
299
  agent: agents.keepAliveAgent(),
298
- __NR__connection: true // Who measures the metrics measurer?
300
+ [symbols.offTheRecord]: true // don't let the http instrumentation record this request
299
301
  }
300
302
  let request
301
303
 
@@ -348,12 +350,10 @@ RemoteMethod.prototype._path = function _path() {
348
350
  query[RUN_ID_NAME] = this._config.run_id
349
351
  }
350
352
 
351
- const formatted = url.format({
353
+ return url.format({
352
354
  pathname: RAW_METHOD_PATH,
353
355
  query: query
354
356
  })
355
-
356
- return formatted
357
357
  }
358
358
 
359
359
  /**
@@ -5,6 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ /* eslint sonarjs/cognitive-complexity: ["error", 16] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
9
+
8
10
  const NO_MATCH = -Infinity
9
11
  const EXACT_MATCH = Infinity
10
12
  const DESTINATIONS = {
@@ -52,7 +54,6 @@ exports.DESTINATIONS = DESTINATIONS
52
54
  *
53
55
  * @class
54
56
  * @private
55
- *
56
57
  * @param {Config} config - The configuration object for the agent.
57
58
  */
58
59
  function AttributeFilter(config) {
@@ -87,8 +88,7 @@ function AttributeFilter(config) {
87
88
  *
88
89
  * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
89
90
  * @param {string} key - The name of the attribute to test.
90
- *
91
- * @return {DESTINATIONS} The destinations the attribute should be put.
91
+ * @returns {DESTINATIONS} The destinations the attribute should be put.
92
92
  */
93
93
  AttributeFilter.prototype.filterTransaction = filterTransaction
94
94
  function filterTransaction(destinations, key) {
@@ -100,8 +100,7 @@ function filterTransaction(destinations, key) {
100
100
  *
101
101
  * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
102
102
  * @param {string} key - The name of the attribute to test.
103
- *
104
- * @return {DESTINATIONS} The destinations the attribute should be put.
103
+ * @returns {DESTINATIONS} The destinations the attribute should be put.
105
104
  */
106
105
  AttributeFilter.prototype.filterSegment = function filterSegment(destinations, key) {
107
106
  return this._filter(SEGMENT_SCOPE_DETAILS, destinations, key)
@@ -112,8 +111,7 @@ AttributeFilter.prototype.filterSegment = function filterSegment(destinations, k
112
111
  *
113
112
  * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
114
113
  * @param {string} key - The name of the attribute to test.
115
- *
116
- * @return {DESTINATIONS} The destinations the attribute should be put.
114
+ * @returns {DESTINATIONS} The destinations the attribute should be put.
117
115
  */
118
116
  AttributeFilter.prototype.filterAll = function filterSegment(destinations, key) {
119
117
  return this._filter(DESTINATION_DETAILS, destinations, key)
@@ -122,11 +120,10 @@ AttributeFilter.prototype.filterAll = function filterSegment(destinations, key)
122
120
  /**
123
121
  * Tests a given key against the global and destination filters.
124
122
  *
125
- * @param {array} scope - The destination details for filtering.
123
+ * @param {Array} scope - The destination details for filtering.
126
124
  * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
127
125
  * @param {string} key - The name of the attribute to test.
128
- *
129
- * @return {DESTINATIONS} The destinations the attribute should be put.
126
+ * @returns {DESTINATIONS} The destinations the attribute should be put.
130
127
  */
131
128
  AttributeFilter.prototype._filter = function _filter(scope, destinations, key) {
132
129
  // This method could be easily memoized since for a given destination and key
@@ -212,9 +209,12 @@ AttributeFilter.prototype.update = function update() {
212
209
  /**
213
210
  * Applies the global and destination rules to this key.
214
211
  *
212
+ * @param globalInclude
213
+ * @param globalExclude
214
+ * @param destConfig
215
+ * @param key
215
216
  * @private
216
- *
217
- * @return {bool|number} True if this key is explicitly included, false if it is
217
+ * @returns {bool|number} True if this key is explicitly included, false if it is
218
218
  * explicitly excluded, or `NO_MATCH` if no rule applies.
219
219
  */
220
220
  function _doTest(globalInclude, globalExclude, destConfig, key) {
@@ -289,10 +289,8 @@ function _matchRules(rules, key) {
289
289
  * Converts the raw rules into a set of regular expressions to test against.
290
290
  *
291
291
  * @private
292
- *
293
- * @param {array.<string>} rules - The set of rules to compose.
294
- *
295
- * @return {object} An object with `exact` and `wildcard` properties which are
292
+ * @param {Array.<string>} rules - The set of rules to compose.
293
+ * @returns {object} An object with `exact` and `wildcard` properties which are
296
294
  * `RegExp` instances for testing keys.
297
295
  */
298
296
  function _importRules(rules) {