rollbar 2.26.3 → 3.0.0-alpha.1

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 (186) hide show
  1. package/.cursor/rules/guidelines.mdc +154 -0
  2. package/.github/workflows/ci.yml +32 -12
  3. package/.lgtm.yml +7 -7
  4. package/.prettierignore +18 -0
  5. package/.vscode/settings.json +39 -0
  6. package/CHANGELOG.md +121 -35
  7. package/CLAUDE.md +201 -0
  8. package/Gruntfile.js +101 -48
  9. package/Makefile +3 -3
  10. package/README.md +2 -4
  11. package/SECURITY.md +5 -0
  12. package/babel.config.json +9 -0
  13. package/bower.json +1 -3
  14. package/codex.md +148 -0
  15. package/defaults.js +17 -5
  16. package/dist/plugins/jquery.min.js +1 -1
  17. package/dist/rollbar.js +18748 -5375
  18. package/dist/rollbar.js.map +1 -1
  19. package/dist/rollbar.min.js +2 -1
  20. package/dist/rollbar.min.js.LICENSE.txt +1 -0
  21. package/dist/rollbar.min.js.map +1 -1
  22. package/dist/rollbar.named-amd.js +19368 -6000
  23. package/dist/rollbar.named-amd.js.map +1 -1
  24. package/dist/rollbar.named-amd.min.js +3 -1
  25. package/dist/rollbar.named-amd.min.js.LICENSE.txt +1 -0
  26. package/dist/rollbar.named-amd.min.js.map +1 -1
  27. package/dist/rollbar.noconflict.umd.js +18749 -5380
  28. package/dist/rollbar.noconflict.umd.js.map +1 -1
  29. package/dist/rollbar.noconflict.umd.min.js +3 -1
  30. package/dist/rollbar.noconflict.umd.min.js.LICENSE.txt +1 -0
  31. package/dist/rollbar.noconflict.umd.min.js.map +1 -1
  32. package/dist/rollbar.snippet.js +1 -1
  33. package/dist/rollbar.umd.js +19367 -6000
  34. package/dist/rollbar.umd.js.map +1 -1
  35. package/dist/rollbar.umd.min.js +3 -1
  36. package/dist/rollbar.umd.min.js.LICENSE.txt +1 -0
  37. package/dist/rollbar.umd.min.js.map +1 -1
  38. package/docs/extension-exceptions.md +35 -30
  39. package/docs/migration_v0_to_v1.md +41 -38
  40. package/eslint.config.mjs +33 -0
  41. package/get_versions.js +33 -0
  42. package/index.d.ts +270 -231
  43. package/karma.conf.js +18 -27
  44. package/package.json +21 -21
  45. package/prettier.config.js +7 -0
  46. package/src/api.js +78 -14
  47. package/src/apiUtility.js +14 -11
  48. package/src/browser/core.js +138 -72
  49. package/src/browser/defaults/scrubFields.js +3 -3
  50. package/src/browser/detection.js +7 -8
  51. package/src/browser/domUtility.js +18 -8
  52. package/src/browser/globalSetup.js +12 -6
  53. package/src/browser/logger.js +1 -1
  54. package/src/browser/plugins/jquery.js +35 -35
  55. package/src/browser/predicates.js +1 -1
  56. package/src/browser/replay/defaults.js +71 -0
  57. package/src/browser/replay/recorder.js +193 -0
  58. package/src/browser/replay/replayMap.js +195 -0
  59. package/src/browser/rollbar.js +12 -8
  60. package/src/browser/rollbarWrapper.js +8 -5
  61. package/src/browser/shim.js +43 -19
  62. package/src/browser/snippet_callback.js +6 -4
  63. package/src/browser/telemetry.js +573 -361
  64. package/src/browser/transforms.js +46 -27
  65. package/src/browser/transport/fetch.js +26 -14
  66. package/src/browser/transport/xhr.js +41 -14
  67. package/src/browser/transport.js +93 -33
  68. package/src/browser/url.js +16 -8
  69. package/src/browser/wrapGlobals.js +27 -8
  70. package/src/defaults.js +3 -3
  71. package/src/errorParser.js +14 -11
  72. package/src/merge.js +32 -23
  73. package/src/notifier.js +16 -13
  74. package/src/predicates.js +43 -23
  75. package/src/queue.js +133 -40
  76. package/src/rateLimiter.js +59 -18
  77. package/src/react-native/logger.js +1 -1
  78. package/src/react-native/rollbar.js +59 -55
  79. package/src/react-native/transforms.js +13 -9
  80. package/src/react-native/transport.js +44 -34
  81. package/src/rollbar.js +72 -21
  82. package/src/scrub.js +0 -1
  83. package/src/server/locals.js +69 -39
  84. package/src/server/logger.js +4 -4
  85. package/src/server/parser.js +72 -47
  86. package/src/server/rollbar.js +135 -56
  87. package/src/server/sourceMap/stackTrace.js +33 -18
  88. package/src/server/telemetry/urlHelpers.js +9 -11
  89. package/src/server/telemetry.js +68 -45
  90. package/src/server/transforms.js +37 -21
  91. package/src/server/transport.js +62 -32
  92. package/src/telemetry.js +162 -33
  93. package/src/tracing/context.js +24 -0
  94. package/src/tracing/contextManager.js +37 -0
  95. package/src/tracing/defaults.js +7 -0
  96. package/src/tracing/exporter.js +188 -0
  97. package/src/tracing/hrtime.js +98 -0
  98. package/src/tracing/id.js +24 -0
  99. package/src/tracing/session.js +55 -0
  100. package/src/tracing/span.js +92 -0
  101. package/src/tracing/spanProcessor.js +15 -0
  102. package/src/tracing/tracer.js +46 -0
  103. package/src/tracing/tracing.js +89 -0
  104. package/src/transforms.js +33 -21
  105. package/src/truncation.js +8 -5
  106. package/src/utility/headers.js +43 -43
  107. package/src/utility/replace.js +9 -0
  108. package/src/utility/traverse.js +1 -1
  109. package/src/utility.js +123 -52
  110. package/test/api.test.js +88 -41
  111. package/test/apiUtility.test.js +48 -50
  112. package/test/browser.core.test.js +142 -141
  113. package/test/browser.domUtility.test.js +53 -36
  114. package/test/browser.predicates.test.js +14 -14
  115. package/test/browser.replay.recorder.test.js +416 -0
  116. package/test/browser.rollbar.test.js +655 -515
  117. package/test/browser.telemetry.test.js +46 -39
  118. package/test/browser.transforms.test.js +164 -139
  119. package/test/browser.transport.test.js +59 -50
  120. package/test/browser.url.test.js +13 -12
  121. package/test/fixtures/locals.fixtures.js +245 -126
  122. package/test/fixtures/replay/index.js +20 -0
  123. package/test/fixtures/replay/payloads.fixtures.js +229 -0
  124. package/test/fixtures/replay/rrwebEvents.fixtures.js +251 -0
  125. package/test/fixtures/replay/rrwebSyntheticEvents.fixtures.js +328 -0
  126. package/test/notifier.test.js +91 -79
  127. package/test/predicates.test.js +261 -215
  128. package/test/queue.test.js +231 -215
  129. package/test/rateLimiter.test.js +51 -43
  130. package/test/react-native.rollbar.test.js +150 -116
  131. package/test/react-native.transforms.test.js +23 -25
  132. package/test/react-native.transport.test.js +26 -14
  133. package/test/replay/index.js +2 -0
  134. package/test/replay/integration/api.spans.test.js +136 -0
  135. package/test/replay/integration/e2e.test.js +228 -0
  136. package/test/replay/integration/index.js +9 -0
  137. package/test/replay/integration/queue.replayMap.test.js +332 -0
  138. package/test/replay/integration/replayMap.test.js +163 -0
  139. package/test/replay/integration/sessionRecording.test.js +390 -0
  140. package/test/replay/unit/api.postSpans.test.js +150 -0
  141. package/test/replay/unit/index.js +7 -0
  142. package/test/replay/unit/queue.replayMap.test.js +225 -0
  143. package/test/replay/unit/replayMap.test.js +348 -0
  144. package/test/replay/util/index.js +5 -0
  145. package/test/replay/util/mockRecordFn.js +80 -0
  146. package/test/server.lambda.mocha.test.mjs +172 -0
  147. package/test/server.locals.constructor.mocha.test.mjs +80 -0
  148. package/test/server.locals.error-handling.mocha.test.mjs +387 -0
  149. package/test/server.locals.merge.mocha.test.mjs +267 -0
  150. package/test/server.locals.test-utils.mjs +114 -0
  151. package/test/server.parser.mocha.test.mjs +87 -0
  152. package/test/server.predicates.mocha.test.mjs +63 -0
  153. package/test/server.rollbar.constructor.mocha.test.mjs +199 -0
  154. package/test/server.rollbar.handlers.mocha.test.mjs +253 -0
  155. package/test/server.rollbar.logging.mocha.test.mjs +326 -0
  156. package/test/server.rollbar.misc.mocha.test.mjs +44 -0
  157. package/test/server.rollbar.test-utils.mjs +57 -0
  158. package/test/server.telemetry.mocha.test.mjs +377 -0
  159. package/test/server.transforms.data.mocha.test.mjs +163 -0
  160. package/test/server.transforms.error.mocha.test.mjs +199 -0
  161. package/test/server.transforms.request.mocha.test.mjs +208 -0
  162. package/test/server.transforms.scrub.mocha.test.mjs +140 -0
  163. package/test/server.transforms.sourcemaps.mocha.test.mjs +122 -0
  164. package/test/server.transforms.test-utils.mjs +62 -0
  165. package/test/server.transport.mocha.test.mjs +269 -0
  166. package/test/telemetry.test.js +178 -38
  167. package/test/tracing/contextManager.test.js +28 -0
  168. package/test/tracing/exporter.toPayload.test.js +400 -0
  169. package/test/tracing/id.test.js +24 -0
  170. package/test/tracing/span.test.js +183 -0
  171. package/test/tracing/spanProcessor.test.js +73 -0
  172. package/test/tracing/tracing.test.js +105 -0
  173. package/test/transforms.test.js +70 -68
  174. package/test/truncation.test.js +57 -55
  175. package/test/utility.test.js +310 -228
  176. package/webpack.config.js +36 -70
  177. package/.eslintignore +0 -7
  178. package/.gitmodules +0 -3
  179. package/test/server.lambda.test.js +0 -177
  180. package/test/server.locals.test.js +0 -841
  181. package/test/server.parser.test.js +0 -72
  182. package/test/server.predicates.test.js +0 -89
  183. package/test/server.rollbar.test.js +0 -676
  184. package/test/server.telemetry.test.js +0 -318
  185. package/test/server.transforms.test.js +0 -1099
  186. package/test/server.transport.test.js +0 -201
@@ -3,46 +3,61 @@
3
3
  /* globals it */
4
4
  /* globals sinon */
5
5
 
6
- var _ = require('../src/utility');
7
- var utility = require('../src/utility');
8
- var polyfillJSON = require('../vendor/JSON-js/json3');
6
+ import _ from '../src/utility.js';
7
+ import utility from '../src/utility.js';
8
+ import polyfillJSON from '../vendor/JSON-js/json3.js';
9
9
 
10
10
  utility.setupJSON();
11
11
 
12
- describe('setupJSON', function() {
13
- beforeEach(function(){
12
+ describe('setupJSON', function () {
13
+ beforeEach(function () {
14
14
  utility.RollbarJSON.stringify = null;
15
15
  utility.RollbarJSON.parse = null;
16
16
  });
17
17
 
18
- afterEach(function(){
18
+ afterEach(function () {
19
19
  // Resets utility.RollbarJSON
20
20
  utility.RollbarJSON.stringify = null;
21
21
  utility.RollbarJSON.parse = null;
22
22
  utility.setupJSON();
23
23
  });
24
24
 
25
- it('should use native interface when polyfill is provided', function() {
26
- var native = {stringify: JSON.stringify, parse: JSON.parse};
25
+ it('should use native interface when polyfill is provided', function () {
26
+ var native = { stringify: JSON.stringify, parse: JSON.parse };
27
27
 
28
28
  utility.setupJSON(polyfillJSON);
29
29
 
30
- expect(utility.RollbarJSON.stringify.toString()).to.equal(native.stringify.toString());
31
- expect(utility.RollbarJSON.parse.toString()).to.equal(native.parse.toString());
30
+ expect(utility.RollbarJSON.stringify.toString()).to.equal(
31
+ native.stringify.toString(),
32
+ );
33
+ expect(utility.RollbarJSON.parse.toString()).to.equal(
34
+ native.parse.toString(),
35
+ );
32
36
  });
33
37
 
34
- it('should use native interface when polyfill is not provided', function() {
35
- var native = {stringify: JSON.stringify, parse: JSON.parse};
38
+ it('should use native interface when polyfill is not provided', function () {
39
+ var native = { stringify: JSON.stringify, parse: JSON.parse };
36
40
 
37
41
  utility.setupJSON();
38
42
 
39
- expect(utility.RollbarJSON.stringify.toString()).to.equal(native.stringify.toString());
40
- expect(utility.RollbarJSON.parse.toString()).to.equal(native.parse.toString());
43
+ expect(utility.RollbarJSON.stringify.toString()).to.equal(
44
+ native.stringify.toString(),
45
+ );
46
+ expect(utility.RollbarJSON.parse.toString()).to.equal(
47
+ native.parse.toString(),
48
+ );
41
49
  });
42
50
 
43
- it('should replace custom interface when polyfill is provided', function() {
44
- var native = {stringify: JSON.stringify, parse: JSON.parse};
45
- var custom = {stringify: function(json){ return json;}, parse: function(json){ return json;}};
51
+ it('should replace custom interface when polyfill is provided', function () {
52
+ var native = { stringify: JSON.stringify, parse: JSON.parse };
53
+ var custom = {
54
+ stringify: function (json) {
55
+ return json;
56
+ },
57
+ parse: function (json) {
58
+ return json;
59
+ },
60
+ };
46
61
  var polyfill = {};
47
62
  polyfillJSON(polyfill);
48
63
 
@@ -52,17 +67,28 @@ describe('setupJSON', function() {
52
67
 
53
68
  utility.setupJSON(polyfillJSON);
54
69
 
55
- expect(utility.RollbarJSON.stringify.toString()).to.equal(polyfill.stringify.toString());
56
- expect(utility.RollbarJSON.parse.toString()).to.equal(polyfill.parse.toString());
70
+ expect(utility.RollbarJSON.stringify.toString()).to.equal(
71
+ polyfill.stringify.toString(),
72
+ );
73
+ expect(utility.RollbarJSON.parse.toString()).to.equal(
74
+ polyfill.parse.toString(),
75
+ );
57
76
 
58
77
  // restore original interface
59
78
  JSON.stringify = native.stringify;
60
79
  JSON.parse = native.parse;
61
80
  });
62
81
 
63
- it('should keep custom interface when polyfill is not provided', function() {
64
- var native = {stringify: JSON.stringify, parse: JSON.parse};
65
- var custom = {stringify: function(json){ return json;}, parse: function(json){ return json;}};
82
+ it('should keep custom interface when polyfill is not provided', function () {
83
+ var native = { stringify: JSON.stringify, parse: JSON.parse };
84
+ var custom = {
85
+ stringify: function (json) {
86
+ return json;
87
+ },
88
+ parse: function (json) {
89
+ return json;
90
+ },
91
+ };
66
92
 
67
93
  // Set to custom interface
68
94
  JSON.stringify = custom.stringify;
@@ -70,8 +96,12 @@ describe('setupJSON', function() {
70
96
 
71
97
  utility.setupJSON();
72
98
 
73
- expect(utility.RollbarJSON.stringify.toString()).to.equal(custom.stringify.toString());
74
- expect(utility.RollbarJSON.parse.toString()).to.equal(custom.parse.toString());
99
+ expect(utility.RollbarJSON.stringify.toString()).to.equal(
100
+ custom.stringify.toString(),
101
+ );
102
+ expect(utility.RollbarJSON.parse.toString()).to.equal(
103
+ custom.parse.toString(),
104
+ );
75
105
 
76
106
  // restore original interface
77
107
  JSON.stringify = native.stringify;
@@ -79,18 +109,18 @@ describe('setupJSON', function() {
79
109
  });
80
110
  });
81
111
 
82
- describe('typeName', function() {
83
- it('should handle undefined', function(done) {
112
+ describe('typeName', function () {
113
+ it('should handle undefined', function (done) {
84
114
  expect(_.typeName(undefined)).to.eql('undefined');
85
115
  done();
86
116
  });
87
117
 
88
- it('should handle null', function(done) {
118
+ it('should handle null', function (done) {
89
119
  expect(_.typeName(null)).to.eql('null');
90
120
  done();
91
121
  });
92
122
 
93
- it('should handle numbers', function(done) {
123
+ it('should handle numbers', function (done) {
94
124
  expect(_.typeName(1)).to.eql('number');
95
125
  expect(_.typeName(-32)).to.eql('number');
96
126
  expect(_.typeName(1.452)).to.eql('number');
@@ -98,49 +128,48 @@ describe('typeName', function() {
98
128
  done();
99
129
  });
100
130
 
101
- it('should handle bools', function(done) {
131
+ it('should handle bools', function (done) {
102
132
  expect(_.typeName(true)).to.eql('boolean');
103
133
  expect(_.typeName(false)).to.eql('boolean');
104
134
  done();
105
135
  });
106
136
 
107
- it('should handle strings', function(done) {
137
+ it('should handle strings', function (done) {
108
138
  expect(_.typeName('')).to.eql('string');
109
139
  expect(_.typeName('a longer string')).to.eql('string');
110
140
  done();
111
141
  });
112
142
 
113
- it('should handle functions', function(done) {
114
- expect(_.typeName(function(){})).to.eql('function');
115
- var f = function(x) {
143
+ it('should handle functions', function (done) {
144
+ expect(_.typeName(function () {})).to.eql('function');
145
+ var f = function (x) {
116
146
  return x;
117
147
  };
118
148
  expect(_.typeName(f)).to.eql('function');
119
149
  done();
120
150
  });
121
151
 
122
- it('should handle objects', function(done) {
152
+ it('should handle objects', function (done) {
123
153
  expect(_.typeName({})).to.eql('object');
124
- expect(_.typeName({a: 123})).to.eql('object');
154
+ expect(_.typeName({ a: 123 })).to.eql('object');
125
155
  done();
126
156
  });
127
157
 
128
- it('should handle arrays', function(done) {
158
+ it('should handle arrays', function (done) {
129
159
  expect(_.typeName([])).to.eql('array');
130
- expect(_.typeName([1, {a: 42}, null])).to.eql('array');
160
+ expect(_.typeName([1, { a: 42 }, null])).to.eql('array');
131
161
  done();
132
162
  });
133
-
134
163
  });
135
164
 
136
- describe('isType', function() {
137
- it('should handle all types', function(done) {
165
+ describe('isType', function () {
166
+ it('should handle all types', function (done) {
138
167
  expect(_.isType(undefined, 'undefined')).to.be.ok();
139
168
  expect(_.isType(undefined, 'null')).to.not.be.ok();
140
169
  expect(_.isType(null, 'null')).to.be.ok();
141
170
  expect(_.isType(null, 'object')).to.not.be.ok();
142
171
  expect(_.isType({}, 'object')).to.be.ok();
143
- expect(_.isType(function(){}, 'function')).to.be.ok();
172
+ expect(_.isType(function () {}, 'function')).to.be.ok();
144
173
  expect(_.isType(42, 'number')).to.be.ok();
145
174
  expect(_.isType('42', 'string')).to.be.ok();
146
175
  expect(_.isType([], 'array')).to.be.ok();
@@ -150,10 +179,12 @@ describe('isType', function() {
150
179
  });
151
180
  });
152
181
 
153
- describe('isFunction', function() {
154
- it('should work for all functions', function(done) {
155
- var f = function() { return; };
156
- var g = function(x) {
182
+ describe('isFunction', function () {
183
+ it('should work for all functions', function (done) {
184
+ var f = function () {
185
+ return;
186
+ };
187
+ var g = function (x) {
157
188
  return f(x);
158
189
  };
159
190
  expect(_.isFunction({})).to.not.be.ok();
@@ -162,12 +193,13 @@ describe('isFunction', function() {
162
193
  expect(_.isFunction(g)).to.be.ok();
163
194
  done();
164
195
  });
165
-
166
196
  });
167
- describe('isNativeFunction', function() {
168
- it('should work for all native functions', function(done) {
169
- var f = function() { return; };
170
- var g = function(x) {
197
+ describe('isNativeFunction', function () {
198
+ it('should work for all native functions', function (done) {
199
+ var f = function () {
200
+ return;
201
+ };
202
+ var g = function (x) {
171
203
  return f(x);
172
204
  };
173
205
  var h = String.prototype.substr;
@@ -182,11 +214,11 @@ describe('isNativeFunction', function() {
182
214
  });
183
215
  });
184
216
 
185
- describe('isIterable', function() {
186
- it('should work for all types', function(done) {
217
+ describe('isIterable', function () {
218
+ it('should work for all types', function (done) {
187
219
  expect(_.isIterable({})).to.be.ok();
188
220
  expect(_.isIterable([])).to.be.ok();
189
- expect(_.isIterable([{a: 1}])).to.be.ok();
221
+ expect(_.isIterable([{ a: 1 }])).to.be.ok();
190
222
  expect(_.isIterable(null)).to.not.be.ok();
191
223
  expect(_.isIterable(undefined)).to.not.be.ok();
192
224
  expect(_.isIterable('object')).to.not.be.ok();
@@ -195,17 +227,17 @@ describe('isIterable', function() {
195
227
  });
196
228
  });
197
229
 
198
- describe('isError', function() {
199
- it('should handle null', function(done) {
230
+ describe('isError', function () {
231
+ it('should handle null', function (done) {
200
232
  expect(_.isError(null)).to.not.be.ok();
201
233
  done();
202
234
  });
203
- it('should handle errors', function(done) {
235
+ it('should handle errors', function (done) {
204
236
  var e = new Error('hello');
205
237
  expect(_.isError(e)).to.be.ok();
206
238
  done();
207
239
  });
208
- it('should handle subclasses of error', function(done) {
240
+ it('should handle subclasses of error', function (done) {
209
241
  // This is a mostly browser compliant way of doing this
210
242
  // just for the sake of doing it, even though we mostly
211
243
  // need this to work in node environments
@@ -213,13 +245,13 @@ describe('isError', function() {
213
245
  Object.defineProperty(this, 'name', {
214
246
  enumerable: false,
215
247
  writable: false,
216
- value: 'TestCustomError'
248
+ value: 'TestCustomError',
217
249
  });
218
250
 
219
251
  Object.defineProperty(this, 'message', {
220
252
  enumerable: false,
221
253
  writable: true,
222
- value: message
254
+ value: message,
223
255
  });
224
256
 
225
257
  if (Error.hasOwnProperty('captureStackTrace')) {
@@ -228,7 +260,7 @@ describe('isError', function() {
228
260
  Object.defineProperty(this, 'stack', {
229
261
  enumerable: false,
230
262
  writable: false,
231
- value: (new Error(message)).stack
263
+ value: new Error(message).stack,
232
264
  });
233
265
  }
234
266
  }
@@ -237,7 +269,7 @@ describe('isError', function() {
237
269
  Object.setPrototypeOf(TestCustomError.prototype, Error.prototype);
238
270
  } else {
239
271
  TestCustomError.prototype = Object.create(Error.prototype, {
240
- constructor: { value: TestCustomError }
272
+ constructor: { value: TestCustomError },
241
273
  });
242
274
  }
243
275
  var e = new TestCustomError('bork');
@@ -246,25 +278,25 @@ describe('isError', function() {
246
278
  });
247
279
  });
248
280
 
249
- describe('isFiniteNumber', function() {
250
- [ NaN, null, undefined, 'x' ].forEach(function(value) {
251
- it(`should return false for ${value}`, function(done) {
281
+ describe('isFiniteNumber', function () {
282
+ [NaN, null, undefined, 'x'].forEach(function (value) {
283
+ it(`should return false for ${value}`, function (done) {
252
284
  expect(_.isFiniteNumber(value)).to.equal(false);
253
285
  done();
254
286
  });
255
287
  });
256
- [ -100, 0, 100 ].forEach(function(value) {
257
- it(`should return true for ${value}`, function(done) {
288
+ [-100, 0, 100].forEach(function (value) {
289
+ it(`should return true for ${value}`, function (done) {
258
290
  expect(_.isFiniteNumber(value)).to.equal(true);
259
291
  done();
260
292
  });
261
293
  });
262
294
  });
263
295
 
264
- describe('merge', function() {
265
- it('should work for simple objects', function(done) {
266
- var o1 = {a: 1, b: 2};
267
- var o2 = {a: 42, c: 101};
296
+ describe('merge', function () {
297
+ it('should work for simple objects', function (done) {
298
+ var o1 = { a: 1, b: 2 };
299
+ var o2 = { a: 42, c: 101 };
268
300
  var e = _.merge(o1, o2);
269
301
 
270
302
  expect(e.a).to.eql(42);
@@ -278,9 +310,9 @@ describe('merge', function() {
278
310
 
279
311
  done();
280
312
  });
281
- it('should not concat arrays', function(done) {
282
- var o1 = {a: 1, b: ['hello', 'world']};
283
- var o2 = {a: 42, b: ['goodbye']};
313
+ it('should not concat arrays', function (done) {
314
+ var o1 = { a: 1, b: ['hello', 'world'] };
315
+ var o2 = { a: 42, b: ['goodbye'] };
284
316
  var e = _.merge(o1, o2);
285
317
 
286
318
  expect(e.a).to.eql(42);
@@ -292,17 +324,17 @@ describe('merge', function() {
292
324
  expect(o1.b).not.to.contain('goodbye');
293
325
  done();
294
326
  });
295
- it('should handle nested objects', function(done) {
327
+ it('should handle nested objects', function (done) {
296
328
  var o1 = {
297
329
  a: 1,
298
330
  c: 100,
299
331
  payload: {
300
332
  person: {
301
333
  id: 'xxx',
302
- name: 'hello'
334
+ name: 'hello',
303
335
  },
304
- environment: 'foo'
305
- }
336
+ environment: 'foo',
337
+ },
306
338
  };
307
339
  var o2 = {
308
340
  a: 42,
@@ -310,10 +342,10 @@ describe('merge', function() {
310
342
  payload: {
311
343
  person: {
312
344
  id: 'yesyes',
313
- email: 'cool'
345
+ email: 'cool',
314
346
  },
315
- other: 'bar'
316
- }
347
+ other: 'bar',
348
+ },
317
349
  };
318
350
  var e = _.merge(o1, o2);
319
351
 
@@ -327,7 +359,7 @@ describe('merge', function() {
327
359
  expect(e.payload.other).to.eql('bar');
328
360
  done();
329
361
  });
330
- it('should handle nested arrays and objects, with non-matching structure', function(done) {
362
+ it('should handle nested arrays and objects, with non-matching structure', function (done) {
331
363
  var o1 = {
332
364
  a: 1,
333
365
  c: {
@@ -335,12 +367,12 @@ describe('merge', function() {
335
367
  other: [99, 100, 101],
336
368
  payload: {
337
369
  foo: {
338
- bar: 'baz'
370
+ bar: 'baz',
339
371
  },
340
372
  hello: 'world',
341
- keeper: 'yup'
342
- }
343
- }
373
+ keeper: 'yup',
374
+ },
375
+ },
344
376
  };
345
377
  var o2 = {
346
378
  a: 32,
@@ -350,10 +382,10 @@ describe('merge', function() {
350
382
  payload: {
351
383
  foo: 'hello',
352
384
  hello: {
353
- baz: 'bar'
354
- }
355
- }
356
- }
385
+ baz: 'bar',
386
+ },
387
+ },
388
+ },
357
389
  };
358
390
  var e = _.merge(o1, o2);
359
391
 
@@ -368,17 +400,17 @@ describe('merge', function() {
368
400
  done();
369
401
  });
370
402
 
371
- it('should handle many nested objects', function(done) {
403
+ it('should handle many nested objects', function (done) {
372
404
  var o1 = {
373
405
  a: 1,
374
406
  c: 100,
375
407
  payload: {
376
408
  person: {
377
409
  id: 'xxx',
378
- name: 'hello'
410
+ name: 'hello',
379
411
  },
380
- environment: 'foo'
381
- }
412
+ environment: 'foo',
413
+ },
382
414
  };
383
415
  var o2 = {
384
416
  a: 42,
@@ -386,19 +418,19 @@ describe('merge', function() {
386
418
  payload: {
387
419
  person: {
388
420
  id: 'yesyes',
389
- email: 'cool'
421
+ email: 'cool',
390
422
  },
391
- other: 'bar'
392
- }
423
+ other: 'bar',
424
+ },
393
425
  };
394
426
  var o3 = {
395
427
  payload: {
396
428
  fuzz: 'buzz',
397
429
  person: {
398
- name: 'nope'
399
- }
430
+ name: 'nope',
431
+ },
400
432
  },
401
- amihere: 'yes'
433
+ amihere: 'yes',
402
434
  };
403
435
  var e = _.merge(o1, o2, o3);
404
436
 
@@ -416,14 +448,14 @@ describe('merge', function() {
416
448
  });
417
449
  });
418
450
 
419
- var traverse = require('../src/utility/traverse');
420
- describe('traverse', function() {
421
- describe('should call the func for every key,value', function() {
422
- it('simple object', function(done) {
423
- var obj = {a: 1, b: 2};
424
- var expectedOutput = {a: 2, b: 3};
451
+ import traverse from '../src/utility/traverse.js';
452
+ describe('traverse', function () {
453
+ describe('should call the func for every key,value', function () {
454
+ it('simple object', function (done) {
455
+ var obj = { a: 1, b: 2 };
456
+ var expectedOutput = { a: 2, b: 3 };
425
457
  var callCount = 0;
426
- var result = traverse(obj, function(k, v) {
458
+ var result = traverse(obj, function (k, v) {
427
459
  callCount++;
428
460
  return v + 1;
429
461
  });
@@ -432,15 +464,15 @@ describe('traverse', function() {
432
464
 
433
465
  done();
434
466
  });
435
- it('nested object', function(done) {
436
- var obj = {a: 1, b: 2, c: {ca: 11}};
437
- var expectedOutput = {a: 2, b: 3, c: {ca: 12}};
467
+ it('nested object', function (done) {
468
+ var obj = { a: 1, b: 2, c: { ca: 11 } };
469
+ var expectedOutput = { a: 2, b: 3, c: { ca: 12 } };
438
470
  var callCount = 0;
439
- var result = traverse(obj, function(k, v) {
471
+ var result = traverse(obj, function (k, v) {
440
472
  callCount++;
441
473
  if (k === 'c') {
442
- return {ca: v.ca+1};
443
- }
474
+ return { ca: v.ca + 1 };
475
+ }
444
476
  return v + 1;
445
477
  });
446
478
  expect(result).to.eql(expectedOutput);
@@ -448,14 +480,18 @@ describe('traverse', function() {
448
480
 
449
481
  done();
450
482
  });
451
- it('array', function(done) {
483
+ it('array', function (done) {
452
484
  var obj = [1, 2, 3];
453
485
  var expected = [0, 1, 2];
454
486
  var callCount = 0;
455
- var result = traverse(obj, function(k, v) {
456
- callCount++;
457
- return v - 1;
458
- }, []);
487
+ var result = traverse(
488
+ obj,
489
+ function (k, v) {
490
+ callCount++;
491
+ return v - 1;
492
+ },
493
+ [],
494
+ );
459
495
  expect(result).to.eql(expected);
460
496
  expect(callCount).to.eql(3);
461
497
  done();
@@ -463,8 +499,8 @@ describe('traverse', function() {
463
499
  });
464
500
  });
465
501
 
466
- describe('uuid4', function() {
467
- it('should return a version 4 uuid', function(done) {
502
+ describe('uuid4', function () {
503
+ it('should return a version 4 uuid', function (done) {
468
504
  var id = _.uuid4();
469
505
  var otherId = _.uuid4();
470
506
  expect(id).to.not.eql(otherId);
@@ -480,11 +516,11 @@ describe('uuid4', function() {
480
516
  });
481
517
  });
482
518
 
483
- describe('redact', function() {
484
- it('should return a string of stars', function(done) {
519
+ describe('redact', function () {
520
+ it('should return a string of stars', function (done) {
485
521
  var s1 = 'thisIsApasswrD';
486
522
  var s2 = 'short';
487
- var o = {a: 123};
523
+ var o = { a: 123 };
488
524
  var a = [12, 34, 56];
489
525
 
490
526
  expect(_.redact(s1)).to.not.match(/[^*]/);
@@ -494,184 +530,198 @@ describe('redact', function() {
494
530
  expect(_.redact(a)).to.not.match(/[^*]/);
495
531
 
496
532
  done();
497
- })
533
+ });
498
534
  });
499
535
 
500
- describe('LEVELS', function() {
501
- it('should include debug', function() {
536
+ describe('LEVELS', function () {
537
+ it('should include debug', function () {
502
538
  expect(_.LEVELS['debug']).to.not.eql(undefined);
503
539
  });
504
- it('should have critical higher than debug', function() {
540
+ it('should have critical higher than debug', function () {
505
541
  expect(_.LEVELS['critical']).to.be.greaterThan(_.LEVELS['debug']);
506
542
  });
507
543
  });
508
544
 
509
- describe('formatUrl', function() {
510
- it('should handle a missing protocol', function() {
545
+ describe('formatUrl', function () {
546
+ it('should handle a missing protocol', function () {
511
547
  var u = {
512
548
  hostname: 'a.b.com',
513
549
  path: '/wooza/',
514
- port: 42
550
+ port: 42,
515
551
  };
516
552
  expect(_.formatUrl(u)).to.eql('https://a.b.com:42/wooza/');
517
553
  });
518
- it('should use a forced protocol', function() {
554
+ it('should use a forced protocol', function () {
519
555
  var u = {
520
556
  hostname: 'a.b.com',
521
557
  path: '/wooza/',
522
- port: 42
558
+ port: 42,
523
559
  };
524
560
  expect(_.formatUrl(u, 'file:')).to.eql('file://a.b.com:42/wooza/');
525
561
  });
526
- it('should pick a protocol based on port if others are missing', function() {
562
+ it('should pick a protocol based on port if others are missing', function () {
527
563
  var u = {
528
564
  hostname: 'a.b.com',
529
565
  port: 80,
530
- path: '/woo'
566
+ path: '/woo',
531
567
  };
532
568
  expect(_.formatUrl(u)).to.eql('http://a.b.com:80/woo');
533
569
  u.protocol = 'https:';
534
570
  expect(_.formatUrl(u)).to.eql('https://a.b.com:80/woo');
535
571
  });
536
- it('should handle missing parts', function() {
572
+ it('should handle missing parts', function () {
537
573
  var u = {
538
- hostname: 'a.b.com'
574
+ hostname: 'a.b.com',
539
575
  };
540
576
  expect(_.formatUrl(u)).to.eql('https://a.b.com');
541
577
  expect(_.formatUrl(u, 'http:')).to.eql('http://a.b.com');
542
578
  });
543
- it('should return null without a hostname', function() {
579
+ it('should return null without a hostname', function () {
544
580
  var u = {};
545
581
  expect(_.formatUrl(u)).to.not.be.ok();
546
582
  expect(_.formatUrl(u, 'https:')).to.not.be.ok();
547
583
  });
548
584
  });
549
585
 
550
- describe('addParamsAndAccessTokenToPath', function() {
586
+ describe('addParamsAndAccessTokenToPath', function () {
551
587
  var accessToken = 'abc123';
552
- it('should handle no params and no path', function() {
588
+ it('should handle no params and no path', function () {
553
589
  var options = {};
554
590
  _.addParamsAndAccessTokenToPath(accessToken, options);
555
591
  expect(options.path).to.eql('?access_token=abc123');
556
592
  });
557
- it('should handle existing params', function() {
558
- var options = {path: '/api?a=b'};
593
+ it('should handle existing params', function () {
594
+ var options = { path: '/api?a=b' };
559
595
  _.addParamsAndAccessTokenToPath(accessToken, options);
560
596
  expect(options.path).to.eql('/api?access_token=abc123&a=b');
561
597
  });
562
- it('should handle a hash with params', function() {
563
- var options = {path: '/api?a=b#moreStuff??here'};
598
+ it('should handle a hash with params', function () {
599
+ var options = { path: '/api?a=b#moreStuff??here' };
564
600
  _.addParamsAndAccessTokenToPath(accessToken, options);
565
601
  expect(options.path).to.eql('/api?access_token=abc123&a=b#moreStuff??here');
566
602
  });
567
- it('should handle a hash without params', function() {
568
- var options = {path: '/api#moreStuff??here'};
603
+ it('should handle a hash without params', function () {
604
+ var options = { path: '/api#moreStuff??here' };
569
605
  _.addParamsAndAccessTokenToPath(accessToken, options);
570
606
  expect(options.path).to.eql('/api?access_token=abc123#moreStuff??here');
571
607
  });
572
- it('should handle a hash without params and no ?', function() {
573
- var options = {path: '/api#moreStuff'};
608
+ it('should handle a hash without params and no ?', function () {
609
+ var options = { path: '/api#moreStuff' };
574
610
  _.addParamsAndAccessTokenToPath(accessToken, options);
575
611
  expect(options.path).to.eql('/api?access_token=abc123#moreStuff');
576
612
  });
577
- it('should handle extra params', function() {
578
- var options = {path: '/api#moreStuff'};
579
- _.addParamsAndAccessTokenToPath(accessToken, options, {foo: 'boo'});
613
+ it('should handle extra params', function () {
614
+ var options = { path: '/api#moreStuff' };
615
+ _.addParamsAndAccessTokenToPath(accessToken, options, { foo: 'boo' });
580
616
  expect(options.path).to.eql('/api?access_token=abc123&foo=boo#moreStuff');
581
617
  });
582
618
  });
583
619
 
584
- describe('json3', function() {
585
- var setupCustomJSON = require('../vendor/JSON-js/json3.js');
586
- it('should replace stringify if not there', function() {
620
+ describe('json3', function () {
621
+ let setupCustomJSON;
622
+
623
+ before(async function () {
624
+ const module = await import('../vendor/JSON-js/json3.js');
625
+ setupCustomJSON = module.default;
626
+ });
627
+
628
+ it('should replace stringify if not there', function () {
587
629
  var j = {};
588
630
  setupCustomJSON(j);
589
- expect(j.stringify({a: 1})).to.eql('{"a":1}');
631
+ expect(j.stringify({ a: 1 })).to.eql('{"a":1}');
590
632
  });
591
- it('should replace parse if not there', function() {
633
+ it('should replace parse if not there', function () {
592
634
  var j = {};
593
635
  setupCustomJSON(j);
594
636
  expect(j.parse('{"a":1}').a).to.eql(1);
595
637
  });
596
- it('should not replace parse if there', function() {
597
- var j = {parse: function(s) { return 42; }};
638
+ it('should not replace parse if there', function () {
639
+ var j = {
640
+ parse: function (s) {
641
+ return 42;
642
+ },
643
+ };
598
644
  setupCustomJSON(j);
599
645
  expect(j.parse('{"a":1}')).to.eql(42);
600
- expect(j.stringify({a: 1})).to.eql('{"a":1}');
646
+ expect(j.stringify({ a: 1 })).to.eql('{"a":1}');
601
647
  });
602
- it('should not replace stringify if there', function() {
603
- var j = {stringify: function(s) { return '42'; }};
648
+ it('should not replace stringify if there', function () {
649
+ var j = {
650
+ stringify: function (s) {
651
+ return '42';
652
+ },
653
+ };
604
654
  setupCustomJSON(j);
605
- expect(j.stringify({a: 1})).to.eql('42');
655
+ expect(j.stringify({ a: 1 })).to.eql('42');
606
656
  expect(j.parse('{"a":1}').a).to.eql(1);
607
657
  });
608
658
  });
609
659
 
610
- describe('get', function() {
611
- it('should get a deeply nested value', function() {
612
- var o = {a: {b: {c: {d: 42}}}};
660
+ describe('get', function () {
661
+ it('should get a deeply nested value', function () {
662
+ var o = { a: { b: { c: { d: 42 } } } };
613
663
  expect(_.get(o, 'a.b.c.d')).to.eql(42);
614
664
  });
615
- it('should be undefined for a missing value', function() {
616
- var o = {a: {b: {c: {d: 42}}}};
665
+ it('should be undefined for a missing value', function () {
666
+ var o = { a: { b: { c: { d: 42 } } } };
617
667
  expect(_.get(o, 'a.b.x.d')).to.not.be.ok();
618
668
  });
619
- it('should handle bad input', function() {
669
+ it('should handle bad input', function () {
620
670
  var o = 'hello';
621
671
  expect(_.get(o, 'oops.1.2.3')).to.not.be.ok();
622
672
  });
623
- it('should actually work with arrays too', function() {
624
- var o = {a: [{b: {c: [1, {d: 42}, null]}}, 99]};
673
+ it('should actually work with arrays too', function () {
674
+ var o = { a: [{ b: { c: [1, { d: 42 }, null] } }, 99] };
625
675
  expect(_.get(o, 'a.0.b.c.1.d')).to.eql(42);
626
676
  });
627
- it('should handle undefined input', function() {
677
+ it('should handle undefined input', function () {
628
678
  var u = undefined;
629
679
  expect(_.get(u, 'a.b.c')).to.not.be.ok();
630
680
  });
631
681
  });
632
682
 
633
- describe('filterIp', function() {
634
- it('no user_ip', function() {
635
- var requestData = {'something': 'but no ip'};
683
+ describe('filterIp', function () {
684
+ it('no user_ip', function () {
685
+ var requestData = { something: 'but no ip' };
636
686
  _.filterIp(requestData, false);
637
687
  expect(requestData['user_ip']).to.not.be.ok();
638
688
  });
639
- it('capture true', function() {
689
+ it('capture true', function () {
640
690
  var ip = '123.32.394.99';
641
- var requestData = {'user_ip': ip};
691
+ var requestData = { user_ip: ip };
642
692
  _.filterIp(requestData, true);
643
693
  expect(requestData['user_ip']).to.eql(ip);
644
694
  });
645
- it('anonymize ip4', function() {
695
+ it('anonymize ip4', function () {
646
696
  var ip = '123.32.394.99';
647
- var requestData = {'user_ip': ip};
697
+ var requestData = { user_ip: ip };
648
698
  _.filterIp(requestData, 'anonymize');
649
699
  expect(requestData['user_ip']).to.not.eql(ip);
650
700
  expect(requestData['user_ip']).to.be.ok();
651
701
  });
652
- it('capture false', function() {
702
+ it('capture false', function () {
653
703
  var ip = '123.32.394.99';
654
- var requestData = {'user_ip': ip};
704
+ var requestData = { user_ip: ip };
655
705
  _.filterIp(requestData, false);
656
706
  expect(requestData['user_ip']).to.not.eql(ip);
657
707
  expect(requestData['user_ip']).to.not.be.ok();
658
708
  });
659
- it('ipv6 capture false', function() {
709
+ it('ipv6 capture false', function () {
660
710
  var ip = '2607:f0d0:1002:51::4';
661
- var requestData = {'user_ip': ip};
711
+ var requestData = { user_ip: ip };
662
712
  _.filterIp(requestData, false);
663
713
  expect(requestData['user_ip']).to.not.eql(ip);
664
714
  expect(requestData['user_ip']).to.not.be.ok();
665
715
  });
666
- it('ipv6 anonymize', function() {
716
+ it('ipv6 anonymize', function () {
667
717
  var ips = [
668
- 'FE80:0000:0000:0000:0202:B3FF:FE1E:8329',
669
- 'FE80::0202:B3FF:FE1E:8329',
670
- '2607:f0d0:1002:51::4',
718
+ 'FE80:0000:0000:0000:0202:B3FF:FE1E:8329',
719
+ 'FE80::0202:B3FF:FE1E:8329',
720
+ '2607:f0d0:1002:51::4',
671
721
  ];
672
722
  for (var i = 0; i < ips.length; i++) {
673
723
  var ip = ips[i];
674
- var requestData = {'user_ip': ip};
724
+ var requestData = { user_ip: ip };
675
725
  _.filterIp(requestData, 'anonymize');
676
726
  expect(requestData['user_ip']).to.not.eql(ip);
677
727
  expect(requestData['user_ip']).to.be.ok();
@@ -679,42 +729,42 @@ describe('filterIp', function() {
679
729
  });
680
730
  });
681
731
 
682
- describe('set', function() {
683
- it('should handle a top level key', function() {
684
- var o = {a: 42};
732
+ describe('set', function () {
733
+ it('should handle a top level key', function () {
734
+ var o = { a: 42 };
685
735
  _.set(o, 'b', 1);
686
736
  expect(o.b).to.eql(1);
687
737
  expect(o.a).to.eql(42);
688
738
  });
689
- it('should handle a top level key', function() {
690
- var o = {a: 42, b: {c: 44, d: {e: 99}}};
739
+ it('should handle a top level key', function () {
740
+ var o = { a: 42, b: { c: 44, d: { e: 99 } } };
691
741
  _.set(o, 'f', 1);
692
742
  expect(o.f).to.eql(1);
693
743
  expect(o.a).to.eql(42);
694
744
  expect(o.b.c).to.eql(44);
695
745
  expect(o.b.d.e).to.eql(99);
696
746
  });
697
- it('should replace a value that is already there', function() {
698
- var o = {a: 42};
747
+ it('should replace a value that is already there', function () {
748
+ var o = { a: 42 };
699
749
  _.set(o, 'a', 1);
700
750
  expect(o.a).to.eql(1);
701
751
  });
702
- it('should set a nested value with missing keys', function() {
703
- var o = {baz: 21};
752
+ it('should set a nested value with missing keys', function () {
753
+ var o = { baz: 21 };
704
754
  _.set(o, 'foo.bar', [42]);
705
755
  expect(o.baz).to.eql(21);
706
756
  expect(o.foo.bar).to.eql([42]);
707
757
  });
708
- it('should replace a nested value', function() {
709
- var o = {woo: 99, foo: {bar: {baz: 42, buzz: 97}, a: 98}};
758
+ it('should replace a nested value', function () {
759
+ var o = { woo: 99, foo: { bar: { baz: 42, buzz: 97 }, a: 98 } };
710
760
  _.set(o, 'foo.bar.baz', 1);
711
761
  expect(o.woo).to.eql(99);
712
762
  expect(o.foo.a).to.eql(98);
713
763
  expect(o.foo.bar.buzz).to.eql(97);
714
764
  expect(o.foo.bar.baz).to.eql(1);
715
765
  });
716
- it('should set a nested value with some missing keys', function() {
717
- var o = {woo: 99, foo: {bar: {buzz: 97}, a: 98}};
766
+ it('should set a nested value with some missing keys', function () {
767
+ var o = { woo: 99, foo: { bar: { buzz: 97 }, a: 98 } };
718
768
  _.set(o, 'foo.bar.baz.fizz', 1);
719
769
  expect(o.woo).to.eql(99);
720
770
  expect(o.foo.a).to.eql(98);
@@ -723,13 +773,13 @@ describe('set', function() {
723
773
  });
724
774
  });
725
775
 
726
- var scrub = require('../src/scrub');
727
- describe('scrub', function() {
728
- it('should not redact fields that are okay', function() {
776
+ import scrub from '../src/scrub.js';
777
+ describe('scrub', function () {
778
+ it('should not redact fields that are okay', function () {
729
779
  var data = {
730
780
  a: 'somestring',
731
781
  password: 'abc123',
732
- tempWorker: 'cool'
782
+ tempWorker: 'cool',
733
783
  };
734
784
  var scrubFields = ['password', 'b', 'pw'];
735
785
 
@@ -738,10 +788,10 @@ describe('scrub', function() {
738
788
  expect(result.a).to.eql('somestring');
739
789
  expect(result.tempWorker).to.eql('cool');
740
790
  });
741
- it('should redact fields that are in the field list', function() {
791
+ it('should redact fields that are in the field list', function () {
742
792
  var data = {
743
793
  a: 'somestring',
744
- password: 'abc123'
794
+ password: 'abc123',
745
795
  };
746
796
  var scrubFields = ['password', 'b'];
747
797
 
@@ -749,17 +799,17 @@ describe('scrub', function() {
749
799
 
750
800
  expect(result.password).to.eql(_.redact());
751
801
  });
752
- it('should handle nested objects', function() {
802
+ it('should handle nested objects', function () {
753
803
  var data = {
754
804
  a: {
755
805
  b: {
756
806
  badthing: 'secret',
757
- other: 'stuff'
807
+ other: 'stuff',
758
808
  },
759
809
  c: 'bork',
760
- password: 'abc123'
810
+ password: 'abc123',
761
811
  },
762
- secret: 'blahblah'
812
+ secret: 'blahblah',
763
813
  };
764
814
  var scrubFields = ['badthing', 'password', 'secret'];
765
815
 
@@ -772,14 +822,14 @@ describe('scrub', function() {
772
822
  expect(result.secret).to.eql(_.redact());
773
823
  expect(data.secret).to.eql('blahblah');
774
824
  });
775
- it('should do something sane for recursive objects', function() {
825
+ it('should do something sane for recursive objects', function () {
776
826
  var inner = {
777
827
  a: 'what',
778
- b: 'yes'
828
+ b: 'yes',
779
829
  };
780
830
  var data = {
781
831
  thing: 'stuff',
782
- password: 'abc123'
832
+ password: 'abc123',
783
833
  };
784
834
  data.inner = inner;
785
835
  inner.outer = data;
@@ -793,15 +843,15 @@ describe('scrub', function() {
793
843
  expect(result.inner.a).to.be.ok();
794
844
  expect(result.inner.b).to.eql('yes');
795
845
  });
796
- it('should scrub objects seen twice', function() {
846
+ it('should scrub objects seen twice', function () {
797
847
  var request = {
798
- password: 'foo'
799
- }
848
+ password: 'foo',
849
+ };
800
850
 
801
851
  var data = {
802
852
  request,
803
- response: { request }
804
- }
853
+ response: { request },
854
+ };
805
855
 
806
856
  var scrubFields = ['password'];
807
857
 
@@ -810,23 +860,23 @@ describe('scrub', function() {
810
860
  expect(result.request.password).to.eql(_.redact());
811
861
  expect(result.response.request.password).to.eql(_.redact());
812
862
  });
813
- it('should handle scrubPaths', function() {
863
+ it('should handle scrubPaths', function () {
814
864
  var data = {
815
865
  a: {
816
866
  b: {
817
867
  foo: 'secret',
818
- bar: 'stuff'
868
+ bar: 'stuff',
819
869
  },
820
870
  c: 'bork',
821
- password: 'abc123'
871
+ password: 'abc123',
822
872
  },
823
- secret: 'blahblah'
873
+ secret: 'blahblah',
824
874
  };
825
875
  var scrubPaths = [
826
876
  'nowhere', // path not found
827
877
  'a.b.foo', // nested path
828
878
  'a.password', // nested path
829
- 'secret' // root path
879
+ 'secret', // root path
830
880
  ];
831
881
 
832
882
  var result = scrub(data, [], scrubPaths);
@@ -839,32 +889,32 @@ describe('scrub', function() {
839
889
  });
840
890
  });
841
891
 
842
- describe('formatArgsAsString', function() {
843
- it('should handle null', function() {
892
+ describe('formatArgsAsString', function () {
893
+ it('should handle null', function () {
844
894
  var args = [null, 1];
845
895
  var result = _.formatArgsAsString(args);
846
896
 
847
897
  expect(result).to.eql('null 1');
848
898
  });
849
- it('should handle undefined', function() {
899
+ it('should handle undefined', function () {
850
900
  var args = [null, 1, undefined];
851
901
  var result = _.formatArgsAsString(args);
852
902
 
853
903
  expect(result).to.eql('null 1 undefined');
854
904
  });
855
- it('should handle objects', function() {
856
- var args = [1, {a: 42}];
905
+ it('should handle objects', function () {
906
+ var args = [1, { a: 42 }];
857
907
  var result = _.formatArgsAsString(args);
858
908
 
859
909
  expect(result).to.eql('1 {"a":42}');
860
910
  });
861
- it('should handle strings', function() {
911
+ it('should handle strings', function () {
862
912
  var args = [1, 'foo'];
863
913
  var result = _.formatArgsAsString(args);
864
914
 
865
915
  expect(result).to.eql('1 foo');
866
916
  });
867
- it('should handle empty args', function() {
917
+ it('should handle empty args', function () {
868
918
  var args = [];
869
919
  var result = _.formatArgsAsString(args);
870
920
 
@@ -880,3 +930,35 @@ describe('formatArgsAsString', function() {
880
930
  });
881
931
  */
882
932
  });
933
+
934
+ describe('addItemAttributes', function () {
935
+ it('should skip undefined values', function () {
936
+ const item = { data: {} };
937
+ const attributes = [
938
+ { key: 'replay_id', value: '12345' },
939
+ { key: 'session_id', value: undefined },
940
+ ];
941
+ _.addItemAttributes(item.data, attributes);
942
+ expect(item.data.attributes).to.be.an('array');
943
+ expect(item.data.attributes.length).to.equal(1);
944
+ expect(item.data.attributes[0].key).to.equal('replay_id');
945
+ expect(item.data.attributes[0].value).to.equal('12345');
946
+ });
947
+ });
948
+
949
+ describe('getItemAttribute', function () {
950
+ it('should skip undefined values', function () {
951
+ const item = {
952
+ data: {
953
+ attributes: [
954
+ { key: 'replay_id', value: '12345' },
955
+ { key: 'session_id', value: '67890' },
956
+ ],
957
+ },
958
+ };
959
+ let value = _.getItemAttribute(item.data, 'replay_id');
960
+ expect(value).to.equal('12345');
961
+ value = _.getItemAttribute(item.data, 'session_id');
962
+ expect(value).to.equal('67890');
963
+ });
964
+ });