noibu-react-native 0.2.7 → 0.2.9

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/android/build.gradle +1 -1
  2. package/dist/api/ClientConfig.d.ts +99 -0
  3. package/dist/api/ClientConfig.js +24 -23
  4. package/dist/api/ClientConfig.test.d.ts +1 -0
  5. package/dist/api/HelpCode.d.ts +16 -0
  6. package/dist/api/HelpCode.js +2 -2
  7. package/dist/api/InputManager.d.ts +39 -0
  8. package/dist/api/InputManager.js +1 -3
  9. package/dist/api/MetroplexSocket.d.ts +132 -0
  10. package/dist/api/MetroplexSocket.js +4 -8
  11. package/dist/api/MetroplexSocket.test.d.ts +1 -0
  12. package/dist/api/StoredMetrics.d.ts +63 -0
  13. package/dist/api/StoredPageVisit.d.ts +43 -0
  14. package/dist/api/StoredPageVisit.js +4 -6
  15. package/dist/const_matchers.d.ts +1 -0
  16. package/dist/constants.d.ts +48 -0
  17. package/dist/constants.js +3 -10
  18. package/dist/entry/index.d.ts +13 -0
  19. package/dist/entry/init.d.ts +8 -0
  20. package/dist/entry/init.js +4 -4
  21. package/dist/monitors/AppNavigationMonitor.d.ts +10 -0
  22. package/dist/monitors/AppNavigationMonitor.js +2 -4
  23. package/dist/monitors/AppNavigationMonitor.test.d.ts +1 -0
  24. package/dist/monitors/BaseMonitor.d.ts +13 -0
  25. package/dist/monitors/BaseMonitor.test.d.ts +1 -0
  26. package/dist/monitors/ClickMonitor.d.ts +28 -0
  27. package/dist/monitors/ClickMonitor.js +1 -3
  28. package/dist/monitors/ClickMonitor.test.d.ts +1 -0
  29. package/dist/monitors/ErrorMonitor.d.ts +39 -0
  30. package/dist/monitors/ErrorMonitor.js +1 -2
  31. package/dist/monitors/KeyboardInputMonitor.d.ts +18 -0
  32. package/dist/monitors/KeyboardInputMonitor.js +1 -3
  33. package/dist/monitors/PageMonitor.d.ts +20 -0
  34. package/dist/monitors/PageMonitor.js +1 -2
  35. package/dist/monitors/RequestMonitor.d.ts +74 -0
  36. package/dist/monitors/RequestMonitor.js +8 -10
  37. package/dist/monitors/http-tools/GqlErrorValidator.d.ts +35 -0
  38. package/dist/monitors/http-tools/GqlErrorValidator.js +4 -3
  39. package/dist/monitors/http-tools/HTTPDataBundler.d.ts +106 -0
  40. package/dist/monitors/http-tools/HTTPDataBundler.js +6 -5
  41. package/dist/monitors/integrations/ReactNativeNavigationIntegration.d.ts +17 -0
  42. package/dist/pageVisit/EventDebouncer.d.ts +23 -0
  43. package/dist/pageVisit/HttpEventManager.d.ts +14 -0
  44. package/dist/pageVisit/HttpEventManager.js +1 -3
  45. package/dist/pageVisit/PageVisitManager.d.ts +31 -0
  46. package/dist/pageVisit/PageVisitManager.js +1 -2
  47. package/dist/pageVisit/pageVisitEventError.d.ts +12 -0
  48. package/dist/pageVisit/pageVisitEventError.js +2 -6
  49. package/dist/react/ErrorBoundary.d.ts +67 -0
  50. package/dist/sessionRecorder/SessionRecorder.d.ts +50 -0
  51. package/dist/sessionRecorder/SessionRecorder.js +7 -8
  52. package/dist/sessionRecorder/nativeSessionRecorderSubscription.d.ts +77 -0
  53. package/dist/sessionRecorder/types.d.ts +91 -0
  54. package/dist/storage/RNStorageProvider.d.ts +19 -0
  55. package/dist/storage/Storage.d.ts +29 -0
  56. package/dist/storage/StorageProvider.d.ts +23 -0
  57. package/dist/types/NavigationIntegration.d.ts +6 -0
  58. package/dist/utils/date.d.ts +7 -0
  59. package/dist/utils/date.js +2 -2
  60. package/dist/utils/eventlistener.d.ts +8 -0
  61. package/dist/utils/eventlistener.js +2 -3
  62. package/dist/utils/function.d.ts +72 -0
  63. package/dist/utils/log.d.ts +4 -0
  64. package/dist/utils/log.js +1 -3
  65. package/dist/utils/object.d.ts +46 -0
  66. package/dist/utils/performance.d.ts +6 -0
  67. package/dist/utils/piiRedactor.d.ts +11 -0
  68. package/dist/utils/polyfills.d.ts +4 -0
  69. package/dist/utils/stacktrace-parser.d.ts +8 -0
  70. package/dist/utils/stacktrace-parser.test.d.ts +1 -0
  71. package/package.json +4 -2
@@ -0,0 +1,48 @@
1
+ /** @module Constants */
2
+ export declare const CURRENT_NOIBUJS_VERSION = 2;
3
+ export declare const MAX_STRING_LENGTH = 1024;
4
+ export declare const MAX_TIME_FOR_UNSENT_DATA_MILLIS = 500;
5
+ export declare const PII_EMAIL_PATTERN: RegExp;
6
+ export declare const PII_REDACTION_REPLACEMENT_STRING = "******";
7
+ export declare const SEVERITY: {
8
+ error: string;
9
+ warn: string;
10
+ info: string;
11
+ debug: string;
12
+ };
13
+ export declare const MAX_METROPLEX_SOCKET_INNACTIVE_TIME: number;
14
+ export declare const MAX_BEACON_PAYLOAD_SIZE = 59000;
15
+ export declare const CONTENT_TYPE = "content-type";
16
+ /**
17
+ * Gets the script id from the cookie object, returns default if cannot be found
18
+ */
19
+ export declare function GET_SCRIPT_ID(): string;
20
+ /**
21
+ * Gets the max metro recon number
22
+ */
23
+ export declare function GET_MAX_METROPLEX_RECONNECTION_NUMBER(): number;
24
+ /**
25
+ * Returns the amount of time in milliseconds to delay a new connection by
26
+ * if we have exceeded the max consecutive connection count
27
+ */
28
+ export declare function GET_METROPLEX_CONSECUTIVE_CONNECTION_DELAY(): number;
29
+ /**
30
+ * gets the base url for metroplex's websocket connection
31
+ */
32
+ export declare function GET_METROPLEX_BASE_SOCKET_URL(): string;
33
+ /**
34
+ * gets the base url for metroplex's HTTP requests
35
+ */
36
+ export declare function GET_METROPLEX_BASE_HTTP_URL(): string;
37
+ /**
38
+ * Returns the URL that accepts http post requests
39
+ */
40
+ export declare function GET_METROPLEX_POST_URL(): string;
41
+ /**
42
+ * Returns the URL for posting metrics data to Metroplex
43
+ */
44
+ export declare function GET_METROPLEX_METRICS_URL(): string;
45
+ /**
46
+ * gets the current env
47
+ */
48
+ export declare function GET_DEVICE_ENV(): string;
package/dist/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- import { MetroplexRoute } from './node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
1
+ import { MetroplexRoute } from 'noibu-metroplex-ts-bindings';
2
2
 
3
3
  /** @module Constants */
4
4
  // current collect version to be sent to front end services
@@ -11,13 +11,6 @@ const MAX_STRING_LENGTH = 1024;
11
11
  const MAX_TIME_FOR_UNSENT_DATA_MILLIS = 500;
12
12
  const PII_EMAIL_PATTERN = /\b[a-z0-9!#$%&'*+/=?^_‘{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_‘{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\b/g;
13
13
  const PII_REDACTION_REPLACEMENT_STRING = '******';
14
- // severity levels for the collect error log
15
- const SEVERITY = {
16
- error: 'error',
17
- warn: 'warn',
18
- info: 'info',
19
- debug: 'debug',
20
- };
21
14
  // maximum seconds that we can spend without sending anything
22
15
  // to our backend. This needs to be less than Silverbolt's session innactivity
23
16
  // time so that PVs don't become part of a separate web session.
@@ -31,7 +24,7 @@ const CONTENT_TYPE = 'content-type';
31
24
  * Gets the script id from the cookie object, returns default if cannot be found
32
25
  */
33
26
  function GET_SCRIPT_ID() {
34
- return "1.0.104-rn-sdk-0.2.7" ;
27
+ return "1.0.104-rn-sdk-0.2.9" ;
35
28
  }
36
29
  /**
37
30
  * Gets the max metro recon number
@@ -82,4 +75,4 @@ function GET_DEVICE_ENV() {
82
75
  return "react-native-expo" ;
83
76
  }
84
77
 
85
- export { CONTENT_TYPE, CURRENT_NOIBUJS_VERSION, GET_DEVICE_ENV, 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, MAX_BEACON_PAYLOAD_SIZE, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, MAX_STRING_LENGTH, MAX_TIME_FOR_UNSENT_DATA_MILLIS, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING, SEVERITY };
78
+ export { CONTENT_TYPE, CURRENT_NOIBUJS_VERSION, GET_DEVICE_ENV, 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, MAX_BEACON_PAYLOAD_SIZE, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, MAX_STRING_LENGTH, MAX_TIME_FOR_UNSENT_DATA_MILLIS, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING };
@@ -0,0 +1,13 @@
1
+ import 'react-native-url-polyfill/auto';
2
+ import 'whatwg-fetch';
3
+ import globalInit from './init';
4
+ import { ErrorBoundary as _ErrorBoundary } from '../react/ErrorBoundary';
5
+ /** @param config */
6
+ export declare const setupNoibu: typeof globalInit;
7
+ export declare const NoibuJS: {
8
+ requestHelpCode: () => Promise<string | null>;
9
+ addCustomAttribute: (name: string, value: string) => Promise<string>;
10
+ addError: (customError: unknown) => string;
11
+ addJsSdkError: (customError: unknown, errorSource: unknown) => string;
12
+ };
13
+ export declare const ErrorBoundary: typeof _ErrorBoundary;
@@ -0,0 +1,8 @@
1
+ export declare const REQUIRED_DATA_PROCESSING_URLS: string[];
2
+ /**
3
+ * isInvalidURLConfig will verify that Collect is being initializes with
4
+ * the correct env vars.
5
+ */
6
+ export declare function isInvalidURLConfig(urls: Record<(typeof REQUIRED_DATA_PROCESSING_URLS)[number], string>): boolean;
7
+ /** initilializes the script to start executing all of NJS features */
8
+ export default function globalInit(customerConfig: CustomerConfig): Promise<void>;
@@ -1,9 +1,9 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import uuid from 'react-native-uuid';
3
- import { MetroplexRoute } from '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
3
+ import { MetroplexRoute, Severity } from 'noibu-metroplex-ts-bindings';
4
4
  import { KeyboardInputMonitor } from '../monitors/KeyboardInputMonitor.js';
5
5
  import { PageMonitor } from '../monitors/PageMonitor.js';
6
- import { SEVERITY, GET_METROPLEX_BASE_SOCKET_URL, GET_METROPLEX_BASE_HTTP_URL } from '../constants.js';
6
+ import { GET_METROPLEX_BASE_SOCKET_URL, GET_METROPLEX_BASE_HTTP_URL } from '../constants.js';
7
7
  import ClientConfig from '../api/ClientConfig.js';
8
8
  import { isNoibuJSAlreadyLoaded } from '../utils/function.js';
9
9
  import { PageVisitManager } from '../pageVisit/PageVisitManager.js';
@@ -85,7 +85,7 @@ function globalInit(customerConfig) {
85
85
  pageMonitor.monitor();
86
86
  SessionRecorder.getInstance().recordUserSession();
87
87
  if (metroplexSocket.connectionPromise) {
88
- metroplexSocket.connectionPromise.catch((error) => ClientConfig.getInstance().postInternalError({ msg: `Error during metroplexSocket initial connection`, error }, false, SEVERITY.error));
88
+ metroplexSocket.connectionPromise.catch((error) => ClientConfig.getInstance().postInternalError({ msg: `Error during metroplexSocket initial connection`, error }, false, Severity.ERROR));
89
89
  }
90
90
  else {
91
91
  throw new Error('metroplex socket not ready');
@@ -93,7 +93,7 @@ function globalInit(customerConfig) {
93
93
  noibuLog('global init finished');
94
94
  }
95
95
  catch (error) {
96
- ClientConfig.getInstance().postInternalError({ msg: `Error during globalInit`, error }, true, SEVERITY.error);
96
+ ClientConfig.getInstance().postInternalError({ msg: `Error during globalInit`, error }, true, Severity.ERROR);
97
97
  noibuLog('exiting');
98
98
  }
99
99
  });
@@ -0,0 +1,10 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ /** Attaches corresponding listener to the passed navigation integration */
3
+ export declare class AppNavigationMonitor extends Singleton implements Monitor {
4
+ /** Main method for starting the monitoring */
5
+ monitor(): void;
6
+ /** handler for updating navigation breadcrumbs and notifying metro of location change */
7
+ private static onNavigation;
8
+ /** Called when the event needs to be emitted */
9
+ private static reportLocationChange;
10
+ }
@@ -1,10 +1,8 @@
1
- import { SEVERITY } from '../constants.js';
2
1
  import { ReactNativeNavigationIntegration } from './integrations/ReactNativeNavigationIntegration.js';
3
2
  import ClientConfig from '../api/ClientConfig.js';
4
3
  import { EventDebouncer } from '../pageVisit/EventDebouncer.js';
5
4
  import { Singleton } from './BaseMonitor.js';
6
- import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
7
- import { EventType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/EventType.js';
5
+ import { Severity, EventType } from 'noibu-metroplex-ts-bindings';
8
6
 
9
7
  /** Attaches corresponding listener to the passed navigation integration */
10
8
  class AppNavigationMonitor extends Singleton {
@@ -22,7 +20,7 @@ class AppNavigationMonitor extends Singleton {
22
20
  ClientConfig.getInstance().postInternalError({
23
21
  msg: `Error while trying to attach to navigation events`,
24
22
  error: e,
25
- }, false, SEVERITY.error);
23
+ }, false, Severity.ERROR);
26
24
  }
27
25
  }
28
26
  /** handler for updating navigation breadcrumbs and notifying metro of location change */
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ export interface Monitor {
2
+ monitor(): void;
3
+ }
4
+ /** Singleton pattern with our flavor */
5
+ export declare abstract class Singleton {
6
+ private static instances;
7
+ /** returns singleton instance */
8
+ static getInstance<T extends Singleton, A extends any[]>(this: new (...args: A) => T, ...args: ConstructorParameters<new (...args: A) => T>): T;
9
+ /** Destructor */
10
+ protected destroy(): void;
11
+ /** used for testing only */
12
+ private static resetInstances;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
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
+ /** Starts monitoring clicks on every Press-able component */
8
+ monitor(): void;
9
+ /** Handles a single click event */
10
+ private static onClickHandle;
11
+ /** Gets the textual content from an element, if any
12
+ */
13
+ private static getTextualContentFromEl;
14
+ /** Parse and trim text */
15
+ private static trimText;
16
+ /** gets id */
17
+ private static getHid;
18
+ /** gets tag name */
19
+ private static getTagName;
20
+ /** Recursively parses element's inner content and masks blocked css classes */
21
+ private static parseInnerContent;
22
+ /** Gets selectors to prevent those elements from being recorded */
23
+ private static getBlockedElements;
24
+ /** normalize value and append to the resulting text if not empty */
25
+ private static parseAndAppendText;
26
+ /** Destructs instance */
27
+ destroy(this: Singleton): void;
28
+ }
@@ -6,9 +6,7 @@ import { maskTextInput } from '../utils/function.js';
6
6
  import ClientConfig from '../api/ClientConfig.js';
7
7
  import { Singleton } from './BaseMonitor.js';
8
8
  import { isNoibuWrapped, replace, unwrapNoibuWrapped } from '../utils/object.js';
9
- import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
10
- import { UserStepType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/UserStepType.js';
11
- import { EventType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/EventType.js';
9
+ import { UserStepType, EventType } from 'noibu-metroplex-ts-bindings';
12
10
 
13
11
  /** @module ClickMonitor */
14
12
  /**
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,39 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ /** Monitors the errors happening on the window */
3
+ export declare class ErrorMonitor extends Singleton implements Monitor {
4
+ static preventInfiniteLoopFlag: boolean;
5
+ /** base method */
6
+ monitor(): void;
7
+ /** proxy error utils */
8
+ private static configureErrorUtilsHandler;
9
+ /** Handles a single error event */
10
+ private static onErrorHandler;
11
+ /** proxy hermes engine */
12
+ private static configureHermesHooks;
13
+ /** handler for promise rejection failures */
14
+ private static onPromiseRejectionHandler;
15
+ /**
16
+ * wraps and replaces the addEventListener property
17
+ * of event targets to try and catch errors
18
+ * eventTargetString: event target name
19
+ */
20
+ private static configureEventListeners;
21
+ /** iterates arguments to try to extract errors from them
22
+ */
23
+ private static processErrorLogArguments;
24
+ /**
25
+ * Constructs error objects based on console args.
26
+ * Relies on isStackTrace() to determine if arg is a stack trace, otherwise the arg must be a message.
27
+ *
28
+ * If there are multiple stack traces or the number of error messages is not equal to one,
29
+ * it maps the stack traces to objects with their respective first lines as messages.
30
+ * Otherwise, if there is exactly one stack trace and one error message,
31
+ * it constructs an array with a single object containing the first stack trace and the first error message.
32
+ */
33
+ private static constructErrors;
34
+ /**
35
+ * transform a log into an error since React hides component errors
36
+ * https://reactjs.org/docs/error-boundaries.html
37
+ */
38
+ private static processErrorLog;
39
+ }
@@ -2,9 +2,8 @@ import { asString, isStackTrace } from '../utils/function.js';
2
2
  import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError.js';
3
3
  import { replace } from '../utils/object.js';
4
4
  import { Singleton } from './BaseMonitor.js';
5
- import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
5
+ import { PageVisitErrorSource } from 'noibu-metroplex-ts-bindings';
6
6
  import ClientConfig from '../api/ClientConfig.js';
7
- import { PageVisitErrorSource } from '../node_modules/@noibu/metroplex-ts-bindings/dist/PageVisitErrorSource.js';
8
7
 
9
8
  /* eslint-disable @typescript-eslint/ban-types,prefer-arrow-callback */
10
9
  /** @module ErrorMonitor */
@@ -0,0 +1,18 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ /**
3
+ * KeyboardInputMonitor is a listener class that attaches a
4
+ * keyboard input listener of the document object.
5
+ */
6
+ export declare class KeyboardInputMonitor extends Singleton implements Monitor {
7
+ private static originalRender;
8
+ /**
9
+ * Begins the monitoring process
10
+ * we currently only monitor two input locations: textarea and input
11
+ */
12
+ monitor(): void;
13
+ /** Validates an event */
14
+ static handle(uiViewClassName: string, props: {
15
+ placeholder?: string;
16
+ testID?: string;
17
+ }): void;
18
+ }
@@ -1,9 +1,7 @@
1
1
  import { EventDebouncer } from '../pageVisit/EventDebouncer.js';
2
2
  import { TextInput } from 'react-native';
3
3
  import { Singleton } from './BaseMonitor.js';
4
- import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
5
- import { EventType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/EventType.js';
6
- import { UserStepType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/UserStepType.js';
4
+ import { EventType, UserStepType } from 'noibu-metroplex-ts-bindings';
7
5
 
8
6
  /** @module KeyboardInputMonitor */
9
7
  /**
@@ -0,0 +1,20 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ type Event = any;
3
+ /** Monitors the page events which we capture and later process */
4
+ export declare class PageMonitor extends Singleton implements Monitor {
5
+ /** Starts monitoring page events on the document */
6
+ monitor(): void;
7
+ /**
8
+ * Handles a single page event
9
+ * todo: don't think these events exist in RN world
10
+ */
11
+ _onPageEventHandle(event: Event): void;
12
+ /** Returns document state */
13
+ getDocumentState(): "passive" | "hidden" | "active";
14
+ /**
15
+ * Returns object size in bytes
16
+ * @param {} obj
17
+ */
18
+ getSizeInBytes(obj: any): number;
19
+ }
20
+ export {};
@@ -1,8 +1,7 @@
1
1
  import { addSafeEventListener } from '../utils/eventlistener.js';
2
2
  import { EventDebouncer } from '../pageVisit/EventDebouncer.js';
3
3
  import { Singleton } from './BaseMonitor.js';
4
- import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
5
- import { EventType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/EventType.js';
4
+ import { EventType } from 'noibu-metroplex-ts-bindings';
6
5
 
7
6
  /** @module PageMonitor */
8
7
  const PAGE_EVENTS_DOCUMENT = ['visibilitychange', 'resume', 'freeze', 'readystatechange', 'cut', 'copy', 'paste'];
@@ -0,0 +1,74 @@
1
+ import { Monitor, Singleton } from './BaseMonitor';
2
+ /** Monitors all requests */
3
+ export default class RequestMonitor extends Singleton implements Monitor {
4
+ /** main method */
5
+ monitor(): void;
6
+ /**
7
+ * Gets a response text Promise out of Response & headers. Returns reason if bundler decides to drop text.
8
+ * Due to async nature of text() and async function sent to Promise.all,
9
+ * our code race competes with client's code consuming the response.
10
+ * So at this point engine somehow gets access to the original ReadableStream and marks it as locked,
11
+ * thus client code may throw an error.
12
+ */
13
+ private static consumeResponseAndGetBodyText;
14
+ /** Generates new PVEventHTTP */
15
+ private static getPvEventHttp;
16
+ /** Gets headers from request or request options. Handles different scenarios where simple conversion is not possible */
17
+ private static getRequestHeaders;
18
+ /**
19
+ * Gets response headers.
20
+ * It is always a Headers object.
21
+ */
22
+ private static getResponseHeaders;
23
+ /** Gets request body from body strings or Request options */
24
+ private static getRequestBody;
25
+ /** Returns the parameters to pass the HttpEventManager constructor. Specific to the fetch wrapper. */
26
+ private static getHttpDataFromFetch;
27
+ /** Clones Response / Request or returns original object if cloning is not possible */
28
+ private static cloneResponse;
29
+ /** Handles fetch response safely. Reports HttpEventManager and error to Pagevisit if needed. */
30
+ private static safeHandleFetchResponse;
31
+ /** Safe function to get method and url from fetch args */
32
+ private static getMethodUrlFromFetchArgs;
33
+ /**
34
+ * Setting up the wrapper around fetch functions to try and
35
+ * catch http errors
36
+ */
37
+ private static setupGlobalFetchWrapper;
38
+ /** Does a check if data collection is enabled and combines it into HttpDataBundle */
39
+ private static getHttpDataFromXhr;
40
+ /**
41
+ * on loadend we catch the event and
42
+ * make sure it was correct
43
+ */
44
+ private static loadendHandler;
45
+ /** Handles fetch failure */
46
+ private static handleFetchFailure;
47
+ /** gets method from xhr */
48
+ private static getMethodFromXHR;
49
+ /**
50
+ * Wraps the send prototype of the xmlhttp object
51
+ * We set nbuWrapper to the handler function so if this returns an error
52
+ * the trace message will start with nbuWrapper which would allow us to
53
+ * detect that this is a wrapped function and not a NoibuJS error
54
+ */
55
+ private static wrapXMLHTTPSend;
56
+ /**
57
+ * Wraps the open prototype of the xmlhttp object
58
+ * We set nbuWrapper to the handler function so if this returns an error
59
+ * the trace message will start with nbuWrapper which would allow us to
60
+ * detect that this is a wrapped function and not a NoibuJS error
61
+ */
62
+ private static wrapXMLHTTPOpen;
63
+ /**
64
+ * Replaces the native XMLHTTPRequest.setHeader() function. We use this to build an array of
65
+ * request headers as these are not stored by the XMLHTTPRequest object.
66
+ * @param {object} proto window.XMLHTTPRequest's prototype
67
+ */
68
+ private static wrapXMLHTTPSetRequestHeader;
69
+ /**
70
+ * Setting up the wrapper around send functions to try and
71
+ * catch http errors
72
+ */
73
+ private static setupGlobalXMLHttpWrapper;
74
+ }
@@ -2,7 +2,6 @@ import { __awaiter } from 'tslib';
2
2
  import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError.js';
3
3
  import { isHttpCodeFailure, saveHTTPEvent } from '../pageVisit/HttpEventManager.js';
4
4
  import { safeEntries, propWriteableOrMadeWriteable, replace } from '../utils/object.js';
5
- import { SEVERITY } from '../constants.js';
6
5
  import ClientConfig from '../api/ClientConfig.js';
7
6
  import { noibuLog } from '../utils/log.js';
8
7
  import { tryGetStackTrace, safeTrim } from '../utils/function.js';
@@ -11,8 +10,7 @@ import { addSafeEventListener } from '../utils/eventlistener.js';
11
10
  import { HTTPDataBundler } from './http-tools/HTTPDataBundler.js';
12
11
  import GqlErrorValidator from './http-tools/GqlErrorValidator.js';
13
12
  import { Singleton } from './BaseMonitor.js';
14
- import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
15
- import { PageVisitErrorSource } from '../node_modules/@noibu/metroplex-ts-bindings/dist/PageVisitErrorSource.js';
13
+ import { Severity, PageVisitErrorSource } from 'noibu-metroplex-ts-bindings';
16
14
 
17
15
  /** request monitor */
18
16
  const BODY_USED_ERROR = 'Response data unavailable due to an improperly wrapped fetch call';
@@ -104,7 +102,7 @@ class RequestMonitor extends Singleton {
104
102
  if (!ogResponse) {
105
103
  // no idea how, but this happens sometimes, esp if other libs override fetch
106
104
  // logging to track the issue if it becomes widespread
107
- return ClientConfig.getInstance().postInternalError({ msg: 'No response object in fetch callback', url, method, options, request }, false, SEVERITY.error);
105
+ return ClientConfig.getInstance().postInternalError({ msg: 'No response object in fetch callback', url, method, options, request }, false, Severity.ERROR);
108
106
  }
109
107
  const clonedResponse = RequestMonitor.cloneResponse(ogResponse); // have to do it as early as possible
110
108
  const graphqlResponse = RequestMonitor.cloneResponse(clonedResponse); // and two times more for each consumption
@@ -139,7 +137,7 @@ class RequestMonitor extends Singleton {
139
137
  return;
140
138
  }
141
139
  const stack = tryGetStackTrace(e);
142
- ClientConfig.getInstance().postInternalError({ msg: `Error in custom fetch() callback`, error: e, stack }, false, SEVERITY.error);
140
+ ClientConfig.getInstance().postInternalError({ msg: `Error in custom fetch() callback`, error: e, stack }, false, Severity.ERROR);
143
141
  }
144
142
  });
145
143
  }
@@ -161,7 +159,7 @@ class RequestMonitor extends Singleton {
161
159
  };
162
160
  }
163
161
  catch (e) {
164
- ClientConfig.getInstance().postInternalError({ msg: `Error in fetch() wrapper`, error: e }, false, SEVERITY.error);
162
+ ClientConfig.getInstance().postInternalError({ msg: `Error in fetch() wrapper`, error: e }, false, Severity.ERROR);
165
163
  }
166
164
  return defaultResource;
167
165
  }
@@ -281,7 +279,7 @@ class RequestMonitor extends Singleton {
281
279
  }
282
280
  catch (e) {
283
281
  const stack = tryGetStackTrace(e);
284
- ClientConfig.getInstance().postInternalError({ msg: `Error in XHR.send() wrapper`, error: e, stack }, false, SEVERITY.error);
282
+ ClientConfig.getInstance().postInternalError({ msg: `Error in XHR.send() wrapper`, error: e, stack }, false, Severity.ERROR);
285
283
  }
286
284
  return originalFunction.call(this, payload);
287
285
  };
@@ -306,7 +304,7 @@ class RequestMonitor extends Singleton {
306
304
  this.noibuHttpUrl = url;
307
305
  }
308
306
  catch (error) {
309
- ClientConfig.getInstance().postInternalError({ msg: `Unable to set custom properties on XHR object`, error }, false, SEVERITY.warn);
307
+ ClientConfig.getInstance().postInternalError({ msg: `Unable to set custom properties on XHR object`, error }, false, Severity.WARN);
310
308
  }
311
309
  if (shouldHandleLoadend) {
312
310
  const startTime = Date.now();
@@ -315,7 +313,7 @@ class RequestMonitor extends Singleton {
315
313
  }
316
314
  catch (e) {
317
315
  const stack = tryGetStackTrace(e);
318
- ClientConfig.getInstance().postInternalError({ msg: `Error in XHR.open() wrapper`, error: e, stack }, false, SEVERITY.error);
316
+ ClientConfig.getInstance().postInternalError({ msg: `Error in XHR.open() wrapper`, error: e, stack }, false, Severity.ERROR);
319
317
  }
320
318
  return originalFunction.call(this, method, url, async, user, password);
321
319
  };
@@ -342,7 +340,7 @@ class RequestMonitor extends Singleton {
342
340
  }
343
341
  }
344
342
  catch (error) {
345
- ClientConfig.getInstance().postInternalError({ msg: `Error in XHR.setRequestHeader() wrapper`, error }, false, SEVERITY.error);
343
+ ClientConfig.getInstance().postInternalError({ msg: `Error in XHR.setRequestHeader() wrapper`, error }, false, Severity.ERROR);
346
344
  }
347
345
  return originalFunction.call(this, header, value);
348
346
  };
@@ -0,0 +1,35 @@
1
+ import { GQLError } from 'noibu-metroplex-ts-bindings';
2
+ /** Try detecting GraphQL errors from http response */
3
+ export default class GqlErrorValidator {
4
+ /** Retrieves GQL error object based on fetch request/response */
5
+ static fromFetch(url: string, options: RequestInit | undefined, request: Request | undefined, response: Response): Promise<GQLError[] | null>;
6
+ /** Retrieves GQL error object based on XHR object */
7
+ static fromXhr(url: string, xhr: unknown): Promise<GQLError[] | null>;
8
+ /** Try safely parse a string and return null if fails */
9
+ static _parseJsonSafely(content: string): any;
10
+ /** Try to get content type for fetch arguments */
11
+ static _getContentTypeFromFetchArguments(options?: RequestInit, request?: Request): string | null;
12
+ /**
13
+ * Checks if request is aborted
14
+ * If it has been aborted we are not able to consume the response
15
+ */
16
+ static _isRequestAborted(options?: RequestInit, request?: RequestInit): boolean | null | undefined;
17
+ /** Determines if request should be processed */
18
+ static _shouldHandleRequest(url: string, contentType?: string | null): boolean;
19
+ /** Sanitizes payload object */
20
+ static _validate(data: unknown, validationIssues: string[]): GQLError[] | null;
21
+ /** Sanitizes message object */
22
+ static _validateMessage(error: GQLError): void;
23
+ /**
24
+ * Sanitizes extensions object
25
+ */
26
+ static _validateExtensions(error: GQLError): void;
27
+ /** Sanitizes locations object */
28
+ static _validateLocations(error: GQLError, validationIssues: string[]): void;
29
+ /** Sanitizes path object */
30
+ static _validatePath(error: object, validationIssues: string[]): void;
31
+ /** Posts error */
32
+ static _postError(message: unknown): void;
33
+ /** Posts issue found during object sanitization */
34
+ static _postValidationIssues(validationIssues: string[]): void;
35
+ }
@@ -1,7 +1,8 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import { isInstanceOf, getMaxSubstringAllowed } from '../../utils/function.js';
3
- import { CONTENT_TYPE, SEVERITY } from '../../constants.js';
3
+ import { CONTENT_TYPE } from '../../constants.js';
4
4
  import ClientConfig from '../../api/ClientConfig.js';
5
+ import { Severity } from 'noibu-metroplex-ts-bindings';
5
6
 
6
7
  const GQL_EXTENSIONS_ATT_NAME = 'extensions';
7
8
  const GQL_LOCATIONS_ATT_NAME = 'locations';
@@ -217,12 +218,12 @@ class GqlErrorValidator {
217
218
  }
218
219
  /** Posts error */
219
220
  static _postError(message) {
220
- ClientConfig.getInstance().postInternalError({ msg: `GQL parse error: ${message}` }, false, SEVERITY.error);
221
+ ClientConfig.getInstance().postInternalError({ msg: `GQL parse error: ${message}` }, false, Severity.ERROR);
221
222
  }
222
223
  /** Posts issue found during object sanitization */
223
224
  static _postValidationIssues(validationIssues) {
224
225
  const message = validationIssues.join(',');
225
- ClientConfig.getInstance().postInternalError({ msg: `GQL error validation warning: ${message}` }, false, SEVERITY.error);
226
+ ClientConfig.getInstance().postInternalError({ msg: `GQL error validation warning: ${message}` }, false, Severity.ERROR);
226
227
  }
227
228
  }
228
229