@newrelic/browser-agent 0.1.230 → 0.1.231

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 (221) hide show
  1. package/README.md +25 -1
  2. package/dist/cjs/common/browser-version/ios-version.js +4 -3
  3. package/dist/cjs/common/config/state/configurable.js +1 -1
  4. package/dist/cjs/common/config/state/info.js +1 -1
  5. package/dist/cjs/common/config/state/init.js +1 -1
  6. package/dist/cjs/common/config/state/loader-config.js +1 -1
  7. package/dist/cjs/common/config/state/runtime.js +5 -5
  8. package/dist/cjs/common/constants/env.cdn.js +29 -0
  9. package/dist/cjs/common/constants/env.js +32 -0
  10. package/dist/cjs/common/constants/env.npm.js +30 -0
  11. package/dist/cjs/common/event-emitter/contextual-ee.test.js +282 -0
  12. package/dist/cjs/common/event-emitter/handle.test.js +58 -0
  13. package/dist/cjs/common/event-emitter/register-handler.test.js +55 -0
  14. package/dist/cjs/common/harvest/harvest.js +2 -2
  15. package/dist/cjs/common/ids/id.js +14 -6
  16. package/dist/cjs/common/ids/id.test.js +85 -0
  17. package/dist/cjs/common/ids/unique-id.js +75 -51
  18. package/dist/cjs/common/ids/unique-id.test.js +49 -0
  19. package/dist/cjs/common/timing/nav-timing.js +51 -30
  20. package/dist/cjs/common/timing/nav-timing.test.js +192 -0
  21. package/dist/cjs/common/url/clean-url.test.js +9 -0
  22. package/dist/cjs/common/url/encode.test.js +74 -0
  23. package/dist/cjs/common/url/location.js +4 -0
  24. package/dist/cjs/common/url/location.test.js +13 -0
  25. package/dist/cjs/common/url/parse-url.test.js +111 -0
  26. package/dist/cjs/common/url/protocol.js +2 -12
  27. package/dist/cjs/common/url/protocol.test.js +16 -0
  28. package/dist/cjs/common/util/console.js +1 -1
  29. package/dist/cjs/common/util/map-own.test.js +3 -3
  30. package/dist/cjs/common/util/obfuscate.js +1 -1
  31. package/dist/cjs/common/window/page-visibility.js +2 -1
  32. package/dist/cjs/common/wrap/index.js +0 -7
  33. package/dist/cjs/common/wrap/wrap-events.js +6 -9
  34. package/dist/cjs/common/wrap/wrap-fetch.js +6 -6
  35. package/dist/cjs/common/wrap/wrap-history.js +7 -6
  36. package/dist/cjs/common/wrap/wrap-jsonp.js +7 -6
  37. package/dist/cjs/common/wrap/wrap-mutation.js +7 -6
  38. package/dist/cjs/common/wrap/wrap-promise.js +7 -6
  39. package/dist/cjs/common/wrap/wrap-promise.test.js +119 -0
  40. package/dist/cjs/common/wrap/wrap-raf.js +6 -6
  41. package/dist/cjs/common/wrap/wrap-timer.js +6 -6
  42. package/dist/cjs/common/wrap/wrap-xhr.js +5 -6
  43. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  44. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +5 -5
  45. package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +1 -1
  46. package/dist/cjs/features/jserrors/aggregate/index.js +3 -3
  47. package/dist/cjs/features/jserrors/instrument/index.js +2 -2
  48. package/dist/cjs/features/metrics/aggregate/index.js +6 -7
  49. package/dist/cjs/features/metrics/instrument/index.js +0 -25
  50. package/dist/cjs/features/metrics/instrument/workers-helper.js +5 -5
  51. package/dist/cjs/features/page_action/aggregate/index.js +1 -1
  52. package/dist/cjs/features/page_view_event/aggregate/index.js +17 -6
  53. package/dist/cjs/features/page_view_timing/aggregate/index.js +36 -26
  54. package/dist/cjs/features/session_trace/aggregate/index.js +16 -13
  55. package/dist/cjs/features/utils/instrument-base.js +6 -2
  56. package/dist/cjs/features/utils/lazy-loader.js +1 -1
  57. package/dist/cjs/loaders/agent.js +1 -1
  58. package/dist/cjs/loaders/api/api.js +8 -5
  59. package/dist/cjs/loaders/features/enabled-features.js +1 -1
  60. package/dist/cjs/loaders/micro-agent.js +2 -1
  61. package/dist/esm/common/browser-version/ios-version.js +4 -3
  62. package/dist/esm/common/config/state/configurable.js +1 -1
  63. package/dist/esm/common/config/state/info.js +1 -1
  64. package/dist/esm/common/config/state/init.js +1 -1
  65. package/dist/esm/common/config/state/loader-config.js +1 -1
  66. package/dist/esm/common/config/state/runtime.js +2 -2
  67. package/dist/esm/common/constants/env.cdn.js +20 -0
  68. package/dist/esm/common/constants/env.js +23 -0
  69. package/dist/esm/common/constants/env.npm.js +21 -0
  70. package/dist/esm/common/event-emitter/contextual-ee.test.js +278 -0
  71. package/dist/esm/common/event-emitter/handle.test.js +54 -0
  72. package/dist/esm/common/event-emitter/register-handler.test.js +51 -0
  73. package/dist/esm/common/harvest/harvest.js +1 -1
  74. package/dist/esm/common/ids/id.js +16 -6
  75. package/dist/esm/common/ids/id.test.js +81 -0
  76. package/dist/esm/common/ids/unique-id.js +75 -51
  77. package/dist/esm/common/ids/unique-id.test.js +44 -0
  78. package/dist/esm/common/timing/nav-timing.js +51 -29
  79. package/dist/esm/common/timing/nav-timing.test.js +190 -0
  80. package/dist/esm/common/url/clean-url.test.js +7 -0
  81. package/dist/esm/common/url/encode.test.js +70 -0
  82. package/dist/esm/common/url/location.js +4 -0
  83. package/dist/esm/common/url/location.test.js +11 -0
  84. package/dist/esm/common/url/parse-url.test.js +107 -0
  85. package/dist/esm/common/url/protocol.js +3 -12
  86. package/dist/esm/common/url/protocol.test.js +14 -0
  87. package/dist/esm/common/util/console.js +1 -1
  88. package/dist/esm/common/util/map-own.test.js +3 -3
  89. package/dist/esm/common/util/obfuscate.js +2 -2
  90. package/dist/esm/common/window/page-visibility.js +2 -1
  91. package/dist/esm/common/wrap/index.js +1 -2
  92. package/dist/esm/common/wrap/wrap-events.js +6 -9
  93. package/dist/esm/common/wrap/wrap-fetch.js +6 -6
  94. package/dist/esm/common/wrap/wrap-history.js +7 -6
  95. package/dist/esm/common/wrap/wrap-jsonp.js +7 -6
  96. package/dist/esm/common/wrap/wrap-mutation.js +7 -6
  97. package/dist/esm/common/wrap/wrap-promise.js +7 -6
  98. package/dist/esm/common/wrap/wrap-promise.test.js +115 -0
  99. package/dist/esm/common/wrap/wrap-raf.js +6 -6
  100. package/dist/esm/common/wrap/wrap-timer.js +6 -6
  101. package/dist/esm/common/wrap/wrap-xhr.js +5 -6
  102. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  103. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +5 -5
  104. package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +1 -1
  105. package/dist/esm/features/jserrors/aggregate/index.js +3 -3
  106. package/dist/esm/features/jserrors/instrument/index.js +2 -2
  107. package/dist/esm/features/metrics/aggregate/index.js +7 -8
  108. package/dist/esm/features/metrics/instrument/index.js +0 -25
  109. package/dist/esm/features/metrics/instrument/workers-helper.js +5 -5
  110. package/dist/esm/features/page_action/aggregate/index.js +1 -1
  111. package/dist/esm/features/page_view_event/aggregate/index.js +17 -6
  112. package/dist/esm/features/page_view_timing/aggregate/index.js +36 -26
  113. package/dist/esm/features/session_trace/aggregate/index.js +16 -13
  114. package/dist/esm/features/utils/instrument-base.js +1 -1
  115. package/dist/esm/features/utils/lazy-loader.js +1 -1
  116. package/dist/esm/loaders/agent.js +1 -1
  117. package/dist/esm/loaders/api/api.js +4 -4
  118. package/dist/esm/loaders/features/enabled-features.js +1 -1
  119. package/dist/types/common/config/state/runtime.d.ts.map +1 -1
  120. package/dist/types/common/constants/env.cdn.d.ts +18 -0
  121. package/dist/types/common/constants/env.cdn.d.ts.map +1 -0
  122. package/dist/types/common/constants/env.d.ts +13 -0
  123. package/dist/types/common/constants/env.d.ts.map +1 -0
  124. package/dist/types/common/constants/env.npm.d.ts +19 -0
  125. package/dist/types/common/constants/env.npm.d.ts.map +1 -0
  126. package/dist/types/common/ids/id.d.ts +11 -1
  127. package/dist/types/common/ids/id.d.ts.map +1 -1
  128. package/dist/types/common/ids/unique-id.d.ts +24 -1
  129. package/dist/types/common/ids/unique-id.d.ts.map +1 -1
  130. package/dist/types/common/timing/nav-timing.d.ts +1 -2
  131. package/dist/types/common/timing/nav-timing.d.ts.map +1 -1
  132. package/dist/types/common/unload/eol.d.ts.map +1 -1
  133. package/dist/types/common/url/location.d.ts +4 -0
  134. package/dist/types/common/url/location.d.ts.map +1 -1
  135. package/dist/types/common/url/parse-url.d.ts.map +1 -1
  136. package/dist/types/common/url/protocol.d.ts +1 -6
  137. package/dist/types/common/url/protocol.d.ts.map +1 -1
  138. package/dist/types/common/util/global-scope.d.ts.map +1 -1
  139. package/dist/types/common/wrap/index.d.ts +1 -2
  140. package/dist/types/common/wrap/index.d.ts.map +1 -1
  141. package/dist/types/common/wrap/wrap-fetch.d.ts.map +1 -1
  142. package/dist/types/common/wrap/wrap-history.d.ts.map +1 -1
  143. package/dist/types/common/wrap/wrap-jsonp.d.ts.map +1 -1
  144. package/dist/types/common/wrap/wrap-mutation.d.ts.map +1 -1
  145. package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
  146. package/dist/types/common/wrap/wrap-raf.d.ts.map +1 -1
  147. package/dist/types/common/wrap/wrap-timer.d.ts.map +1 -1
  148. package/dist/types/common/wrap/wrap-xhr.d.ts.map +1 -1
  149. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  150. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  151. package/dist/types/features/metrics/instrument/index.d.ts +0 -1
  152. package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
  153. package/dist/types/features/metrics/instrument/workers-helper.d.ts.map +1 -1
  154. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  155. package/dist/types/features/page_view_timing/aggregate/index.d.ts +1 -2
  156. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  157. package/dist/types/features/session_trace/aggregate/index.d.ts +1 -1
  158. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  159. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  160. package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
  161. package/package.json +9 -30
  162. package/src/common/browser-version/ios-version.js +4 -3
  163. package/src/common/config/state/runtime.js +26 -24
  164. package/src/common/constants/env.cdn.js +20 -0
  165. package/src/common/constants/env.js +23 -0
  166. package/src/common/constants/env.npm.js +21 -0
  167. package/src/common/event-emitter/contextual-ee.test.js +310 -0
  168. package/src/common/event-emitter/handle.test.js +56 -0
  169. package/src/common/event-emitter/register-handler.test.js +61 -0
  170. package/src/common/harvest/harvest.js +2 -2
  171. package/src/common/ids/id.js +15 -6
  172. package/src/common/ids/id.test.js +92 -0
  173. package/src/common/ids/unique-id.js +77 -54
  174. package/src/common/ids/unique-id.test.js +58 -0
  175. package/src/common/timing/nav-timing.js +50 -30
  176. package/src/common/timing/nav-timing.test.js +161 -0
  177. package/src/common/unload/eol.js +1 -2
  178. package/src/common/url/clean-url.test.js +25 -0
  179. package/src/common/url/encode.test.js +80 -0
  180. package/src/common/url/location.js +4 -0
  181. package/src/common/url/location.test.js +15 -0
  182. package/src/common/url/parse-url.js +1 -2
  183. package/src/common/url/parse-url.test.js +110 -0
  184. package/src/common/url/protocol.js +3 -13
  185. package/src/common/url/protocol.test.js +18 -0
  186. package/src/common/util/global-scope.js +1 -2
  187. package/src/common/util/obfuscate.js +2 -2
  188. package/src/common/window/page-visibility.js +1 -1
  189. package/src/common/wrap/index.js +1 -2
  190. package/src/common/wrap/wrap-events.js +5 -5
  191. package/src/common/wrap/wrap-fetch.js +4 -3
  192. package/src/common/wrap/wrap-history.js +6 -3
  193. package/src/common/wrap/wrap-jsonp.js +5 -3
  194. package/src/common/wrap/wrap-mutation.js +6 -3
  195. package/src/common/wrap/wrap-promise.js +7 -6
  196. package/src/common/wrap/wrap-promise.test.js +140 -0
  197. package/src/common/wrap/wrap-raf.js +5 -3
  198. package/src/common/wrap/wrap-timer.js +5 -3
  199. package/src/common/wrap/wrap-xhr.js +4 -3
  200. package/src/features/ajax/instrument/index.js +1 -1
  201. package/src/features/jserrors/instrument/index.js +4 -2
  202. package/src/features/metrics/aggregate/index.js +3 -4
  203. package/src/features/metrics/instrument/index.js +0 -30
  204. package/src/features/metrics/instrument/workers-helper.js +9 -6
  205. package/src/features/page_view_event/aggregate/index.js +15 -6
  206. package/src/features/page_view_timing/aggregate/index.js +36 -25
  207. package/src/features/page_view_timing/long-tasks.js +10 -10
  208. package/src/features/session_trace/aggregate/index.js +15 -12
  209. package/src/features/session_trace/instrument/index.js +3 -2
  210. package/src/features/spa/instrument/index.js +4 -2
  211. package/src/loaders/api/api.js +1 -1
  212. package/dist/cjs/common/constants/environment-variables.js +0 -20
  213. package/dist/cjs/common/wrap/wrap-console.js +0 -54
  214. package/dist/esm/common/constants/environment-variables.js +0 -11
  215. package/dist/esm/common/wrap/wrap-console.js +0 -46
  216. package/dist/types/common/constants/environment-variables.d.ts +0 -4
  217. package/dist/types/common/constants/environment-variables.d.ts.map +0 -1
  218. package/dist/types/common/wrap/wrap-console.d.ts +0 -16
  219. package/dist/types/common/wrap/wrap-console.d.ts.map +0 -1
  220. package/src/common/constants/environment-variables.js +0 -11
  221. package/src/common/wrap/wrap-console.js +0 -47
@@ -11,15 +11,23 @@ var _globalScope = require("../util/global-scope");
11
11
  * SPDX-License-Identifier: Apache-2.0
12
12
  */
13
13
 
14
- // Start assigning ids at 1 so 0 can always be used for WindowOrWorkerGlobalScope, without
14
+ // Start assigning ids at 1 so 0 can always be used for Window or WorkerGlobalScope, without
15
15
  // actually setting it (which would create a global variable).
16
+ let index = 1;
17
+ const prop = 'nr@id';
16
18
 
17
- var index = 1;
18
- var prop = 'nr@id';
19
-
20
- // Always returns id of obj, may tag obj with an id in the process.
19
+ /**
20
+ * Tags a specified object with an identifier if it does not already
21
+ * have one. If the object is the global scope, zero will be returned
22
+ * and the object will not be modified. If the object already contains
23
+ * an identifier, it will be returned without modification. If the passed
24
+ * value is not an object, function, or array, -1 will be returned without
25
+ * modifying the passed value.
26
+ * @param {object|function|array} obj Object to be tagged with an identifier
27
+ * @returns {number} Identifier of the given object
28
+ */
21
29
  function id(obj) {
22
- var type = typeof obj;
30
+ const type = typeof obj;
23
31
  // We can only tag objects, functions, and arrays with ids.
24
32
  // For all primitive values we instead return -1.
25
33
  if (!obj || !(type === 'object' || type === 'function')) return -1;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
4
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
5
+ let idFn;
6
+ beforeEach(async () => {
7
+ idFn = (await Promise.resolve().then(() => _interopRequireWildcard(require('./id')))).id;
8
+ });
9
+ afterEach(() => {
10
+ jest.resetModules();
11
+ jest.clearAllMocks();
12
+ });
13
+ test.each([{
14
+ input: undefined,
15
+ expected: -1,
16
+ title: 'id of undefined is -1'
17
+ }, {
18
+ input: null,
19
+ expected: -1,
20
+ title: 'id of null is -1'
21
+ }, {
22
+ input: 2,
23
+ expected: -1,
24
+ title: 'id of number is -1'
25
+ }, {
26
+ input: 'foo',
27
+ expected: -1,
28
+ title: 'id of string is -1'
29
+ }])('$title', _ref => {
30
+ let {
31
+ input,
32
+ expected
33
+ } = _ref;
34
+ const result = idFn(input);
35
+ expect(typeof result).toEqual('number');
36
+ expect(result).toEqual(expected);
37
+ });
38
+ test('id values increment sequentially', () => {
39
+ const inputA = {};
40
+ const inputB = {};
41
+ const resultA = idFn(inputA);
42
+ const resultB = idFn(inputB);
43
+ expect(resultA - resultB).toEqual(-1);
44
+ });
45
+ test('id is correctly assigned to function type', () => {
46
+ const input = jest.fn();
47
+ const result = idFn(input);
48
+ expect(result).toEqual(1);
49
+ expect(input['nr@id']).toEqual(1);
50
+ });
51
+ test('id is correctly assigned to object type', () => {
52
+ const input = {};
53
+ const result = idFn(input);
54
+ expect(result).toEqual(1);
55
+ expect(input['nr@id']).toEqual(1);
56
+ });
57
+ test('id is the same when called twice on the same input', () => {
58
+ const input = {};
59
+ const result1 = idFn(input);
60
+ const result2 = idFn(input);
61
+ expect(result1).toEqual(1);
62
+ expect(result2).toEqual(1);
63
+ expect(input['nr@id']).toEqual(1);
64
+ });
65
+ test('id is zero on global scope', async () => {
66
+ const result = idFn(global);
67
+ expect(result).toEqual(0);
68
+ });
69
+ test('id on prototype is correctly inherited', () => {
70
+ const fn = jest.fn();
71
+ const a = {};
72
+ idFn(a);
73
+ fn.prototype = a;
74
+ const b = new fn();
75
+ expect(b['nr@id']).toEqual(a['nr@id']);
76
+ });
77
+ test('id on prototype is different from instance', () => {
78
+ const fn = jest.fn();
79
+ const a = {};
80
+ idFn(a);
81
+ fn.prototype = a;
82
+ const b = new fn();
83
+ const result = idFn(b);
84
+ expect(b['nr@id']).toEqual(result);
85
+ });
@@ -13,72 +13,96 @@ var _globalScope = require("../util/global-scope");
13
13
  * SPDX-License-Identifier: Apache-2.0
14
14
  */
15
15
 
16
+ const uuidv4Template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
17
+
18
+ /**
19
+ * Creates a random single hexadecimal value from a provided random value
20
+ * table and corresponding index. If a random value table is not provided,
21
+ * Math.random will be used to generate the value.
22
+ *
23
+ * @param {Uint8Array} valueTable Random value table typically generated using
24
+ * the built-in crypto engine.
25
+ * @param {int} tableIndex The index of the value table to use for generating
26
+ * the hexadecimal value.
27
+ * @returns {int} single hexadecimal value in decimal format
28
+ */
29
+ function getRandomValue(valueTable, tableIndex) {
30
+ if (valueTable) {
31
+ /**
32
+ * The value table could have any number value in the given index. Use
33
+ * bitwise AND to ensure the value we generate is a valid hex value.
34
+ * x & 15 will ensure the value converted to hex using `toString(16)`
35
+ * falls within the range of 0 and 15 inclusively.
36
+ */
37
+ return valueTable[tableIndex] & 15;
38
+ } else {
39
+ return Math.random() * 16 | 0;
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Generates a RFC compliant UUIDv4 using native browser crypto engine. If the browser
45
+ * does not support the crypto engine, the function will fallback to insecure Math.random()
46
+ * @returns {string} uuid version 4 string
47
+ */
16
48
  function generateUuid() {
17
- var randomVals = null;
18
- var rvIndex = 0;
19
- var crypto = _globalScope.globalScope?.crypto || _globalScope.globalScope?.msCrypto;
49
+ const crypto = _globalScope.globalScope?.crypto || _globalScope.globalScope?.msCrypto;
50
+ let randomValueTable;
51
+ let randomValueIndex = 0;
20
52
  if (crypto && crypto.getRandomValues) {
21
53
  // eslint-disable-next-line
22
- randomVals = crypto.getRandomValues(new Uint8Array(31));
23
- }
24
- function getRandomValue() {
25
- if (randomVals) {
26
- // same as % 16
27
- return randomVals[rvIndex++] & 15;
28
- } else {
29
- return Math.random() * 16 | 0;
30
- }
54
+ randomValueTable = crypto.getRandomValues(new Uint8Array(31));
31
55
  }
32
-
33
- // v4 UUID
34
- var template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
35
- var id = '';
36
- var c;
37
- for (var i = 0; i < template.length; i++) {
38
- c = template[i];
39
- if (c === 'x') {
40
- id += getRandomValue().toString(16);
41
- } else if (c === 'y') {
56
+ return uuidv4Template.split('').map(templateInput => {
57
+ if (templateInput === 'x') {
58
+ return getRandomValue(randomValueTable, ++randomValueIndex).toString(16);
59
+ } else if (templateInput === 'y') {
42
60
  // this is the uuid variant per spec (8, 9, a, b)
43
61
  // % 4, then shift to get values 8-11
44
- c = getRandomValue() & 0x3 | 0x8;
45
- id += c.toString(16);
62
+ return (getRandomValue() & 0x3 | 0x8).toString(16);
46
63
  } else {
47
- id += c;
64
+ return templateInput;
48
65
  }
66
+ }).join('');
67
+ }
68
+
69
+ /**
70
+ * Generates a string of the given length containing only hexadecimal
71
+ * value 0-9 and a-f.
72
+ * @param {int} length length of the string to generate
73
+ * @returns {string} generated hex string
74
+ */
75
+ function generateRandomHexString(length) {
76
+ const crypto = _globalScope.globalScope?.crypto || _globalScope.globalScope?.msCrypto;
77
+ let randomValueTable;
78
+ let randomValueIndex = 0;
79
+ if (crypto && crypto.getRandomValues) {
80
+ // eslint-disable-next-line
81
+ randomValueTable = crypto.getRandomValues(new Uint8Array(31));
49
82
  }
50
- return id;
83
+ const chars = [];
84
+ for (var i = 0; i < length; i++) {
85
+ chars.push(getRandomValue(randomValueTable, ++randomValueIndex).toString(16));
86
+ }
87
+ return chars.join('');
51
88
  }
52
89
 
53
- // 16-character hex string (per DT spec)
90
+ /**
91
+ * Generates a 16 character length hexadecimal string.
92
+ * per DT-spec.
93
+ * @see generateRandomHexString
94
+ * @returns {string} generated hex string
95
+ */
54
96
  function generateSpanId() {
55
97
  return generateRandomHexString(16);
56
98
  }
57
99
 
58
- // 32-character hex string (per DT spec)
100
+ /**
101
+ * Generates a 32 character length hexadecimal string.
102
+ * per DT-spec.
103
+ * @see generateRandomHexString
104
+ * @returns {string} generated hex string
105
+ */
59
106
  function generateTraceId() {
60
107
  return generateRandomHexString(32);
61
- }
62
- function generateRandomHexString(length) {
63
- var randomVals = null;
64
- var rvIndex = 0;
65
- var crypto = self.crypto || self.msCrypto;
66
- // eslint-disable-next-line
67
- if (crypto && crypto.getRandomValues && Uint8Array) {
68
- // eslint-disable-next-line
69
- randomVals = crypto.getRandomValues(new Uint8Array(31));
70
- }
71
- var chars = [];
72
- for (var i = 0; i < length; i++) {
73
- chars.push(getRandomValue().toString(16));
74
- }
75
- return chars.join('');
76
- function getRandomValue() {
77
- if (randomVals) {
78
- // same as % 16
79
- return randomVals[rvIndex++] & 15;
80
- } else {
81
- return Math.random() * 16 | 0;
82
- }
83
- }
84
108
  }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ var _crypto = _interopRequireDefault(require("crypto"));
4
+ var uniqueId = _interopRequireWildcard(require("./unique-id"));
5
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
6
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
7
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
+ const getRandomValues = jest.fn(arr => _crypto.default.randomBytes(arr.length));
9
+ afterEach(() => {
10
+ delete global.crypto;
11
+ });
12
+ describe('generateUuid', () => {
13
+ const uuidv4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
14
+ test('should generate a uuidv4 that matches the expected format', () => {
15
+ const id = uniqueId.generateUuid();
16
+ expect(uuidv4Regex.test(id)).toEqual(true);
17
+ });
18
+ test('should support using native crypto library', () => {
19
+ global.crypto = {
20
+ getRandomValues
21
+ };
22
+ const id = uniqueId.generateUuid();
23
+ expect(uuidv4Regex.test(id)).toEqual(true);
24
+ expect(getRandomValues).toHaveBeenCalledTimes(1);
25
+ });
26
+ });
27
+ describe('generateRandomHexString', () => {
28
+ const hexRegex = /^[0-9a-f]{8}$/;
29
+ test('should generate a valid hex string', () => {
30
+ const id = uniqueId.generateRandomHexString(8);
31
+ expect(hexRegex.test(id)).toEqual(true);
32
+ });
33
+ test('should support using native crypto library', () => {
34
+ global.crypto = {
35
+ getRandomValues
36
+ };
37
+ const id = uniqueId.generateRandomHexString(8);
38
+ expect(hexRegex.test(id)).toEqual(true);
39
+ expect(getRandomValues).toHaveBeenCalledTimes(1);
40
+ });
41
+ });
42
+ test('generateSpanId should generate a 16 character hex string', () => {
43
+ const id = uniqueId.generateSpanId();
44
+ expect(/^[0-9a-f]{16}$/.test(id)).toEqual(true);
45
+ });
46
+ test('generateTraceId should generate a 32 character hex string', () => {
47
+ const id = uniqueId.generateTraceId();
48
+ expect(/^[0-9a-f]{32}$/.test(id)).toEqual(true);
49
+ });
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.addPN = addPN;
7
7
  exports.addPT = addPT;
8
- exports.addRel = addRel;
9
8
  exports.navTimingValues = void 0;
10
9
  /*
11
10
  * Copyright 2020 New Relic Corporation. All rights reserved.
@@ -35,43 +34,65 @@ var LOAD_EVENT = 'loadEvent';
35
34
  var DOM_CONTENT_LOAD_EVENT = 'domContentLoadedEvent';
36
35
  var navTimingValues = [];
37
36
  exports.navTimingValues = navTimingValues;
38
- function addPT(offset, pt, v) {
37
+ function getPntType(type) {
38
+ if (typeof type == 'number') return type;
39
+ const types = {
40
+ navigate: undefined,
41
+ reload: 1,
42
+ back_forward: 2,
43
+ prerender: 3
44
+ };
45
+ return types[type];
46
+ }
47
+ function addPT(offset, pt) {
48
+ let v = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
49
+ let isL1Api = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
50
+ if (!pt) return;
39
51
  v.of = offset;
40
- addRel(offset, offset, v, 'n');
41
- addRel(pt[UNLOAD_EVENT + START], offset, v, 'u');
42
- addRel(pt[REDIRECT + START], offset, v, 'r');
43
- addRel(pt[UNLOAD_EVENT + END], offset, v, 'ue');
44
- addRel(pt[REDIRECT + END], offset, v, 're');
45
- addRel(pt['fetch' + START], offset, v, 'f');
46
- addRel(pt[DOMAIN_LOOKUP + START], offset, v, 'dn');
47
- addRel(pt[DOMAIN_LOOKUP + END], offset, v, 'dne');
48
- addRel(pt['c' + ONNECT + START], offset, v, 'c');
49
- addRel(pt['secureC' + ONNECT + 'ion' + START], offset, v, 's');
50
- addRel(pt['c' + ONNECT + END], offset, v, 'ce');
51
- addRel(pt[REQUEST + START], offset, v, 'rq');
52
- addRel(pt[RESPONSE + START], offset, v, 'rp');
53
- addRel(pt[RESPONSE + END], offset, v, 'rpe');
54
- addRel(pt.domLoading, offset, v, 'dl');
55
- addRel(pt.domInteractive, offset, v, 'di');
56
- addRel(pt[DOM_CONTENT_LOAD_EVENT + START], offset, v, 'ds');
57
- addRel(pt[DOM_CONTENT_LOAD_EVENT + END], offset, v, 'de');
58
- addRel(pt.domComplete, offset, v, 'dc');
59
- addRel(pt[LOAD_EVENT + START], offset, v, 'l');
60
- addRel(pt[LOAD_EVENT + END], offset, v, 'le');
52
+ handleValue(v.of, v, 'n', true);
53
+ handleValue(pt[UNLOAD_EVENT + START], v, 'u', isL1Api);
54
+ handleValue(pt[REDIRECT + START], v, 'r', isL1Api);
55
+ handleValue(pt[UNLOAD_EVENT + END], v, 'ue', isL1Api);
56
+ handleValue(pt[REDIRECT + END], v, 're', isL1Api);
57
+ handleValue(pt['fetch' + START], v, 'f', isL1Api);
58
+ handleValue(pt[DOMAIN_LOOKUP + START], v, 'dn', isL1Api);
59
+ handleValue(pt[DOMAIN_LOOKUP + END], v, 'dne', isL1Api);
60
+ handleValue(pt['c' + ONNECT + START], v, 'c', isL1Api);
61
+ handleValue(pt['secureC' + ONNECT + 'ion' + START], v, 's', isL1Api);
62
+ handleValue(pt['c' + ONNECT + END], v, 'ce', isL1Api);
63
+ handleValue(pt[REQUEST + START], v, 'rq', isL1Api);
64
+ handleValue(pt[RESPONSE + START], v, 'rp', isL1Api);
65
+ handleValue(pt[RESPONSE + END], v, 'rpe', isL1Api);
66
+ handleValue(pt.domLoading, v, 'dl', isL1Api);
67
+ handleValue(pt.domInteractive, v, 'di', isL1Api);
68
+ handleValue(pt[DOM_CONTENT_LOAD_EVENT + START], v, 'ds', isL1Api);
69
+ handleValue(pt[DOM_CONTENT_LOAD_EVENT + END], v, 'de', isL1Api);
70
+ handleValue(pt.domComplete, v, 'dc', isL1Api);
71
+ handleValue(pt[LOAD_EVENT + START], v, 'l', isL1Api);
72
+ handleValue(pt[LOAD_EVENT + END], v, 'le', isL1Api);
61
73
  return v;
62
74
  }
63
75
 
64
76
  // Add Performance Navigation values to the given object
65
77
  function addPN(pn, v) {
66
- addRel(pn.type, 0, v, 'ty');
67
- addRel(pn.redirectCount, 0, v, 'rc');
78
+ handleValue(getPntType(pn.type), v, 'ty');
79
+ handleValue(pn.redirectCount, v, 'rc');
68
80
  return v;
69
81
  }
70
- function addRel(value, offset, obj, prop) {
71
- var relativeValue;
82
+ function handleValue(value, obj, prop, isOldApi) {
83
+ /*
84
+ For L2 Timing API, the value will already be a relative-to-previous-document DOMHighResTimeStamp.
85
+ For L1 (deprecated) Timing, the value is an UNIX epoch timestamp, which we will convert to a relative time using our offset.
86
+ PNT.type is reported as undefined, 1, 2, etc -- note that zero-value properties will be recorded as 'undefined', however DEM interprets undefined "types" as "navigate"
87
+ */
72
88
  if (typeof value === 'number' && value > 0) {
73
- relativeValue = Math.max(Math.round(value - offset), 0);
74
- obj[prop] = relativeValue;
89
+ // note that zero-value properties will be recorded as 'undefined'
90
+ if (isOldApi) {
91
+ const offset = obj?.of > 0 ? obj.of : 0; // expect an epoch timestamp, if called by addPT
92
+ value = Math.max(value - offset, 0);
93
+ }
94
+ value = Math.round(value);
95
+ obj[prop] = value;
75
96
  }
76
- navTimingValues.push(relativeValue);
97
+ navTimingValues.push(value);
77
98
  }
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+
3
+ var _navTiming = require("./nav-timing");
4
+ const offset = 123;
5
+ const testValues = {
6
+ unloadEventStart: 1,
7
+ redirectStart: 2,
8
+ unloadEventEnd: 3,
9
+ redirectEnd: 4,
10
+ fetchStart: 5,
11
+ domainLookupStart: 6,
12
+ domainLookupEnd: 7,
13
+ connectStart: 8,
14
+ secureConnectionStart: 9,
15
+ connectEnd: 10,
16
+ requestStart: 11,
17
+ responseStart: 12,
18
+ responseEnd: 13,
19
+ domLoading: 14,
20
+ domInteractive: 15,
21
+ domContentLoadedEventStart: 16,
22
+ domContentLoadedEventEnd: 17,
23
+ domComplete: 18,
24
+ loadEventStart: 19,
25
+ loadEventEnd: 20,
26
+ type: 'reload',
27
+ redirectCount: 22
28
+ };
29
+ const legacyTestValues = {
30
+ unloadEventStart: offset + 1,
31
+ redirectStart: offset + 2,
32
+ unloadEventEnd: offset + 3,
33
+ redirectEnd: offset + 4,
34
+ fetchStart: offset + 5,
35
+ domainLookupStart: offset + 6,
36
+ domainLookupEnd: offset + 7,
37
+ connectStart: offset + 8,
38
+ secureConnectionStart: offset + 9,
39
+ connectEnd: offset + 10,
40
+ requestStart: offset + 11,
41
+ responseStart: offset + 12,
42
+ responseEnd: offset + 13,
43
+ domLoading: offset + 14,
44
+ domInteractive: offset + 15,
45
+ domContentLoadedEventStart: offset + 16,
46
+ domContentLoadedEventEnd: offset + 17,
47
+ domComplete: offset + 18,
48
+ loadEventStart: offset + 19,
49
+ loadEventEnd: offset + 20,
50
+ type: 'reload',
51
+ redirectCount: offset + 22
52
+ };
53
+ const expectedPT = {
54
+ of: offset,
55
+ n: 0,
56
+ u: 1,
57
+ r: 2,
58
+ ue: 3,
59
+ re: 4,
60
+ f: 5,
61
+ dn: 6,
62
+ dne: 7,
63
+ c: 8,
64
+ s: 9,
65
+ ce: 10,
66
+ rq: 11,
67
+ rp: 12,
68
+ rpe: 13,
69
+ dl: 14,
70
+ di: 15,
71
+ ds: 16,
72
+ de: 17,
73
+ dc: 18,
74
+ l: 19,
75
+ le: 20
76
+ };
77
+ const expectedPN = {
78
+ ty: 1,
79
+ rc: 22
80
+ };
81
+ describe('addPT()', () => {
82
+ test('an output object is populated with valid values', () => {
83
+ const output = (0, _navTiming.addPT)(offset, testValues, {});
84
+ expect(output).toEqual(expectedPT);
85
+ });
86
+ test('an object with invalid values is handled', () => {
87
+ const output = (0, _navTiming.addPT)(offset, {
88
+ ...testValues,
89
+ invalidValue: 'test'
90
+ }, {});
91
+ expect(output).toEqual(expectedPT);
92
+ const output2 = (0, _navTiming.addPT)(offset, {
93
+ ...testValues,
94
+ loadEventEnd: -1
95
+ }, {});
96
+ let expected = {
97
+ ...expectedPT
98
+ };
99
+ delete expected.le;
100
+ expect(output2).toEqual(expected);
101
+ const output3 = (0, _navTiming.addPT)(offset, {
102
+ ...testValues,
103
+ loadEventEnd: 'test'
104
+ }, {});
105
+ expected = {
106
+ ...expectedPT
107
+ };
108
+ delete expected.le;
109
+ expect(output3).toEqual(expected);
110
+ const output4 = (0, _navTiming.addPT)(offset, {
111
+ ...testValues,
112
+ loadEventEnd: null
113
+ }, {});
114
+ expected = {
115
+ ...expectedPT
116
+ };
117
+ delete expected.le;
118
+ expect(output4).toEqual(expected);
119
+ const legacyoutput = (0, _navTiming.addPT)(offset, {
120
+ ...legacyTestValues,
121
+ invalidValue: 'test'
122
+ }, {}, true);
123
+ expect(legacyoutput).toEqual(expectedPT);
124
+ const legacyoutput2 = (0, _navTiming.addPT)(offset, {
125
+ ...legacyTestValues,
126
+ loadEventEnd: -1
127
+ }, {}, true);
128
+ let legacyexpected = {
129
+ ...expectedPT
130
+ };
131
+ delete legacyexpected.le;
132
+ expect(legacyoutput2).toEqual(expected);
133
+ const legacyoutput3 = (0, _navTiming.addPT)(offset, {
134
+ ...legacyTestValues,
135
+ loadEventEnd: 'test'
136
+ }, {}, true);
137
+ legacyexpected = {
138
+ ...expectedPT
139
+ };
140
+ delete legacyexpected.le;
141
+ expect(legacyoutput3).toEqual(legacyexpected);
142
+ const legacyoutput4 = (0, _navTiming.addPT)(offset, {
143
+ ...legacyTestValues,
144
+ loadEventEnd: null
145
+ }, {}, true);
146
+ legacyexpected = {
147
+ ...expectedPT
148
+ };
149
+ delete legacyexpected.le;
150
+ expect(legacyoutput4).toEqual(legacyexpected);
151
+ });
152
+ test('rounds values to integers', () => {
153
+ const output = (0, _navTiming.addPT)(offset, {
154
+ unloadEventStart: 3.14159
155
+ }, {});
156
+ expect(output.u).toEqual(3);
157
+ const legacyoutput = (0, _navTiming.addPT)(0, {
158
+ unloadEventStart: 3.14159
159
+ }, {}, true);
160
+ expect(legacyoutput.u).toEqual(3);
161
+ });
162
+ test('adds entries to navTimingValues', () => {
163
+ const beforeLength = _navTiming.navTimingValues.length;
164
+ (0, _navTiming.addPT)(offset, {
165
+ testValues
166
+ }, {});
167
+ const afterLength = _navTiming.navTimingValues.length;
168
+ expect(afterLength - beforeLength).toEqual(21); // 20 + value of n
169
+
170
+ const legacybeforeLength = _navTiming.navTimingValues.length;
171
+ (0, _navTiming.addPT)(offset, {
172
+ legacyTestValues
173
+ }, {}, true);
174
+ const legacyafterLength = _navTiming.navTimingValues.length;
175
+ expect(legacyafterLength - legacybeforeLength).toEqual(21); // 20 + value of n
176
+ });
177
+ });
178
+
179
+ describe('addPN()', () => {
180
+ test('an output object is populated with valid values', () => {
181
+ const output = (0, _navTiming.addPN)(testValues, {});
182
+ expect(output).toEqual(expectedPN);
183
+ });
184
+ test('adds entries to navTimingValues', () => {
185
+ const beforeLength = _navTiming.navTimingValues.length;
186
+ (0, _navTiming.addPN)(offset, {
187
+ testValues
188
+ }, {});
189
+ const afterLength = _navTiming.navTimingValues.length;
190
+ expect(afterLength - beforeLength).toEqual(2);
191
+ });
192
+ });
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ var _cleanUrl = require("./clean-url");
4
+ test.each([['http://domain.com/path?query=5', 'http://domain.com/path'], ['http://domain.com/path#fragment', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment', 'http://domain.com/path'], ['http://domain.com/path?query=5?dumb#fragment', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment#dumb', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment#dumb?additional_query', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment/silly/dumber#dumbest?additional_query=silly#what_is_this_even', 'http://domain.com/path']])('cleanURL should remove hash', (input, expected) => {
5
+ expect((0, _cleanUrl.cleanURL)(input)).toEqual(expected);
6
+ });
7
+ test.each([['http://domain.com/path?query=5', 'http://domain.com/path'], ['http://domain.com/path#fragment', 'http://domain.com/path#fragment'], ['http://domain.com/path?query=5#fragment', 'http://domain.com/path#fragment'], ['http://domain.com/path?query=5?dumb#fragment', 'http://domain.com/path#fragment'], ['http://domain.com/path?query=5#fragment#dumb', 'http://domain.com/path#fragment#dumb'], ['http://domain.com/path?query=5#fragment#dumb?additional_query', 'http://domain.com/path#fragment#dumb'], ['http://domain.com/path?query=5#fragment/silly/dumber#dumbest?additional_query=silly#what_is_this_even', 'http://domain.com/path#fragment/silly/dumber#dumbest']])('cleanURL should retain hash if second argument is true', (input, expected) => {
8
+ expect((0, _cleanUrl.cleanURL)(input, true)).toEqual(expected);
9
+ });