noibu-react-native 0.2.3 → 0.2.5

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 (71) hide show
  1. package/dist/api/clientConfig.js +20 -27
  2. package/dist/api/helpCode.js +61 -87
  3. package/dist/api/metroplexSocket.js +72 -65
  4. package/dist/api/storedPageVisit.js +150 -208
  5. package/dist/constants.js +3 -7
  6. package/dist/entry/init.js +13 -15
  7. package/dist/monitors/{appNavigationMonitor.js → AppNavigationMonitor.js} +10 -19
  8. package/dist/monitors/BaseMonitor.js +23 -0
  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/{httpDataBundler.js → http-tools/HTTPDataBundler.js} +23 -102
  16. package/dist/pageVisit/{eventDebouncer.js → EventDebouncer.js} +36 -47
  17. package/dist/pageVisit/pageVisitEventError.js +3 -3
  18. package/dist/pageVisit/pageVisitEventHTTP.js +5 -4
  19. package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +22 -5
  20. package/dist/sessionRecorder/sessionRecorder.js +5 -2
  21. package/dist/src/api/clientConfig.d.ts +8 -13
  22. package/dist/src/api/clientConfig.test.d.ts +1 -0
  23. package/dist/src/api/helpCode.d.ts +10 -16
  24. package/dist/src/api/metroplexSocket.d.ts +52 -71
  25. package/dist/src/api/storedPageVisit.d.ts +12 -21
  26. package/dist/src/constants.d.ts +1 -0
  27. package/dist/src/monitors/AppNavigationMonitor.d.ts +18 -0
  28. package/dist/src/monitors/BaseMonitor.d.ts +13 -0
  29. package/dist/src/monitors/BaseMonitor.test.d.ts +1 -0
  30. package/dist/src/monitors/ClickMonitor.d.ts +31 -0
  31. package/dist/src/monitors/ErrorMonitor.d.ts +63 -0
  32. package/dist/src/monitors/{keyboardInputMonitor.d.ts → KeyboardInputMonitor.d.ts} +7 -4
  33. package/dist/src/monitors/{pageMonitor.d.ts → 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/{httpDataBundler.d.ts → http-tools/HTTPDataBundler.d.ts} +13 -28
  37. package/dist/src/monitors/integrations/react-native-navigation-integration.d.ts +3 -2
  38. package/dist/src/pageVisit/{eventDebouncer.d.ts → EventDebouncer.d.ts} +3 -10
  39. package/dist/src/pageVisit/pageVisit.d.ts +1 -1
  40. package/dist/src/pageVisit/pageVisitEventHTTP.d.ts +3 -3
  41. package/dist/src/sessionRecorder/nativeSessionRecorderSubscription.d.ts +15 -0
  42. package/dist/src/storage/rnStorageProvider.d.ts +1 -1
  43. package/dist/src/storage/storage.d.ts +1 -1
  44. package/dist/src/storage/storageProvider.d.ts +2 -2
  45. package/dist/src/utils/function.d.ts +4 -5
  46. package/dist/src/utils/object.d.ts +3 -5
  47. package/dist/src/utils/polyfills.d.ts +1 -4
  48. package/dist/types/Metroplex.types.d.ts +73 -0
  49. package/dist/types/PageVisit.types.d.ts +2 -145
  50. package/dist/types/PageVisitErrors.types.d.ts +114 -0
  51. package/dist/types/PageVisitEvents.types.d.ts +91 -0
  52. package/dist/types/Storage.d.ts +1 -1
  53. package/dist/types/StoredPageVisit.types.d.ts +4 -45
  54. package/dist/utils/function.js +0 -1
  55. package/dist/utils/object.js +1 -0
  56. package/package.json +11 -7
  57. package/dist/monitors/clickMonitor.js +0 -258
  58. package/dist/monitors/errorMonitor.js +0 -202
  59. package/dist/monitors/gqlErrorValidator.js +0 -306
  60. package/dist/monitors/inputMonitor.js +0 -138
  61. package/dist/monitors/keyboardInputMonitor.js +0 -66
  62. package/dist/monitors/pageMonitor.js +0 -122
  63. package/dist/monitors/requestMonitor.js +0 -386
  64. package/dist/src/monitors/appNavigationMonitor.d.ts +0 -22
  65. package/dist/src/monitors/clickMonitor.d.ts +0 -44
  66. package/dist/src/monitors/errorMonitor.d.ts +0 -28
  67. package/dist/src/monitors/gqlErrorValidator.d.ts +0 -82
  68. package/dist/src/monitors/inputMonitor.d.ts +0 -34
  69. package/dist/src/monitors/requestMonitor.d.ts +0 -10
  70. package/dist/types/RRWeb.d.ts +0 -48
  71. package/dist/types/ReactNative.d.ts +0 -4
@@ -1,67 +1,67 @@
1
- import { END_AT_ATT_NAME } from '../constants';
1
+ import { PAGE_VISIT_PART_ATT_NAME, PAGE_VISIT_VID_FRAG_ATT_NAME } from '../constants';
2
+ import { CompletePageVisit, InboundMessageType, OutboundMessageType, OutboundMessageTypeMap, PageVisitFrag, PageVisitInfo, SlidingMessage, VideoFrag } from '../../types/Metroplex.types';
3
+ import { PVEventMessage } from '../../types/PageVisitEvents.types';
4
+ import { Singleton } from '../monitors/BaseMonitor';
5
+ /**
6
+ * Implements rolling window of specified size,
7
+ * but only makes a cut once array length exceeds 150%.
8
+ * During downsize deletes oldest (lowest indexes) elements.
9
+ */
10
+ export declare function createSlidingArrayOfSize<T>(size: number, arraySource?: T[], downsizeThreshold?: number, downsizeFactor?: number): T[];
2
11
  /** Manages the socket to Metroplex */
3
- export default class MetroplexSocket {
4
- _initialURL: any;
5
- ackedOnce: any;
6
- connectionCount: any;
7
- connectionPromise: Promise<any>;
8
- connectionURL: any;
9
- currentConnectionAttempts: any;
10
- forceClosed: any;
11
- helpCodeCb: null | ((...args: any[]) => any);
12
- initialReferingURL: any;
13
- static instance: MetroplexSocket;
14
- instanceId: any;
15
- isRetryLoopDisabled: any;
16
- latestReceivedSeqNumStoredTime: any;
17
- latestReceivedSeqNumber: any;
18
- messageSequenceNum: any;
19
- metroRetryFrequencyMS: any;
20
- metroplexTypeLock: Record<any, any>;
21
- pageVisitInfoSent: any;
22
- postURL: any;
23
- previousMessageType: any;
24
- retryMessageQueue: any[];
25
- retryMetroplexInterval: null | number;
26
- scriptInstanceId: any;
27
- sessionLength: any;
28
- sessionStartTime: any;
29
- sessionTimestamp: any;
12
+ export default class MetroplexSocket extends Singleton {
13
+ forceClosed: boolean;
30
14
  socket: WebSocket | null;
31
- socketInstanceId: string | number[] | null;
15
+ socketInstanceId: string | null;
16
+ previousMessageType: string;
17
+ currentConnectionAttempts: number;
18
+ connectionCount: number;
19
+ sessionStartTime: any;
20
+ connectionPromise: Promise<void> | null;
21
+ pageVisitInfoSent: boolean;
22
+ connectionURL: string;
23
+ postURL: string;
24
+ messageSequenceNum: number;
25
+ latestReceivedSeqNumber: number;
26
+ isRetryLoopDisabled: boolean;
27
+ /** messages that need to be resent to metroplex since they are lacking confirmation */
28
+ retryMessageQueue: SlidingMessage<keyof OutboundMessageTypeMap>[];
29
+ metroplexTypeLock: Record<OutboundMessageType, boolean>;
30
+ initialURL: string;
31
+ initialReferringURL: string;
32
+ sessionTimestamp: Date;
33
+ latestReceivedSeqNumStoredTime: Date;
34
+ instanceId: string;
35
+ scriptInstanceId?: string;
36
+ sessionLength: number;
32
37
  socketCloseCodes: string[];
33
38
  socketOpens: string[];
39
+ ackedOnce: boolean;
40
+ metroRetryFrequencyMS: 30000;
41
+ retryMetroplexInterval: ReturnType<typeof setTimeout> | null;
42
+ private helpCodeCb;
34
43
  /**
35
44
  * Creates an instance of metroplex
36
45
  * id of script, to make sure only a single socket is open
37
46
  */
38
- constructor(scriptInstanceId?: string | number[]);
39
- /**
40
- * gets the singleton instance
41
- * @returns {MetroplexSocket}
42
- */
43
- static getInstance(scriptInstanceId?: string | number[]): MetroplexSocket;
47
+ constructor(scriptInstanceId?: string);
48
+ private static readonly typeToPayloadPropMap;
44
49
  /**
45
50
  * Adds the seq num field to the given payload depending on whether its
46
51
  * a page visit part or video frag
47
52
  */
48
- _addSeqNumToPayload(type: string, payload: any): void;
49
- /**
50
- * sets the seq num in the payload for the given key and increments the
51
- * global seq number
52
- */
53
- _setSeqNumInPayloadAndIncrementSeqNum(payloadKey: string, payload: any): void;
53
+ _addSeqNumToPayload<T>(type: OutboundMessageType, payload: T): T;
54
54
  /** requests help code and saves a callback to be called on response */
55
- requestHelpCode(cb: (typeof this)['helpCodeCb']): Promise<boolean>;
55
+ requestHelpCode(cb: typeof this.helpCodeCb): Promise<boolean>;
56
56
  /**
57
57
  * Immediately sends a message to Metroplex over the web socket
58
58
  * Queues the message if the connection isn't open yet.
59
59
  * returns true if message was sent succefully, false otherwise
60
60
  */
61
- sendMessage(type: string, payload: any): Promise<boolean>;
61
+ sendMessage<T extends OutboundMessageType>(type: T, payload: OutboundMessageTypeMap[T]): Promise<boolean>;
62
62
  /** Updates the latest pv message sent timestamp if events contain any user steps
63
63
  */
64
- _updateLatestPvTimestamp(events: any[]): Promise<void>;
64
+ _updateLatestPvTimestamp(events: PVEventMessage[]): Promise<void>;
65
65
  /** returns true if the socket is either connecting or connected to metroplex */
66
66
  isConnected(): boolean;
67
67
  /** returns true if we are connecting to the socket */
@@ -75,25 +75,23 @@ export default class MetroplexSocket {
75
75
  * connectSocket will establish a websocket connection to the metroplex
76
76
  * service
77
77
  */
78
- connectSocket(): Promise<any>;
78
+ connectSocket(): Promise<void>;
79
79
  /** Calculates and sets the end_at field of the payload
80
80
  * @param {} payload
81
81
  * @param {} isPageVisit
82
82
  */
83
- addEndTimeToPayload(payload: any, isPageVisit: boolean): typeof payload & {
84
- [END_AT_ATT_NAME]: string;
85
- };
83
+ addEndTimeToPayload<T extends VideoFrag | PageVisitFrag>(payload: T, isPageVisit: boolean): T;
86
84
  /** open handler for socket */
87
85
  _onSocketOpen(): Promise<void>;
88
86
  /** message handler for socket
89
87
  * @param {} event
90
88
  */
91
- _onSocketMessage(event: any): Promise<void>;
89
+ _onSocketMessage(event: InboundMessageType): Promise<void>;
92
90
  /**
93
91
  * Returns true if the message's payload has the payload type given and has a sequence
94
92
  * number higher than seqNum
95
93
  */
96
- _messagePayloadHasLargerSeqNum(message: any, payloadType: string, seqNum: number): any;
94
+ _messagePayloadHasLargerSeqNum(message: SlidingMessage, payloadType: typeof PAGE_VISIT_PART_ATT_NAME | typeof PAGE_VISIT_VID_FRAG_ATT_NAME, seqNum: number): boolean;
97
95
  /**
98
96
  * removes messages from the retry queue that are smaller than the
99
97
  * latest stored message in metroplex
@@ -118,39 +116,22 @@ export default class MetroplexSocket {
118
116
  /**
119
117
  * will send a message to metroplex via a post request that will outlive the current page
120
118
  */
121
- postMessage(msg: any): Promise<void>;
119
+ postMessage(msg: CompletePageVisit): Promise<void>;
122
120
  /**
123
121
  * Stringifies the payload into JSON, sends it to the back end if the session
124
122
  * is active and returns true. If inactive the session and socket are closed
125
123
  * and this method returns false.
126
124
  */
127
- _sendSocketMessage(payload: any): Promise<void>;
125
+ _sendSocketMessage<T extends ValueOf<OutboundMessageTypeMap>>(payload: T): Promise<void>;
128
126
  /**
129
127
  * Closes the socket connection if the session is inactive. Returns true if the
130
128
  * session is inactive
131
129
  */
132
130
  closeIfInactive(): Promise<boolean>;
133
131
  /** will get page information, calling this will increase the connection count */
134
- getPageInformation(): Promise<{
135
- br_id: string;
136
- pv_id: string;
137
- v: 5;
138
- seq: number | null;
139
- on_url: any;
140
- ref_url: any;
141
- start_at: any;
142
- conc: any;
143
- cv: 2;
144
- last: boolean;
145
- script_id: string;
146
- script_inst_id: any;
147
- mp_sock_inst_id: any;
148
- sock_inst_id: string | number[] | null;
149
- video_recorder: string;
150
- }>;
132
+ getPageInformation(): Promise<PageVisitInfo>;
151
133
  /**
152
134
  * Try to parse help code response and fire custom event
153
- * @param {String} response
154
135
  */
155
- _tryProcessHelpCodeResponse(response: any): boolean;
136
+ _tryProcessHelpCodeResponse(response: unknown): boolean;
156
137
  }
@@ -1,39 +1,30 @@
1
+ import { CompletePageVisit, PageVisitFrag, PageVisitInfo, SlidingMessage } from '../../types/Metroplex.types';
2
+ import { Singleton } from '../monitors/BaseMonitor';
1
3
  /**
2
4
  * This class holds the final page visit. It flushes it to storage and then
3
5
  * finally sends it to Metroplex via the post route when the next page is loaded
4
6
  */
5
- export default class StoredPageVisit {
6
- /** gets the singleton instance */
7
- static getInstance(): StoredPageVisit;
8
- latestPageVisitFrag: any;
9
- writeTimeout: any;
10
- flushedStorage: boolean;
7
+ export default class StoredPageVisit extends Singleton {
8
+ /**
9
+ * Creates a new instance of StoredPageVisit
10
+ */
11
+ constructor();
11
12
  /**
12
13
  * Check if the events contain a click or location change. If they do then write the retry
13
14
  * queue (which contains the metroplex msg sent above) to storage
14
- * @param {} retryMessageQueue
15
- * @param {} pvInfo
16
15
  */
17
- checkAndStoreRetryQueue(retryMessageQueue: any, pvInfo: any): void;
16
+ checkAndStoreRetryQueue(retryMessageQueue: SlidingMessage[], pvInfo: PageVisitInfo): void;
18
17
  /** Writes the page visit frags in the retry queue to storage
19
- * @param {} retryMessageQueue
20
- * @param {} pvInfo
21
18
  */
22
- writePageVisitsFromRetryQueue(retryMessageQueue: any, pvInfo: any): void;
19
+ writePageVisitsFromRetryQueue(retryMessageQueue: SlidingMessage[], pvInfo: PageVisitInfo): void;
23
20
  /** Write the given page visit frags to storage
24
- * @param {} pageVisitFrags
25
- * @param {} pvInfo
26
21
  */
27
- _writePageVisitFrags(pageVisitFrags: any, pvInfo: any): Promise<void>;
22
+ _writePageVisitFrags(pageVisitFrags: PageVisitFrag[], pvInfo: PageVisitInfo): Promise<void>;
28
23
  /**
29
24
  * Read the stored page visit from storage, create a complete page visit object
30
25
  * and then post that to Metroplex
31
26
  */
32
- _getPostData(): Promise<{
33
- pvi: any;
34
- pvp: never[];
35
- pvvf: never[];
36
- } | null>;
27
+ _getPostData(): Promise<CompletePageVisit>;
37
28
  /**
38
29
  * Creates and tries to resolve a promise that posts the previous page visit
39
30
  * to Metroplex from storage
@@ -45,5 +36,5 @@ export default class StoredPageVisit {
45
36
  */
46
37
  _updateStorageFlushed(): void;
47
38
  /** Returns a promise that resolves to post the page visit in storage to Metroplex */
48
- _getPostPageVisitPromise(): Promise<any>;
39
+ _getPostPageVisitPromise(): Promise<void>;
49
40
  }
@@ -141,6 +141,7 @@ export declare const VIDEO_PART_COUNT_ATT_NAME: "vpnum";
141
141
  export declare const CSS_SEQ_SENT: "seq_sent";
142
142
  export declare const CSS_RECEIVED: "received";
143
143
  export declare const MAX_BEACON_PAYLOAD_SIZE: 59000;
144
+ export declare const MAX_RETRY_MSG_Q_SIZE = 500;
144
145
  export declare const MAX_METROPLEX_CONNECTION_COUNT: 100;
145
146
  export declare const NOIBU_INPUT_URLS: string[];
146
147
  export declare const METROPLEX_FRAG_ROUTE: "pv_part";
@@ -0,0 +1,18 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ /**
3
+ * Attaches corresponding listener to the passed navigation integration
4
+ */
5
+ export declare class AppNavigationMonitor extends Singleton implements Monitor {
6
+ /**
7
+ * Main method for starting the monitoring
8
+ */
9
+ monitor(): void;
10
+ /**
11
+ * handler for updating navigation breadcrumbs and notifying metro of location change
12
+ */
13
+ private static onNavigation;
14
+ /**
15
+ * Called when the event needs to be emitted
16
+ */
17
+ private static reportLocationChange;
18
+ }
@@ -0,0 +1,13 @@
1
+ export interface Monitor {
2
+ monitor(): void;
3
+ }
4
+ /**
5
+ * Singleton pattern with our flavor
6
+ */
7
+ export declare abstract class Singleton {
8
+ private static instances;
9
+ /** returns singleton instance */
10
+ static getInstance<T extends Singleton, A extends any[]>(this: new (...args: A) => T, ...args: A): T;
11
+ /** used for testing only */
12
+ protected resetInstances(): void;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ /** @module ClickMonitor */
2
+ import { Monitor, Singleton } from './BaseMonitor';
3
+ /** Monitors the clicks which we capture and later process */
4
+ export declare class ClickMonitor extends Singleton implements Monitor {
5
+ private static textCapturedWhiteListRegex;
6
+ private static htmlIDAllowListRegex;
7
+ private static originalCreateEventHandlers;
8
+ /** Starts monitoring clicks on every Press-able component */
9
+ monitor(): void;
10
+ /**
11
+ * Handles a single click event
12
+ */
13
+ private static onClickHandle;
14
+ /** Gets the textual content from an element, if any
15
+ */
16
+ private static getTextualContentFromEl;
17
+ /** Parse and trim text */
18
+ private static trimText;
19
+ /**
20
+ * Recursively parses element's inner content and masks blocked css classes
21
+ */
22
+ private static parseInnerContent;
23
+ /**
24
+ * Gets selectors to prevent those elements from being recorded
25
+ */
26
+ private static getBlockedElements;
27
+ /**
28
+ * normalize value and append to the resulting text if not empty
29
+ */
30
+ private static parseAndAppendText;
31
+ }
@@ -0,0 +1,63 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ type WrappedFunction<T extends Function = Function> = T & Partial<{
3
+ __noibu__: boolean;
4
+ __noibu_wrapped__: T;
5
+ }>;
6
+ /**
7
+ * wraps a provided function into a function that try and catches
8
+ * the original function, doing so allows us to catch errors
9
+ * functionToWrap: function to be wrapped
10
+ * @param {} functionToWrap
11
+ */
12
+ export declare function wrap(functionToWrap: WrappedFunction): Function;
13
+ /**
14
+ * Monitors the errors happening on the window
15
+ */
16
+ export declare class ErrorMonitor extends Singleton implements Monitor {
17
+ /** base method */
18
+ monitor(): void;
19
+ /** proxy error utils */
20
+ private static configureErrorUtilsHandler;
21
+ /**
22
+ * Handles a single error event
23
+ */
24
+ private static onErrorHandler;
25
+ /** proxy hermes engine */
26
+ private static configureHermesHooks;
27
+ /**
28
+ * handler for promise rejection failures
29
+ */
30
+ private static onPromiseRejectionHandler;
31
+ /**
32
+ * wraps and replaces the addEventListener property
33
+ * of event targets to try and catch errors
34
+ * eventTargetString: event target name
35
+ */
36
+ private static configureEventListeners;
37
+ /** iterates arguments to try to extract errors from them
38
+ */
39
+ private static processErrorLogArguments;
40
+ /**
41
+ * Constructs error objects based on console args.
42
+ * Relies on isStackTrace() to determine if arg is a stack trace, otherwise the arg must be a message.
43
+ *
44
+ * If there are multiple stack traces or the number of error messages is not equal to one,
45
+ * it maps the stack traces to objects with their respective first lines as messages.
46
+ * Otherwise, if there is exactly one stack trace and one error message,
47
+ * it constructs an array with a single object containing the first stack trace and the first error message.
48
+ * @param {Array<string>} args
49
+ */
50
+ private static constructErrors;
51
+ /**
52
+ * returns boolean that indicates wether we should
53
+ * ignore the next error event caught by the error event
54
+ * listener.
55
+ */
56
+ private static shouldIgnoreError;
57
+ /**
58
+ * transform a log into an error since React hides component errors
59
+ * https://reactjs.org/docs/error-boundaries.html
60
+ */
61
+ private static processErrorLog;
62
+ }
63
+ export {};
@@ -1,8 +1,10 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
1
2
  /**
2
3
  * KeyboardInputMonitor is a listener class that attaches a
3
4
  * keyboard input listener of the document object.
4
5
  */
5
- export class KeyboardInputMonitor {
6
+ export declare class KeyboardInputMonitor extends Singleton implements Monitor {
7
+ private static originalRender;
6
8
  /**
7
9
  * Begins the monitoring process
8
10
  * we currently only monitor two input locations: textarea and input
@@ -10,8 +12,9 @@ export class KeyboardInputMonitor {
10
12
  monitor(): void;
11
13
  /**
12
14
  * Validates an event
13
- * @param uiViewClassName
14
- * @param props
15
15
  */
16
- _handle(uiViewClassName: any, props: any): void;
16
+ static handle(uiViewClassName: string, props: {
17
+ placeholder?: string;
18
+ testID?: string;
19
+ }): void;
17
20
  }
@@ -1,17 +1,14 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ type Event = any;
1
3
  /** Monitors the page events which we capture and later process */
2
- export class PageMonitor {
3
- /**
4
- * gets the singleton instance
5
- * @returns {PageMonitor}
6
- */
7
- static getInstance(): PageMonitor;
4
+ export declare class PageMonitor extends Singleton implements Monitor {
8
5
  /** Starts monitoring page events on the document */
9
6
  monitor(): void;
10
7
  /**
11
8
  * Handles a single page event
12
- * @param {} event
9
+ * todo: don't think these events exist in RN world
13
10
  */
14
- _onPageEventHandle(event: any): void;
11
+ _onPageEventHandle(event: Event): void;
15
12
  /** Returns document state */
16
13
  getDocumentState(): "hidden" | "active" | "passive";
17
14
  /**
@@ -20,3 +17,4 @@ export class PageMonitor {
20
17
  */
21
18
  getSizeInBytes(obj: any): number;
22
19
  }
20
+ export {};
@@ -0,0 +1,94 @@
1
+ /** @module RequestMonitor */
2
+ import 'react-native/Libraries/Network/fetch';
3
+ import { Monitor, Singleton } from './BaseMonitor';
4
+ /**
5
+ * Monitors all requests
6
+ */
7
+ export default class RequestMonitor extends Singleton implements Monitor {
8
+ /** main method */
9
+ monitor(): void;
10
+ /**
11
+ * Gets a response text Promise out of Response & headers. Returns reason if bundler decides to drop text.
12
+ * Due to async nature of text() and async function sent to Promise.all,
13
+ * our code race competes with client's code consuming the response.
14
+ * So at this point engine somehow gets access to the original ReadableStream and marks it as locked,
15
+ * thus client code may throw an error.
16
+ */
17
+ private static consumeResponseAndGetBodyText;
18
+ /**
19
+ * Generates new PVEventHTTP
20
+ */
21
+ private static getPvEventHttp;
22
+ /**
23
+ * Gets headers from request or request options. Handles different scenarios where simple conversion is not possible
24
+ */
25
+ private static getRequestHeaders;
26
+ /**
27
+ * Gets response headers.
28
+ * It is always a Headers object.
29
+ */
30
+ private static getResponseHeaders;
31
+ /**
32
+ * Gets request body from body strings or Request options
33
+ */
34
+ private static getRequestBody;
35
+ /**
36
+ * Returns the parameters to pass the PageVisitEventHTTP constructor. Specific to the fetch wrapper.
37
+ */
38
+ private static getHttpDataFromFetch;
39
+ /** Clones Response / Request or returns original object if cloning is not possible */
40
+ private static cloneResponse;
41
+ /**
42
+ * Handles fetch response safely. Reports PageVisitEventHTTP and error to Pagevisit if needed.
43
+ */
44
+ private static safeHandleFetchResponse;
45
+ /**
46
+ * Safe function to get method and url from fetch args
47
+ */
48
+ private static getMethodUrlFromFetchArgs;
49
+ /**
50
+ * Setting up the wrapper around fetch functions to try and
51
+ * catch http errors
52
+ */
53
+ private static setupGlobalFetchWrapper;
54
+ /**
55
+ * Does a check if data collection is enabled and combines it into HttpDataBundle
56
+ */
57
+ private static getHttpDataFromXhr;
58
+ /**
59
+ * on loadend we catch the event and
60
+ * make sure it was correct
61
+ */
62
+ private static loadendHandler;
63
+ /**
64
+ * Handles fetch failure
65
+ */
66
+ private static handleFetchFailure;
67
+ /** gets method from xhr */
68
+ private static getMethodFromXHR;
69
+ /**
70
+ * Wraps the send prototype of the xmlhttp object
71
+ * We set nbuWrapper to the handler function so if this returns an error
72
+ * the trace message will start with nbuWrapper which would allow us to
73
+ * detect that this is a wrapped function and not a NoibuJS error
74
+ */
75
+ private static wrapXMLHTTPSend;
76
+ /**
77
+ * Wraps the open prototype of the xmlhttp object
78
+ * We set nbuWrapper to the handler function so if this returns an error
79
+ * the trace message will start with nbuWrapper which would allow us to
80
+ * detect that this is a wrapped function and not a NoibuJS error
81
+ */
82
+ private static wrapXMLHTTPOpen;
83
+ /**
84
+ * Replaces the native XMLHTTPRequest.setHeader() function. We use this to build an array of
85
+ * request headers as these are not stored by the XMLHTTPRequest object.
86
+ * @param {object} proto window.XMLHTTPRequest's prototype
87
+ */
88
+ private static wrapXMLHTTPSetRequestHeader;
89
+ /**
90
+ * Setting up the wrapper around send functions to try and
91
+ * catch http errors
92
+ */
93
+ private static setupGlobalXMLHttpWrapper;
94
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Try detecting GraphQL errors from http response
3
+ */
4
+ export default class GqlErrorValidator {
5
+ /**
6
+ * Retrieves GQL error object based on fetch request/response
7
+ */
8
+ static fromFetch(url: string, options: RequestInit | undefined, request: Request | undefined, response: Response): Promise<unknown[]>;
9
+ /**
10
+ * Retrieves GQL error object based on XHR object
11
+ */
12
+ static fromXhr(url: string, xhr: unknown): Promise<unknown[]>;
13
+ /**
14
+ * Try safely parse a string and return null if fails
15
+ */
16
+ static _parseJsonSafely(content: string): any;
17
+ /**
18
+ * Try to get content type for fetch arguments
19
+ */
20
+ static _getContentTypeFromFetchArguments(options?: RequestInit, request?: Request): string;
21
+ /**
22
+ * Checks if request is aborted
23
+ * If it has been aborted we are not able to consume the response
24
+ */
25
+ static _isRequestAborted(options?: RequestInit, request?: RequestInit): boolean;
26
+ /**
27
+ * Determines if request should be processed
28
+ */
29
+ static _shouldHandleRequest(url: string, contentType?: string | null): boolean;
30
+ /**
31
+ * Sanitizes payload object
32
+ */
33
+ static _validate(data: unknown, validationIssues: string[]): unknown[];
34
+ /**
35
+ * Sanitizes message object
36
+ */
37
+ static _validateMessage(error: object): void;
38
+ /**
39
+ * Sanitizes extensions object
40
+ * @param {any} error
41
+ */
42
+ static _validateExtensions(error: any): void;
43
+ /**
44
+ * Sanitizes locations object
45
+ */
46
+ static _validateLocations(error: object, validationIssues: string[]): void;
47
+ /**
48
+ * Sanitizes path object
49
+ */
50
+ static _validatePath(error: object, validationIssues: string[]): void;
51
+ /**
52
+ * Posts error
53
+ */
54
+ static _postError(message: unknown): void;
55
+ /**
56
+ * Posts issue found during object sanitization
57
+ */
58
+ static _postValidationIssues(validationIssues: string[]): void;
59
+ }