noibu-react-native 0.2.2 → 0.2.4

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 (100) hide show
  1. package/README.md +1 -1
  2. package/dist/api/clientConfig.js +225 -217
  3. package/dist/api/helpCode.js +61 -87
  4. package/dist/api/metroplexSocket.js +460 -463
  5. package/dist/api/storedPageVisit.js +150 -208
  6. package/dist/constants.js +10 -2
  7. package/dist/entry/init.js +65 -63
  8. package/dist/monitors/{appNavigationMonitor.js → AppNavigationMonitor.js} +12 -22
  9. package/dist/monitors/ClickMonitor.js +198 -0
  10. package/dist/monitors/ErrorMonitor.js +206 -0
  11. package/dist/monitors/KeyboardInputMonitor.js +60 -0
  12. package/dist/monitors/PageMonitor.js +98 -0
  13. package/dist/monitors/RequestMonitor.js +390 -0
  14. package/dist/monitors/http-tools/GqlErrorValidator.js +259 -0
  15. package/dist/monitors/http-tools/HTTPDataBundler.js +458 -0
  16. package/dist/monitors/integrations/react-native-navigation-integration.js +4 -2
  17. package/dist/pageVisit/EventDebouncer.js +99 -0
  18. package/dist/pageVisit/pageVisitEventError.js +2 -2
  19. package/dist/pageVisit/pageVisitEventHTTP.js +79 -93
  20. package/dist/react/ErrorBoundary.js +18 -15
  21. package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +3 -2
  22. package/dist/sessionRecorder/sessionRecorder.js +152 -151
  23. package/dist/{api → src/api}/clientConfig.d.ts +2 -2
  24. package/dist/{api → src/api}/helpCode.d.ts +10 -16
  25. package/dist/{api → src/api}/metroplexSocket.d.ts +48 -67
  26. package/dist/{api → src/api}/storedPageVisit.d.ts +12 -21
  27. package/dist/{constants.d.ts → src/constants.d.ts} +45 -0
  28. package/dist/{entry → src/entry}/init.d.ts +1 -1
  29. package/dist/src/monitors/AppNavigationMonitor.d.ts +18 -0
  30. package/dist/src/monitors/ClickMonitor.d.ts +31 -0
  31. package/dist/src/monitors/ErrorMonitor.d.ts +63 -0
  32. package/dist/{monitors/keyboardInputMonitor.d.ts → src/monitors/KeyboardInputMonitor.d.ts} +7 -4
  33. package/dist/{monitors/pageMonitor.d.ts → src/monitors/PageMonitor.d.ts} +6 -8
  34. package/dist/src/monitors/RequestMonitor.d.ts +94 -0
  35. package/dist/src/monitors/http-tools/GqlErrorValidator.d.ts +59 -0
  36. package/dist/src/monitors/http-tools/HTTPDataBundler.d.ts +112 -0
  37. package/dist/{monitors → src/monitors}/integrations/react-native-navigation-integration.d.ts +3 -2
  38. package/dist/src/pageVisit/EventDebouncer.d.ts +24 -0
  39. package/dist/{pageVisit → src/pageVisit}/pageVisit.d.ts +1 -1
  40. package/dist/src/pageVisit/pageVisitEventHTTP.d.ts +25 -0
  41. package/dist/{sessionRecorder → src/sessionRecorder}/types.d.ts +1 -1
  42. package/dist/{storage → src/storage}/rnStorageProvider.d.ts +1 -1
  43. package/dist/{storage → src/storage}/storage.d.ts +2 -2
  44. package/dist/{storage → src/storage}/storageProvider.d.ts +3 -3
  45. package/dist/{utils → src/utils}/function.d.ts +27 -7
  46. package/dist/{utils → src/utils}/object.d.ts +11 -8
  47. package/dist/src/utils/piiRedactor.d.ts +11 -0
  48. package/dist/src/utils/polyfills.d.ts +4 -0
  49. package/dist/storage/rnStorageProvider.js +7 -4
  50. package/dist/storage/storage.js +43 -35
  51. package/dist/storage/storageProvider.js +23 -19
  52. package/dist/types/Config.d.ts +24 -20
  53. package/dist/types/Metroplex.types.d.ts +73 -0
  54. package/dist/types/Monitor.d.ts +11 -0
  55. package/dist/types/Monitor.js +19 -0
  56. package/dist/types/PageVisit.types.d.ts +8 -0
  57. package/dist/types/PageVisitErrors.types.d.ts +114 -0
  58. package/dist/types/PageVisitEvents.types.d.ts +91 -0
  59. package/dist/types/PageVisitMetrics.types.d.ts +27 -0
  60. package/dist/types/Storage.d.ts +1 -1
  61. package/dist/types/StoredPageVisit.types.d.ts +4 -47
  62. package/dist/types/WrappedObjects.d.ts +6 -0
  63. package/dist/utils/function.js +110 -77
  64. package/dist/utils/object.js +59 -6
  65. package/dist/utils/piiRedactor.js +98 -0
  66. package/dist/utils/polyfills.js +24 -0
  67. package/package.json +8 -8
  68. package/dist/monitors/appNavigationMonitor.d.ts +0 -22
  69. package/dist/monitors/clickMonitor.d.ts +0 -44
  70. package/dist/monitors/clickMonitor.js +0 -251
  71. package/dist/monitors/errorMonitor.d.ts +0 -28
  72. package/dist/monitors/errorMonitor.js +0 -180
  73. package/dist/monitors/gqlErrorValidator.d.ts +0 -82
  74. package/dist/monitors/gqlErrorValidator.js +0 -306
  75. package/dist/monitors/httpDataBundler.d.ts +0 -161
  76. package/dist/monitors/httpDataBundler.js +0 -725
  77. package/dist/monitors/inputMonitor.d.ts +0 -34
  78. package/dist/monitors/inputMonitor.js +0 -138
  79. package/dist/monitors/keyboardInputMonitor.js +0 -66
  80. package/dist/monitors/pageMonitor.js +0 -122
  81. package/dist/monitors/requestMonitor.d.ts +0 -10
  82. package/dist/monitors/requestMonitor.js +0 -401
  83. package/dist/pageVisit/pageVisitEventHTTP.d.ts +0 -18
  84. package/dist/types/PageVisit.d.ts +0 -22
  85. package/dist/types/ReactNative.d.ts +0 -4
  86. package/dist/types/globals.d.ts +0 -45
  87. /package/dist/{api → src/api}/inputManager.d.ts +0 -0
  88. /package/dist/{api → src/api}/storedMetrics.d.ts +0 -0
  89. /package/dist/{const_matchers.d.ts → src/const_matchers.d.ts} +0 -0
  90. /package/dist/{entry → src/entry}/index.d.ts +0 -0
  91. /package/dist/{pageVisit → src/pageVisit}/pageVisitEventError.d.ts +0 -0
  92. /package/dist/{pageVisit → src/pageVisit}/userStep.d.ts +0 -0
  93. /package/dist/{react → src/react}/ErrorBoundary.d.ts +0 -0
  94. /package/dist/{sessionRecorder → src/sessionRecorder}/nativeSessionRecorderSubscription.d.ts +0 -0
  95. /package/dist/{sessionRecorder → src/sessionRecorder}/sessionRecorder.d.ts +0 -0
  96. /package/dist/{utils → src/utils}/date.d.ts +0 -0
  97. /package/dist/{utils → src/utils}/eventlistener.d.ts +0 -0
  98. /package/dist/{utils → src/utils}/log.d.ts +0 -0
  99. /package/dist/{utils → src/utils}/performance.d.ts +0 -0
  100. /package/dist/{utils → src/utils}/stacktrace-parser.d.ts +0 -0
@@ -1,306 +0,0 @@
1
- import { CONTENT_TYPE, SEVERITY } from '../constants.js';
2
- import { isInstanceOf, getMaxSubstringAllowed } from '../utils/function.js';
3
- import ClientConfig from '../api/clientConfig.js';
4
-
5
- const MESSAGE_ATT_NAME = 'message';
6
- const EXTENSIONS_ATT_NAME = 'extensions';
7
- const LOCATIONS_ATT_NAME = 'locations';
8
- const PATH_ATT_NAME = 'path';
9
- const LINE_ATT_NAME = 'line';
10
- const COLUMN_ATT_NAME = 'column';
11
- const MESSAGE_MAX_LENGTH = 1000;
12
-
13
- /* eslint-disable no-restricted-syntax */
14
- /* eslint-disable no-param-reassign */
15
-
16
- /**
17
- * Try detecting GraphQL errors from http response
18
- */
19
- class GqlErrorValidator {
20
- /**
21
- * Retrieves GQL error object based on fetch request/response
22
- * @param {String} url
23
- * @param {{}} options
24
- * @param {Request} request
25
- * @param {Response} response - cloned() from original response
26
- */
27
- static async fromFetch(url, options, request, response) {
28
- try {
29
- const isResponseValid = isInstanceOf(response, Response) && response.ok;
30
- if (!isResponseValid) {
31
- return null;
32
- }
33
- const contentType = this._getContentTypeFromFetchArguments(
34
- options,
35
- request,
36
- );
37
- if (this._shouldHandleRequest(url, contentType)) {
38
- const data = await response.json();
39
- return this._validate(data, []);
40
- }
41
- } catch (e) {
42
- // can't read the response if request is aborted
43
- // so just ignore it
44
- if (!this._isRequestAborted(options, request)) {
45
- this._postError(e);
46
- }
47
- }
48
-
49
- return null;
50
- }
51
-
52
- /**
53
- * Retrieves GQL error object based on XHR object
54
- * @param {String} url
55
- * @param {XMLHttpRequest} xhr
56
- */
57
- static async fromXhr(url, xhr) {
58
- try {
59
- const isResponseValid =
60
- isInstanceOf(xhr, XMLHttpRequest) &&
61
- xhr.status >= 200 &&
62
- xhr.status <= 299;
63
- if (!isResponseValid) {
64
- return null;
65
- }
66
- let contentType = null;
67
- if (xhr.noibuRequestHeaders) {
68
- contentType = xhr.noibuRequestHeaders.get(CONTENT_TYPE);
69
- }
70
- if (this._shouldHandleRequest(url, contentType)) {
71
- let data = null;
72
- if (xhr.responseType === 'blob') {
73
- if (xhr.response.text) {
74
- const content = await xhr.response.text();
75
- data = this._parseJsonSafely(content);
76
- }
77
- } else if (xhr.responseType === 'json') {
78
- data = xhr.response;
79
- } else {
80
- const content = xhr.responseText;
81
- data = this._parseJsonSafely(content);
82
- }
83
- if (data) {
84
- return this._validate(data, []);
85
- }
86
- }
87
- } catch (e) {
88
- this._postError(e);
89
- }
90
-
91
- return null;
92
- }
93
-
94
- /**
95
- * Try safely parse a string and return null if fails
96
- * @param {String} content
97
- */
98
- static _parseJsonSafely(content) {
99
- try {
100
- return JSON.parse(content);
101
- } catch (e) {
102
- return null;
103
- }
104
- }
105
-
106
- /**
107
- * Try to get content type for fetch arguments
108
- * @param {{}} options
109
- * @param {Request} request
110
- */
111
- static _getContentTypeFromFetchArguments(options, request) {
112
- let headers = null;
113
- if (isInstanceOf(request, Request)) {
114
- headers = request.headers;
115
- } else if (options && options.headers) {
116
- headers = new Headers(options.headers);
117
- }
118
- let contentType = null;
119
- if (headers) {
120
- contentType = headers.get(CONTENT_TYPE);
121
- }
122
- return contentType;
123
- }
124
-
125
- /**
126
- * Checks if request is aborted
127
- * If it has been aborder we are not able to consume the response
128
- * @param {{}} options
129
- * @param {Request} request
130
- */
131
- static _isRequestAborted(options, request) {
132
- if (isInstanceOf(request, Request)) {
133
- return request.signal && request.signal.aborted;
134
- }
135
- if (options && isInstanceOf(options.signal, AbortSignal)) {
136
- return options.signal.aborted;
137
- }
138
- return false;
139
- }
140
-
141
- /**
142
- * Determines if request should be processed
143
- * @param {String|URL} url
144
- * @param {String} contentType
145
- */
146
- static _shouldHandleRequest(url, contentType) {
147
- if (contentType) {
148
- contentType = contentType.toLowerCase();
149
- }
150
- let isGqlUrl = false;
151
- if (url) {
152
- if (isInstanceOf(url, URL)) {
153
- url = url.toString();
154
- }
155
- isGqlUrl = url.toLowerCase().includes('graphql');
156
- }
157
- return (
158
- (contentType === 'application/json' && isGqlUrl) ||
159
- contentType === 'application/graphql'
160
- );
161
- }
162
-
163
- /**
164
- * Sanitizes payload object
165
- * @param {any} data
166
- * @param {Array<String>} validationIssues
167
- */
168
- static _validate(data, validationIssues) {
169
- let errors = null;
170
-
171
- if (data && Array.isArray(data.errors)) {
172
- errors = data.errors;
173
-
174
- for (const error of errors) {
175
- const properties = Object.keys(error);
176
- for (const property of properties) {
177
- switch (property) {
178
- case MESSAGE_ATT_NAME:
179
- this._validateMessage(error);
180
- break;
181
- case LOCATIONS_ATT_NAME:
182
- this._validateLocations(error, validationIssues);
183
- break;
184
- case PATH_ATT_NAME:
185
- this._validatePath(error, validationIssues);
186
- break;
187
- case EXTENSIONS_ATT_NAME:
188
- this._validateExtensions(error);
189
- break;
190
- default:
191
- delete error[property];
192
- validationIssues.push(`unexpected error.${property}`);
193
- break;
194
- }
195
- }
196
- }
197
-
198
- if (validationIssues.length > 0) {
199
- this._postValidationIssues(validationIssues);
200
- }
201
- }
202
-
203
- return errors;
204
- }
205
-
206
- /**
207
- * Sanitizes message object
208
- * @param {any} error
209
- */
210
- static _validateMessage(error) {
211
- error[MESSAGE_ATT_NAME] = getMaxSubstringAllowed(
212
- error[MESSAGE_ATT_NAME],
213
- MESSAGE_MAX_LENGTH,
214
- );
215
- }
216
-
217
- /**
218
- * Sanitizes extensions object
219
- * @param {any} error
220
- * @param {Array<String>} validationIssues
221
- */
222
- static _validateExtensions(error) {
223
- const json = JSON.stringify(error[EXTENSIONS_ATT_NAME]);
224
- error[EXTENSIONS_ATT_NAME] = getMaxSubstringAllowed(
225
- json,
226
- MESSAGE_MAX_LENGTH,
227
- );
228
- }
229
-
230
- /**
231
- * Sanitizes locations object
232
- * @param {any} error
233
- * @param {Array<String>} validationIssues
234
- */
235
- static _validateLocations(error, validationIssues) {
236
- const locations = error[LOCATIONS_ATT_NAME];
237
- if (Array.isArray(locations)) {
238
- for (const location of locations) {
239
- const properties = Object.keys(location);
240
- for (const property of properties) {
241
- switch (property) {
242
- case LINE_ATT_NAME:
243
- case COLUMN_ATT_NAME:
244
- if (!Number.isSafeInteger(location[property])) {
245
- const value = location[property];
246
- location[property] = 0;
247
- validationIssues.push(
248
- `unexpected ${property} value '${value}'`,
249
- );
250
- }
251
- break;
252
- default:
253
- delete location[property];
254
- validationIssues.push(`unexpected error.location.${property}`);
255
- break;
256
- }
257
- }
258
- }
259
- } else {
260
- delete error[LOCATIONS_ATT_NAME];
261
- validationIssues.push(`unexpected error.locations`);
262
- }
263
- }
264
-
265
- /**
266
- * Sanitizes path object
267
- * @param {any} error
268
- * @param {Array<String>} validationIssues
269
- */
270
- static _validatePath(error, validationIssues) {
271
- const path = error[PATH_ATT_NAME];
272
- if (Array.isArray(path)) {
273
- error[PATH_ATT_NAME] = error[PATH_ATT_NAME].map(x => x.toString());
274
- } else {
275
- delete error[PATH_ATT_NAME];
276
- validationIssues.push(`unexpected error.path`);
277
- }
278
- }
279
-
280
- /**
281
- * Posts error
282
- * @param {String} message
283
- */
284
- static _postError(message) {
285
- ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
286
- `GQL parse error: ${message}`,
287
- false,
288
- SEVERITY.error,
289
- );
290
- }
291
-
292
- /**
293
- * Posts issue found during object sanitization
294
- * @param {Array<String>} validationIssues
295
- */
296
- static _postValidationIssues(validationIssues) {
297
- const message = validationIssues.join(',');
298
- ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
299
- `GQL error validation warning: ${message}`,
300
- false,
301
- SEVERITY.error,
302
- );
303
- }
304
- }
305
-
306
- export { GqlErrorValidator as default };
@@ -1,161 +0,0 @@
1
- /** Bundles HTTP payloads and headers */
2
- export class HTTPDataBundler {
3
- /** gets http data payload allowed URLs */
4
- static getHttpPayloadAllowedURLs(): string[];
5
- /**
6
- * gets the singleton instance
7
- * @returns {HTTPDataBundler}
8
- */
9
- static getInstance(): HTTPDataBundler;
10
- /**
11
- * Builds the HTTP payload allowed regexes for full and relative URLs
12
- * @param allowedURLs A list of allowed URLs
13
- * @param {'absolute' | 'relative'} strategy Use only absolute URLs if true, use only relative URL if false
14
- * @returns a regex of allowed URLs
15
- */
16
- static buildAllowedRegex(allowedURLs: any, strategy: "absolute" | "relative"): RegExp | null;
17
- /**
18
- * Takes an iterator and returns a map of strings representing headers.
19
- * @param {object} headersIterable any iterable object
20
- * @returns a map of strings (as expected by metroplex) representing HTTP
21
- * request or response headers
22
- */
23
- static headersMapFromIterable(headersIterable: object): Map<any, any>;
24
- /**
25
- * Takes a string of headers with 'name: value' and returns
26
- * a map of strings representing headers.
27
- * @param {string} headersString is all the headers in one string
28
- * @returns a map of strings (as expected by metroplex) representing HTTP
29
- * request or response headers
30
- */
31
- static headersMapFromString(headersString: string): Map<any, any>;
32
- /**
33
- * For an XHR object, checks the responseType property and handles the response or
34
- * responseText property accordingly to return a string representation of the response.
35
- * @param {object} xhr an XMLHTTPRequest object
36
- * @returns a string representation of the response, or null if this fails.
37
- */
38
- static responseStringFromXHRResponseType(xhr: object): any;
39
- /**
40
- * Determins if the URL is absolute or relative
41
- * @param {string} url
42
- * @returns boolean indicating whether the URL passed is either absolute or relative
43
- */
44
- static isAbsoluteURL(url: string): boolean;
45
- contentTypeReadableRegex: RegExp;
46
- initialURLPartsReversed: any[];
47
- httpDataCollectionEnabled: boolean;
48
- httpDataAllowedAbsoluteRegex: RegExp | null;
49
- httpDataAllowedRelativeRegex: RegExp | null;
50
- fuzzyFieldsToRedact: string[];
51
- exactFieldsToRedact: string[];
52
- /**
53
- * Takes a URL and returns true if it is determined to be on the same domain as the URL
54
- * the script is running on. Ignores protocol and path, and allows the URL to be a subdomain.
55
- * @param {string} requestURL the URL of a request to compare to the script website's URL
56
- */
57
- isURLSameDomain(requestURL: string): boolean;
58
- /**
59
- * Builds an HTTP Data bundle
60
- * @param url
61
- * @param requestHeaders is a map of request headers
62
- * @param rawRequestPayload
63
- * @param responseHeaders is a map of response headers
64
- * @param responsePayload
65
- * @param method
66
- * @param shouldCollectPayload
67
- */
68
- bundleHTTPData(url: any, requestHeaders: any, rawRequestPayload: any, responseHeaders: any, responsePayload: any, method: any, shouldCollectPayload: any): {
69
- rqh: any;
70
- rqp: string | null;
71
- rsh: any;
72
- rsp: string | null;
73
- } | null;
74
- /**
75
- * Validates a request based on the URL and method. When enabled, will handle
76
- * de-duping the requests
77
- * @param {string} url
78
- * @param {string} method
79
- * @returns boolean indicating whether the validation passed
80
- */
81
- isValidRequest(url: string, method: string): boolean;
82
- /**
83
- * Checks two things: that the URL is either on the same domain (or an address relative to the
84
- * current domain), and also checks that the config http_data_collection flag is enabled.
85
- * @param {string} url
86
- * @returns boolean indicating whether the URL passed is either relative (in which case it is
87
- * inherently on the current domain) or matches the current domain.
88
- */
89
- shouldContinueForURL(url: string): boolean;
90
- /**
91
- * Checks whether HTTP payloads can be collected on this URL
92
- * @param {string} url
93
- * @returns boolean indicating whether HTTP payloads can be collected on this URL
94
- */
95
- shouldCollectPayloadForURL(url: string): boolean;
96
- /**
97
- * Double checks content length if we couldn't read the headers, and redacts PII
98
- * @param {string} payload
99
- * @param {string} url
100
- * @returns the restricted payload
101
- */
102
- restrictPayload(payload: string, url: string): string | null;
103
- /**
104
- * Returns true if the content length is acceptable to collect
105
- * If the headers are not found, check actual content for length
106
- * @param {Headers} headers
107
- * @returns boolean true if acceptable to collect
108
- */
109
- contentLengthAcceptable(headers: Headers): boolean;
110
- /**
111
- * Returns true if the content type according to the headers is valid for collection.
112
- * Also returns assumed true if content type is not stated in headers.
113
- * @param {Map} headersMap
114
- * @returns boolean true if acceptable to collect
115
- */
116
- contentTypeAcceptable(headersMap: Map<any, any>): boolean;
117
- /**
118
- * Returns a descriptive string if we have to drop payload based on the length
119
- * or type listed in the headers passed. Returns an empty string otherwise.
120
- * @param {Headers} headers a Headers object
121
- * @returns A string, which is empty if the payload doesn't need to be dropped, or is a
122
- * descriptive string explaining the circumstances of the drop otherwise.
123
- */
124
- dropPayloadIfNecessaryFromHeaders(headers: Headers): string;
125
- /**
126
- * Returns content length from the headers, if available
127
- * If the headers are not found or not a number, return -1
128
- * @param {} headersObject
129
- * @returns content length
130
- */
131
- contentLength(headersObject: any): number;
132
- /**
133
- * Accepts a value that could be any type used as a request payload, and returns a string
134
- * representation. First attemtps to find a .toString() method, then tries to handle it
135
- * like an XML or HTML element, then finally falls back to JSON.stringify(). If none of
136
- * these are successful, returns null.
137
- * @param {*} value request paylad body, of any type
138
- * @returns string representation of the value passed, or null if this fails.
139
- */
140
- stringFromRequestBody(value: any): any;
141
- /**
142
- * Removes possible PII from headers.
143
- * @param {Map} dirtyHeaders a Map of HTTP response or request headers
144
- * @returns a map of headers with PII redacted
145
- */
146
- removePIIHeaders(dirtyHeaders: Map<any, any>): Map<any, any> | null;
147
- /**
148
- * Takes a body payload string and redacts any PII we're able to detect
149
- *
150
- * @param {string} dirtyBody the string from which we want to redact PII
151
- * @returns the string with any PII we're able to detect redacted.
152
- */
153
- removePIIBody(dirtyBody: string): string | null;
154
- /**
155
- * Try to parse content as a JSON object and
156
- * iterate it recursively removing PII.
157
- * Returns original content if nothing was changes or error is thrown.
158
- * @param {String} content
159
- */
160
- tryParseObjectAndRemovePII(content: string): string;
161
- }