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/README.md
CHANGED
|
@@ -164,10 +164,6 @@ import { NoibuJS } from 'noibu-react-native';
|
|
|
164
164
|
NoibuJS.addJsSdkError(new Error('My Error'), 'myModule.js');
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
-
## Contributing
|
|
168
|
-
|
|
169
|
-
You can contribute by checking out the project page and open issues. https://linear.app/noibu/project/react-native-sdk-5ccd19a3343a
|
|
170
|
-
|
|
171
167
|
## License
|
|
172
168
|
|
|
173
169
|
Copyright 2023 Noibu.com
|
package/dist/api/clientConfig.js
CHANGED
|
@@ -2,6 +2,8 @@ import uuid from 'react-native-uuid';
|
|
|
2
2
|
import { MAX_METROPLEX_SOCKET_INNACTIVE_TIME, SEVERITY, NOIBU_BROWSER_ID_KYWRD, PV_SEQ_NUM_RESET_TIME_MINUTES, JS_ENV, MAX_PAGEVISIT_VISITED, CLIENT_LOCK_TIME_MINUTES, GET_SCRIPT_ID, MAX_COLLECT_ERROR_LOG } from '../constants.js';
|
|
3
3
|
import { stringifyJSON, getMaxSubstringAllowed, getUserAgent, makeRequest } from '../utils/function.js';
|
|
4
4
|
import Storage from '../storage/storage.js';
|
|
5
|
+
import { noibuLog } from '../utils/log.js';
|
|
6
|
+
import { unwrapNoibuWrapped } from '../utils/object.js';
|
|
5
7
|
|
|
6
8
|
/** @module ClientConfig */
|
|
7
9
|
/**
|
|
@@ -292,6 +294,12 @@ class ClientConfig {
|
|
|
292
294
|
* severity expects one of the SEVERITY_x level constants, or else error will be used
|
|
293
295
|
*/
|
|
294
296
|
async postNoibuErrorAndOptionallyDisableClient(errorMsg, disableClient, severity, keepAlive = false) {
|
|
297
|
+
noibuLog('postNoibuErrorAndOptionallyDisableClient', {
|
|
298
|
+
errorMsg,
|
|
299
|
+
disableClient,
|
|
300
|
+
severity,
|
|
301
|
+
keepAlive,
|
|
302
|
+
});
|
|
295
303
|
if (this.isClientDisabled) {
|
|
296
304
|
return;
|
|
297
305
|
}
|
|
@@ -339,7 +347,7 @@ class ClientConfig {
|
|
|
339
347
|
});
|
|
340
348
|
}
|
|
341
349
|
else {
|
|
342
|
-
fetch(this.noibuErrorURL, {
|
|
350
|
+
unwrapNoibuWrapped(fetch)(this.noibuErrorURL, {
|
|
343
351
|
method: 'POST',
|
|
344
352
|
headers,
|
|
345
353
|
body: stringifyJSON(errorContent),
|
package/dist/api/inputManager.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NOIBUJS_SDK_REQUEST_HELP_CODE, NOIBUJS_SDK_ADD_ID_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FROM_JS_FMW_FUNCTION, MAX_CUSTOM_ERRORS_PER_PAGEVISIT, MAX_CUSTOM_IDS_PER_PAGEVISIT, META_DATA_METROPLEX_TYPE, PAGE_VISIT_META_DATA_ATT_NAME, CUSTOM_ID_NAME_TYPE, CUSTOM_ID_VALUE_TYPE, CUSTOM_ERROR_EVENT_TYPE } from '../constants.js';
|
|
2
2
|
import MetroplexSocket from './metroplexSocket.js';
|
|
3
|
-
import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError
|
|
3
|
+
import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError.js';
|
|
4
4
|
import HelpCode from './helpCode.js';
|
|
5
5
|
|
|
6
6
|
/** @module InputManager */
|
|
@@ -7,6 +7,8 @@ import StoredMetrics from './storedMetrics.js';
|
|
|
7
7
|
import StoredPageVisit from './storedPageVisit.js';
|
|
8
8
|
import { safePerformanceNow } from '../utils/performance.js';
|
|
9
9
|
import { isDateOverwritten } from '../utils/date.js';
|
|
10
|
+
import { unwrapNoibuWrapped } from '../utils/object.js';
|
|
11
|
+
import { noibuLog } from '../utils/log.js';
|
|
10
12
|
|
|
11
13
|
/** @module MetroplexSocket */
|
|
12
14
|
|
|
@@ -174,11 +176,16 @@ class MetroplexSocket {
|
|
|
174
176
|
* @returns {Promise<boolean>} true if message was sent succefully, false otherwise
|
|
175
177
|
*/
|
|
176
178
|
async sendMessage(type, payload) {
|
|
179
|
+
noibuLog('sendMessage start', { type });
|
|
177
180
|
// if we have a lock on this specific type, we dont send it
|
|
178
181
|
if (
|
|
179
182
|
type in this.metroplexTypeLock ||
|
|
180
183
|
ClientConfig.getInstance().isClientDisabled
|
|
181
184
|
) {
|
|
185
|
+
noibuLog('sendMessage quitting due to', {
|
|
186
|
+
typeInLock: type in this.metroplexTypeLock,
|
|
187
|
+
isClientDisabled: ClientConfig.getInstance().isClientDisabled,
|
|
188
|
+
});
|
|
182
189
|
return false;
|
|
183
190
|
}
|
|
184
191
|
|
|
@@ -749,7 +756,7 @@ class MetroplexSocket {
|
|
|
749
756
|
updatedMsg[VIDEO_PART_COUNT_ATT_NAME] += 1;
|
|
750
757
|
|
|
751
758
|
// we send the remainder elements
|
|
752
|
-
|
|
759
|
+
unwrapNoibuWrapped(fetch)(this.postURL, {
|
|
753
760
|
method: 'POST',
|
|
754
761
|
headers: {
|
|
755
762
|
'content-type': 'application/json',
|
|
@@ -768,10 +775,15 @@ class MetroplexSocket {
|
|
|
768
775
|
* @param {} payload
|
|
769
776
|
*/
|
|
770
777
|
_sendSocketMessage(payload) {
|
|
771
|
-
|
|
778
|
+
noibuLog('_sendSocketMessage');
|
|
779
|
+
const closeIfInactive = this.closeIfInactive();
|
|
780
|
+
if (closeIfInactive) {
|
|
781
|
+
noibuLog('_sendSocketMessage dropped due to', { closeIfInactive });
|
|
772
782
|
return false;
|
|
773
783
|
}
|
|
774
|
-
|
|
784
|
+
const payloadJson = stringifyJSON(payload);
|
|
785
|
+
noibuLog(`_sendSocketMessage sending: ${payloadJson}`);
|
|
786
|
+
this.socket.send(payloadJson);
|
|
775
787
|
return true;
|
|
776
788
|
}
|
|
777
789
|
|
|
@@ -2,6 +2,7 @@ import { BROWSER_ID_ATT_NAME, PV_ID_ATT_NAME, COLLECT_VER_ATT_NAME, CURRENT_NOIB
|
|
|
2
2
|
import ClientConfig from './clientConfig.js';
|
|
3
3
|
import { getUserAgent, stringifyJSON } from '../utils/function.js';
|
|
4
4
|
import { addSafeEventListener } from '../utils/eventlistener.js';
|
|
5
|
+
import { unwrapNoibuWrapped } from '../utils/object.js';
|
|
5
6
|
|
|
6
7
|
/** @module StoredMetrics */
|
|
7
8
|
|
|
@@ -181,7 +182,7 @@ class StoredMetrics {
|
|
|
181
182
|
[ERR_COUNT_EXPECTED_ATT_NAME]: this.errCount,
|
|
182
183
|
[ON_URL_ATT_NAME]: ClientConfig.getInstance().globalUrl,
|
|
183
184
|
};
|
|
184
|
-
|
|
185
|
+
unwrapNoibuWrapped(fetch)(GET_METROPLEX_METRICS_URL(), {
|
|
185
186
|
method: 'POST',
|
|
186
187
|
headers: {
|
|
187
188
|
'content-type': 'application/json',
|
package/dist/constants.d.ts
CHANGED
|
@@ -226,3 +226,11 @@ export declare function GET_METROPLEX_METRICS_URL(): string;
|
|
|
226
226
|
*/
|
|
227
227
|
export declare function JS_ENV(): string;
|
|
228
228
|
export declare const METROPLEX_RETRY_FREQUENCY: 30000;
|
|
229
|
+
export declare const STACK_TRACE_SANITIZE_REGEXP: RegExp;
|
|
230
|
+
export declare const BLOCKLISTED_DOMAINS: {
|
|
231
|
+
'input.noibu.com': boolean;
|
|
232
|
+
'input.staging.noibu.com': boolean;
|
|
233
|
+
'vf.noibu.com': boolean;
|
|
234
|
+
'vf.staging.noibu.com': boolean;
|
|
235
|
+
'cdn.noibu.com': boolean;
|
|
236
|
+
};
|
package/dist/constants.js
CHANGED
|
@@ -315,7 +315,7 @@ const CONTENT_LENGTH = 'content-length';
|
|
|
315
315
|
* Gets the script id from the cookie object, returns default if cannot be found
|
|
316
316
|
*/
|
|
317
317
|
function GET_SCRIPT_ID() {
|
|
318
|
-
return "1.0.104-rn-sdk-0.
|
|
318
|
+
return "1.0.104-rn-sdk-0.1.2" ;
|
|
319
319
|
}
|
|
320
320
|
/**
|
|
321
321
|
*
|
|
@@ -423,5 +423,13 @@ function JS_ENV() {
|
|
|
423
423
|
}
|
|
424
424
|
// gets the frequency at which the client resends the message that were not confirmed by metroplex
|
|
425
425
|
const METROPLEX_RETRY_FREQUENCY = 30000;
|
|
426
|
+
const STACK_TRACE_SANITIZE_REGEXP = /(nbuGlobalPromiseRejectWrapper|(hermes.*InternalBytecode\/InternalBytecode))/gi;
|
|
427
|
+
const BLOCKLISTED_DOMAINS = {
|
|
428
|
+
'input.noibu.com': true,
|
|
429
|
+
'input.staging.noibu.com': true,
|
|
430
|
+
'vf.noibu.com': true,
|
|
431
|
+
'vf.staging.noibu.com': true,
|
|
432
|
+
'cdn.noibu.com': true,
|
|
433
|
+
};
|
|
426
434
|
|
|
427
|
-
export { APP_NAVIGATION_EVENT_TYPE, BLOCKED_HTTP_HEADER_KEYS, BLOCK_SOCKET_MESSAGE, BROWSER_ID_ATT_NAME, CLICK_EVENT_TYPE, CLIENT_LOCK_TIME_MINUTES, CLOSE_CONNECTION_FORCEFULLY, COLLECT_VER_ATT_NAME, CONN_COUNT_ATT_NAME, CONSOLE_FUNCTION_OVERRIDES, CONTENT_LENGTH, CONTENT_TYPE, CSS_CLASS_ATT_NAME, CURRENT_METRICS_VERSION, CURRENT_NOIBUJS_VERSION, CURRENT_PV_VERSION, CUSTOM_ERROR_EVENT_TYPE, CUSTOM_ID_NAME_TYPE, CUSTOM_ID_VALUE_TYPE, DEFAULT_STACK_FRAME_FIELD_VALUE, DEFAULT_WEBSITE_SUBDOMAIN_PATTERN, DID_CUT_PV_ATT_NAME, DID_CUT_VID_ATT_NAME, DID_START_VID_ATT_NAME, END_AT_ATT_NAME, ERROR_EVENT_ERROR_TYPE, ERROR_EVENT_TYPE, ERROR_EVENT_UNHANDLED_REJECTION_TYPE, ERROR_LOG_EVENT_ERROR_TYPE, ERROR_SOURCE_ATT_NAME, ERR_COUNT_EXPECTED_ATT_NAME, EVENT_ERROR_TYPE, EXP_VIDEO_LENGTH_ATT_NAME, FETCH_EXCEPTION_ERROR_TYPE, GET_MAX_METROPLEX_RECONNECTION_NUMBER, GET_METROPLEX_BASE_HTTP_URL, GET_METROPLEX_BASE_SOCKET_URL, GET_METROPLEX_CONSECUTIVE_CONNECTION_DELAY, GET_METROPLEX_METRICS_URL, GET_METROPLEX_POST_URL, GET_SCRIPT_ID, GQL_ERROR_ATT_NAME, GQL_ERROR_TYPE, GQL_EVENT_TYPE, HELP_CODE_ATT_NAME, HTMLID_ATT_NAME, HTTP_BODY_DROPPED_LENGTH_MSG, HTTP_BODY_DROPPED_TYPE_MSG, HTTP_BODY_NULL_STRING, HTTP_CODE_ATT_NAME, HTTP_COUNT_EXPECTED_ATT_NAME, HTTP_DATA_METROPLEX_TYPE, HTTP_DATA_PAYLOAD_ATT_NAME, HTTP_DATA_REQ_HEADERS_ATT_NAME, HTTP_DATA_RESP_HEADERS_ATT_NAME, HTTP_DATA_RESP_PAYLOAD_ATT_NAME, HTTP_EVENT_TYPE, HTTP_METHOD_ATT_NAME, HTTP_PII_BLOCKING_PATTERNS, HTTP_RESP_CODE_ATT_NAME, HTTP_RESP_LENGTH_ATT_NAME, HTTP_RESP_TIME_ATT_NAME, HUMAN_READABLE_CONTENT_TYPE_REGEX, IS_LAST_ATT_NAME, IS_NJS_VERSION_BETA, JS_ENV, JS_ERROR_ATT_NAME, JS_EVENT_TYPE, JS_STACK_FILE_ATT_NAME, JS_STACK_FRAMES_ATT_NAME, JS_STACK_MESSAGE_ATT_NAME, JS_STACK_METHOD_ATT_NAME, KEYBOARD_EVENT_TYPE, MAX_BEACON_PAYLOAD_SIZE, MAX_COLLECT_ERROR_LOG, MAX_CUSTOM_ERRORS_PER_PAGEVISIT, MAX_CUSTOM_IDS_PER_PAGEVISIT, MAX_FRAMES_IN_ARRAY, MAX_HTTP_DATA_EVENT_COUNT, MAX_HTTP_DATA_PAYLOAD_LENGTH, MAX_METROPLEX_CONNECTION_COUNT, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, MAX_PAGEVISIT_EVENTS, MAX_PAGEVISIT_PARTS, MAX_PAGEVISIT_VISITED, MAX_STRING_LENGTH, MAX_TIME_FOR_UNSENT_DATA_MILLIS, META_DATA_METROPLEX_TYPE, METROPLEX_ERROR_ROUTE, METROPLEX_FRAG_ROUTE, METROPLEX_FULL_PV_ROUTE, METROPLEX_METRICS_ROUTE, METROPLEX_RETRY_FREQUENCY, METROPLEX_SOCKET_INSTANCE_ID_ATT_NAME, NOIBUJS_SDK_ADD_ERROR_FROM_JS_FMW_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FUNCTION, NOIBUJS_SDK_ADD_ID_FUNCTION, NOIBUJS_SDK_REQUEST_HELP_CODE, NOIBU_BROWSER_ID_KYWRD, NOIBU_INPUT_URLS, NOIBU_LOCAL_STORAGE_TEST_KEY, NOIBU_STORED_PAGE_VISIT, OCCURRED_AT_ATT_NAME, OK_SOCKET_MESSAGE, ON_URL_ATT_NAME, PAGE_EVENTS_DOCUMENT, PAGE_EVENTS_WINDOW, PAGE_EVENT_TYPE, PAGE_VISIT_HTTP_DATA_ATT_NAME, PAGE_VISIT_INFORMATION_ATT_NAME, PAGE_VISIT_META_DATA_ATT_NAME, PAGE_VISIT_PART_ATT_NAME, PAGE_VISIT_VID_FRAG_ATT_NAME, PII_DIGIT_PATTERN, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING, PV_CLICKS_ATT_NAME, PV_EVENTS_ATT_NAME, PV_EXP_HTTP_DATA_SEQ_ATT_NAME, PV_EXP_PART_COUNTER_ATT_NAME, PV_EXP_VF_SEQ_ATT_NAME, PV_HTTP_PAYLOADS_COLLECTED_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_OVERSIZE_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_TYPE_ATT_NAME, PV_HTTP_REQUESTS_DROPPED_OVER_LIMIT, PV_ID_ATT_NAME, PV_METROPLEX_TYPE, PV_PART_COUNTER_ATT_NAME, PV_SEQ_ATT_NAME, PV_SEQ_NUM_RESET_TIME_MINUTES, REF_URL_ATT_NAME, REQUIRED_DATA_PROCESSING_URLS, RESPONSE_ERROR_TYPE, SCRIPT_ID_ATT_NAME, SCRIPT_INSTANCE_ID_ATT_NAME, SEQ_NUM_ATT_NAME, SEVERITY, SOCKET_INSTANCE_ID_ATT_NAME, SOURCE_ATT_NAME, STARTED_AT_ATT_NAME, STOP_STORING_PV_SOCKET_MESSAGE, STOP_STORING_VID_SOCKET_MESSAGE, TAGNAME_ATT_NAME, TEXT_ATT_NAME, TYPE_ATT_NAME, URL_ATT_NAME, USERSTEP_EVENT_TYPE, VER_ATT_NAME, VIDEO_CLICKS_ATT_NAME, VIDEO_METROPLEX_TYPE, VIDEO_PART_COUNT_ATT_NAME, WHITELIST_HTML_ID_TEXT_REGEX, WORK_REQUEST_ATT_NAME, WRAPPED_EXCEPTION_ERROR_TYPE, XML_HTTP_REQUEST_ERROR_TYPE };
|
|
435
|
+
export { APP_NAVIGATION_EVENT_TYPE, BLOCKED_HTTP_HEADER_KEYS, BLOCKLISTED_DOMAINS, BLOCK_SOCKET_MESSAGE, BROWSER_ID_ATT_NAME, CLICK_EVENT_TYPE, CLIENT_LOCK_TIME_MINUTES, CLOSE_CONNECTION_FORCEFULLY, COLLECT_VER_ATT_NAME, CONN_COUNT_ATT_NAME, CONSOLE_FUNCTION_OVERRIDES, CONTENT_LENGTH, CONTENT_TYPE, CSS_CLASS_ATT_NAME, CURRENT_METRICS_VERSION, CURRENT_NOIBUJS_VERSION, CURRENT_PV_VERSION, CUSTOM_ERROR_EVENT_TYPE, CUSTOM_ID_NAME_TYPE, CUSTOM_ID_VALUE_TYPE, DEFAULT_STACK_FRAME_FIELD_VALUE, DEFAULT_WEBSITE_SUBDOMAIN_PATTERN, DID_CUT_PV_ATT_NAME, DID_CUT_VID_ATT_NAME, DID_START_VID_ATT_NAME, END_AT_ATT_NAME, ERROR_EVENT_ERROR_TYPE, ERROR_EVENT_TYPE, ERROR_EVENT_UNHANDLED_REJECTION_TYPE, ERROR_LOG_EVENT_ERROR_TYPE, ERROR_SOURCE_ATT_NAME, ERR_COUNT_EXPECTED_ATT_NAME, EVENT_ERROR_TYPE, EXP_VIDEO_LENGTH_ATT_NAME, FETCH_EXCEPTION_ERROR_TYPE, GET_MAX_METROPLEX_RECONNECTION_NUMBER, GET_METROPLEX_BASE_HTTP_URL, GET_METROPLEX_BASE_SOCKET_URL, GET_METROPLEX_CONSECUTIVE_CONNECTION_DELAY, GET_METROPLEX_METRICS_URL, GET_METROPLEX_POST_URL, GET_SCRIPT_ID, GQL_ERROR_ATT_NAME, GQL_ERROR_TYPE, GQL_EVENT_TYPE, HELP_CODE_ATT_NAME, HTMLID_ATT_NAME, HTTP_BODY_DROPPED_LENGTH_MSG, HTTP_BODY_DROPPED_TYPE_MSG, HTTP_BODY_NULL_STRING, HTTP_CODE_ATT_NAME, HTTP_COUNT_EXPECTED_ATT_NAME, HTTP_DATA_METROPLEX_TYPE, HTTP_DATA_PAYLOAD_ATT_NAME, HTTP_DATA_REQ_HEADERS_ATT_NAME, HTTP_DATA_RESP_HEADERS_ATT_NAME, HTTP_DATA_RESP_PAYLOAD_ATT_NAME, HTTP_EVENT_TYPE, HTTP_METHOD_ATT_NAME, HTTP_PII_BLOCKING_PATTERNS, HTTP_RESP_CODE_ATT_NAME, HTTP_RESP_LENGTH_ATT_NAME, HTTP_RESP_TIME_ATT_NAME, HUMAN_READABLE_CONTENT_TYPE_REGEX, IS_LAST_ATT_NAME, IS_NJS_VERSION_BETA, JS_ENV, JS_ERROR_ATT_NAME, JS_EVENT_TYPE, JS_STACK_FILE_ATT_NAME, JS_STACK_FRAMES_ATT_NAME, JS_STACK_MESSAGE_ATT_NAME, JS_STACK_METHOD_ATT_NAME, KEYBOARD_EVENT_TYPE, MAX_BEACON_PAYLOAD_SIZE, MAX_COLLECT_ERROR_LOG, MAX_CUSTOM_ERRORS_PER_PAGEVISIT, MAX_CUSTOM_IDS_PER_PAGEVISIT, MAX_FRAMES_IN_ARRAY, MAX_HTTP_DATA_EVENT_COUNT, MAX_HTTP_DATA_PAYLOAD_LENGTH, MAX_METROPLEX_CONNECTION_COUNT, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, MAX_PAGEVISIT_EVENTS, MAX_PAGEVISIT_PARTS, MAX_PAGEVISIT_VISITED, MAX_STRING_LENGTH, MAX_TIME_FOR_UNSENT_DATA_MILLIS, META_DATA_METROPLEX_TYPE, METROPLEX_ERROR_ROUTE, METROPLEX_FRAG_ROUTE, METROPLEX_FULL_PV_ROUTE, METROPLEX_METRICS_ROUTE, METROPLEX_RETRY_FREQUENCY, METROPLEX_SOCKET_INSTANCE_ID_ATT_NAME, NOIBUJS_SDK_ADD_ERROR_FROM_JS_FMW_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FUNCTION, NOIBUJS_SDK_ADD_ID_FUNCTION, NOIBUJS_SDK_REQUEST_HELP_CODE, NOIBU_BROWSER_ID_KYWRD, NOIBU_INPUT_URLS, NOIBU_LOCAL_STORAGE_TEST_KEY, NOIBU_STORED_PAGE_VISIT, OCCURRED_AT_ATT_NAME, OK_SOCKET_MESSAGE, ON_URL_ATT_NAME, PAGE_EVENTS_DOCUMENT, PAGE_EVENTS_WINDOW, PAGE_EVENT_TYPE, PAGE_VISIT_HTTP_DATA_ATT_NAME, PAGE_VISIT_INFORMATION_ATT_NAME, PAGE_VISIT_META_DATA_ATT_NAME, PAGE_VISIT_PART_ATT_NAME, PAGE_VISIT_VID_FRAG_ATT_NAME, PII_DIGIT_PATTERN, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING, PV_CLICKS_ATT_NAME, PV_EVENTS_ATT_NAME, PV_EXP_HTTP_DATA_SEQ_ATT_NAME, PV_EXP_PART_COUNTER_ATT_NAME, PV_EXP_VF_SEQ_ATT_NAME, PV_HTTP_PAYLOADS_COLLECTED_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_OVERSIZE_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_TYPE_ATT_NAME, PV_HTTP_REQUESTS_DROPPED_OVER_LIMIT, PV_ID_ATT_NAME, PV_METROPLEX_TYPE, PV_PART_COUNTER_ATT_NAME, PV_SEQ_ATT_NAME, PV_SEQ_NUM_RESET_TIME_MINUTES, REF_URL_ATT_NAME, REQUIRED_DATA_PROCESSING_URLS, RESPONSE_ERROR_TYPE, SCRIPT_ID_ATT_NAME, SCRIPT_INSTANCE_ID_ATT_NAME, SEQ_NUM_ATT_NAME, SEVERITY, SOCKET_INSTANCE_ID_ATT_NAME, SOURCE_ATT_NAME, STACK_TRACE_SANITIZE_REGEXP, STARTED_AT_ATT_NAME, STOP_STORING_PV_SOCKET_MESSAGE, STOP_STORING_VID_SOCKET_MESSAGE, TAGNAME_ATT_NAME, TEXT_ATT_NAME, TYPE_ATT_NAME, URL_ATT_NAME, USERSTEP_EVENT_TYPE, VER_ATT_NAME, VIDEO_CLICKS_ATT_NAME, VIDEO_METROPLEX_TYPE, VIDEO_PART_COUNT_ATT_NAME, WHITELIST_HTML_ID_TEXT_REGEX, WORK_REQUEST_ATT_NAME, WRAPPED_EXCEPTION_ERROR_TYPE, XML_HTTP_REQUEST_ERROR_TYPE };
|
package/dist/entry/index.js
CHANGED
|
@@ -2,7 +2,9 @@ import 'react-native-url-polyfill/auto';
|
|
|
2
2
|
import globalInit from './init.js';
|
|
3
3
|
import { ErrorBoundary as ErrorBoundary$1 } from '../react/ErrorBoundary.js';
|
|
4
4
|
import InputManager from '../api/inputManager.js';
|
|
5
|
+
import { noibuLog } from '../utils/log.js';
|
|
5
6
|
|
|
7
|
+
noibuLog('imported');
|
|
6
8
|
/**
|
|
7
9
|
* @param config
|
|
8
10
|
*/
|
package/dist/entry/init.js
CHANGED
|
@@ -13,6 +13,7 @@ import MetroplexSocket from '../api/metroplexSocket.js';
|
|
|
13
13
|
import StoredPageVisit from '../api/storedPageVisit.js';
|
|
14
14
|
import HelpCode from '../api/helpCode.js';
|
|
15
15
|
import { AppNavigationMonitor } from '../monitors/appNavigationMonitor.js';
|
|
16
|
+
import { noibuLog } from '../utils/log.js';
|
|
16
17
|
|
|
17
18
|
/** @module Init */
|
|
18
19
|
// these are set via rollup
|
|
@@ -24,12 +25,15 @@ const urlConfig = {
|
|
|
24
25
|
* initilializes the script to start executing all of NJS features
|
|
25
26
|
*/
|
|
26
27
|
function globalInit(customerConfig) {
|
|
28
|
+
noibuLog('global init started');
|
|
27
29
|
// if the config url is invalid we block collect from executing
|
|
28
30
|
if (isInvalidURLConfig({ ...urlConfig, domain: customerConfig.domain })) {
|
|
31
|
+
noibuLog('exiting');
|
|
29
32
|
return;
|
|
30
33
|
}
|
|
31
34
|
// ensure only one copy of NoibuJS is running at a time
|
|
32
35
|
if (isNoibuJSAlreadyLoaded()) {
|
|
36
|
+
noibuLog('exiting');
|
|
33
37
|
return;
|
|
34
38
|
}
|
|
35
39
|
const noibuErrorURL = `${urlConfig.metroplexHTTPBase}/${METROPLEX_ERROR_ROUTE}`;
|
|
@@ -43,6 +47,7 @@ function globalInit(customerConfig) {
|
|
|
43
47
|
const instanceId = uuid.v4();
|
|
44
48
|
// verifying if collect was disabled by other microservices
|
|
45
49
|
if (ClientConfig.getInstance().isClientDisabled) {
|
|
50
|
+
noibuLog('client disabled, exiting');
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
48
53
|
HelpCode.getInstance();
|
|
@@ -68,9 +73,11 @@ function globalInit(customerConfig) {
|
|
|
68
73
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
69
74
|
// @ts-ignore
|
|
70
75
|
metroplexSocket.connectionPromise.catch((e) => ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(`Error during metroplexSocket initial connection: ${e}`, false, SEVERITY.error));
|
|
76
|
+
noibuLog('global init finished');
|
|
71
77
|
}
|
|
72
78
|
catch (err) {
|
|
73
79
|
ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(`Error during globalInit: ${err}`, true, SEVERITY.error);
|
|
80
|
+
noibuLog('exiting');
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Pressability from 'react-native/Libraries/Pressability/Pressability';
|
|
2
2
|
import { WHITELIST_HTML_ID_TEXT_REGEX, USERSTEP_EVENT_TYPE, SOURCE_ATT_NAME, TEXT_ATT_NAME, TAGNAME_ATT_NAME, HTMLID_ATT_NAME, TYPE_ATT_NAME, CLICK_EVENT_TYPE, CSS_CLASS_ATT_NAME } from '../constants.js';
|
|
3
3
|
import { PageVisit } from '../pageVisit/pageVisit.js';
|
|
4
|
-
import { updatePayload } from '../pageVisit/userStep
|
|
4
|
+
import { updatePayload } from '../pageVisit/userStep.js';
|
|
5
5
|
import StoredMetrics from '../api/storedMetrics.js';
|
|
6
6
|
import { WHITELIST_TEXT_REGEX_STRING } from '../const_matchers.js';
|
|
7
7
|
import { maskTextInput } from '../utils/function.js';
|
|
@@ -15,9 +15,12 @@ export declare function wrap(functionToWrap: WrappedFunction): Function;
|
|
|
15
15
|
export declare function processErrorLogArguments(argsFromErrorLog: any[]): void;
|
|
16
16
|
/**
|
|
17
17
|
* handler for promise rejection failures
|
|
18
|
-
* @param
|
|
18
|
+
* @param error
|
|
19
19
|
*/
|
|
20
|
-
export declare function onPromiseRejectionHandler(
|
|
20
|
+
export declare function onPromiseRejectionHandler(error: {
|
|
21
|
+
message: string;
|
|
22
|
+
stack?: string;
|
|
23
|
+
}): void;
|
|
21
24
|
/**
|
|
22
25
|
* Monitors the errors happening on the window
|
|
23
26
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { asString, isStackTrace } from '../utils/function.js';
|
|
2
|
+
import { CONSOLE_FUNCTION_OVERRIDES, ERROR_EVENT_ERROR_TYPE, STACK_TRACE_SANITIZE_REGEXP, ERROR_EVENT_UNHANDLED_REJECTION_TYPE, ERROR_LOG_EVENT_ERROR_TYPE } from '../constants.js';
|
|
3
|
+
import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError.js';
|
|
1
4
|
import { replace } from '../utils/object.js';
|
|
2
|
-
import { isStackTrace } from '../utils/function.js';
|
|
3
|
-
import { ERROR_EVENT_ERROR_TYPE, CONSOLE_FUNCTION_OVERRIDES, ERROR_LOG_EVENT_ERROR_TYPE } from '../constants.js';
|
|
4
|
-
import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError/pageVisitEventError.js';
|
|
5
5
|
|
|
6
6
|
/* eslint-disable @typescript-eslint/ban-types,prefer-arrow-callback */
|
|
7
7
|
/** @module ErrorMonitor */
|
|
@@ -117,11 +117,49 @@ function configureEventListeners() {
|
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
|
-
*
|
|
120
|
+
* handler for promise rejection failures
|
|
121
|
+
* @param error
|
|
121
122
|
*/
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
function onPromiseRejectionHandler(error) {
|
|
124
|
+
if (!error || !error.message || !error.stack) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const sanitizedStack = error.stack
|
|
128
|
+
.split('\n')
|
|
129
|
+
.filter(line => !line.match(STACK_TRACE_SANITIZE_REGEXP))
|
|
130
|
+
.join('\n');
|
|
131
|
+
const payload = {
|
|
132
|
+
error: {
|
|
133
|
+
message: error.message,
|
|
134
|
+
stack: sanitizedStack,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
saveErrorToPagevisit(ERROR_EVENT_UNHANDLED_REJECTION_TYPE, payload);
|
|
138
|
+
}
|
|
139
|
+
function configureHermesHooks() {
|
|
140
|
+
if (global.HermesInternal) {
|
|
141
|
+
global.HermesInternal.enablePromiseRejectionTracker?.({
|
|
142
|
+
allRejections: true,
|
|
143
|
+
});
|
|
144
|
+
/**
|
|
145
|
+
* This internal promise implementation method is populated only after enabling the promise tracker.
|
|
146
|
+
* It represents an improvement over the previous approach,
|
|
147
|
+
* which would lose stack context regarding the rejection because it ran asynchronously through setTimeout.
|
|
148
|
+
*
|
|
149
|
+
* This updated method ensures synchronous error capturing and retrieves the correct stack frames.
|
|
150
|
+
*/
|
|
151
|
+
replace(Promise, '_m', (originalFunction) => function nbuGlobalPromiseRejectWrapper(promise, error) {
|
|
152
|
+
if (error.message && error.stack) {
|
|
153
|
+
onPromiseRejectionHandler(error);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
onPromiseRejectionHandler(new Error(asString(error)));
|
|
157
|
+
}
|
|
158
|
+
return originalFunction?.(promise, error);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function configureErrorUtilsHandler() {
|
|
125
163
|
const existingHandler = global.ErrorUtils.getGlobalHandler() || (() => { });
|
|
126
164
|
global.ErrorUtils.setGlobalHandler((error, ...rest) => {
|
|
127
165
|
saveErrorToPagevisit(ERROR_EVENT_ERROR_TYPE, {
|
|
@@ -129,16 +167,14 @@ function monitorErrors() {
|
|
|
129
167
|
});
|
|
130
168
|
return existingHandler(error, ...rest);
|
|
131
169
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
});
|
|
141
|
-
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Monitors the errors happening on the window
|
|
173
|
+
*/
|
|
174
|
+
function monitorErrors() {
|
|
175
|
+
configureEventListeners();
|
|
176
|
+
configureHermesHooks();
|
|
177
|
+
configureErrorUtilsHandler();
|
|
142
178
|
}
|
|
143
179
|
|
|
144
|
-
export { monitorErrors, processErrorLogArguments };
|
|
180
|
+
export { monitorErrors, onPromiseRejectionHandler, processErrorLogArguments };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { HUMAN_READABLE_CONTENT_TYPE_REGEX, DEFAULT_WEBSITE_SUBDOMAIN_PATTERN, SEVERITY, HTTP_BODY_NULL_STRING, HTTP_DATA_REQ_HEADERS_ATT_NAME, HTTP_DATA_PAYLOAD_ATT_NAME, HTTP_DATA_RESP_HEADERS_ATT_NAME, HTTP_DATA_RESP_PAYLOAD_ATT_NAME, HTTP_BODY_DROPPED_LENGTH_MSG, HTTP_BODY_DROPPED_TYPE_MSG, MAX_HTTP_DATA_PAYLOAD_LENGTH, CONTENT_TYPE, CONTENT_LENGTH, BLOCKED_HTTP_HEADER_KEYS, PII_REDACTION_REPLACEMENT_STRING, HTTP_PII_BLOCKING_PATTERNS } from '../constants.js';
|
|
2
2
|
import ClientConfig from '../api/clientConfig.js';
|
|
3
3
|
import StoredMetrics from '../api/storedMetrics.js';
|
|
4
|
-
import {
|
|
5
|
-
import '
|
|
4
|
+
import { iterateObjectRecursively } from '../utils/object.js';
|
|
5
|
+
import { noibuLog } from '../utils/log.js';
|
|
6
6
|
|
|
7
7
|
/** @module HTTPDataBundler */
|
|
8
8
|
|
|
@@ -183,6 +183,7 @@ class HTTPDataBundler {
|
|
|
183
183
|
if (xhr === undefined || xhr === null) return null;
|
|
184
184
|
|
|
185
185
|
// If the XHR object exists but the response is null, return null as a string.
|
|
186
|
+
// noinspection PointlessBooleanExpressionJS
|
|
186
187
|
if (xhr.response && xhr.response === null) return HTTP_BODY_NULL_STRING;
|
|
187
188
|
|
|
188
189
|
if (xhr.responseType === '' || xhr.responseType === 'text') {
|
|
@@ -266,12 +267,13 @@ class HTTPDataBundler {
|
|
|
266
267
|
|
|
267
268
|
/**
|
|
268
269
|
* Builds an HTTP Data bundle
|
|
269
|
-
* @param
|
|
270
|
-
* @param
|
|
271
|
-
* @param
|
|
272
|
-
* @param
|
|
273
|
-
* @param
|
|
274
|
-
* @param
|
|
270
|
+
* @param url
|
|
271
|
+
* @param requestHeaders is a map of request headers
|
|
272
|
+
* @param rawRequestPayload
|
|
273
|
+
* @param responseHeaders is a map of response headers
|
|
274
|
+
* @param responsePayload
|
|
275
|
+
* @param method
|
|
276
|
+
* @param shouldCollectPayload
|
|
275
277
|
*/
|
|
276
278
|
bundleHTTPData(
|
|
277
279
|
url,
|
|
@@ -280,15 +282,23 @@ class HTTPDataBundler {
|
|
|
280
282
|
responseHeaders,
|
|
281
283
|
responsePayload,
|
|
282
284
|
method,
|
|
285
|
+
shouldCollectPayload,
|
|
283
286
|
) {
|
|
284
|
-
|
|
287
|
+
noibuLog('bundleHTTPData started for', method, url);
|
|
288
|
+
if (!this.isValidRequest(url, method)) {
|
|
289
|
+
noibuLog('quitting');
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
285
292
|
|
|
286
293
|
// stringify payload if correct type and not too large
|
|
287
294
|
let requestPayload = '';
|
|
288
|
-
if (
|
|
295
|
+
if (shouldCollectPayload) {
|
|
296
|
+
noibuLog('bundleHTTPData collecting payload');
|
|
289
297
|
requestPayload =
|
|
290
298
|
this.dropPayloadIfNecessaryFromHeaders(requestHeaders) ||
|
|
291
299
|
this.stringFromRequestBody(rawRequestPayload);
|
|
300
|
+
} else {
|
|
301
|
+
noibuLog('bundleHTTPData not collecting payload');
|
|
292
302
|
}
|
|
293
303
|
|
|
294
304
|
// don't bundle if there is no data
|
|
@@ -302,6 +312,7 @@ class HTTPDataBundler {
|
|
|
302
312
|
safeResponseHeaders.size === 0 &&
|
|
303
313
|
safeResponsePayload.length === 0
|
|
304
314
|
) {
|
|
315
|
+
noibuLog('bundleHTTPData payload is empty, quitting');
|
|
305
316
|
return null;
|
|
306
317
|
}
|
|
307
318
|
|
|
@@ -320,11 +331,11 @@ class HTTPDataBundler {
|
|
|
320
331
|
// build the http bundle
|
|
321
332
|
return {
|
|
322
333
|
[HTTP_DATA_REQ_HEADERS_ATT_NAME]: cleanRequestHeaders
|
|
323
|
-
?
|
|
334
|
+
? Object.fromEntries(cleanRequestHeaders)
|
|
324
335
|
: {},
|
|
325
336
|
[HTTP_DATA_PAYLOAD_ATT_NAME]: requestPayloadUpdated,
|
|
326
337
|
[HTTP_DATA_RESP_HEADERS_ATT_NAME]: cleanResponseHeaders
|
|
327
|
-
?
|
|
338
|
+
? Object.fromEntries(cleanResponseHeaders)
|
|
328
339
|
: {},
|
|
329
340
|
[HTTP_DATA_RESP_PAYLOAD_ATT_NAME]: responsePayloadUpdated,
|
|
330
341
|
};
|
|
@@ -338,8 +349,13 @@ class HTTPDataBundler {
|
|
|
338
349
|
* @returns boolean indicating whether the validation passed
|
|
339
350
|
*/
|
|
340
351
|
isValidRequest(url, method) {
|
|
341
|
-
|
|
352
|
+
noibuLog('isValidRequest');
|
|
353
|
+
if (!this.httpDataCollectionEnabled) {
|
|
354
|
+
noibuLog('isValidRequest httpDataCollectionEnabled is off, quitting');
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
342
357
|
if (!method || typeof method !== 'string') {
|
|
358
|
+
noibuLog('isValidRequest method is invalid, quitting');
|
|
343
359
|
return false;
|
|
344
360
|
}
|
|
345
361
|
// TODO: Check below disabled for beta. NOI-4253
|
|
@@ -361,16 +377,32 @@ class HTTPDataBundler {
|
|
|
361
377
|
* inherently on the current domain) or matches the current domain.
|
|
362
378
|
*/
|
|
363
379
|
shouldContinueForURL(url) {
|
|
364
|
-
|
|
380
|
+
noibuLog('shouldContinueForURL started for', url);
|
|
381
|
+
if (!this.httpDataCollectionEnabled) {
|
|
382
|
+
noibuLog('shouldContinueForURL httpDataCollection turned off, quitting');
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
365
385
|
if (!url || typeof url !== 'string' || !this.initialURLPartsReversed) {
|
|
386
|
+
noibuLog('shouldContinueForURL url is not valid, quitting', {
|
|
387
|
+
initialUrlPartsReversed: this.initialURLPartsReversed,
|
|
388
|
+
});
|
|
366
389
|
return false;
|
|
367
390
|
}
|
|
368
391
|
// URL is absolute; either "http://example.com" or "//example.com"
|
|
369
392
|
if (HTTPDataBundler.isAbsoluteURL(url)) {
|
|
370
393
|
// Only capture requests on the same domain or in the allowed list
|
|
371
|
-
if (!this.isURLSameDomain(url) && !this.shouldCollectPayloadForURL(url))
|
|
394
|
+
if (!this.isURLSameDomain(url) && !this.shouldCollectPayloadForURL(url)) {
|
|
395
|
+
noibuLog(
|
|
396
|
+
'shouldContinueForURL url is not same domain or is not in allow list, quitting',
|
|
397
|
+
{
|
|
398
|
+
shouldCollectPayloadForURL: this.shouldCollectPayloadForURL(url),
|
|
399
|
+
},
|
|
400
|
+
);
|
|
372
401
|
return false;
|
|
402
|
+
}
|
|
373
403
|
} // end `if` (if URL is relative, it is on the same domain.)
|
|
404
|
+
|
|
405
|
+
noibuLog('shouldContinueForURL - yes');
|
|
374
406
|
return true;
|
|
375
407
|
}
|
|
376
408
|
|
|
@@ -392,7 +424,9 @@ class HTTPDataBundler {
|
|
|
392
424
|
* @returns boolean indicating whether HTTP payloads can be collected on this URL
|
|
393
425
|
*/
|
|
394
426
|
shouldCollectPayloadForURL(url) {
|
|
427
|
+
noibuLog('shouldCollectPayloadForURL', url);
|
|
395
428
|
if (!url || typeof url !== 'string') {
|
|
429
|
+
noibuLog('shouldCollectPayloadForURL url is invalid, quitting');
|
|
396
430
|
return false;
|
|
397
431
|
}
|
|
398
432
|
// check if in the full URL allowed list
|
|
@@ -400,6 +434,7 @@ class HTTPDataBundler {
|
|
|
400
434
|
this.httpDataAllowedAbsoluteRegex &&
|
|
401
435
|
this.httpDataAllowedAbsoluteRegex.test(url.toLowerCase())
|
|
402
436
|
) {
|
|
437
|
+
noibuLog('shouldCollectPayloadForURL yes, absolute');
|
|
403
438
|
return true;
|
|
404
439
|
}
|
|
405
440
|
// check if in the relative URL allowed list, if on domain
|
|
@@ -409,8 +444,20 @@ class HTTPDataBundler {
|
|
|
409
444
|
(!HTTPDataBundler.isAbsoluteURL(url) || this.isURLSameDomain(url)) &&
|
|
410
445
|
this.httpDataAllowedRelativeRegex.test(url.toLowerCase())
|
|
411
446
|
) {
|
|
447
|
+
noibuLog('shouldCollectPayloadForURL yes, relative');
|
|
412
448
|
return true;
|
|
413
449
|
}
|
|
450
|
+
|
|
451
|
+
noibuLog('shouldCollectPayloadForURL answer is no, reason', {
|
|
452
|
+
httpDataAllowedAbsoluteRegexTest:
|
|
453
|
+
this.httpDataAllowedAbsoluteRegex &&
|
|
454
|
+
this.httpDataAllowedAbsoluteRegex.test(url.toLowerCase()),
|
|
455
|
+
httpDataAllowedRelativeRegexTest:
|
|
456
|
+
this.httpDataAllowedRelativeRegex &&
|
|
457
|
+
this.httpDataAllowedRelativeRegex.test(url.toLowerCase()),
|
|
458
|
+
isAbsoluteURL: HTTPDataBundler.isAbsoluteURL(url),
|
|
459
|
+
isURLSameDomain: this.isURLSameDomain(url),
|
|
460
|
+
});
|
|
414
461
|
return false;
|
|
415
462
|
}
|
|
416
463
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TextInput } from 'react-native';
|
|
2
|
-
import { updatePayload } from '../pageVisit/userStep
|
|
2
|
+
import { updatePayload } from '../pageVisit/userStep.js';
|
|
3
3
|
import { InputMonitor } from './inputMonitor.js';
|
|
4
4
|
import { SOURCE_ATT_NAME, TEXT_ATT_NAME, TAGNAME_ATT_NAME, TYPE_ATT_NAME, KEYBOARD_EVENT_TYPE } from '../constants.js';
|
|
5
5
|
|