noibu-react-native 0.2.6 → 0.2.7
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.
- package/README.md +15 -15
- package/dist/api/{clientConfig.js → ClientConfig.js} +69 -52
- package/dist/api/{helpCode.js → HelpCode.js} +6 -13
- package/dist/api/InputManager.js +156 -0
- package/dist/api/{metroplexSocket.js → MetroplexSocket.js} +189 -178
- package/dist/api/StoredMetrics.js +158 -0
- package/dist/api/{storedPageVisit.js → StoredPageVisit.js} +61 -48
- package/dist/const_matchers.js +1 -5
- package/dist/constants.js +15 -390
- package/dist/entry/index.js +3 -4
- package/dist/entry/init.js +33 -19
- package/dist/monitors/AppNavigationMonitor.js +19 -19
- package/dist/monitors/BaseMonitor.js +9 -4
- package/dist/monitors/ClickMonitor.js +72 -76
- package/dist/monitors/ErrorMonitor.js +45 -55
- package/dist/monitors/KeyboardInputMonitor.js +13 -11
- package/dist/monitors/PageMonitor.js +25 -2
- package/dist/monitors/RequestMonitor.js +46 -57
- package/dist/monitors/http-tools/GqlErrorValidator.js +39 -69
- package/dist/monitors/http-tools/HTTPDataBundler.js +71 -66
- package/dist/monitors/integrations/{react-native-navigation-integration.js → ReactNativeNavigationIntegration.js} +15 -12
- package/dist/pageVisit/EventDebouncer.js +43 -74
- package/dist/pageVisit/HttpEventManager.js +88 -0
- package/dist/pageVisit/PageVisitManager.js +99 -0
- package/dist/pageVisit/pageVisitEventError.js +170 -280
- package/dist/react/ErrorBoundary.js +3 -6
- package/dist/sessionRecorder/{sessionRecorder.js → SessionRecorder.js} +58 -70
- package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +3 -5
- package/dist/storage/{rnStorageProvider.js → RNStorageProvider.js} +3 -7
- package/dist/storage/{storage.js → Storage.js} +17 -30
- package/dist/storage/{storageProvider.js → StorageProvider.js} +7 -8
- package/dist/utils/date.js +39 -50
- package/dist/utils/eventlistener.js +5 -12
- package/dist/utils/function.js +42 -113
- package/dist/utils/log.js +5 -5
- package/dist/utils/object.js +12 -12
- package/dist/utils/piiRedactor.js +31 -3
- package/dist/utils/stacktrace-parser.js +29 -21
- package/package.json +14 -14
- package/dist/api/inputManager.js +0 -227
- package/dist/api/storedMetrics.js +0 -198
- package/dist/pageVisit/pageVisit.js +0 -181
- package/dist/pageVisit/pageVisitEventHTTP.js +0 -98
- package/dist/pageVisit/userStep.js +0 -20
- package/dist/src/api/clientConfig.d.ts +0 -100
- package/dist/src/api/clientConfig.test.d.ts +0 -1
- package/dist/src/api/helpCode.d.ts +0 -23
- package/dist/src/api/inputManager.d.ts +0 -87
- package/dist/src/api/metroplexSocket.d.ts +0 -137
- package/dist/src/api/storedMetrics.d.ts +0 -73
- package/dist/src/api/storedPageVisit.d.ts +0 -40
- package/dist/src/const_matchers.d.ts +0 -1
- package/dist/src/constants.d.ts +0 -290
- package/dist/src/entry/index.d.ts +0 -14
- package/dist/src/entry/init.d.ts +0 -5
- package/dist/src/monitors/AppNavigationMonitor.d.ts +0 -18
- package/dist/src/monitors/BaseMonitor.d.ts +0 -13
- package/dist/src/monitors/BaseMonitor.test.d.ts +0 -1
- package/dist/src/monitors/ClickMonitor.d.ts +0 -31
- package/dist/src/monitors/ErrorMonitor.d.ts +0 -63
- package/dist/src/monitors/KeyboardInputMonitor.d.ts +0 -20
- package/dist/src/monitors/PageMonitor.d.ts +0 -20
- package/dist/src/monitors/RequestMonitor.d.ts +0 -94
- package/dist/src/monitors/http-tools/GqlErrorValidator.d.ts +0 -59
- package/dist/src/monitors/http-tools/HTTPDataBundler.d.ts +0 -112
- package/dist/src/monitors/integrations/react-native-navigation-integration.d.ts +0 -20
- package/dist/src/pageVisit/EventDebouncer.d.ts +0 -24
- package/dist/src/pageVisit/pageVisit.d.ts +0 -52
- package/dist/src/pageVisit/pageVisitEventError.d.ts +0 -15
- package/dist/src/pageVisit/pageVisitEventHTTP.d.ts +0 -25
- package/dist/src/pageVisit/userStep.d.ts +0 -5
- package/dist/src/react/ErrorBoundary.d.ts +0 -72
- package/dist/src/sessionRecorder/nativeSessionRecorderSubscription.d.ts +0 -79
- package/dist/src/sessionRecorder/sessionRecorder.d.ts +0 -60
- package/dist/src/sessionRecorder/types.d.ts +0 -91
- package/dist/src/storage/rnStorageProvider.d.ts +0 -23
- package/dist/src/storage/storage.d.ts +0 -39
- package/dist/src/storage/storageProvider.d.ts +0 -26
- package/dist/src/utils/date.d.ts +0 -6
- package/dist/src/utils/eventlistener.d.ts +0 -8
- package/dist/src/utils/function.d.ts +0 -102
- package/dist/src/utils/log.d.ts +0 -4
- package/dist/src/utils/object.d.ts +0 -44
- package/dist/src/utils/performance.d.ts +0 -6
- package/dist/src/utils/piiRedactor.d.ts +0 -11
- package/dist/src/utils/polyfills.d.ts +0 -4
- package/dist/src/utils/stacktrace-parser.d.ts +0 -7
- package/dist/types/Config.d.ts +0 -31
- package/dist/types/Metroplex.types.d.ts +0 -73
- package/dist/types/NavigationIntegration.d.ts +0 -6
- package/dist/types/PageVisit.types.d.ts +0 -8
- package/dist/types/PageVisitErrors.types.d.ts +0 -114
- package/dist/types/PageVisitEvents.types.d.ts +0 -91
- package/dist/types/PageVisitMetrics.types.d.ts +0 -27
- package/dist/types/Storage.d.ts +0 -14
- package/dist/types/StoredPageVisit.types.d.ts +0 -11
- package/dist/types/WrappedObjects.d.ts +0 -6
package/dist/utils/function.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import { Platform } from 'react-native';
|
|
3
3
|
import { parseStack } from './stacktrace-parser.js';
|
|
4
|
-
import { MAX_STRING_LENGTH, MAX_BEACON_PAYLOAD_SIZE,
|
|
4
|
+
import { MAX_STRING_LENGTH, MAX_BEACON_PAYLOAD_SIZE, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING } from '../constants.js';
|
|
5
5
|
import { noibuLog } from './log.js';
|
|
6
6
|
import { unwrapNoibuWrapped } from './object.js';
|
|
7
7
|
|
|
8
|
+
// default string for stack frame fields
|
|
9
|
+
const DEFAULT_STACK_FRAME_FIELD_VALUE = '_';
|
|
10
|
+
const PII_DIGIT_PATTERN = /[0-9]+/g;
|
|
11
|
+
const STACK_TRACE_SANITIZE_REGEXP = /(nbuGlobalPromiseRejectWrapper|InternalBytecode)/gi;
|
|
8
12
|
/**
|
|
9
13
|
* Returns a stack trace frame with default filed values
|
|
10
14
|
*/
|
|
11
15
|
const getDefaultFrame = () => ({
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
line: DEFAULT_STACK_FRAME_FIELD_VALUE,
|
|
17
|
+
mname: DEFAULT_STACK_FRAME_FIELD_VALUE,
|
|
18
|
+
file: DEFAULT_STACK_FRAME_FIELD_VALUE,
|
|
15
19
|
});
|
|
16
20
|
/**
|
|
17
21
|
* returns a string that satisfies a max length
|
|
@@ -55,22 +59,15 @@ function processFrames(rawFrames) {
|
|
|
55
59
|
return processedFrame;
|
|
56
60
|
});
|
|
57
61
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Retrieves the javascript stack and message from an error event object
|
|
60
|
-
* @param errObj error to extract stack from
|
|
61
|
-
*/
|
|
62
|
+
/** Retrieves the javascript stack and message from an error event object */
|
|
62
63
|
function getJSStack(errObj) {
|
|
63
|
-
let frames = [getDefaultFrame()];
|
|
64
64
|
// if the errObj type is not an object or null
|
|
65
65
|
// return a default frame
|
|
66
66
|
if (typeof errObj !== 'object' || !errObj || !errObj.stack) {
|
|
67
|
-
return {
|
|
68
|
-
frames,
|
|
69
|
-
msg: '',
|
|
70
|
-
};
|
|
67
|
+
return { frames: [getDefaultFrame()], msg: '' };
|
|
71
68
|
}
|
|
72
|
-
frames = processFrames(parseStack(errObj.stack));
|
|
73
69
|
const msg = errObj.message ? getMaxSubstringAllowed(errObj.message) : '';
|
|
70
|
+
const frames = processFrames(parseStack(errObj.stack)).filter(line => !`${line.file}|${line.mname}`.match(STACK_TRACE_SANITIZE_REGEXP));
|
|
74
71
|
return {
|
|
75
72
|
frames,
|
|
76
73
|
msg,
|
|
@@ -111,63 +108,36 @@ function stringifyJSON(jsonObject) {
|
|
|
111
108
|
});
|
|
112
109
|
}
|
|
113
110
|
/**
|
|
114
|
-
* Wrapper for a request
|
|
115
|
-
*
|
|
116
|
-
* @param url
|
|
117
|
-
* @param data
|
|
118
|
-
* @param headers
|
|
119
|
-
* @param timeout
|
|
120
|
-
* @param sendAndForget
|
|
111
|
+
* Wrapper for a request with an ability to send-and-forget
|
|
112
|
+
* a send-and-forget request can outlive the page
|
|
121
113
|
*/
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
Object.keys(headersWithUa).forEach(header => {
|
|
150
|
-
xhr.setRequestHeader(header, headers[header]);
|
|
151
|
-
});
|
|
152
|
-
xhr.onload = () => {
|
|
153
|
-
if (xhr.status >= 200 && xhr.status < 300) {
|
|
154
|
-
resolve(xhr.response);
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
reject(new Error(`Custom Request failed: ${xhr.statusText}`));
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
xhr.onerror = () => {
|
|
161
|
-
reject(new Error(`Custom Request failed: ${xhr.statusText}`));
|
|
162
|
-
};
|
|
163
|
-
if (data) {
|
|
164
|
-
xhr.send(stringifyJSON(data));
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
xhr.send();
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
});
|
|
114
|
+
function postRequest(url, data, headers, sendAndForget = false, timeout = 2000) {
|
|
115
|
+
if (typeof fetch !== 'function') {
|
|
116
|
+
return Promise.resolve();
|
|
117
|
+
}
|
|
118
|
+
const body = asString(data);
|
|
119
|
+
const currentPayloadSize = new Blob([body]).size;
|
|
120
|
+
if (sendAndForget && currentPayloadSize > MAX_BEACON_PAYLOAD_SIZE) {
|
|
121
|
+
return Promise.reject("Can't queue data for transfer due to it's size.");
|
|
122
|
+
}
|
|
123
|
+
const init = {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
headers,
|
|
126
|
+
body,
|
|
127
|
+
keepalive: sendAndForget,
|
|
128
|
+
};
|
|
129
|
+
let timer;
|
|
130
|
+
if (typeof AbortController !== 'undefined') {
|
|
131
|
+
const controller = new AbortController();
|
|
132
|
+
init.signal = controller.signal;
|
|
133
|
+
timer = setTimeout(() => controller.abort('Timeout exceeded'), timeout);
|
|
134
|
+
}
|
|
135
|
+
const originalFetch = unwrapNoibuWrapped(fetch);
|
|
136
|
+
const promise = originalFetch(url, init).then(() => { });
|
|
137
|
+
if (typeof AbortController !== 'undefined') {
|
|
138
|
+
promise.finally(() => clearTimeout(timer));
|
|
139
|
+
}
|
|
140
|
+
return promise;
|
|
171
141
|
}
|
|
172
142
|
/**
|
|
173
143
|
* makes sure the url sent is a valid URL
|
|
@@ -202,20 +172,6 @@ function getUserAgent() {
|
|
|
202
172
|
return userAgentCache;
|
|
203
173
|
});
|
|
204
174
|
}
|
|
205
|
-
/**
|
|
206
|
-
* isInvalidURLConfig will verify that Collect is being initializes with
|
|
207
|
-
* the correct env vars.
|
|
208
|
-
*/
|
|
209
|
-
function isInvalidURLConfig(urls) {
|
|
210
|
-
for (let i = 0; i < REQUIRED_DATA_PROCESSING_URLS.length; i += 1) {
|
|
211
|
-
const u = REQUIRED_DATA_PROCESSING_URLS[i];
|
|
212
|
-
if (!urls[u]) {
|
|
213
|
-
noibuLog('urlConfig invalid, reason', u);
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
175
|
/**
|
|
220
176
|
* isNoibuJSAlreadyLoaded will verify if there are already other
|
|
221
177
|
* copies of NoibuJS runnung
|
|
@@ -249,9 +205,7 @@ function asString(obj) {
|
|
|
249
205
|
*/
|
|
250
206
|
function maskTextInput(text) {
|
|
251
207
|
// if it has an email or digit(s), we mask the text
|
|
252
|
-
return text
|
|
253
|
-
.replace(PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING)
|
|
254
|
-
.replace(PII_DIGIT_PATTERN, '*');
|
|
208
|
+
return text.replace(PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING).replace(PII_DIGIT_PATTERN, '*');
|
|
255
209
|
}
|
|
256
210
|
/**
|
|
257
211
|
* Checks if the provided object is an instance of the specified type.
|
|
@@ -266,20 +220,6 @@ function isInstanceOf(instance, type) {
|
|
|
266
220
|
return false;
|
|
267
221
|
}
|
|
268
222
|
}
|
|
269
|
-
/**
|
|
270
|
-
* To grab the video recorder type based on the device we run the app on.
|
|
271
|
-
*/
|
|
272
|
-
function getVideoRecorderType() {
|
|
273
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
274
|
-
if (Platform.OS === 'android') {
|
|
275
|
-
return 'AndroidNative';
|
|
276
|
-
}
|
|
277
|
-
if (Platform.OS === 'ios') {
|
|
278
|
-
return 'IOSNative';
|
|
279
|
-
}
|
|
280
|
-
return '';
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
223
|
/** String.trim, but safe */
|
|
284
224
|
function safeTrim(text) {
|
|
285
225
|
if (typeof text !== 'string') {
|
|
@@ -290,9 +230,6 @@ function safeTrim(text) {
|
|
|
290
230
|
/**
|
|
291
231
|
* Tries to get the stack trace from the given error object and returns it.
|
|
292
232
|
* If the error object does not have a stack trace, an empty string is returned.
|
|
293
|
-
*
|
|
294
|
-
* @param {Error} error - The error object from which to retrieve the stack trace.
|
|
295
|
-
* @returns {string} The stack trace of the error, if available. Otherwise, an empty string is returned.
|
|
296
233
|
*/
|
|
297
234
|
function tryGetStackTrace(error) {
|
|
298
235
|
let result = '';
|
|
@@ -306,13 +243,5 @@ function tryGetStackTrace(error) {
|
|
|
306
243
|
}
|
|
307
244
|
return result;
|
|
308
245
|
}
|
|
309
|
-
/**
|
|
310
|
-
* Checks whether the given value is a string or an instance of String.
|
|
311
|
-
* @param {*} value - The value to be checked.
|
|
312
|
-
* @returns {boolean} Returns true if the value is a string or an instance of String, otherwise returns false.
|
|
313
|
-
*/
|
|
314
|
-
function isString(value) {
|
|
315
|
-
return typeof value === 'string' || value instanceof String;
|
|
316
|
-
}
|
|
317
246
|
|
|
318
|
-
export { asString, getJSStack, getMaxSubstringAllowed, getUserAgent,
|
|
247
|
+
export { asString, getJSStack, getMaxSubstringAllowed, getUserAgent, isInstanceOf, isNoibuJSAlreadyLoaded, isStackTrace, isValidURL, maskTextInput, postRequest, processFrames, safeTrim, stringifyJSON, tryGetStackTrace };
|
package/dist/utils/log.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* checks if was overridden and calls original console function
|
|
5
5
|
*/
|
|
6
6
|
const getConsoleMethod = (ogProp) => {
|
|
7
|
-
// @ts-
|
|
7
|
+
// @ts-expect-error __noibu_original__ is not a standard property
|
|
8
8
|
return console[ogProp].__noibu_original__ || console[ogProp];
|
|
9
9
|
};
|
|
10
|
-
/**
|
|
11
|
-
* log with level = info
|
|
12
|
-
*/
|
|
10
|
+
/**log with level = info */
|
|
13
11
|
const noibuLog = (...msgs) => getConsoleMethod('log')('Noibu', ...msgs);
|
|
12
|
+
/**log with level = error */
|
|
13
|
+
const noibuErr = (...msgs) => getConsoleMethod('error')('Noibu', ...msgs);
|
|
14
14
|
|
|
15
|
-
export { noibuLog };
|
|
15
|
+
export { noibuErr, noibuLog };
|
package/dist/utils/object.js
CHANGED
|
@@ -6,16 +6,13 @@
|
|
|
6
6
|
* attributeName: the attribute key whose value will be replace
|
|
7
7
|
* processingFunction: function that accepts the original value
|
|
8
8
|
* and returns the newValue
|
|
9
|
-
* @param {} sourceObject
|
|
10
|
-
* @param {} attributeName
|
|
11
|
-
* @param {} processingFunction
|
|
12
9
|
*/
|
|
13
|
-
|
|
10
|
+
function replace(sourceObject, attributeName, processingFunction) {
|
|
14
11
|
if (!(attributeName in sourceObject)) {
|
|
15
12
|
return;
|
|
16
13
|
}
|
|
17
14
|
const originalAttribute = sourceObject[attributeName];
|
|
18
|
-
const newValue = processingFunction(originalAttribute);
|
|
15
|
+
const newValue = processingFunction.call(sourceObject, originalAttribute);
|
|
19
16
|
if (typeof newValue === 'function') {
|
|
20
17
|
try {
|
|
21
18
|
newValue.prototype = newValue.prototype || {};
|
|
@@ -40,14 +37,19 @@ const replace = (sourceObject, attributeName, processingFunction) => {
|
|
|
40
37
|
}
|
|
41
38
|
// eslint-disable-next-line no-param-reassign
|
|
42
39
|
sourceObject[attributeName] = newValue;
|
|
43
|
-
}
|
|
40
|
+
}
|
|
44
41
|
/**
|
|
45
42
|
* unwraps wrapped property, so we can use it without side effects
|
|
46
|
-
* @param anything
|
|
47
43
|
*/
|
|
48
44
|
function unwrapNoibuWrapped(anything) {
|
|
49
45
|
return anything.__noibu_original__ || anything;
|
|
50
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Checks if the given object is wrapped
|
|
49
|
+
*/
|
|
50
|
+
function isNoibuWrapped(anything) {
|
|
51
|
+
return '__noibu_original__' in anything;
|
|
52
|
+
}
|
|
51
53
|
/**
|
|
52
54
|
* Checks whether the prototype's property is writeable. If it is not,
|
|
53
55
|
* checks whether the property can be made writeable. If it can, it is
|
|
@@ -55,9 +57,7 @@ function unwrapNoibuWrapped(anything) {
|
|
|
55
57
|
* returns Whether the property on the prototype is (or is now) writeable
|
|
56
58
|
*/
|
|
57
59
|
const propWriteableOrMadeWriteable = (proto, property) => {
|
|
58
|
-
if (!proto ||
|
|
59
|
-
!proto.hasOwnProperty ||
|
|
60
|
-
!Object.prototype.hasOwnProperty.call(proto, property)) {
|
|
60
|
+
if (!proto || !proto.hasOwnProperty || !Object.prototype.hasOwnProperty.call(proto, property)) {
|
|
61
61
|
return false;
|
|
62
62
|
}
|
|
63
63
|
// Getting the properties that this the prototype
|
|
@@ -82,7 +82,7 @@ const propWriteableOrMadeWriteable = (proto, property) => {
|
|
|
82
82
|
* Iterates object recursively and calls visit function
|
|
83
83
|
* for each property allowing to override its value
|
|
84
84
|
* @param {Object} instance An object to iterate through
|
|
85
|
-
* @param {Function} visit
|
|
85
|
+
* @param {Function} visit Target callback function that is called for each property
|
|
86
86
|
* There are 3 arguments: current object, current property and its value
|
|
87
87
|
* @param {{depth: number}} limit Use limit config object to set depth of the recursion
|
|
88
88
|
*/
|
|
@@ -171,4 +171,4 @@ const safeFromEntries = (entries) => {
|
|
|
171
171
|
return obj;
|
|
172
172
|
};
|
|
173
173
|
|
|
174
|
-
export { iterateObjectRecursively, propWriteableOrMadeWriteable, replace, safeEntries, safeFromEntries, unwrapNoibuWrapped };
|
|
174
|
+
export { isNoibuWrapped, iterateObjectRecursively, propWriteableOrMadeWriteable, replace, safeEntries, safeFromEntries, unwrapNoibuWrapped };
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
import { iterateObjectRecursively } from './object.js';
|
|
2
|
-
import {
|
|
2
|
+
import { PII_REDACTION_REPLACEMENT_STRING, PII_EMAIL_PATTERN } from '../constants.js';
|
|
3
3
|
import { stringifyJSON } from './function.js';
|
|
4
4
|
|
|
5
|
+
// Regex patterns for a best-effort attempt at blocking PII in HTTP requests
|
|
6
|
+
const HTTP_PII_BLOCKING_PATTERNS = [
|
|
7
|
+
// Match credit cards [https://www.regular-expressions.info/creditcard.html]
|
|
8
|
+
// Visa
|
|
9
|
+
/\b4\d{12}(?:\d{3})?\b/g,
|
|
10
|
+
// MasterCard
|
|
11
|
+
/\b(?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}\b/g,
|
|
12
|
+
// Amex
|
|
13
|
+
/\b3[47]\d{13}\b/g,
|
|
14
|
+
// Diners Club
|
|
15
|
+
/\b3(?:0[0-5]|[68]\d)\d{11}\b/g,
|
|
16
|
+
// Discover
|
|
17
|
+
/\b6(?:011|5\d{2})\d{12}\b/g,
|
|
18
|
+
// JCB
|
|
19
|
+
/\b(?:2131|1800|35\d{3})\d{11}\b/g,
|
|
20
|
+
// Emails [https://www.regular-expressions.info/email.html]
|
|
21
|
+
PII_EMAIL_PATTERN,
|
|
22
|
+
// US SSN with or without dashes
|
|
23
|
+
// [https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s12.html]
|
|
24
|
+
/\b(?!000|666)[0-8]\d{2}[-.● ]?(?!00)\d{2}[-.● ]?(?!0000)\d{4}\b/g,
|
|
25
|
+
// Canadian SIN with or without dashes [https://regexpattern.com/social-insurance-number-ca]
|
|
26
|
+
/\b(\d{3}[-.● ]?\d{3}[-.● ]?\d{3})\b/g,
|
|
27
|
+
// International phone numbers
|
|
28
|
+
// [https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s03.html]
|
|
29
|
+
/\+(?:\d●?){6,14}\d\b/g,
|
|
30
|
+
// US/Canada phone numbers
|
|
31
|
+
// [https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s02.html]
|
|
32
|
+
/(\b|\+)?(1[-.● ]?)?\(?(\d{3})\)?[-.● ]?(\d{3})[-.● ]?(\d{4})\b/g,
|
|
33
|
+
];
|
|
5
34
|
const fuzzyFieldsToRedact = [
|
|
6
35
|
'password',
|
|
7
36
|
'address',
|
|
@@ -35,8 +64,7 @@ const exactFieldsToRedact = [
|
|
|
35
64
|
*/
|
|
36
65
|
function shouldRedact(field) {
|
|
37
66
|
// check for exact and fuzzy matches
|
|
38
|
-
return
|
|
39
|
-
fuzzyFieldsToRedact.some(v => field.indexOf(v) >= 0));
|
|
67
|
+
return exactFieldsToRedact.some(v => field === v) || fuzzyFieldsToRedact.some(v => field.indexOf(v) >= 0);
|
|
40
68
|
}
|
|
41
69
|
/**
|
|
42
70
|
* Try to parse content as a JSON object and
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MAX_STRING_LENGTH } from '../constants.js';
|
|
2
2
|
|
|
3
3
|
/* eslint-disable require-jsdoc,prefer-destructuring,camelcase */
|
|
4
4
|
// This is a loose copy of ravenjs code
|
|
@@ -15,13 +15,14 @@ import { MAX_FRAMES_IN_ARRAY, MAX_STRING_LENGTH } from '../constants.js';
|
|
|
15
15
|
// or substantial portions of the Software.
|
|
16
16
|
//
|
|
17
17
|
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
18
|
-
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
|
18
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR Target
|
|
19
19
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
20
20
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
21
21
|
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
22
22
|
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
// global reference to slice
|
|
24
24
|
const UNKNOWN_FUNCTION = '<unknown>';
|
|
25
|
+
const MAX_FRAMES_IN_ARRAY = 15;
|
|
25
26
|
/**
|
|
26
27
|
* Safari web extensions, starting version unknown, can produce "frames-only" stacktraces.
|
|
27
28
|
* What it means, is that instead of format like:
|
|
@@ -48,9 +49,7 @@ const extractSafariExtensionDetails = (func, filename) => {
|
|
|
48
49
|
return isSafariExtension || isSafariWebExtension
|
|
49
50
|
? [
|
|
50
51
|
func.indexOf('@') !== -1 ? func.split('@')[0] : UNKNOWN_FUNCTION,
|
|
51
|
-
isSafariExtension
|
|
52
|
-
? `safari-extension:${filename}`
|
|
53
|
-
: `safari-web-extension:${filename}`,
|
|
52
|
+
isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`,
|
|
54
53
|
]
|
|
55
54
|
: [func, filename];
|
|
56
55
|
};
|
|
@@ -68,8 +67,8 @@ function createFrame(filename, func, lineno, colno) {
|
|
|
68
67
|
return frame;
|
|
69
68
|
}
|
|
70
69
|
// Chromium based browsers: Chrome, Brave, new Opera, new Edge
|
|
71
|
-
const chromeRegex = /^\s*at (?:(.+?\)(?: \[
|
|
72
|
-
const chromeEvalRegex = /\((\S*)(
|
|
70
|
+
const chromeRegex = /^\s*at (?:(.+?\)(?: \[.+])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
|
|
71
|
+
const chromeEvalRegex = /\((\S*):(\d+):(\d+)\)/;
|
|
73
72
|
const chrome = (line) => {
|
|
74
73
|
const parts = chromeRegex.exec(line);
|
|
75
74
|
if (parts) {
|
|
@@ -89,20 +88,29 @@ const chrome = (line) => {
|
|
|
89
88
|
return undefined;
|
|
90
89
|
};
|
|
91
90
|
function parseStack(stackString) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
if (typeof stackString === 'string') {
|
|
92
|
+
return stackString
|
|
93
|
+
.split('\n')
|
|
94
|
+
.slice(0, MAX_FRAMES_IN_ARRAY + 1)
|
|
95
|
+
.reduce((stack, line) => {
|
|
96
|
+
if (line.length > MAX_STRING_LENGTH) {
|
|
97
|
+
return stack;
|
|
98
|
+
}
|
|
99
|
+
const parseResult = chrome(line);
|
|
100
|
+
if (parseResult) {
|
|
101
|
+
stack.push(parseResult);
|
|
102
|
+
}
|
|
98
103
|
return stack;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
}, []);
|
|
105
|
+
}
|
|
106
|
+
if (stackString.length && stackString[0].file) {
|
|
107
|
+
return stackString.map(frame => ({
|
|
108
|
+
file: frame.file || '<unknown>',
|
|
109
|
+
line: frame.lineNumber,
|
|
110
|
+
mname: `${frame.class}.${frame.methodName}`,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
return [];
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
export { parseStack };
|
|
116
|
+
export { MAX_FRAMES_IN_ARRAY, parseStack };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noibu-react-native",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"targetNjsVersion": "1.0.104",
|
|
5
5
|
"description": "React-Native SDK for NoibuJS to collect errors in React-Native applications",
|
|
6
6
|
"main": "dist/entry/index.js",
|
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
"clean": "rimraf ./dist/*",
|
|
17
17
|
"build": "node ./build.js",
|
|
18
18
|
"build:dev": "node ./build.watch.js",
|
|
19
|
-
"
|
|
19
|
+
"prepack": "npm run clean; npm run build;",
|
|
20
20
|
"test": "jest --coverage",
|
|
21
21
|
"tsc": "tsc",
|
|
22
|
-
"lint": "eslint
|
|
23
|
-
"lint_output": "eslint src -c .eslintrc.json --ext js,ts,jsx,tsx -f json > eslint_report.json",
|
|
24
|
-
"codecov": "codecov"
|
|
22
|
+
"lint": "tsc eslint.config.ts && eslint ."
|
|
25
23
|
},
|
|
26
24
|
"peerDependenciesMeta": {
|
|
27
25
|
"react-native-navigation": {
|
|
@@ -42,13 +40,16 @@
|
|
|
42
40
|
"react-native": ">=0.63.0",
|
|
43
41
|
"react-native-navigation": ">=2.29.0",
|
|
44
42
|
"react-native-url-polyfill": "^1.3.0",
|
|
45
|
-
"react-native-uuid": "^2.0.1"
|
|
43
|
+
"react-native-uuid": "^2.0.1",
|
|
44
|
+
"whatwg-fetch": "^3.6.20"
|
|
46
45
|
},
|
|
47
46
|
"devDependencies": {
|
|
48
47
|
"@babel/core": "^7.26.0",
|
|
49
48
|
"@babel/preset-env": "^7.26.0",
|
|
50
49
|
"@babel/preset-typescript": "^7.26.0",
|
|
50
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
51
51
|
"@jest/globals": "^29.7.0",
|
|
52
|
+
"@noibu/metroplex-ts-bindings": "1.0.24",
|
|
52
53
|
"@react-native-async-storage/async-storage": "^1.19.0",
|
|
53
54
|
"@rollup/plugin-commonjs": "^25.0.0",
|
|
54
55
|
"@rollup/plugin-json": "^6.0.0",
|
|
@@ -60,20 +61,19 @@
|
|
|
60
61
|
"@types/node": "^20.2.3",
|
|
61
62
|
"@types/react": "16.14.62",
|
|
62
63
|
"@types/react-test-renderer": "^18.0.0",
|
|
63
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
64
|
-
"@typescript-eslint/parser": "^
|
|
64
|
+
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
65
|
+
"@typescript-eslint/parser": "^8.19.1",
|
|
65
66
|
"babel-jest": "^29.7.0",
|
|
66
67
|
"babel-plugin-transform-flow-strip-types": "^6.22.0",
|
|
67
68
|
"codecov": "^3.8.3",
|
|
68
69
|
"dotenv": "^16.1.3",
|
|
69
|
-
"eslint": "^
|
|
70
|
-
"eslint-
|
|
71
|
-
"eslint-
|
|
72
|
-
"eslint-plugin-
|
|
73
|
-
"eslint-plugin-prettier": "^4.2.1",
|
|
70
|
+
"eslint": "^9.17.0",
|
|
71
|
+
"eslint-plugin-jsdoc": "^50.6.1",
|
|
72
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
73
|
+
"eslint-plugin-react": "^7.37.3",
|
|
74
74
|
"fflate": "0.8.2",
|
|
75
75
|
"jest": "^29.7.0",
|
|
76
|
-
"prettier": "^
|
|
76
|
+
"prettier": "^3.4.2",
|
|
77
77
|
"react": "16.13.1",
|
|
78
78
|
"react-native": "0.63.0",
|
|
79
79
|
"react-native-navigation": "^7.40.3",
|