From bb035f16b1284430ff07419f3843bd66dafffccb Mon Sep 17 00:00:00 2001 From: RNEvok <81921589+RNEvok@users.noreply.github.com> Date: Sat, 17 Jun 2023 03:54:23 +0300 Subject: [PATCH] Console logs updated + Classic & XMLHttp interceptors now headers are shown --- Connector.ts | 31 ++++++++++++++-------------- Network/NetworkInterceptorClassic.ts | 16 ++++++++------ Network/NetworkInterceptorRN.ts | 3 ++- Network/NetworkInterceptorXMLHttp.ts | 15 ++++++++------ config.ts | 1 + encryption/index.ts | 6 +++--- helperFunctions.ts | 26 +++++++++++++++++++++++ index.d.ts | 2 +- index.ts | 24 +++++++++------------ rn/utils/logger.ts | 4 +++- types.ts | 2 +- 11 files changed, 81 insertions(+), 49 deletions(-) diff --git a/Connector.ts b/Connector.ts index 70bdfea..1cbf964 100644 --- a/Connector.ts +++ b/Connector.ts @@ -22,7 +22,7 @@ import { EventHandleError, ScenarioHandleError } from './Errors'; import { api, SOCKET_EVENTS_LISTEN, SOCKET_EVENTS_EMIT } from './api/api'; import { SPECIAL_INSTRUCTIONS_TABLE, SPECIAL_INSTRUCTIONS } from './constants/events'; import { io, Socket } from "socket.io-client"; -import { stringifyIfNotString } from './helperFunctions'; +import { codebudConsoleLog, codebudConsoleWarn, stringifyIfNotString } from './helperFunctions'; import moment from 'moment'; export class Connector { @@ -97,7 +97,7 @@ export class Connector { }; private async _innerHandleEvent(event: RemoteEvent, isPartOfScenario: boolean = false) { - console.log('On event:', event); + codebudConsoleLog('On event:', event); try { const correspondingInstructionsTable = event.eventType === "default" ? this._instructionsTable: SPECIAL_INSTRUCTIONS_TABLE; @@ -153,7 +153,7 @@ export class Connector { return eventLog; } catch (error) { - console.log(`Error while trying to handle event.`, error); + codebudConsoleLog(`Error while trying to handle event.`, error); // If current event was part of scenario then throw error so it would be processed inside _innerHandleScenario's catch block if (isPartOfScenario) @@ -164,7 +164,7 @@ export class Connector { } private async _innerHandleScenario(scenario: RemoteScenario) { - console.log('On scenario:', scenario); + // codebudConsoleLog('On scenario:', scenario); var eventIndex = 0; this._lastEventLog = undefined; @@ -199,7 +199,7 @@ export class Connector { }; this._socket.emit(SOCKET_EVENTS_EMIT.SAVE_SCENARIO_LOG, scenarioLog); } catch (error) { - console.log(`Error while trying to handle scenario.`, error); + codebudConsoleLog(`Error while trying to handle scenario.`, error); const scenarioError = new ScenarioHandleError(scenario, scenario.events[eventIndex], "Scenario execution failed."); this._socket.emit(SOCKET_EVENTS_EMIT.SAVE_SCENARIO_LOG, {scenario, ok: false, error: scenarioError}); } @@ -219,20 +219,20 @@ export class Connector { Connector._remoteSettings = remoteSettings; callbackFn && callbackFn(remoteSettings); } catch (e) { - console.warn("Error while trying to fetch remote settings", e); + codebudConsoleWarn("Error while trying to fetch remote settings", e); } } private async _setupNetworkMonitor(config: PackageConfig) { this._networkInterceptor = new config.Interceptor({ onRequest: ({ request, requestId }: NetworkInterceptorOnRequestPayload) => { - // console.log(`Intercepted request ${requestId}`, request); + // codebudConsoleLog(`Intercepted request ${requestId}`, request); const timestamp = moment().valueOf(); const encryptedData = this._encryptData({request, requestId, timestamp}); this._socket?.emit(SOCKET_EVENTS_EMIT.SAVE_INTERCEPTED_REQUEST, encryptedData); }, onResponse: ({ response, request, requestId }: NetworkInterceptorOnResponsePayload) => { - // console.log(`Intercepted response ${requestId}`, response); + // codebudConsoleLog(`Intercepted response ${requestId}`, response); const timestamp = moment().valueOf(); const encryptedData = this._encryptData({response, request, requestId, timestamp}); this._socket?.emit(SOCKET_EVENTS_EMIT.SAVE_INTERCEPTED_RESPONSE, encryptedData); @@ -283,14 +283,13 @@ export class Connector { this.refreshRemoteSettings(); this._socket.on(SOCKET_EVENTS_LISTEN.CONNECT, () => { - console.log('Socket connected:', this._socket.connected); + codebudConsoleLog('Socket connected:', this._socket.connected); this._socket.emit(SOCKET_EVENTS_EMIT.SET_CONNECTION_INFO, this._connectionInfoPacket); }); this._socket.on(SOCKET_EVENTS_LISTEN.ADMIN_CONNECTED, (data: AdminConnectedData) => { - console.log("AdminConnected", data) + codebudConsoleLog("AdminConnected"); if (!data.isAdmin) { - console.warn('Warning: client connected'); return; } @@ -303,7 +302,7 @@ export class Connector { this._socket.on(SOCKET_EVENTS_LISTEN.SCENARIO, (scenario: RemoteScenario) => this._innerHandleScenario(scenario)); this._socket.on(SOCKET_EVENTS_LISTEN.STOP_SCENARIO_EXECUTION, () => { - console.log("Stopping scenario manually..."); + codebudConsoleLog("Stopping scenario manually..."); this._shouldStopScenarioExecution = true; }); @@ -314,15 +313,15 @@ export class Connector { }); this._socket.on(SOCKET_EVENTS_LISTEN.CONNECT_ERROR, (err) => { - console.warn(`Socket connect_error: ${err.message}`); + codebudConsoleWarn(`Socket connect_error: ${err.message}`); }); this._socket.on(SOCKET_EVENTS_LISTEN.ERROR, (error) => { - console.log('Socket send error:', error); + codebudConsoleLog('Socket send error:', error); }); this._socket.on(SOCKET_EVENTS_LISTEN.DISCONNECT, async () => { - console.log('Socket disconnected.'); + codebudConsoleLog('Socket disconnected.'); setTimeout(() => { this._socket.connect(); }, CONFIG.SOCKET_RECONNECTION_DELAY); @@ -346,7 +345,7 @@ export class Connector { } } } catch (e) { - console.warn(`Error while trying to create ReduxStoreChangeHandler`, e); + codebudConsoleWarn(`Error while trying to create ReduxStoreChangeHandler`, e); return () => {}; } } diff --git a/Network/NetworkInterceptorClassic.ts b/Network/NetworkInterceptorClassic.ts index d1f4f85..23cdd32 100644 --- a/Network/NetworkInterceptorClassic.ts +++ b/Network/NetworkInterceptorClassic.ts @@ -2,11 +2,13 @@ import { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'; import { NetworkInterceptorApi } from './AbstractInterceptor'; import { NetworkInterceptorCallbacksTable } from '../types'; import { shouldProceedIntercepted } from './helpers'; +import { codebudConsoleLog } from '../helperFunctions'; class NetworkInterceptorClassic extends NetworkInterceptorApi { private _interceptor: ClientRequestInterceptor | null = null; protected async formatRequest(request: any) { + console.log('DEBUG', Object.fromEntries(request.headers)); let body: any; const isJsonContentType = request.headers.get("content-type")?.includes("application/json"); @@ -17,13 +19,14 @@ class NetworkInterceptorClassic extends NetworkInterceptorApi { body = await request.clone().text(); } } catch (e) { - console.log('Request transfrom error'); + codebudConsoleLog('Request transfrom error'); } const formattedRequest = { method: request.method, body, - url: request.url + url: request.url, + requestHeaders: Object.fromEntries(request.headers) }; return formattedRequest; @@ -40,13 +43,14 @@ class NetworkInterceptorClassic extends NetworkInterceptorApi { data = await response.clone().text(); } } catch (e) { - console.log('Response transfrom error'); + codebudConsoleLog('Response transfrom error'); } const formattedResponse = { status: response.status, statusText: response.statusText, - data + data, + responseHeaders: Object.fromEntries(response.headers) }; return formattedResponse; @@ -68,7 +72,7 @@ class NetworkInterceptorClassic extends NetworkInterceptorApi { requestId }); } catch (e) { - console.log(e); + codebudConsoleLog(e); } } }); @@ -84,7 +88,7 @@ class NetworkInterceptorClassic extends NetworkInterceptorApi { requestId }); } catch (e) { - console.log(e); + codebudConsoleLog(e); } } }); diff --git a/Network/NetworkInterceptorRN.ts b/Network/NetworkInterceptorRN.ts index 1c6c7b9..fe4671e 100644 --- a/Network/NetworkInterceptorRN.ts +++ b/Network/NetworkInterceptorRN.ts @@ -2,6 +2,7 @@ import { NetworkInterceptorApi } from './AbstractInterceptor'; import { startNetworkLogging, stopNetworkLogging, clearRequests } from "./../rn"; import { NetworkInterceptorCallbacksTable } from '../types'; import { CONFIG } from './../config'; +import { codebudConsoleLog } from '../helperFunctions'; class NetworkInterceptorRN extends NetworkInterceptorApi { protected async formatRequest(data: any) { @@ -60,7 +61,7 @@ class NetworkInterceptorRN extends NetworkInterceptorApi { requestId: data.id }); } catch (e) { - console.log(e); + codebudConsoleLog(e); } } }); diff --git a/Network/NetworkInterceptorXMLHttp.ts b/Network/NetworkInterceptorXMLHttp.ts index a5ecf44..8d6a528 100644 --- a/Network/NetworkInterceptorXMLHttp.ts +++ b/Network/NetworkInterceptorXMLHttp.ts @@ -2,6 +2,7 @@ import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'; import { NetworkInterceptorApi } from './AbstractInterceptor'; import { NetworkInterceptorCallbacksTable } from '../types'; import { shouldProceedIntercepted } from './helpers'; +import { codebudConsoleLog } from '../helperFunctions'; class NetworkInterceptorXMLHttp extends NetworkInterceptorApi { private _interceptor: XMLHttpRequestInterceptor | null = null; @@ -17,13 +18,14 @@ class NetworkInterceptorXMLHttp extends NetworkInterceptorApi { body = await request.clone().text(); } } catch (e) { - console.log('Request transfrom error'); + codebudConsoleLog('Request transfrom error'); } const formattedRequest = { method: request.method, body, - url: request.url + url: request.url, + requestHeaders: Object.fromEntries(request.headers) }; return formattedRequest; @@ -40,13 +42,14 @@ class NetworkInterceptorXMLHttp extends NetworkInterceptorApi { data = await response.clone().text(); } } catch (e) { - console.log('Response transfrom error'); + codebudConsoleLog(e); } const formattedResponse = { status: response.status, statusText: response.statusText, - data + data, + responseHeaders: Object.fromEntries(response.headers) }; return formattedResponse; @@ -68,7 +71,7 @@ class NetworkInterceptorXMLHttp extends NetworkInterceptorApi { requestId }); } catch (e) { - console.log(e); + codebudConsoleLog(e); } } }); @@ -84,7 +87,7 @@ class NetworkInterceptorXMLHttp extends NetworkInterceptorApi { requestId }); } catch (e) { - console.log(e); + codebudConsoleLog(e); } } }); diff --git a/config.ts b/config.ts index 04c3070..02f5299 100644 --- a/config.ts +++ b/config.ts @@ -4,6 +4,7 @@ const DEV_MODE: DevMode = "PRODUCTION"; const CONFIG_INNER = { PRODUCT_NAME: "CodeBud", + MAX_IDENTICAL_CONSOLE_WARNINGS_IN_A_ROW: 3, DOMAIN: "unitap.online", MAIN_URL: "https://unitap.online", BASE_URL: 'https://unitap.online/api', diff --git a/encryption/index.ts b/encryption/index.ts index 9bad4c7..9b027dc 100644 --- a/encryption/index.ts +++ b/encryption/index.ts @@ -1,5 +1,6 @@ import { box, randomBytes } from 'tweetnacl'; import { decodeUTF8, encodeBase64 } from 'tweetnacl-util'; +import { codebudConsoleLog, codebudConsoleWarn } from '../helperFunctions'; export class EncryptionPlugin { private _keyPair: nacl.BoxKeyPair | null = null; @@ -27,7 +28,7 @@ export class EncryptionPlugin { const base64FullMessage = encodeBase64(fullMessage); return base64FullMessage; } catch (e) { - console.log(e); + codebudConsoleLog(e); return JSON.stringify({msg: "Data encryption error"}); } }; @@ -44,9 +45,8 @@ export class EncryptionPlugin { if (this._keyPair) { this._adminPanelPublicKey = new Uint8Array(data); this._sharedKey = box.before(this._adminPanelPublicKey, this._keyPair.secretKey); - console.log('this._sharedKey',this._sharedKey) } else { - console.warn("No keypair generated!"); + codebudConsoleWarn("No keypair generated!"); } } }; \ No newline at end of file diff --git a/helperFunctions.ts b/helperFunctions.ts index 6f5fc79..e1b919f 100644 --- a/helperFunctions.ts +++ b/helperFunctions.ts @@ -1,3 +1,5 @@ +import { CONFIG } from "./config"; + export function delay(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)); } @@ -9,4 +11,28 @@ export const stringifyIfNotString = (data: any) => { } return JSON.stringify(data); +} + +const memo = { + warn: { + data: "", + identicalInARow: 0 + } +} + +export const codebudConsoleWarn = (...data: any[]) => { + const dataStr = JSON.stringify(data); + + if (dataStr === memo.warn.data) { + if (memo.warn.identicalInARow++ < CONFIG.MAX_IDENTICAL_CONSOLE_WARNINGS_IN_A_ROW) + console.warn(`${CONFIG.PRODUCT_NAME}:`, ...data); + } else { + memo.warn.data = dataStr; + memo.warn.identicalInARow = 1; + console.warn(`${CONFIG.PRODUCT_NAME}:`, ...data); + } +} + +export const codebudConsoleLog = (...data: any[]) => { + console.log(`${CONFIG.PRODUCT_NAME}:`, ...data); } \ No newline at end of file diff --git a/index.d.ts b/index.d.ts index daa6f84..b1e61ac 100644 --- a/index.d.ts +++ b/index.d.ts @@ -47,7 +47,7 @@ declare module '@appklaar/codebud' { type InstructionPrototype = "login" | "logout"; - type ParamType = "number" | "string" | "object" | "array"; + type ParamType = "number" | "string" | "object" | "array" | "boolean"; type InstructionPublicFields = { id: string; diff --git a/index.ts b/index.ts index c30befd..d4122d9 100644 --- a/index.ts +++ b/index.ts @@ -5,6 +5,7 @@ import { EXISTING_SPECIAL_INSTRUCTION_IDS } from './constants/events'; import { validateApiKey } from './constants/regex'; import { AppKlaarSdk as ModuleInterface } from './moduleInterface'; import { CONFIG } from './config'; +import { codebudConsoleWarn } from './helperFunctions'; export type { Instruction } from './types'; @@ -16,12 +17,12 @@ export const CodeBud: ModuleInterface = { init(apiKey, instructions, config) { if (this._currentState === "WORKING") { - console.warn(`${CONFIG.PRODUCT_NAME} already initiated!`); + codebudConsoleWarn(`${CONFIG.PRODUCT_NAME} already initiated!`); return; } if (!validateApiKey(apiKey)) { - console.warn(`Wrong API_KEY format!`); + codebudConsoleWarn(`Wrong API_KEY format!`); this._currentState = "INVALID_PARAMETERS"; return; } @@ -32,13 +33,13 @@ export const CodeBud: ModuleInterface = { const instructionPrototypes = new Set(); for (let el of instructions) { if (EXISTING_SPECIAL_INSTRUCTION_IDS.has(el.id as any)) { - console.warn(`Instruction id: ${el.id} is reserved for special instruction. You should change it for something else.`); + codebudConsoleWarn(`Instruction id: ${el.id} is reserved for special instruction. You should change it for something else.`); this._currentState = "INVALID_PARAMETERS"; return; } if (instructionIds.has(el.id)) { - console.warn(`Duplicate instruction id passed; InstructionId: ${el.id}`); + codebudConsoleWarn(`Duplicate instruction id passed; InstructionId: ${el.id}`); this._currentState = "INVALID_PARAMETERS"; return; } else { @@ -46,25 +47,20 @@ export const CodeBud: ModuleInterface = { } if (el.handler.length > 1) { - console.warn(`Instruction id: ${el.id} handler takes ${el.handler.length} args. Your handler should accept max 1 object as arguement. Number of fields is not limited.`); + codebudConsoleWarn(`Instruction id: ${el.id} handler takes ${el.handler.length} args. Your handler should accept max 1 object as arguement. Number of fields is not limited.`); this._currentState = "INVALID_PARAMETERS"; return; } - // if (el.prototype === "login") { - // if (!el.parametersDescription?.login || !el.parametersDescription.pass) - // console.warn(`Instruction with id ${el.id} is marked with login prototype, but its parameters dont match the prototype. We recommend to pass parametersDescription with "login" and "pass" fields, where "login" means user identifier (such as phone number or email). You can ignore this warning if you are sure what you are doing.`); - // } - if (el.prototype) instructionPrototypes.add(el.prototype); } if (!(instructionPrototypes.has("login") && instructionPrototypes.has("logout"))) { if (!instructionPrototypes.has("login")) - console.warn(`Login instruction is required. Please, provide at least one instruction with prototype "login"`); + codebudConsoleWarn(`Login instruction is required. Please, provide at least one instruction with prototype "login"`); if (!instructionPrototypes.has("logout")) - console.warn(`Logout instruction is required. Please, provide at least one instruction with prototype "logout"`); + codebudConsoleWarn(`Logout instruction is required. Please, provide at least one instruction with prototype "logout"`); this._currentState = "INVALID_PARAMETERS"; return; @@ -98,7 +94,7 @@ export const CodeBud: ModuleInterface = { if (this._connector) this._connector.refreshRemoteSettings(callbackFn); else - console.warn(`${CONFIG.PRODUCT_NAME} not initiated.`); + codebudConsoleWarn(`${CONFIG.PRODUCT_NAME} not initiated.`); }, createReduxStoreChangeHandler(store, selectFn, batchingTimeMs = 500) { @@ -108,7 +104,7 @@ export const CodeBud: ModuleInterface = { return this._connector.createReduxStoreChangeHandler(store, selectFn, batchingTimeMs); } catch (e) { - console.warn(e); + codebudConsoleWarn(e); return () => {}; } }, diff --git a/rn/utils/logger.ts b/rn/utils/logger.ts index e45f057..63a621c 100644 --- a/rn/utils/logger.ts +++ b/rn/utils/logger.ts @@ -1,2 +1,4 @@ +import { CONFIG } from "../../config"; + export const warn = (message: string) => - console.warn(`react-native-network-logger: ${message}`); + console.warn(`${CONFIG.PRODUCT_NAME}: react-native-network-logger: ${message}`); diff --git a/types.ts b/types.ts index 384b6a9..e50d30b 100644 --- a/types.ts +++ b/types.ts @@ -49,7 +49,7 @@ export type ErrorResponse = { type InstructionPrototype = "login" | "logout"; -type ParamType = "number" | "string" | "object" | "array"; +type ParamType = "number" | "string" | "object" | "array" | "boolean"; type InstructionPublicFields = { id: string;