From e858cf9b10244319e45e61390bb541bba7187440 Mon Sep 17 00:00:00 2001 From: Quinn Hanam Date: Wed, 28 Sep 2022 08:36:01 -0700 Subject: [PATCH] chore: Enable typescript strict mode (#237) --- .eslintrc.js | 2 + package-lock.json | 123 ++++++++++++-------- src/CommandQueue.ts | 22 +++- src/dispatch/Authentication.ts | 10 +- src/dispatch/CognitoIdentityClient.ts | 6 +- src/dispatch/Dispatch.ts | 10 +- src/dispatch/EnhancedAuthentication.ts | 8 +- src/dispatch/FetchHttpHandler.ts | 8 +- src/dispatch/RetryHttpHandler.ts | 2 +- src/dispatch/StsClient.ts | 2 +- src/event-cache/EventCache.ts | 2 +- src/index-browser.ts | 2 +- src/plugins/InternalPlugin.ts | 2 +- src/plugins/MonkeyPatched.ts | 27 +++-- src/plugins/event-plugins/DemoPlugin.ts | 4 +- src/plugins/event-plugins/DomEventPlugin.ts | 6 +- src/plugins/event-plugins/FetchPlugin.ts | 51 ++++---- src/plugins/event-plugins/PageViewPlugin.ts | 4 +- src/plugins/event-plugins/XhrPlugin.ts | 77 ++++++------ src/plugins/types.ts | 2 +- src/plugins/utils/http-utils.ts | 16 +-- src/sessions/PageManager.ts | 55 +++++---- src/sessions/SessionManager.ts | 10 +- src/sessions/VirtualPageLoadTimer.ts | 36 +++--- tsconfig.json | 2 +- 25 files changed, 282 insertions(+), 207 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 32bc0d97..81159257 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -100,6 +100,7 @@ module.exports = { '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-misused-new': 'error', '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-parameter-properties': 'off', '@typescript-eslint/no-shadow': [ 'off', @@ -128,6 +129,7 @@ module.exports = { '@typescript-eslint/require-await': 'warn', '@typescript-eslint/no-unsafe-member-access': 'warn', '@typescript-eslint/no-this-alias': 'warn', + '@typescript-eslint/no-unnecessary-type-assertion': 'off', '@typescript-eslint/member-ordering': 'off', '@typescript-eslint/triple-slash-reference': [ 'error', diff --git a/package-lock.json b/package-lock.json index 1f91cdc4..83b99f8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4388,9 +4388,9 @@ } }, "node_modules/@testim/chrome-version": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.2.tgz", - "integrity": "sha512-1c4ZOETSRpI0iBfIFUqU4KqwBAB2lHUAlBjZz/YqOHqwM9dTTzjV6Km0ZkiEiSCx/tLr1BtESIKyWWMww+RUqw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz", + "integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==", "dev": true, "optional": true, "peer": true @@ -5736,14 +5736,15 @@ } }, "node_modules/axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "dev": true, "optional": true, "peer": true, "dependencies": { - "follow-redirects": "^1.14.4" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "node_modules/babel-jest": { @@ -6775,19 +6776,19 @@ } }, "node_modules/chromedriver": { - "version": "101.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", - "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", + "version": "105.0.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-105.0.1.tgz", + "integrity": "sha512-QqylH9mvl4Ybq3mmHsym7jeq/LhEi2sPtD8ffd9ixiDFdPRlh2F4vzrzK+myj1MiXb0TYJK7+OCcMEmsB3Sm/Q==", "dev": true, "hasInstallScript": true, "optional": true, "peer": true, "dependencies": { - "@testim/chrome-version": "^1.1.2", - "axios": "^0.24.0", - "del": "^6.0.0", + "@testim/chrome-version": "^1.1.3", + "axios": "^0.27.2", + "del": "^6.1.1", "extract-zip": "^2.0.1", - "https-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", "proxy-from-env": "^1.1.0", "tcp-port-used": "^1.0.1" }, @@ -6799,9 +6800,9 @@ } }, "node_modules/chromedriver/node_modules/del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", "dev": true, "optional": true, "peer": true, @@ -9861,9 +9862,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", - "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true, "funding": [ { @@ -9880,6 +9881,22 @@ } } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -10590,9 +10607,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "dependencies": { "agent-base": "6", @@ -24769,9 +24786,9 @@ } }, "@testim/chrome-version": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.2.tgz", - "integrity": "sha512-1c4ZOETSRpI0iBfIFUqU4KqwBAB2lHUAlBjZz/YqOHqwM9dTTzjV6Km0ZkiEiSCx/tLr1BtESIKyWWMww+RUqw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz", + "integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==", "dev": true, "optional": true, "peer": true @@ -25845,14 +25862,15 @@ "dev": true }, "axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "dev": true, "optional": true, "peer": true, "requires": { - "follow-redirects": "^1.14.4" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "babel-jest": { @@ -26634,26 +26652,26 @@ "dev": true }, "chromedriver": { - "version": "101.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", - "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", + "version": "105.0.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-105.0.1.tgz", + "integrity": "sha512-QqylH9mvl4Ybq3mmHsym7jeq/LhEi2sPtD8ffd9ixiDFdPRlh2F4vzrzK+myj1MiXb0TYJK7+OCcMEmsB3Sm/Q==", "dev": true, "optional": true, "peer": true, "requires": { - "@testim/chrome-version": "^1.1.2", - "axios": "^0.24.0", - "del": "^6.0.0", + "@testim/chrome-version": "^1.1.3", + "axios": "^0.27.2", + "del": "^6.1.1", "extract-zip": "^2.0.1", - "https-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", "proxy-from-env": "^1.1.0", "tcp-port-used": "^1.0.1" }, "dependencies": { "del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", "dev": true, "optional": true, "peer": true, @@ -29049,11 +29067,24 @@ "dev": true }, "follow-redirects": { - "version": "1.14.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", - "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -29592,9 +29623,9 @@ } }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "requires": { "agent-base": "6", diff --git a/src/CommandQueue.ts b/src/CommandQueue.ts index 566207f0..4d42d47b 100644 --- a/src/CommandQueue.ts +++ b/src/CommandQueue.ts @@ -2,6 +2,20 @@ import { CredentialProvider, Credentials } from '@aws-sdk/types'; import { PartialConfig, Orchestration } from './orchestration/Orchestration'; import { getRemoteConfig } from './remote-config/remote-config'; +export type CommandFunction = (payload?: any) => void; + +interface CommandFunctions { + setAwsCredentials: CommandFunction; + recordPageView: CommandFunction; + recordError: CommandFunction; + registerDomEvents: CommandFunction; + dispatch: CommandFunction; + dispatchBeacon: CommandFunction; + enable: CommandFunction; + disable: CommandFunction; + allowCookies: CommandFunction; +} + /** * An AWS RUM Client command. */ @@ -32,7 +46,7 @@ export type AwsRumClientInit = { export class CommandQueue { private orchestration!: Orchestration; - private commandHandlerMap = { + private commandHandlerMap: CommandFunctions = { setAwsCredentials: ( payload: Credentials | CredentialProvider ): void => { @@ -93,7 +107,9 @@ export class CommandQueue { * Add a command to the command queue. */ public async push(command: Command) { - const commandHandler = this.commandHandlerMap[command.c]; + const commandHandler = this.commandHandlerMap[ + command.c as keyof CommandFunctions + ]; if (commandHandler) { commandHandler(command.p); } else { @@ -110,7 +126,7 @@ export class CommandQueue { ); // Overwrite the global API to use CommandQueue - window[awsRum.n] = (c: string, p: any) => { + (window as any)[awsRum.n] = (c: string, p: any) => { this.push({ c, p }); }; diff --git a/src/dispatch/Authentication.ts b/src/dispatch/Authentication.ts index 47523898..96899d46 100644 --- a/src/dispatch/Authentication.ts +++ b/src/dispatch/Authentication.ts @@ -12,7 +12,7 @@ export class Authentication { private credentials: Credentials | undefined; constructor(config: Config) { - const region: string = config.identityPoolId.split(':')[0]; + const region: string = config.identityPoolId!.split(':')[0]; this.config = config; this.stsClient = new StsClient({ fetchRequestHandler: new FetchHttpHandler(), @@ -70,7 +70,7 @@ export class Authentication { // The credentials have expired. return reject(); } - resolve(this.credentials); + resolve(this.credentials!); }); }; @@ -83,7 +83,7 @@ export class Authentication { return new Promise((resolve, reject) => { let credentials; try { - credentials = JSON.parse(localStorage.getItem(CRED_KEY)); + credentials = JSON.parse(localStorage.getItem(CRED_KEY)!); } catch (e) { // Error retrieving, decoding or parsing the cred string -- abort return reject(); @@ -113,14 +113,14 @@ export class Authentication { private AnonymousCognitoCredentialsProvider = async (): Promise => { return this.cognitoIdentityClient .getId({ - IdentityPoolId: this.config.identityPoolId + IdentityPoolId: this.config.identityPoolId as string }) .then((getIdResponse) => this.cognitoIdentityClient.getOpenIdToken(getIdResponse) ) .then((getOpenIdTokenResponse) => this.stsClient.assumeRoleWithWebIdentity({ - RoleArn: this.config.guestRoleArn, + RoleArn: this.config.guestRoleArn as string, RoleSessionName: 'cwr', WebIdentityToken: getOpenIdTokenResponse.Token }) diff --git a/src/dispatch/CognitoIdentityClient.ts b/src/dispatch/CognitoIdentityClient.ts index 628c9e7a..1471e2f6 100644 --- a/src/dispatch/CognitoIdentityClient.ts +++ b/src/dispatch/CognitoIdentityClient.ts @@ -54,7 +54,7 @@ export class CognitoIdentityClient { response.body .getReader() .read() - .then(({ value }) => + .then(({ value }: { value: number[] }) => JSON.parse(String.fromCharCode.apply(null, value)) ) ) @@ -76,7 +76,7 @@ export class CognitoIdentityClient { response.body .getReader() .read() - .then(({ value }) => + .then(({ value }: { value: number[] }) => JSON.parse(String.fromCharCode.apply(null, value)) ) ) @@ -100,7 +100,7 @@ export class CognitoIdentityClient { return response.body .getReader() .read() - .then(({ value }) => { + .then(({ value }: { value: number[] }) => { const { IdentityId, Credentials } = JSON.parse( String.fromCharCode.apply(null, value) ); diff --git a/src/dispatch/Dispatch.ts b/src/dispatch/Dispatch.ts index d877f3f5..9c35258a 100644 --- a/src/dispatch/Dispatch.ts +++ b/src/dispatch/Dispatch.ts @@ -98,7 +98,9 @@ export class Dispatch { /** * Send meta data and events to the AWS RUM data plane service via fetch. */ - public dispatchFetch = async (): Promise<{ response: HttpResponse }> => { + public dispatchFetch = async (): Promise< + { response: HttpResponse } | undefined + > => { if (this.doRequest()) { return this.rum .sendFetch(this.createRequest()) @@ -109,7 +111,9 @@ export class Dispatch { /** * Send meta data and events to the AWS RUM data plane service via beacon. */ - public dispatchBeacon = async (): Promise<{ response: HttpResponse }> => { + public dispatchBeacon = async (): Promise< + { response: HttpResponse } | undefined + > => { if (this.doRequest()) { const request: PutRumEventsRequest = this.createRequest(); return this.rum @@ -208,7 +212,7 @@ export class Dispatch { return this.enabled && this.eventCache.hasEvents(); } - private createRequest(): PutRumEventsRequest | undefined { + private createRequest(): PutRumEventsRequest { return { BatchId: v4(), AppMonitorDetails: this.eventCache.getAppMonitorDetails(), diff --git a/src/dispatch/EnhancedAuthentication.ts b/src/dispatch/EnhancedAuthentication.ts index 51a4bcee..aed41fc7 100644 --- a/src/dispatch/EnhancedAuthentication.ts +++ b/src/dispatch/EnhancedAuthentication.ts @@ -13,7 +13,7 @@ export class EnhancedAuthentication { private credentials: Credentials | undefined; constructor(config: Config) { - const region: string = config.identityPoolId.split(':')[0]; + const region: string = config.identityPoolId!.split(':')[0]; this.config = config; this.cognitoIdentityClient = new CognitoIdentityClient({ fetchRequestHandler: new FetchHttpHandler(), @@ -67,7 +67,7 @@ export class EnhancedAuthentication { // The credentials have expired. return reject(); } - resolve(this.credentials); + resolve(this.credentials!); }); }; @@ -80,7 +80,7 @@ export class EnhancedAuthentication { return new Promise((resolve, reject) => { let credentials; try { - credentials = JSON.parse(localStorage.getItem(CRED_KEY)); + credentials = JSON.parse(localStorage.getItem(CRED_KEY)!); } catch (e) { // Error decoding or parsing the cookie -- abort reject(); @@ -110,7 +110,7 @@ export class EnhancedAuthentication { private AnonymousCognitoCredentialsProvider = async (): Promise => { const credentialProvider: CredentialProvider = fromCognitoIdentityPool({ client: this.cognitoIdentityClient, - identityPoolId: this.config.identityPoolId + identityPoolId: this.config.identityPoolId as string }); return credentialProvider().then((credentials) => { diff --git a/src/dispatch/FetchHttpHandler.ts b/src/dispatch/FetchHttpHandler.ts index 948481c0..691f1bef 100644 --- a/src/dispatch/FetchHttpHandler.ts +++ b/src/dispatch/FetchHttpHandler.ts @@ -88,9 +88,8 @@ export class FetchHttpHandler implements HttpHandler { const fetchRequest = new Request(url, requestOptions); const raceOfPromises = [ - this.fetchFunction - .apply(window, [fetchRequest]) - .then((response) => { + this.fetchFunction!.apply(window, [fetchRequest]).then( + (response) => { const fetchHeaders: any = response.headers; const transformedHeaders: HeaderBag = {}; @@ -118,7 +117,8 @@ export class FetchHttpHandler implements HttpHandler { body: response.body }) }; - }), + } + ), requestTimeout(requestTimeoutInMs) ]; if (abortSignal) { diff --git a/src/dispatch/RetryHttpHandler.ts b/src/dispatch/RetryHttpHandler.ts index d9fe2867..9de10c37 100644 --- a/src/dispatch/RetryHttpHandler.ts +++ b/src/dispatch/RetryHttpHandler.ts @@ -44,7 +44,7 @@ export class RetryHttpHandler implements HttpHandler { } } - private async sleep(milliseconds): Promise { + private async sleep(milliseconds: number): Promise { return new Promise((resolve) => setTimeout(resolve, milliseconds) ); diff --git a/src/dispatch/StsClient.ts b/src/dispatch/StsClient.ts index e3ab8675..d88b1115 100644 --- a/src/dispatch/StsClient.ts +++ b/src/dispatch/StsClient.ts @@ -49,7 +49,7 @@ export class StsClient { response.body .getReader() .read() - .then(({ value }) => { + .then(({ value }: { value: number[] }) => { const xmlResponse = String.fromCharCode.apply( null, value diff --git a/src/event-cache/EventCache.ts b/src/event-cache/EventCache.ts index 5000cc27..47343b2d 100644 --- a/src/event-cache/EventCache.ts +++ b/src/event-cache/EventCache.ts @@ -170,7 +170,7 @@ export class EventCache { } }; - private canRecord = (session): boolean => { + private canRecord = (session: Session): boolean => { return ( session.record && (session.eventCount <= this.config.sessionEventLimit || diff --git a/src/index-browser.ts b/src/index-browser.ts index 10760c4c..7e455090 100644 --- a/src/index-browser.ts +++ b/src/index-browser.ts @@ -12,5 +12,5 @@ if (typeof fetch === 'function' && typeof navigator.sendBeacon === 'function') { new CommandQueue().init(window.AwsRumClient); } else { // eslint-disable-next-line @typescript-eslint/no-empty-function - window[window.AwsRumClient.n] = () => {}; + (window as any)[window.AwsRumClient.n] = () => {}; } diff --git a/src/plugins/InternalPlugin.ts b/src/plugins/InternalPlugin.ts index d951c715..f3129b66 100644 --- a/src/plugins/InternalPlugin.ts +++ b/src/plugins/InternalPlugin.ts @@ -7,7 +7,7 @@ export abstract class InternalPlugin static idPrefix = RUM_AWS_PREFIX; protected enabled = true; - protected context?: PluginContext; + protected context!: PluginContext; private readonly pluginId: string; constructor(name: string) { diff --git a/src/plugins/MonkeyPatched.ts b/src/plugins/MonkeyPatched.ts index 3ba48a44..8a58886b 100644 --- a/src/plugins/MonkeyPatched.ts +++ b/src/plugins/MonkeyPatched.ts @@ -22,18 +22,27 @@ export abstract class MonkeyPatched< protected abstract patches: MonkeyPatch[]; + private patchAll() { + const wrap = shimmer.wrap.bind(shimmer); + for (const patch of this.patches) { + wrap(patch.nodule, patch.name, patch.wrapper()); + } + } + + private unpatchAll() { + const unwrap = shimmer.unwrap.bind(shimmer); + for (const patch of this.patches) { + unwrap(patch.nodule, patch.name); + } + } + private patch(shouldPatch = true) { if (this.enabled !== shouldPatch) { this.enabled = shouldPatch; - const patchMethod = shouldPatch - ? shimmer.wrap.bind(shimmer) - : shimmer.unwrap.bind(shimmer); - for (const patch of this.patches) { - patchMethod( - patch.nodule, - patch.name, - shouldPatch ? patch.wrapper() : undefined - ); + if (shouldPatch) { + this.patchAll(); + } else { + this.unpatchAll(); } } } diff --git a/src/plugins/event-plugins/DemoPlugin.ts b/src/plugins/event-plugins/DemoPlugin.ts index 3f4e2a2b..e7e72f27 100644 --- a/src/plugins/event-plugins/DemoPlugin.ts +++ b/src/plugins/event-plugins/DemoPlugin.ts @@ -13,11 +13,13 @@ export const DEMO_PLUGIN_ID = 'demo'; export class DemoPlugin implements Plugin { configuration: any; timerId: number | undefined; - private recordEvent: RecordEvent | undefined; + private recordEvent: RecordEvent; constructor() { this.configuration = {}; this.timerId = undefined; + // eslint-disable-next-line @typescript-eslint/no-empty-function + this.recordEvent = () => {}; } getPluginId(): string { diff --git a/src/plugins/event-plugins/DomEventPlugin.ts b/src/plugins/event-plugins/DomEventPlugin.ts index 49cacc19..358dfa6f 100644 --- a/src/plugins/event-plugins/DomEventPlugin.ts +++ b/src/plugins/event-plugins/DomEventPlugin.ts @@ -39,7 +39,7 @@ export type DomEventPluginConfig = { }; const defaultConfig: DomEventPluginConfig = { - interactionId: () => undefined, + interactionId: () => '', enableMutationObserver: false, events: [] }; @@ -60,7 +60,7 @@ export class DomEventPlugin< enabled = false; private eventListenerMap: Map; private config: DomEventPluginConfig; - private observer: MutationObserver; + private observer: MutationObserver | undefined; constructor(config?: PartialDomEventPluginConfig) { super(DOM_EVENT_PLUGIN_ID); @@ -163,7 +163,7 @@ export class DomEventPlugin< const elementEventListenerList: ElementEventListener[] = this.eventListenerMap.has( domEvent ) - ? this.eventListenerMap.get(domEvent) + ? (this.eventListenerMap.get(domEvent) as ElementEventListener[]) : []; // first add event listener to all elements identified by the CSS locator diff --git a/src/plugins/event-plugins/FetchPlugin.ts b/src/plugins/event-plugins/FetchPlugin.ts index d0bdb462..8b9ebcd7 100644 --- a/src/plugins/event-plugins/FetchPlugin.ts +++ b/src/plugins/event-plugins/FetchPlugin.ts @@ -81,8 +81,8 @@ export class FetchPlugin extends MonkeyPatched { }; private beginTrace = ( - input: RequestInfo, - init: RequestInit, + input: RequestInfo | URL | string, + init: RequestInit | undefined, argsArray: IArguments ): XRayTraceEvent => { const startTime = epochTime(); @@ -96,7 +96,7 @@ export class FetchPlugin extends MonkeyPatched { startTime, http ); - xRayTraceEvent.subsegments.push(subsegment); + xRayTraceEvent.subsegments!.push(subsegment); if (this.config.addXRayTraceIdHeader) { this.addXRayTraceIdHeader(input, init, argsArray, xRayTraceEvent); @@ -106,8 +106,8 @@ export class FetchPlugin extends MonkeyPatched { }; private addXRayTraceIdHeader = ( - input: RequestInfo, - init: RequestInit, + input: RequestInfo | URL | string, + init: RequestInit | undefined, argsArray: IArguments, xRayTraceEvent: XRayTraceEvent ) => { @@ -115,51 +115,52 @@ export class FetchPlugin extends MonkeyPatched { return addAmznTraceIdHeaderToHeaders( (input as Request).headers, xRayTraceEvent.trace_id, - xRayTraceEvent.subsegments[0].id + xRayTraceEvent.subsegments![0].id ); } if (!init) { init = {}; - [].push.call(argsArray, init); + [].push.call(argsArray, init as never); } addAmznTraceIdHeaderToInit( init, xRayTraceEvent.trace_id, - xRayTraceEvent.subsegments[0].id + xRayTraceEvent.subsegments![0].id ); }; private endTrace = ( - xRayTraceEvent: XRayTraceEvent, + xRayTraceEvent: XRayTraceEvent | undefined, response: Response | undefined, error: Error | string | number | boolean | undefined ) => { if (xRayTraceEvent) { const endTime = epochTime(); - xRayTraceEvent.subsegments[0].end_time = endTime; + xRayTraceEvent.subsegments![0].end_time = endTime; xRayTraceEvent.end_time = endTime; if (response) { - xRayTraceEvent.subsegments[0].http.response = { + xRayTraceEvent.subsegments![0].http!.response = { status: response.status }; if (is429(response.status)) { - xRayTraceEvent.subsegments[0].throttle = true; + xRayTraceEvent.subsegments![0].throttle = true; xRayTraceEvent.throttle = true; } else if (is4xx(response.status)) { - xRayTraceEvent.subsegments[0].error = true; + xRayTraceEvent.subsegments![0].error = true; xRayTraceEvent.error = true; } else if (is5xx(response.status)) { - xRayTraceEvent.subsegments[0].fault = true; + xRayTraceEvent.subsegments![0].fault = true; xRayTraceEvent.fault = true; } - const cl = parseInt(response.headers.get('Content-Length'), 10); + const clStr = response.headers.get('Content-Length'); + const cl = clStr ? parseInt(clStr, 10) : NaN; if (!isNaN(cl)) { - xRayTraceEvent.subsegments[0].http.response.content_length = cl; + xRayTraceEvent.subsegments![0].http!.response.content_length = cl; } } @@ -169,15 +170,15 @@ export class FetchPlugin extends MonkeyPatched { // > error to the user, and in subsegments when a downstream call // > returns an error. xRayTraceEvent.fault = true; - xRayTraceEvent.subsegments[0].fault = true; + xRayTraceEvent.subsegments![0].fault = true; if (error instanceof Object) { this.appendErrorCauseFromObject( - xRayTraceEvent.subsegments[0], + xRayTraceEvent.subsegments![0], error ); } else if (isErrorPrimitive(error)) { this.appendErrorCauseFromPrimitive( - xRayTraceEvent.subsegments[0], + xRayTraceEvent.subsegments![0], error.toString() ); } @@ -212,8 +213,8 @@ export class FetchPlugin extends MonkeyPatched { } private createHttpEvent = ( - input: RequestInfo, - init: RequestInit + input: RequestInfo | URL | string, + init?: RequestInit ): HttpEvent => { return { version: '1.0.0', @@ -255,14 +256,14 @@ export class FetchPlugin extends MonkeyPatched { original: Fetch, thisArg: Fetch, argsArray: IArguments, - input: RequestInfo, + input: RequestInfo | URL | string, init?: RequestInit ): Promise => { const httpEvent: HttpEvent = this.createHttpEvent(input, init); let trace: XRayTraceEvent | undefined; if (!isUrlAllowed(resourceToUrlString(input), this.config)) { - return original.apply(thisArg, argsArray); + return original.apply(thisArg, argsArray as any); } if (this.isTracingEnabled() && this.isSessionRecorded()) { @@ -270,7 +271,7 @@ export class FetchPlugin extends MonkeyPatched { } return original - .apply(thisArg, argsArray) + .apply(thisArg, argsArray as any) .then((response: Response) => { this.endTrace(trace, response, undefined); this.recordHttpEventWithResponse(httpEvent, response); @@ -288,7 +289,7 @@ export class FetchPlugin extends MonkeyPatched { return (original: Fetch): Fetch => { return function ( this: Fetch, - input: RequestInfo, + input: RequestInfo | URL | string, init?: RequestInit ): Promise { return self.fetch(original, this, arguments, input, init); diff --git a/src/plugins/event-plugins/PageViewPlugin.ts b/src/plugins/event-plugins/PageViewPlugin.ts index eca6c40f..8a06ed27 100644 --- a/src/plugins/event-plugins/PageViewPlugin.ts +++ b/src/plugins/event-plugins/PageViewPlugin.ts @@ -50,7 +50,7 @@ export class PageViewPlugin extends MonkeyPatched< title: string, url?: string | null ): void { - const retVal = original.apply(this, arguments); + const retVal = original.apply(this, arguments as any); self.recordPageView(); return retVal; }; @@ -66,7 +66,7 @@ export class PageViewPlugin extends MonkeyPatched< title: string, url?: string | null ): void { - const retVal = original.apply(this, arguments); + const retVal = original.apply(this, arguments as any); self.recordPageView(); return retVal; }; diff --git a/src/plugins/event-plugins/XhrPlugin.ts b/src/plugins/event-plugins/XhrPlugin.ts index 0d873280..985f8684 100644 --- a/src/plugins/event-plugins/XhrPlugin.ts +++ b/src/plugins/event-plugins/XhrPlugin.ts @@ -136,41 +136,39 @@ export class XhrPlugin extends MonkeyPatched { private handleXhrLoadEvent = (e: Event) => { const xhr: XMLHttpRequest = e.target as XMLHttpRequest; - const xhrDetails: XhrDetails = this.xhrMap.get(xhr); + const xhrDetails: XhrDetails = this.xhrMap.get(xhr) as XhrDetails; if (xhrDetails) { - const endTime = epochTime(); - xhrDetails.trace.end_time = endTime; - xhrDetails.trace.subsegments[0].end_time = endTime; - xhrDetails.trace.subsegments[0].http.response = { + const endTimee = epochTime(); + xhrDetails.trace!.end_time = endTimee; + xhrDetails.trace!.subsegments![0].end_time = endTimee; + xhrDetails.trace!.subsegments![0].http!.response = { status: xhr.status }; if (is429(xhr.status)) { - xhrDetails.trace.subsegments[0].throttle = true; - xhrDetails.trace.throttle = true; + xhrDetails.trace!.subsegments![0].throttle = true; + xhrDetails.trace!.throttle = true; } else if (is4xx(xhr.status)) { - xhrDetails.trace.subsegments[0].error = true; - xhrDetails.trace.error = true; + xhrDetails.trace!.subsegments![0].error = true; + xhrDetails.trace!.error = true; } else if (is5xx(xhr.status)) { - xhrDetails.trace.subsegments[0].fault = true; - xhrDetails.trace.fault = true; + xhrDetails.trace!.subsegments![0].fault = true; + xhrDetails.trace!.fault = true; } - const cl = parseInt(xhr.getResponseHeader('Content-Length'), 10); + const clStr = xhr.getResponseHeader('Content-Length'); + const cl = clStr ? parseInt(clStr, 10) : NaN; if (!isNaN(cl)) { - xhrDetails.trace.subsegments[0].http.response.content_length = parseInt( - xhr.getResponseHeader('Content-Length'), - 10 - ); + xhrDetails.trace!.subsegments![0].http!.response.content_length = cl; } - this.recordTraceEvent(xhrDetails.trace); + this.recordTraceEvent(xhrDetails.trace!); this.recordHttpEventWithResponse(xhrDetails, xhr); } }; private handleXhrErrorEvent = (e: Event) => { const xhr: XMLHttpRequest = e.target as XMLHttpRequest; - const xhrDetails: XhrDetails = this.xhrMap.get(xhr); + const xhrDetails = this.xhrMap.get(xhr); const errorName = 'XMLHttpRequest error'; const errorMessage: string = xhr.statusText ? xhr.status.toString() + ': ' + xhr.statusText @@ -181,11 +179,11 @@ export class XhrPlugin extends MonkeyPatched { // > Record errors in segments when your application returns an // > error to the user, and in subsegments when a downstream call // > returns an error. - xhrDetails.trace.fault = true; - xhrDetails.trace.end_time = endTime; - xhrDetails.trace.subsegments[0].end_time = endTime; - xhrDetails.trace.subsegments[0].fault = true; - xhrDetails.trace.subsegments[0].cause = { + xhrDetails.trace!.fault = true; + xhrDetails.trace!.end_time = endTime; + xhrDetails.trace!.subsegments![0].end_time = endTime; + xhrDetails.trace!.subsegments![0].fault = true; + xhrDetails.trace!.subsegments![0].cause = { exceptions: [ { type: errorName, @@ -193,7 +191,7 @@ export class XhrPlugin extends MonkeyPatched { } ] }; - this.recordTraceEvent(xhrDetails.trace); + this.recordTraceEvent(xhrDetails.trace!); this.recordHttpEventWithError( xhrDetails, new XhrError(errorMessage) @@ -203,32 +201,35 @@ export class XhrPlugin extends MonkeyPatched { private handleXhrAbortEvent = (e: Event) => { const xhr: XMLHttpRequest = e.target as XMLHttpRequest; - const xhrDetails: XhrDetails = this.xhrMap.get(xhr); + const xhrDetails = this.xhrMap.get(xhr); const errorName = 'XMLHttpRequest abort'; this.handleXhrDetailsOnError(xhrDetails, errorName); }; private handleXhrTimeoutEvent = (e: Event) => { const xhr: XMLHttpRequest = e.target as XMLHttpRequest; - const xhrDetails: XhrDetails = this.xhrMap.get(xhr); + const xhrDetails = this.xhrMap.get(xhr); const errorName = 'XMLHttpRequest timeout'; this.handleXhrDetailsOnError(xhrDetails, errorName); }; - private handleXhrDetailsOnError(xhrDetails: XhrDetails, errorName: string) { + private handleXhrDetailsOnError( + xhrDetails: XhrDetails | undefined, + errorName: string + ) { if (xhrDetails) { const endTime = epochTime(); - xhrDetails.trace.end_time = endTime; - xhrDetails.trace.subsegments[0].end_time = endTime; - xhrDetails.trace.subsegments[0].error = true; - xhrDetails.trace.subsegments[0].cause = { + xhrDetails.trace!.end_time = endTime; + xhrDetails.trace!.subsegments![0].end_time = endTime; + xhrDetails.trace!.subsegments![0].error = true; + xhrDetails.trace!.subsegments![0].cause = { exceptions: [ { type: errorName } ] }; - this.recordTraceEvent(xhrDetails.trace); + this.recordTraceEvent(xhrDetails.trace!); this.recordHttpEventWithError(xhrDetails, errorName); } } @@ -280,7 +281,7 @@ export class XhrPlugin extends MonkeyPatched { this.config.logicalServiceName, startTime ); - xhrDetails.trace.subsegments.push( + xhrDetails.trace.subsegments!.push( createXRaySubsegment( requestInfoToHostname(xhrDetails.url), startTime, @@ -297,9 +298,9 @@ export class XhrPlugin extends MonkeyPatched { private sendWrapper = () => { const self = this; - return (original) => { + return (original: any) => { return function (this: XMLHttpRequest): void { - const xhrDetails: XhrDetails = self.xhrMap.get(this); + const xhrDetails = self.xhrMap.get(this); if (xhrDetails) { this.addEventListener('load', self.handleXhrLoadEvent); this.addEventListener('error', self.handleXhrErrorEvent); @@ -319,8 +320,8 @@ export class XhrPlugin extends MonkeyPatched { this.setRequestHeader( X_AMZN_TRACE_ID, getAmznTraceIdHeaderValue( - xhrDetails.trace.trace_id, - xhrDetails.trace.subsegments[0].id + xhrDetails.trace!.trace_id, + xhrDetails.trace!.subsegments![0].id ) ); } @@ -332,7 +333,7 @@ export class XhrPlugin extends MonkeyPatched { private openWrapper = () => { const self = this; - return (original) => { + return (original: any) => { return function ( this: XMLHttpRequest, method: string, diff --git a/src/plugins/types.ts b/src/plugins/types.ts index 98d9b3bf..2aec3745 100644 --- a/src/plugins/types.ts +++ b/src/plugins/types.ts @@ -4,7 +4,7 @@ import { Session } from '../sessions/SessionManager'; export type RecordEvent = (type: string, eventData: object) => void; export type RecordPageView = (pageId: string) => void; -export type GetSession = () => Session; +export type GetSession = () => Session | undefined; export type PluginContext = { applicationId: string; diff --git a/src/plugins/utils/http-utils.ts b/src/plugins/utils/http-utils.ts index f5a86152..5efa008d 100644 --- a/src/plugins/utils/http-utils.ts +++ b/src/plugins/utils/http-utils.ts @@ -6,7 +6,7 @@ import { import { getRandomValues } from '../../utils/random'; // All one-byte hex strings from 0x00 to 0xff. -export const byteToHex = []; +export const byteToHex: string[] = []; for (let i = 0; i < 256; i++) { byteToHex[i] = (i + 0x100).toString(16).substr(1); } @@ -83,14 +83,14 @@ export const epochTime = () => { }; export const createXRayTraceEventHttp = ( - input: RequestInfo, - init: RequestInit, + input: RequestInfo | URL | string, + init: RequestInit | undefined, traced: boolean ): Http => { const http: Http = { request: {} }; - http.request.method = init?.method ? init.method : 'GET'; - http.request.traced = traced; - http.request.url = resourceToUrlString(input); + http.request!.method = init?.method ? init.method : 'GET'; + http.request!.traced = traced; + http.request!.url = resourceToUrlString(input); return http; }; @@ -118,7 +118,7 @@ export const createXRayTraceEvent = ( export const createXRaySubsegment = ( name: string, - startTime, + startTime: number, http?: Http ): Subsegment => { const subsegment: Subsegment = { @@ -160,7 +160,7 @@ export const addAmznTraceIdHeaderToInit = ( if (!init.headers) { init.headers = {}; } - init.headers[X_AMZN_TRACE_ID] = getAmznTraceIdHeaderValue( + (init.headers as any)[X_AMZN_TRACE_ID] = getAmznTraceIdHeaderValue( traceId, segmentId ); diff --git a/src/sessions/PageManager.ts b/src/sessions/PageManager.ts index 66b276d3..9f58638b 100644 --- a/src/sessions/PageManager.ts +++ b/src/sessions/PageManager.ts @@ -17,11 +17,13 @@ export type Attributes = { parentPageId?: string; interaction?: number; pageTags?: string[]; + [key: string]: string | number | string[] | undefined; }; export type PageAttributes = { pageId: string; pageTags?: string[]; + [key: string]: string[] | string | undefined; }; /** @@ -94,36 +96,39 @@ export class PageManager { } if (!this.page && this.resumed) { - this.createResumedPage(pageId); + this.createResumedPage(pageId, this.resumed); } else if (!this.page) { this.createLandingPage(pageId); } else if (this.page.pageId !== pageId) { - this.createNextPage(pageId); + this.createNextPage(this.page, pageId); } else { // The view has not changed. return; } + // this.page is guaranteed to have been initialized + // Attributes will be added to all events as meta data this.collectAttributes( + this.page as Page, typeof payload === 'object' ? payload : undefined ); // The SessionManager will update its cookie with the new page - this.recordPageViewEvent(); + this.recordPageViewEvent(this.page as Page); } - private createResumedPage(pageId: string) { + private createResumedPage(pageId: string, resumed: Page) { this.page = { pageId, - parentPageId: this.resumed.pageId, - interaction: this.resumed.interaction + 1, + parentPageId: resumed.pageId, + interaction: resumed.interaction + 1, start: Date.now() }; this.resumed = undefined; } - private createNextPage(pageId: string) { + private createNextPage(currentPage: Page, pageId: string) { let startTime = Date.now(); const interactionTime = this.virtualPageLoadTimer.latestInteractionTime; @@ -152,8 +157,8 @@ export class PageManager { } this.page = { pageId, - parentPageId: this.page.pageId, - interaction: this.page.interaction + 1, + parentPageId: currentPage.pageId, + interaction: currentPage.interaction + 1, start: startTime }; } @@ -166,48 +171,52 @@ export class PageManager { }; } - private collectAttributes(customPageAttributes?: PageAttributes) { + private collectAttributes( + page: Page, + customPageAttributes?: PageAttributes + ) { this.attributes = { title: document.title, - pageId: this.page.pageId + pageId: page.pageId }; if (this.recordInteraction) { - this.attributes.interaction = this.page.interaction; - if (this.page.parentPageId !== undefined) { - this.attributes.parentPageId = this.page.parentPageId; + this.attributes.interaction = page.interaction; + if (page.parentPageId !== undefined) { + this.attributes.parentPageId = page.parentPageId; } } if (customPageAttributes) { Object.keys(customPageAttributes).forEach((attribute) => { - this.attributes[attribute] = customPageAttributes[attribute]; + (this.attributes as Attributes)[attribute] = + customPageAttributes[attribute]; }); } } - private createPageViewEvent() { + private createPageViewEvent(page: Page) { const pageViewEvent: PageViewEvent = { version: '1.0.0', - pageId: this.page.pageId + pageId: page.pageId }; if (this.recordInteraction) { - pageViewEvent.interaction = this.page.interaction; + pageViewEvent.interaction = page.interaction; pageViewEvent.pageInteractionId = - this.page.pageId + '-' + this.page.interaction; + page.pageId + '-' + page.interaction; - if (this.page.parentPageId !== undefined) { + if (page.parentPageId !== undefined) { pageViewEvent.parentPageInteractionId = - this.page.parentPageId + '-' + (this.page.interaction - 1); + page.parentPageId + '-' + (page.interaction - 1); } } return pageViewEvent; } - private recordPageViewEvent() { - this.record(PAGE_VIEW_EVENT_TYPE, this.createPageViewEvent()); + private recordPageViewEvent(page: Page) { + this.record(PAGE_VIEW_EVENT_TYPE, this.createPageViewEvent(page)); } /** diff --git a/src/sessions/SessionManager.ts b/src/sessions/SessionManager.ts index 5868d39f..84930468 100644 --- a/src/sessions/SessionManager.ts +++ b/src/sessions/SessionManager.ts @@ -60,13 +60,13 @@ export class SessionManager { private pageManager: PageManager; private appMonitorDetails: AppMonitorDetails; - private userExpiry: Date; - private sessionExpiry: Date; + private userExpiry!: Date; + private sessionExpiry!: Date; private userId!: string; private session: Session; private config: Config; private record: RecordSessionInitEvent; - private attributes: Attributes; + private attributes!: Attributes; constructor( appMonitorDetails: AppMonitorDetails, @@ -190,8 +190,8 @@ export class SessionManager { try { this.session = JSON.parse(atob(cookie)); this.pageManager.resumeSession( - this.session.page.pageId, - this.session.page.interaction + this.session.page!.pageId, + this.session.page!.interaction ); } catch (e) { // Error decoding or parsing the cookie -- ignore diff --git a/src/sessions/VirtualPageLoadTimer.ts b/src/sessions/VirtualPageLoadTimer.ts index 1b20de42..7a5439ed 100644 --- a/src/sessions/VirtualPageLoadTimer.ts +++ b/src/sessions/VirtualPageLoadTimer.ts @@ -23,21 +23,21 @@ export class VirtualPageLoadTimer extends MonkeyPatched< { nodule: (XMLHttpRequest.prototype as unknown) as Patching, name: 'send' as const, - wrapper: this.sendWrapper + wrapper: this.sendWrapper as any }, { nodule: (window as unknown) as Patching, name: 'fetch' as const, - wrapper: this.fetchWrapper + wrapper: this.fetchWrapper as any } ]; } /** Latest interaction time by user on the document */ public latestInteractionTime: number; /** Unique ID of virtual page load periodic checker. */ - private periodicCheckerId; + private periodicCheckerId: number | undefined; /** Unique ID of virtual page load timeout checker. */ - private timeoutCheckerId; + private timeoutCheckerId: number | undefined; /** Observer to liten for DOM changes. */ private domMutationObserver: MutationObserver; /** Set to hold outgoing XMLHttpRequests for current virtual page. */ @@ -94,14 +94,14 @@ export class VirtualPageLoadTimer extends MonkeyPatched< this.domMutationObserver.disconnect(); // Initialize timer objects and start observing - this.periodicCheckerId = setInterval( + this.periodicCheckerId = (setInterval( this.checkLoadStatus, this.config.routeChangeComplete - ); - this.timeoutCheckerId = setTimeout( + ) as unknown) as number; + this.timeoutCheckerId = (setTimeout( this.declareTimeout, this.config.routeChangeTimeout - ); + ) as unknown) as number; // observing the add/delete of nodes this.domMutationObserver.observe(document, { subtree: true, @@ -123,7 +123,7 @@ export class VirtualPageLoadTimer extends MonkeyPatched< return function (this: XMLHttpRequest): void { self.recordXhr(this); this.addEventListener('loadend', self.endTracking); - return original.apply(this, arguments); + return original.apply(this, arguments as any); }; }; }; @@ -162,12 +162,10 @@ export class VirtualPageLoadTimer extends MonkeyPatched< private fetch = ( original: Fetch, thisArg: Fetch, - argsArray: IArguments, - input: RequestInfo, - init?: RequestInit + argsArray: IArguments ): Promise => { return original - .apply(thisArg, argsArray) + .apply(thisArg, argsArray as any) .catch((error) => { throw error; }) @@ -182,11 +180,11 @@ export class VirtualPageLoadTimer extends MonkeyPatched< return (original: Fetch): Fetch => { return function ( this: Fetch, - input: RequestInfo, + input: RequestInfo | URL, init?: RequestInit ): Promise { self.fetchCounter += 1; - return self.fetch(original, this, arguments, input, init); + return self.fetch(original, this, arguments); }; }; }; @@ -210,7 +208,9 @@ export class VirtualPageLoadTimer extends MonkeyPatched< clearInterval(this.periodicCheckerId); clearTimeout(this.timeoutCheckerId); this.domMutationObserver.disconnect(); - this.recordRouteChangeNavigationEvent(this.pageManager.getPage()); + this.recordRouteChangeNavigationEvent( + this.pageManager.getPage() as Page + ); this.periodicCheckerId = undefined; this.timeoutCheckerId = undefined; this.isPageLoaded = true; @@ -229,10 +229,10 @@ export class VirtualPageLoadTimer extends MonkeyPatched< private resetInterval = () => { this.latestEndTime = Date.now(); clearInterval(this.periodicCheckerId); - this.periodicCheckerId = setInterval( + this.periodicCheckerId = (setInterval( this.checkLoadStatus, this.config.routeChangeComplete - ); + ) as unknown) as number; }; private moveItemsFromBuffer = (item: XMLHttpRequest) => { diff --git a/tsconfig.json b/tsconfig.json index 3ad37e38..648e480e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "lib": ["dom", "es2018"], "module": "esnext", "moduleResolution": "node", - "strict": false, + "strict": true, "target": "es5" }, "include": ["src/**/*"]