noibu-react-native 0.0.9 → 0.1.2
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 +0 -4
- package/dist/api/clientConfig.js +9 -1
- package/dist/api/inputManager.js +1 -1
- package/dist/api/metroplexSocket.js +15 -3
- package/dist/api/storedMetrics.js +2 -1
- package/dist/constants.d.ts +8 -0
- package/dist/constants.js +10 -2
- package/dist/entry/index.js +2 -0
- package/dist/entry/init.js +7 -0
- package/dist/monitors/clickMonitor.js +1 -1
- package/dist/monitors/errorMonitor.d.ts +5 -2
- package/dist/monitors/errorMonitor.js +54 -18
- package/dist/monitors/httpDataBundler.js +62 -15
- package/dist/monitors/keyboardInputMonitor.js +1 -1
- package/dist/monitors/requestMonitor.js +47 -310
- package/dist/pageVisit/{pageVisitEventError/pageVisitEventError.js → pageVisitEventError.js} +22 -22
- package/dist/pageVisit/{pageVisitEventHTTP/pageVisitEventHTTP.js → pageVisitEventHTTP.js} +15 -7
- package/dist/pageVisit/{userStep/userStep.js → userStep.js} +2 -2
- package/dist/react/ErrorBoundary.js +1 -1
- package/dist/types/globals.d.ts +12 -2
- package/dist/utils/function.js +9 -1
- package/dist/utils/log.d.ts +5 -0
- package/dist/utils/log.js +15 -0
- package/dist/utils/object.d.ts +41 -0
- package/dist/utils/object.js +85 -108
- package/dist/utils/performance.d.ts +6 -0
- package/dist/utils/performance.js +1 -2
- package/dist/utils/stacktrace-parser.js +1 -49
- package/package.json +1 -1
- package/dist/pageVisit/pageVisitEventError/blacklistedDomains.js +0 -9
package/dist/utils/function.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import DeviceInfo from 'react-native-device-info';
|
|
2
2
|
import { parseStack } from './stacktrace-parser.js';
|
|
3
3
|
import { MAX_STRING_LENGTH, MAX_BEACON_PAYLOAD_SIZE, REQUIRED_DATA_PROCESSING_URLS, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING, PII_DIGIT_PATTERN, DEFAULT_STACK_FRAME_FIELD_VALUE } from '../constants.js';
|
|
4
|
+
import { noibuLog } from './log.js';
|
|
5
|
+
import { unwrapNoibuWrapped } from './object.js';
|
|
4
6
|
|
|
5
7
|
/** @module Functions */
|
|
6
8
|
/**
|
|
@@ -41,6 +43,10 @@ function processFrames(rawFrames) {
|
|
|
41
43
|
}
|
|
42
44
|
if (frame.file && frame.file !== '<unknown>') {
|
|
43
45
|
processedFrame.file = String(frame.file);
|
|
46
|
+
if (isValidURL(processedFrame.file)) {
|
|
47
|
+
// todo remove comment if assumption that react native only has local urls in filenames is correct
|
|
48
|
+
processedFrame.file = new URL(processedFrame.file).pathname;
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
51
|
if (frame.column) {
|
|
46
52
|
if (Number.isInteger(frame.column)) {
|
|
@@ -135,7 +141,7 @@ async function makeRequest(method, url, data, headers, timeout, sendAndForget) {
|
|
|
135
141
|
if (currentPayloadSize > MAX_BEACON_PAYLOAD_SIZE) {
|
|
136
142
|
return Promise.resolve();
|
|
137
143
|
}
|
|
138
|
-
return fetch(url, {
|
|
144
|
+
return unwrapNoibuWrapped(fetch)(url, {
|
|
139
145
|
method: 'POST',
|
|
140
146
|
headers: headersWithUa,
|
|
141
147
|
body: stringifyJSON(data),
|
|
@@ -206,6 +212,7 @@ function isInvalidURLConfig(urls) {
|
|
|
206
212
|
for (let i = 0; i < REQUIRED_DATA_PROCESSING_URLS.length; i += 1) {
|
|
207
213
|
const u = REQUIRED_DATA_PROCESSING_URLS[i];
|
|
208
214
|
if (!urls[u]) {
|
|
215
|
+
noibuLog('urlConfig invalid, reason', u);
|
|
209
216
|
return true;
|
|
210
217
|
}
|
|
211
218
|
}
|
|
@@ -220,6 +227,7 @@ function isNoibuJSAlreadyLoaded() {
|
|
|
220
227
|
const loaded = window.noibuJSLoaded !== undefined;
|
|
221
228
|
// set the variable so future copies of the script
|
|
222
229
|
// will know this instance is running
|
|
230
|
+
noibuLog('is already loaded? -', loaded);
|
|
223
231
|
window.noibuJSLoaded = true;
|
|
224
232
|
return loaded;
|
|
225
233
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* eslint-disable no-console,@typescript-eslint/no-empty-function */
|
|
2
|
+
/** no operation */
|
|
3
|
+
/**
|
|
4
|
+
* checks if was overridden and calls original console function
|
|
5
|
+
*/
|
|
6
|
+
const getConsoleMethod = (ogProp) => {
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
return console[ogProp].__noibu_original__ || console[ogProp];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* log with level = info
|
|
12
|
+
*/
|
|
13
|
+
const noibuLog = (...msgs) => getConsoleMethod('log')('Noibu', ...msgs);
|
|
14
|
+
|
|
15
|
+
export { noibuLog };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** @module Object */
|
|
2
|
+
type Func = (...args: any[]) => any;
|
|
3
|
+
/**
|
|
4
|
+
* Replaces an attribute value found in an object with another value
|
|
5
|
+
* sourceObject: source object whose attribute will get replaced
|
|
6
|
+
* attributeName: the attribute key whose value will be replace
|
|
7
|
+
* processingFunction: function that accepts the original value
|
|
8
|
+
* and returns the newValue
|
|
9
|
+
* @param {} sourceObject
|
|
10
|
+
* @param {} attributeName
|
|
11
|
+
* @param {} processingFunction
|
|
12
|
+
*/
|
|
13
|
+
export declare const replace: <A extends { [k in K]: Func; }, K extends keyof A>(sourceObject: A, attributeName: K, processingFunction: (arg: A[K]) => A[K]) => void;
|
|
14
|
+
/**
|
|
15
|
+
* unwraps wrapped property, so we can use it without side effects
|
|
16
|
+
* @param anything
|
|
17
|
+
*/
|
|
18
|
+
export declare function unwrapNoibuWrapped<T>(anything: {
|
|
19
|
+
__noibu_original__?: T;
|
|
20
|
+
} & T): NonNullable<T>;
|
|
21
|
+
/**
|
|
22
|
+
* Checks whether the prototype's property is writeable. If it is not,
|
|
23
|
+
* checks whether the property can be made writeable. If it can, it is
|
|
24
|
+
* set to writeable.
|
|
25
|
+
* @param {object} proto
|
|
26
|
+
* @param {string} property
|
|
27
|
+
* @returns {boolean} Whether the property on the prototype is (or is now) writeable
|
|
28
|
+
*/
|
|
29
|
+
export declare const propWriteableOrMadeWriteable: (proto: object, property: never) => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Iterates object recursively and calls visit function
|
|
32
|
+
* for each property allowing to override its value
|
|
33
|
+
* @param {Object} instance An object to iterate through
|
|
34
|
+
* @param {Function} visit A callback function that is called for each property
|
|
35
|
+
* There are 3 arguments: current object, current property and its value
|
|
36
|
+
* @param {{depth: number}} limit Use limit config object to set depth of the recursion
|
|
37
|
+
*/
|
|
38
|
+
export declare const iterateObjectRecursively: (instance: Record<any, any>, visit: (i: Record<any, any>, p: any, v: any) => any, limit?: {
|
|
39
|
+
depth: number;
|
|
40
|
+
}) => void;
|
|
41
|
+
export {};
|
package/dist/utils/object.js
CHANGED
|
@@ -10,39 +10,43 @@
|
|
|
10
10
|
* @param {} processingFunction
|
|
11
11
|
*/
|
|
12
12
|
const replace = (sourceObject, attributeName, processingFunction) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const originalAttribute = sourceObject[attributeName];
|
|
18
|
-
const newValue = processingFunction(originalAttribute);
|
|
19
|
-
|
|
20
|
-
if (typeof newValue === 'function') {
|
|
21
|
-
try {
|
|
22
|
-
newValue.prototype = newValue.prototype || {};
|
|
23
|
-
Object.defineProperties(newValue, {
|
|
24
|
-
__noibu__: {
|
|
25
|
-
enumerable: false,
|
|
26
|
-
value: true,
|
|
27
|
-
},
|
|
28
|
-
__noibu_original__: {
|
|
29
|
-
enumerable: false,
|
|
30
|
-
value: originalAttribute,
|
|
31
|
-
},
|
|
32
|
-
__noibu_wrapped__: {
|
|
33
|
-
enumerable: false,
|
|
34
|
-
value: newValue,
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
} catch (err) {
|
|
38
|
-
// silent fail
|
|
13
|
+
if (!(attributeName in sourceObject)) {
|
|
14
|
+
return;
|
|
39
15
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
16
|
+
const originalAttribute = sourceObject[attributeName];
|
|
17
|
+
const newValue = processingFunction(originalAttribute);
|
|
18
|
+
if (typeof newValue === 'function') {
|
|
19
|
+
try {
|
|
20
|
+
newValue.prototype = newValue.prototype || {};
|
|
21
|
+
Object.defineProperties(newValue, {
|
|
22
|
+
__noibu__: {
|
|
23
|
+
enumerable: false,
|
|
24
|
+
value: true,
|
|
25
|
+
},
|
|
26
|
+
__noibu_original__: {
|
|
27
|
+
enumerable: false,
|
|
28
|
+
value: originalAttribute,
|
|
29
|
+
},
|
|
30
|
+
__noibu_wrapped__: {
|
|
31
|
+
enumerable: false,
|
|
32
|
+
value: newValue,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
// silent fail
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// eslint-disable-next-line no-param-reassign
|
|
41
|
+
sourceObject[attributeName] = newValue;
|
|
44
42
|
};
|
|
45
|
-
|
|
43
|
+
/**
|
|
44
|
+
* unwraps wrapped property, so we can use it without side effects
|
|
45
|
+
* @param anything
|
|
46
|
+
*/
|
|
47
|
+
function unwrapNoibuWrapped(anything) {
|
|
48
|
+
return anything.__noibu_original__ || anything;
|
|
49
|
+
}
|
|
46
50
|
/**
|
|
47
51
|
* Checks whether the prototype's property is writeable. If it is not,
|
|
48
52
|
* checks whether the property can be made writeable. If it can, it is
|
|
@@ -52,50 +56,29 @@ const replace = (sourceObject, attributeName, processingFunction) => {
|
|
|
52
56
|
* @returns {boolean} Whether the property on the prototype is (or is now) writeable
|
|
53
57
|
*/
|
|
54
58
|
const propWriteableOrMadeWriteable = (proto, property) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Getting the properties that this the prototype
|
|
64
|
-
// has under the open property
|
|
65
|
-
const propDescriptor = Object.getOwnPropertyDescriptor(proto, property);
|
|
66
|
-
|
|
67
|
-
// Checking if the open property is read-only
|
|
68
|
-
if (!propDescriptor.writable) {
|
|
69
|
-
// Checking if we can write to it
|
|
70
|
-
if (propDescriptor.configurable) {
|
|
71
|
-
// Making it writable to wrap it
|
|
72
|
-
Object.defineProperty(proto, property, {
|
|
73
|
-
writable: true,
|
|
74
|
-
});
|
|
75
|
-
} else {
|
|
76
|
-
return false;
|
|
59
|
+
if (!proto ||
|
|
60
|
+
!proto.hasOwnProperty ||
|
|
61
|
+
!Object.prototype.hasOwnProperty.call(proto, property)) {
|
|
62
|
+
return false;
|
|
77
63
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
return obj;
|
|
64
|
+
// Getting the properties that this the prototype
|
|
65
|
+
// has under the open property
|
|
66
|
+
const propDescriptor = Object.getOwnPropertyDescriptor(proto, property);
|
|
67
|
+
// Checking if the open property is read-only
|
|
68
|
+
if (!propDescriptor?.writable) {
|
|
69
|
+
// Checking if we can write to it
|
|
70
|
+
if (propDescriptor?.configurable) {
|
|
71
|
+
// Making it writable to wrap it
|
|
72
|
+
Object.defineProperty(proto, property, {
|
|
73
|
+
writable: true,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
97
81
|
};
|
|
98
|
-
|
|
99
82
|
/**
|
|
100
83
|
* Iterates object recursively and calls visit function
|
|
101
84
|
* for each property allowing to override its value
|
|
@@ -104,41 +87,35 @@ const safeFromEntries = entries => {
|
|
|
104
87
|
* There are 3 arguments: current object, current property and its value
|
|
105
88
|
* @param {{depth: number}} limit Use limit config object to set depth of the recursion
|
|
106
89
|
*/
|
|
107
|
-
const iterateObjectRecursively = (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
iterate(instance[property], depth + 1);
|
|
90
|
+
const iterateObjectRecursively = (instance, visit, limit = { depth: 5 }) => {
|
|
91
|
+
/* eslint-disable no-shadow, no-restricted-syntax, no-param-reassign, guard-for-in */
|
|
92
|
+
/**
|
|
93
|
+
* internal recursive function
|
|
94
|
+
* @param {Object} inst Current object
|
|
95
|
+
* @param {Number} depth Current depth
|
|
96
|
+
*/
|
|
97
|
+
const iterate = (inst, depth) => {
|
|
98
|
+
// stop to go deeper if it is deep enough already
|
|
99
|
+
if (depth > limit.depth)
|
|
100
|
+
return;
|
|
101
|
+
for (const property in inst) {
|
|
102
|
+
try {
|
|
103
|
+
// call visit function and assign its result if not undefined
|
|
104
|
+
const newValue = visit(inst, property, inst[property]);
|
|
105
|
+
if (newValue !== undefined) {
|
|
106
|
+
inst[property] = newValue;
|
|
107
|
+
}
|
|
108
|
+
// go one level deeper if it is an object
|
|
109
|
+
if (inst[property] !== null && typeof inst[property] === 'object') {
|
|
110
|
+
iterate(inst[property], depth + 1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
// just continue to the next property
|
|
115
|
+
}
|
|
134
116
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
iterate(instance, 1);
|
|
117
|
+
};
|
|
118
|
+
iterate(instance, 1);
|
|
142
119
|
};
|
|
143
120
|
|
|
144
|
-
export { iterateObjectRecursively, propWriteableOrMadeWriteable, replace,
|
|
121
|
+
export { iterateObjectRecursively, propWriteableOrMadeWriteable, replace, unwrapNoibuWrapped };
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { timestampWrapper } from './date.js';
|
|
2
2
|
|
|
3
3
|
/** @module Performance */
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
5
|
* Wrapper function for window.performance.now() to ensure
|
|
7
6
|
* it's available before calling it. If it's not available,
|
|
8
7
|
* we return Date.now() instead.
|
|
9
8
|
*/
|
|
10
9
|
function safePerformanceNow() {
|
|
11
|
-
|
|
10
|
+
return timestampWrapper(Date.now());
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
export { safePerformanceNow };
|
|
@@ -88,50 +88,6 @@ const chrome = (line) => {
|
|
|
88
88
|
}
|
|
89
89
|
return undefined;
|
|
90
90
|
};
|
|
91
|
-
const geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
|
|
92
|
-
const geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
|
|
93
|
-
const gecko = (line) => {
|
|
94
|
-
const parts = geckoREgex.exec(line);
|
|
95
|
-
if (parts) {
|
|
96
|
-
const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
|
|
97
|
-
if (isEval) {
|
|
98
|
-
const subMatch = geckoEvalRegex.exec(parts[3]);
|
|
99
|
-
if (subMatch) {
|
|
100
|
-
// throw out eval line/column and use top-most line number
|
|
101
|
-
parts[1] = parts[1] || 'eval';
|
|
102
|
-
parts[3] = subMatch[1];
|
|
103
|
-
parts[4] = subMatch[2];
|
|
104
|
-
parts[5] = ''; // no column when eval
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
let filename = parts[3];
|
|
108
|
-
let func = parts[1] || UNKNOWN_FUNCTION;
|
|
109
|
-
[func, filename] = extractSafariExtensionDetails(func, filename);
|
|
110
|
-
return createFrame(filename, func, parts[4] ? +parts[4] : undefined, parts[5] ? +parts[5] : undefined);
|
|
111
|
-
}
|
|
112
|
-
return undefined;
|
|
113
|
-
};
|
|
114
|
-
const winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
|
115
|
-
const winjs = (line) => {
|
|
116
|
-
const parts = winjsRegex.exec(line);
|
|
117
|
-
return parts
|
|
118
|
-
? createFrame(parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined)
|
|
119
|
-
: undefined;
|
|
120
|
-
};
|
|
121
|
-
const opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
|
|
122
|
-
const opera10 = (line) => {
|
|
123
|
-
const parts = opera10Regex.exec(line);
|
|
124
|
-
return parts
|
|
125
|
-
? createFrame(parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1])
|
|
126
|
-
: undefined;
|
|
127
|
-
};
|
|
128
|
-
const opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
|
|
129
|
-
const opera11 = (line) => {
|
|
130
|
-
const parts = opera11Regex.exec(line);
|
|
131
|
-
return parts
|
|
132
|
-
? createFrame(parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2])
|
|
133
|
-
: undefined;
|
|
134
|
-
};
|
|
135
91
|
function parseStack(stackString) {
|
|
136
92
|
const lines = stackString.split('\n');
|
|
137
93
|
if (lines.length > MAX_FRAMES_IN_ARRAY) {
|
|
@@ -141,11 +97,7 @@ function parseStack(stackString) {
|
|
|
141
97
|
if (line.length > MAX_STRING_LENGTH) {
|
|
142
98
|
return stack;
|
|
143
99
|
}
|
|
144
|
-
const parseResult =
|
|
145
|
-
chrome(line) ||
|
|
146
|
-
winjs(line) ||
|
|
147
|
-
opera11(line) ||
|
|
148
|
-
opera10(line);
|
|
100
|
+
const parseResult = chrome(line);
|
|
149
101
|
if (parseResult) {
|
|
150
102
|
stack.push(parseResult);
|
|
151
103
|
}
|
package/package.json
CHANGED