react-native-inapp-inspector 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/commonjs/components/AnalyticsDetail.d.ts +6 -0
- package/dist/commonjs/components/AnalyticsDetail.js +558 -0
- package/dist/commonjs/components/AnalyticsEventCard.d.ts +18 -0
- package/dist/commonjs/components/AnalyticsEventCard.js +327 -0
- package/dist/commonjs/components/AnalyticsGraph.d.ts +8 -0
- package/dist/commonjs/components/AnalyticsGraph.js +416 -0
- package/dist/commonjs/components/CodeSnippet.d.ts +8 -0
- package/dist/commonjs/components/CodeSnippet.js +427 -0
- package/dist/commonjs/components/ConsoleLogCard.d.ts +10 -0
- package/dist/commonjs/components/ConsoleLogCard.js +401 -0
- package/dist/commonjs/components/CopyButton.d.ts +4 -0
- package/dist/commonjs/components/CopyButton.js +69 -0
- package/dist/commonjs/components/DiffViewer.d.ts +7 -0
- package/dist/commonjs/components/DiffViewer.js +86 -0
- package/dist/commonjs/components/DomainHeader.d.ts +18 -0
- package/dist/commonjs/components/DomainHeader.js +136 -0
- package/dist/commonjs/components/EmptyState.d.ts +5 -0
- package/dist/commonjs/components/EmptyState.js +40 -0
- package/dist/commonjs/components/HeadersSection.d.ts +4 -0
- package/dist/commonjs/components/HeadersSection.js +155 -0
- package/dist/commonjs/components/HighlightText.d.ts +3 -0
- package/dist/commonjs/components/HighlightText.js +57 -0
- package/dist/commonjs/components/JsonViewer.d.ts +7 -0
- package/dist/commonjs/components/JsonViewer.js +19 -0
- package/dist/commonjs/components/LogCard.d.ts +4 -0
- package/dist/commonjs/components/LogCard.js +179 -0
- package/dist/commonjs/components/MetaAccordion.d.ts +4 -0
- package/dist/commonjs/components/MetaAccordion.js +113 -0
- package/dist/commonjs/components/MiniBarChart.d.ts +7 -0
- package/dist/commonjs/components/MiniBarChart.js +56 -0
- package/dist/commonjs/components/MiniLineChart.d.ts +6 -0
- package/dist/commonjs/components/MiniLineChart.js +58 -0
- package/dist/commonjs/components/NetworkIcons.d.ts +31 -0
- package/dist/commonjs/components/NetworkIcons.js +245 -0
- package/dist/commonjs/components/SectionHeader.d.ts +4 -0
- package/dist/commonjs/components/SectionHeader.js +87 -0
- package/dist/commonjs/components/SourcePageCard.d.ts +4 -0
- package/dist/commonjs/components/SourcePageCard.js +132 -0
- package/dist/commonjs/components/TouchableScale.d.ts +9 -0
- package/dist/commonjs/components/TouchableScale.js +44 -0
- package/dist/commonjs/components/TreeNode.d.ts +4 -0
- package/dist/commonjs/components/TreeNode.js +140 -0
- package/dist/commonjs/constants/index.d.ts +7 -0
- package/dist/commonjs/constants/index.js +35 -0
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +21 -0
- package/dist/commonjs/customHooks/analyticsLogger.js +160 -0
- package/dist/commonjs/customHooks/consoleLogger.d.ts +5 -0
- package/dist/commonjs/customHooks/consoleLogger.js +141 -0
- package/dist/commonjs/customHooks/logFilters.d.ts +5 -0
- package/dist/commonjs/customHooks/logFilters.js +34 -0
- package/dist/commonjs/customHooks/networkLogger.d.ts +20 -0
- package/dist/commonjs/customHooks/networkLogger.js +272 -0
- package/dist/commonjs/customHooks/useAccordion.d.ts +17 -0
- package/dist/commonjs/customHooks/useAccordion.js +48 -0
- package/dist/commonjs/customHooks/webViewLogger.d.ts +22 -0
- package/dist/commonjs/customHooks/webViewLogger.js +412 -0
- package/dist/commonjs/helpers/index.d.ts +20 -0
- package/dist/commonjs/helpers/index.js +229 -0
- package/dist/commonjs/index.d.ts +7 -0
- package/dist/commonjs/index.js +2668 -0
- package/dist/commonjs/styles/AppColors.d.ts +27 -0
- package/dist/commonjs/styles/AppColors.js +30 -0
- package/dist/commonjs/styles/AppFonts.d.ts +7 -0
- package/dist/commonjs/styles/AppFonts.js +10 -0
- package/dist/commonjs/styles/index.d.ts +1488 -0
- package/dist/commonjs/styles/index.js +1357 -0
- package/dist/commonjs/types/index.d.ts +127 -0
- package/dist/commonjs/types/index.js +2 -0
- package/dist/esm/components/AnalyticsDetail.d.ts +6 -0
- package/dist/esm/components/AnalyticsDetail.js +520 -0
- package/dist/esm/components/AnalyticsEventCard.d.ts +18 -0
- package/dist/esm/components/AnalyticsEventCard.js +288 -0
- package/dist/esm/components/AnalyticsGraph.d.ts +8 -0
- package/dist/esm/components/AnalyticsGraph.js +378 -0
- package/dist/esm/components/CodeSnippet.d.ts +8 -0
- package/dist/esm/components/CodeSnippet.js +392 -0
- package/dist/esm/components/ConsoleLogCard.d.ts +10 -0
- package/dist/esm/components/ConsoleLogCard.js +362 -0
- package/dist/esm/components/CopyButton.d.ts +4 -0
- package/dist/esm/components/CopyButton.js +31 -0
- package/dist/esm/components/DiffViewer.d.ts +7 -0
- package/dist/esm/components/DiffViewer.js +48 -0
- package/dist/esm/components/DomainHeader.d.ts +18 -0
- package/dist/esm/components/DomainHeader.js +98 -0
- package/dist/esm/components/EmptyState.d.ts +5 -0
- package/dist/esm/components/EmptyState.js +35 -0
- package/dist/esm/components/HeadersSection.d.ts +4 -0
- package/dist/esm/components/HeadersSection.js +117 -0
- package/dist/esm/components/HighlightText.d.ts +3 -0
- package/dist/esm/components/HighlightText.js +52 -0
- package/dist/esm/components/JsonViewer.d.ts +7 -0
- package/dist/esm/components/JsonViewer.js +14 -0
- package/dist/esm/components/LogCard.d.ts +4 -0
- package/dist/esm/components/LogCard.js +141 -0
- package/dist/esm/components/MetaAccordion.d.ts +4 -0
- package/dist/esm/components/MetaAccordion.js +108 -0
- package/dist/esm/components/MiniBarChart.d.ts +7 -0
- package/dist/esm/components/MiniBarChart.js +18 -0
- package/dist/esm/components/MiniLineChart.d.ts +6 -0
- package/dist/esm/components/MiniLineChart.js +20 -0
- package/dist/esm/components/NetworkIcons.d.ts +31 -0
- package/dist/esm/components/NetworkIcons.js +176 -0
- package/dist/esm/components/SectionHeader.d.ts +4 -0
- package/dist/esm/components/SectionHeader.js +49 -0
- package/dist/esm/components/SourcePageCard.d.ts +4 -0
- package/dist/esm/components/SourcePageCard.js +94 -0
- package/dist/esm/components/TouchableScale.d.ts +9 -0
- package/dist/esm/components/TouchableScale.js +9 -0
- package/dist/esm/components/TreeNode.d.ts +4 -0
- package/dist/esm/components/TreeNode.js +102 -0
- package/dist/esm/constants/index.d.ts +7 -0
- package/dist/esm/constants/index.js +32 -0
- package/dist/esm/customHooks/analyticsLogger.d.ts +21 -0
- package/dist/esm/customHooks/analyticsLogger.js +152 -0
- package/dist/esm/customHooks/consoleLogger.d.ts +5 -0
- package/dist/esm/customHooks/consoleLogger.js +134 -0
- package/dist/esm/customHooks/logFilters.d.ts +5 -0
- package/dist/esm/customHooks/logFilters.js +31 -0
- package/dist/esm/customHooks/networkLogger.d.ts +20 -0
- package/dist/esm/customHooks/networkLogger.js +264 -0
- package/dist/esm/customHooks/useAccordion.d.ts +17 -0
- package/dist/esm/customHooks/useAccordion.js +46 -0
- package/dist/esm/customHooks/webViewLogger.d.ts +22 -0
- package/dist/esm/customHooks/webViewLogger.js +365 -0
- package/dist/esm/helpers/index.d.ts +20 -0
- package/dist/esm/helpers/index.js +207 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +2611 -0
- package/dist/esm/styles/AppColors.d.ts +27 -0
- package/dist/esm/styles/AppColors.js +27 -0
- package/dist/esm/styles/AppFonts.d.ts +7 -0
- package/dist/esm/styles/AppFonts.js +7 -0
- package/dist/esm/styles/index.d.ts +1488 -0
- package/dist/esm/styles/index.js +1355 -0
- package/dist/esm/types/index.d.ts +127 -0
- package/dist/esm/types/index.js +1 -0
- package/fonts/Inter/Inter.ttc +0 -0
- package/fonts/Inter/InterVariable-Italic.ttf +0 -0
- package/fonts/Inter/InterVariable.ttf +0 -0
- package/fonts/Inter/LICENSE.txt +92 -0
- package/fonts/Inter/extras/otf/Inter-Black.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-BlackItalic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-Bold.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-BoldItalic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-ExtraBold.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-ExtraBoldItalic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-ExtraLight.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-ExtraLightItalic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-Italic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-Light.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-LightItalic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-Medium.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-MediumItalic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-Regular.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-SemiBold.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-SemiBoldItalic.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-Thin.otf +0 -0
- package/fonts/Inter/extras/otf/Inter-ThinItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-Black.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-BlackItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-Bold.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-BoldItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-ExtraBold.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-ExtraBoldItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-ExtraLight.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-ExtraLightItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-Italic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-Light.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-LightItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-Medium.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-MediumItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-Regular.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-SemiBold.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-SemiBoldItalic.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-Thin.otf +0 -0
- package/fonts/Inter/extras/otf/InterDisplay-ThinItalic.otf +0 -0
- package/fonts/Inter/extras/ttf/Inter-Black.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-BlackItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-Bold.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-BoldItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-ExtraBold.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-ExtraBoldItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-ExtraLight.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-ExtraLightItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-Italic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-Light.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-LightItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-Medium.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-MediumItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-Regular.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-SemiBold.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-SemiBoldItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-Thin.ttf +0 -0
- package/fonts/Inter/extras/ttf/Inter-ThinItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-Black.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-BlackItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-Bold.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-BoldItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-ExtraBold.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-ExtraBoldItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-ExtraLight.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-ExtraLightItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-Italic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-Light.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-LightItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-Medium.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-MediumItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-Regular.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-SemiBold.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-SemiBoldItalic.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-Thin.ttf +0 -0
- package/fonts/Inter/extras/ttf/InterDisplay-ThinItalic.ttf +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-Black.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-BlackItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-Bold.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-BoldItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-ExtraBold.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-ExtraBoldItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-ExtraLight.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-ExtraLightItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-Italic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-Light.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-LightItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-Medium.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-MediumItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-Regular.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-SemiBold.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-SemiBoldItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-Thin.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/Inter-ThinItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-Black.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-BlackItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-Bold.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-BoldItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-ExtraBold.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-ExtraBoldItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-ExtraLight.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-ExtraLightItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-Italic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-Light.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-LightItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-Medium.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-MediumItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-Regular.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-SemiBold.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-SemiBoldItalic.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-Thin.woff2 +0 -0
- package/fonts/Inter/extras/woff-hinted/InterDisplay-ThinItalic.woff2 +0 -0
- package/fonts/Inter/help.txt +165 -0
- package/fonts/Inter/web/Inter-Black.woff2 +0 -0
- package/fonts/Inter/web/Inter-BlackItalic.woff2 +0 -0
- package/fonts/Inter/web/Inter-Bold.woff2 +0 -0
- package/fonts/Inter/web/Inter-BoldItalic.woff2 +0 -0
- package/fonts/Inter/web/Inter-ExtraBold.woff2 +0 -0
- package/fonts/Inter/web/Inter-ExtraBoldItalic.woff2 +0 -0
- package/fonts/Inter/web/Inter-ExtraLight.woff2 +0 -0
- package/fonts/Inter/web/Inter-ExtraLightItalic.woff2 +0 -0
- package/fonts/Inter/web/Inter-Italic.woff2 +0 -0
- package/fonts/Inter/web/Inter-Light.woff2 +0 -0
- package/fonts/Inter/web/Inter-LightItalic.woff2 +0 -0
- package/fonts/Inter/web/Inter-Medium.woff2 +0 -0
- package/fonts/Inter/web/Inter-MediumItalic.woff2 +0 -0
- package/fonts/Inter/web/Inter-Regular.woff2 +0 -0
- package/fonts/Inter/web/Inter-SemiBold.woff2 +0 -0
- package/fonts/Inter/web/Inter-SemiBoldItalic.woff2 +0 -0
- package/fonts/Inter/web/Inter-Thin.woff2 +0 -0
- package/fonts/Inter/web/Inter-ThinItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-Black.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-BlackItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-Bold.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-BoldItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-ExtraBold.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-ExtraBoldItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-ExtraLight.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-ExtraLightItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-Italic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-Light.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-LightItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-Medium.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-MediumItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-Regular.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-SemiBold.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-SemiBoldItalic.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-Thin.woff2 +0 -0
- package/fonts/Inter/web/InterDisplay-ThinItalic.woff2 +0 -0
- package/fonts/Inter/web/InterVariable-Italic.woff2 +0 -0
- package/fonts/Inter/web/InterVariable.woff2 +0 -0
- package/fonts/Inter/web/inter.css +148 -0
- package/package.json +52 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface WebViewLog {
|
|
2
|
+
id: number;
|
|
3
|
+
type: 'log' | 'info' | 'warn' | 'error';
|
|
4
|
+
message: string;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
}
|
|
7
|
+
export interface WebViewNavState {
|
|
8
|
+
url: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}
|
|
12
|
+
export declare const addWebViewLog: (type: "log" | "info" | "warn" | "error", message: string) => void;
|
|
13
|
+
export declare const addWebViewNav: (url: string, title?: string) => void;
|
|
14
|
+
export declare const addWebViewHtml: (url: string, html: string, css?: string, js?: string) => void;
|
|
15
|
+
export declare const getWebViewLogs: () => WebViewLog[];
|
|
16
|
+
export declare const getWebViewNavHistory: () => WebViewNavState[];
|
|
17
|
+
export declare const getWebViewHtml: () => string;
|
|
18
|
+
export declare const getWebViewCss: () => string;
|
|
19
|
+
export declare const getWebViewJs: () => string;
|
|
20
|
+
export declare const getWebViewHtmlUrl: () => string;
|
|
21
|
+
export declare const clearWebViewData: () => void;
|
|
22
|
+
export declare const subscribeWebView: (cb: () => void) => () => void;
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
// Intercept react-native-webview exports to capture console logs and URL navigation changes globally
|
|
3
|
+
try {
|
|
4
|
+
const RNWebView = require('react-native-webview');
|
|
5
|
+
const OriginalWebView = RNWebView.WebView || RNWebView.default;
|
|
6
|
+
if (OriginalWebView) {
|
|
7
|
+
const injectJS = `
|
|
8
|
+
(function() {
|
|
9
|
+
if (!window.__webview_console_overridden__) {
|
|
10
|
+
window.__webview_console_overridden__ = true;
|
|
11
|
+
var originalLog = console.log;
|
|
12
|
+
var originalWarn = console.warn;
|
|
13
|
+
var originalError = console.error;
|
|
14
|
+
var originalInfo = console.info;
|
|
15
|
+
|
|
16
|
+
var sendToRN = function(type, args) {
|
|
17
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
18
|
+
var messageStr = '';
|
|
19
|
+
try {
|
|
20
|
+
var argsList = [];
|
|
21
|
+
for (var i = 0; i < args.length; i++) {
|
|
22
|
+
var arg = args[i];
|
|
23
|
+
if (typeof arg === 'object') {
|
|
24
|
+
try {
|
|
25
|
+
argsList.push(JSON.stringify(arg));
|
|
26
|
+
} catch (e) {
|
|
27
|
+
argsList.push(String(arg));
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
argsList.push(String(arg));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
messageStr = argsList.join(' ');
|
|
34
|
+
} catch (err) {
|
|
35
|
+
messageStr = String(args);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
40
|
+
type: 'webview-log',
|
|
41
|
+
logType: type,
|
|
42
|
+
message: messageStr
|
|
43
|
+
}));
|
|
44
|
+
} catch (postErr) {}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
console.log = function() {
|
|
49
|
+
if (originalLog) {
|
|
50
|
+
originalLog.apply(console, arguments);
|
|
51
|
+
}
|
|
52
|
+
sendToRN('log', arguments);
|
|
53
|
+
};
|
|
54
|
+
console.warn = function() {
|
|
55
|
+
if (originalWarn) {
|
|
56
|
+
originalWarn.apply(console, arguments);
|
|
57
|
+
}
|
|
58
|
+
sendToRN('warn', arguments);
|
|
59
|
+
};
|
|
60
|
+
console.error = function() {
|
|
61
|
+
if (originalError) {
|
|
62
|
+
originalError.apply(console, arguments);
|
|
63
|
+
}
|
|
64
|
+
sendToRN('error', arguments);
|
|
65
|
+
};
|
|
66
|
+
console.info = function() {
|
|
67
|
+
if (originalInfo) {
|
|
68
|
+
originalInfo.apply(console, arguments);
|
|
69
|
+
}
|
|
70
|
+
sendToRN('info', arguments);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!window.__webview_html_capture_setup__) {
|
|
75
|
+
window.__webview_html_capture_setup__ = true;
|
|
76
|
+
|
|
77
|
+
var sendHtmlRetries = 0;
|
|
78
|
+
window.__webview_send_html__ = function() {
|
|
79
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
80
|
+
try {
|
|
81
|
+
var html = '';
|
|
82
|
+
try {
|
|
83
|
+
if (document && document.documentElement) {
|
|
84
|
+
html = document.documentElement.outerHTML || '';
|
|
85
|
+
}
|
|
86
|
+
} catch (e) {}
|
|
87
|
+
|
|
88
|
+
// Get CSS
|
|
89
|
+
var css = '';
|
|
90
|
+
try {
|
|
91
|
+
var sheets = document.styleSheets;
|
|
92
|
+
if (sheets) {
|
|
93
|
+
for (var i = 0; i < sheets.length; i++) {
|
|
94
|
+
var sheet = sheets[i];
|
|
95
|
+
try {
|
|
96
|
+
var rules = sheet.cssRules || sheet.rules;
|
|
97
|
+
if (rules) {
|
|
98
|
+
for (var j = 0; j < rules.length; j++) {
|
|
99
|
+
css += rules[j].cssText + String.fromCharCode(10);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
if (sheet.href) {
|
|
104
|
+
css += '/* External stylesheet: ' + sheet.href + ' */' + String.fromCharCode(10);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} catch (e) {}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
var styles = document.querySelectorAll('style');
|
|
113
|
+
if (styles) {
|
|
114
|
+
for (var i = 0; i < styles.length; i++) {
|
|
115
|
+
var style = styles[i];
|
|
116
|
+
if (style && style.textContent) {
|
|
117
|
+
if (css.indexOf(style.textContent) === -1) {
|
|
118
|
+
css += style.textContent + String.fromCharCode(10);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch (e) {}
|
|
124
|
+
|
|
125
|
+
// Get JS
|
|
126
|
+
var js = '';
|
|
127
|
+
try {
|
|
128
|
+
var scripts = document.querySelectorAll('script');
|
|
129
|
+
if (scripts) {
|
|
130
|
+
for (var i = 0; i < scripts.length; i++) {
|
|
131
|
+
var script = scripts[i];
|
|
132
|
+
if (script) {
|
|
133
|
+
if (script.src) {
|
|
134
|
+
js += '// External Script: ' + script.src + String.fromCharCode(10);
|
|
135
|
+
} else if (script.textContent) {
|
|
136
|
+
js += script.textContent + String.fromCharCode(10);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} catch (e) {}
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
145
|
+
type: 'webview-html',
|
|
146
|
+
html: html,
|
|
147
|
+
css: css,
|
|
148
|
+
js: js,
|
|
149
|
+
url: window.location.href
|
|
150
|
+
}));
|
|
151
|
+
} catch (postError) {
|
|
152
|
+
try {
|
|
153
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
154
|
+
type: 'webview-html',
|
|
155
|
+
html: html,
|
|
156
|
+
css: '/* CSS truncated due to size limit */',
|
|
157
|
+
js: '/* JS truncated due to size limit */',
|
|
158
|
+
url: window.location.href
|
|
159
|
+
}));
|
|
160
|
+
} catch (htmlOnlyError) {
|
|
161
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
162
|
+
type: 'webview-html',
|
|
163
|
+
html: '<h1>Page source too large to capture</h1>',
|
|
164
|
+
url: window.location.href
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} catch (err) {}
|
|
169
|
+
} else if (sendHtmlRetries < 50) {
|
|
170
|
+
sendHtmlRetries++;
|
|
171
|
+
setTimeout(window.__webview_send_html__, 100);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
var debounceTimeout = null;
|
|
176
|
+
window.__webview_debounced_send_html__ = function() {
|
|
177
|
+
if (debounceTimeout) {
|
|
178
|
+
clearTimeout(debounceTimeout);
|
|
179
|
+
}
|
|
180
|
+
debounceTimeout = setTimeout(window.__webview_send_html__, 500);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Setup MutationObserver for SPAs
|
|
184
|
+
try {
|
|
185
|
+
var observer = new MutationObserver(function() {
|
|
186
|
+
window.__webview_debounced_send_html__();
|
|
187
|
+
});
|
|
188
|
+
observer.observe(document.documentElement, {
|
|
189
|
+
attributes: true,
|
|
190
|
+
childList: true,
|
|
191
|
+
subtree: true
|
|
192
|
+
});
|
|
193
|
+
} catch (e) {}
|
|
194
|
+
|
|
195
|
+
// Setup SPA router state changes
|
|
196
|
+
try {
|
|
197
|
+
var originalPushState = history.pushState;
|
|
198
|
+
history.pushState = function() {
|
|
199
|
+
originalPushState.apply(this, arguments);
|
|
200
|
+
window.__webview_debounced_send_html__();
|
|
201
|
+
};
|
|
202
|
+
var originalReplaceState = history.replaceState;
|
|
203
|
+
history.replaceState = function() {
|
|
204
|
+
originalReplaceState.apply(this, arguments);
|
|
205
|
+
window.__webview_debounced_send_html__();
|
|
206
|
+
};
|
|
207
|
+
window.addEventListener('popstate', window.__webview_debounced_send_html__);
|
|
208
|
+
window.addEventListener('hashchange', window.__webview_debounced_send_html__);
|
|
209
|
+
} catch (e) {}
|
|
210
|
+
|
|
211
|
+
window.addEventListener('DOMContentLoaded', window.__webview_send_html__);
|
|
212
|
+
window.addEventListener('load', window.__webview_send_html__);
|
|
213
|
+
if (document.readyState === 'interactive' || document.readyState === 'complete') {
|
|
214
|
+
window.__webview_send_html__();
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
if (window.__webview_send_html__) {
|
|
218
|
+
window.__webview_send_html__();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
})();
|
|
222
|
+
true;
|
|
223
|
+
`;
|
|
224
|
+
const InterceptedWebView = forwardRef((props, ref) => {
|
|
225
|
+
const handleMessage = (event) => {
|
|
226
|
+
try {
|
|
227
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
228
|
+
if (data.type === 'webview-log') {
|
|
229
|
+
addWebViewLog(data.logType, data.message);
|
|
230
|
+
}
|
|
231
|
+
else if (data.type === 'webview-html') {
|
|
232
|
+
addWebViewHtml(data.url, data.html, data.css, data.js);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (e) { }
|
|
236
|
+
if (props.onMessage) {
|
|
237
|
+
props.onMessage(event);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const handleNavigationStateChange = (navState) => {
|
|
241
|
+
addWebViewNav(navState.url, navState.title);
|
|
242
|
+
if (props.onNavigationStateChange) {
|
|
243
|
+
props.onNavigationStateChange(navState);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
// Register initial URL
|
|
247
|
+
React.useEffect(() => {
|
|
248
|
+
if (props.source && props.source.uri) {
|
|
249
|
+
addWebViewNav(props.source.uri, 'Initial Page');
|
|
250
|
+
}
|
|
251
|
+
}, [props.source?.uri]);
|
|
252
|
+
const combinedInjectedJSBefore = props.injectedJavaScriptBeforeContentLoaded
|
|
253
|
+
? `${injectJS}\n${props.injectedJavaScriptBeforeContentLoaded}`
|
|
254
|
+
: injectJS;
|
|
255
|
+
const combinedInjectedJS = props.injectedJavaScript
|
|
256
|
+
? `${injectJS}\n${props.injectedJavaScript}`
|
|
257
|
+
: injectJS;
|
|
258
|
+
return React.createElement(OriginalWebView, {
|
|
259
|
+
...props,
|
|
260
|
+
ref: ref,
|
|
261
|
+
injectedJavaScriptBeforeContentLoaded: combinedInjectedJSBefore,
|
|
262
|
+
injectedJavaScript: combinedInjectedJS,
|
|
263
|
+
onMessage: handleMessage,
|
|
264
|
+
onNavigationStateChange: handleNavigationStateChange,
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
// Replace properties on required module singleton to redirect all imports globally
|
|
268
|
+
const defineProp = (obj, prop, value) => {
|
|
269
|
+
try {
|
|
270
|
+
Object.defineProperty(obj, prop, {
|
|
271
|
+
value: value,
|
|
272
|
+
configurable: true,
|
|
273
|
+
writable: true,
|
|
274
|
+
enumerable: true,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch (e) {
|
|
278
|
+
try {
|
|
279
|
+
obj[prop] = value;
|
|
280
|
+
}
|
|
281
|
+
catch (err) { }
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
if (RNWebView.WebView) {
|
|
285
|
+
defineProp(RNWebView, 'WebView', InterceptedWebView);
|
|
286
|
+
}
|
|
287
|
+
if (RNWebView.default) {
|
|
288
|
+
if (RNWebView.default.WebView) {
|
|
289
|
+
defineProp(RNWebView.default, 'WebView', InterceptedWebView);
|
|
290
|
+
}
|
|
291
|
+
defineProp(RNWebView, 'default', InterceptedWebView);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch (e) {
|
|
296
|
+
// Silent fail if react-native-webview is not resolved
|
|
297
|
+
}
|
|
298
|
+
let logs = [];
|
|
299
|
+
let navHistory = [];
|
|
300
|
+
let currentHtml = '';
|
|
301
|
+
let currentCss = '';
|
|
302
|
+
let currentJs = '';
|
|
303
|
+
let currentHtmlUrl = '';
|
|
304
|
+
let listeners = [];
|
|
305
|
+
let counter = 0;
|
|
306
|
+
const notify = () => {
|
|
307
|
+
const snapshotLogs = [...logs];
|
|
308
|
+
const snapshotHistory = [...navHistory];
|
|
309
|
+
listeners.forEach(cb => cb());
|
|
310
|
+
};
|
|
311
|
+
export const addWebViewLog = (type, message) => {
|
|
312
|
+
logs.unshift({
|
|
313
|
+
id: counter++,
|
|
314
|
+
type,
|
|
315
|
+
message,
|
|
316
|
+
timestamp: Date.now(),
|
|
317
|
+
});
|
|
318
|
+
logs = logs.slice(0, 100);
|
|
319
|
+
notify();
|
|
320
|
+
};
|
|
321
|
+
export const addWebViewNav = (url, title) => {
|
|
322
|
+
// Prevent duplicate consecutive navigation events for the same URL
|
|
323
|
+
if (navHistory.length > 0 && navHistory[0].url === url) {
|
|
324
|
+
if (title && !navHistory[0].title) {
|
|
325
|
+
navHistory[0].title = title;
|
|
326
|
+
notify();
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
navHistory.unshift({
|
|
331
|
+
url,
|
|
332
|
+
title,
|
|
333
|
+
timestamp: Date.now(),
|
|
334
|
+
});
|
|
335
|
+
navHistory = navHistory.slice(0, 50);
|
|
336
|
+
notify();
|
|
337
|
+
};
|
|
338
|
+
export const addWebViewHtml = (url, html, css, js) => {
|
|
339
|
+
currentHtml = html;
|
|
340
|
+
currentCss = css || '';
|
|
341
|
+
currentJs = js || '';
|
|
342
|
+
currentHtmlUrl = url;
|
|
343
|
+
notify();
|
|
344
|
+
};
|
|
345
|
+
export const getWebViewLogs = () => [...logs];
|
|
346
|
+
export const getWebViewNavHistory = () => [...navHistory];
|
|
347
|
+
export const getWebViewHtml = () => currentHtml;
|
|
348
|
+
export const getWebViewCss = () => currentCss;
|
|
349
|
+
export const getWebViewJs = () => currentJs;
|
|
350
|
+
export const getWebViewHtmlUrl = () => currentHtmlUrl;
|
|
351
|
+
export const clearWebViewData = () => {
|
|
352
|
+
logs = [];
|
|
353
|
+
navHistory = [];
|
|
354
|
+
currentHtml = '';
|
|
355
|
+
currentCss = '';
|
|
356
|
+
currentJs = '';
|
|
357
|
+
currentHtmlUrl = '';
|
|
358
|
+
notify();
|
|
359
|
+
};
|
|
360
|
+
export const subscribeWebView = (cb) => {
|
|
361
|
+
listeners.push(cb);
|
|
362
|
+
return () => {
|
|
363
|
+
listeners = listeners.filter(l => l !== cb);
|
|
364
|
+
};
|
|
365
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { NetworkLog, RouteInfo, DiffResult } from '../types';
|
|
2
|
+
export declare const getDomainColor: (domain: string) => string;
|
|
3
|
+
export declare const formatDateTime: (timestamp: number) => string;
|
|
4
|
+
export declare const getStatusColor: (status: number | null) => string;
|
|
5
|
+
export declare const getDurationColor: (duration: number | null) => string;
|
|
6
|
+
export declare const getSize: (data: unknown) => string;
|
|
7
|
+
export declare const copyToClipboard: (value: unknown, label: string) => void;
|
|
8
|
+
export declare const getPath: (url: string) => string;
|
|
9
|
+
export declare const getCurlCommand: (log: NetworkLog) => string;
|
|
10
|
+
export declare const getFetchCommand: (log: NetworkLog) => string;
|
|
11
|
+
export declare const deduplicateLogs: (raw: NetworkLog[]) => NetworkLog[];
|
|
12
|
+
export declare const escapeRegex: (str: string) => string;
|
|
13
|
+
export declare const getNavigationInfo: (state: any, path?: string[]) => RouteInfo;
|
|
14
|
+
export declare const flattenObject: (obj: any, prefix?: string) => Record<string, any>;
|
|
15
|
+
export declare const getDiff: (oldObj: any, newObj: any) => DiffResult[];
|
|
16
|
+
export declare const formatDisplayUrl: (url: string) => string;
|
|
17
|
+
export declare const getLocalizedFilePath: (path: string | any, country: string | any, language: string | any) => any;
|
|
18
|
+
export declare const getLocalizedFilePathWithSlash: (path: string | any, country: string | any, language: string | any) => any;
|
|
19
|
+
export declare const isAllValuesEmpty: (obj: Record<string, any>) => boolean;
|
|
20
|
+
export declare const formatDateTimeToAnalytics: (ts: number) => string;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Clipboard, Platform, ToastAndroid, Alert } from 'react-native';
|
|
2
|
+
// Stylesheet
|
|
3
|
+
import { AppColors } from '../styles/AppColors';
|
|
4
|
+
// Constants
|
|
5
|
+
import { DOMAIN_COLORS, DURATION_FAST_MS, DURATION_SLOW_MS } from '../constants';
|
|
6
|
+
export const getDomainColor = (domain) => {
|
|
7
|
+
if (!domain)
|
|
8
|
+
return DOMAIN_COLORS[0];
|
|
9
|
+
let hash = 0;
|
|
10
|
+
for (let i = 0; i < domain.length; i++) {
|
|
11
|
+
hash = domain.charCodeAt(i) + ((hash << 5) - hash);
|
|
12
|
+
}
|
|
13
|
+
return DOMAIN_COLORS[Math.abs(hash) % DOMAIN_COLORS.length];
|
|
14
|
+
};
|
|
15
|
+
export const formatDateTime = (timestamp) => {
|
|
16
|
+
const date = new Date(timestamp);
|
|
17
|
+
const pad = (n, len = 2) => String(n).padStart(len, '0');
|
|
18
|
+
const day = pad(date.getDate());
|
|
19
|
+
const month = pad(date.getMonth() + 1);
|
|
20
|
+
const year = date.getFullYear();
|
|
21
|
+
const hours = pad(date.getHours());
|
|
22
|
+
const minutes = pad(date.getMinutes());
|
|
23
|
+
const seconds = pad(date.getSeconds());
|
|
24
|
+
return `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`;
|
|
25
|
+
};
|
|
26
|
+
export const getStatusColor = (status) => {
|
|
27
|
+
if (!status || status === 0)
|
|
28
|
+
return AppColors.errorColor;
|
|
29
|
+
if (status >= 500)
|
|
30
|
+
return AppColors.errorColor;
|
|
31
|
+
if (status >= 400)
|
|
32
|
+
return AppColors.darkOrange;
|
|
33
|
+
if (status >= 300)
|
|
34
|
+
return AppColors.warningIconGold;
|
|
35
|
+
return AppColors.greenColor;
|
|
36
|
+
};
|
|
37
|
+
export const getDurationColor = (duration) => {
|
|
38
|
+
if (duration == null)
|
|
39
|
+
return AppColors.grayTextWeak;
|
|
40
|
+
if (duration < DURATION_FAST_MS)
|
|
41
|
+
return AppColors.greenColor;
|
|
42
|
+
if (duration < DURATION_SLOW_MS)
|
|
43
|
+
return AppColors.lightOrange;
|
|
44
|
+
return AppColors.errorColor;
|
|
45
|
+
};
|
|
46
|
+
export const getSize = (data) => {
|
|
47
|
+
try {
|
|
48
|
+
const bytes = JSON.stringify(data)?.length ?? 0;
|
|
49
|
+
return bytes < 1024 ? `${bytes} B` : `${(bytes / 1024).toFixed(1)} KB`;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return '—';
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export const copyToClipboard = (value, label) => {
|
|
56
|
+
const text = typeof value === 'string' ? value : JSON.stringify(value, null, 2);
|
|
57
|
+
Clipboard.setString(text ?? '');
|
|
58
|
+
if (Platform.OS === 'android') {
|
|
59
|
+
ToastAndroid.show(`${label} copied`, ToastAndroid.SHORT);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
Alert.alert('Copied', `${label} copied to clipboard`, [{ text: 'OK' }]);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
export const getPath = (url) => {
|
|
66
|
+
try {
|
|
67
|
+
const u = new URL(url);
|
|
68
|
+
return u.pathname + (u.search ? u.search : '');
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
const withoutDomain = url.replace(/^https?:\/\/[^/?#]+/, '');
|
|
72
|
+
return withoutDomain || '/';
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
export const getCurlCommand = (log) => {
|
|
76
|
+
let cmd = `curl -X ${log.method} "${log.url}"`;
|
|
77
|
+
if (log.requestHeaders) {
|
|
78
|
+
Object.entries(log.requestHeaders).forEach(([k, v]) => {
|
|
79
|
+
cmd += ` \\\n -H "${k}: ${v}"`;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (log.request && log.method !== 'GET') {
|
|
83
|
+
const body = typeof log.request === 'string'
|
|
84
|
+
? log.request
|
|
85
|
+
: JSON.stringify(log.request);
|
|
86
|
+
cmd += ` \\\n -d '${body.replace(/'/g, "'\\''")}'`;
|
|
87
|
+
}
|
|
88
|
+
return cmd;
|
|
89
|
+
};
|
|
90
|
+
export const getFetchCommand = (log) => {
|
|
91
|
+
const opts = { method: log.method };
|
|
92
|
+
if (log.requestHeaders && Object.keys(log.requestHeaders).length > 0) {
|
|
93
|
+
opts.headers = log.requestHeaders;
|
|
94
|
+
}
|
|
95
|
+
if (log.request && log.method !== 'GET') {
|
|
96
|
+
opts.body = JSON.stringify(log.request);
|
|
97
|
+
}
|
|
98
|
+
return `fetch("${log.url}", ${JSON.stringify(opts, null, 2)})`;
|
|
99
|
+
};
|
|
100
|
+
export const deduplicateLogs = (raw) => {
|
|
101
|
+
const map = new Map();
|
|
102
|
+
raw.forEach(entry => {
|
|
103
|
+
if (!map.has(entry.id) || entry.status != null) {
|
|
104
|
+
map.set(entry.id, entry);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return Array.from(map.values()).sort((a, b) => b.id - a.id);
|
|
108
|
+
};
|
|
109
|
+
export const escapeRegex = (str) => {
|
|
110
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
111
|
+
};
|
|
112
|
+
export const getNavigationInfo = (state, path = []) => {
|
|
113
|
+
if (!state?.routes) {
|
|
114
|
+
return {
|
|
115
|
+
path: path.length > 0 ? path.join(' ➔ ') : 'Navigators',
|
|
116
|
+
params: null,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const route = state.routes[state.index ?? 0];
|
|
120
|
+
if (!route) {
|
|
121
|
+
return {
|
|
122
|
+
path: path.length > 0 ? path.join(' ➔ ') : 'Navigators',
|
|
123
|
+
params: null,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const currentPath = route.name ? [...path, route.name] : path;
|
|
127
|
+
if (route?.state) {
|
|
128
|
+
return getNavigationInfo(route.state, currentPath);
|
|
129
|
+
}
|
|
130
|
+
const resolved = currentPath.length > 0 ? currentPath.join(' ➔ ') : 'Navigators';
|
|
131
|
+
return { path: resolved, params: route.params || null };
|
|
132
|
+
};
|
|
133
|
+
export const flattenObject = (obj, prefix = '') => {
|
|
134
|
+
let result = {};
|
|
135
|
+
if (typeof obj === 'object' && obj !== null) {
|
|
136
|
+
if (Array.isArray(obj)) {
|
|
137
|
+
obj.forEach((v, i) => {
|
|
138
|
+
Object.assign(result, flattenObject(v, prefix ? `${prefix}[${i}]` : `[${i}]`));
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
Object.keys(obj).forEach(k => {
|
|
143
|
+
Object.assign(result, flattenObject(obj[k], prefix ? `${prefix}.${k}` : k));
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
result[prefix || 'root'] = obj;
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
};
|
|
152
|
+
export const getDiff = (oldObj, newObj) => {
|
|
153
|
+
const oldFlat = flattenObject(oldObj);
|
|
154
|
+
const newFlat = flattenObject(newObj);
|
|
155
|
+
const diff = [];
|
|
156
|
+
const allKeys = new Set([...Object.keys(oldFlat), ...Object.keys(newFlat)]);
|
|
157
|
+
allKeys.forEach(k => {
|
|
158
|
+
if (!(k in oldFlat)) {
|
|
159
|
+
diff.push({ type: 'added', path: k, newVal: newFlat[k] });
|
|
160
|
+
}
|
|
161
|
+
else if (!(k in newFlat)) {
|
|
162
|
+
diff.push({ type: 'removed', path: k, oldVal: oldFlat[k] });
|
|
163
|
+
}
|
|
164
|
+
else if (oldFlat[k] !== newFlat[k]) {
|
|
165
|
+
diff.push({
|
|
166
|
+
type: 'changed',
|
|
167
|
+
path: k,
|
|
168
|
+
oldVal: oldFlat[k],
|
|
169
|
+
newVal: newFlat[k],
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return diff.sort((a, b) => a.path.localeCompare(b.path));
|
|
174
|
+
};
|
|
175
|
+
export const formatDisplayUrl = (url) => {
|
|
176
|
+
if (!url)
|
|
177
|
+
return '';
|
|
178
|
+
if (url.startsWith('http://') || url.startsWith('https://'))
|
|
179
|
+
return url;
|
|
180
|
+
return `https://${url}`;
|
|
181
|
+
};
|
|
182
|
+
export const getLocalizedFilePath = (path, country, language) => {
|
|
183
|
+
const url = path.replace('country-language', `${country?.toLowerCase()}-${language?.toLowerCase()}`);
|
|
184
|
+
return url;
|
|
185
|
+
};
|
|
186
|
+
export const getLocalizedFilePathWithSlash = (path, country, language) => {
|
|
187
|
+
const url = path.replace('country/language', `${country?.toLowerCase()}/${language?.toLowerCase()}`);
|
|
188
|
+
return url;
|
|
189
|
+
};
|
|
190
|
+
export const isAllValuesEmpty = (obj) => {
|
|
191
|
+
if (!obj || typeof obj !== 'object')
|
|
192
|
+
return true;
|
|
193
|
+
return Object.values(obj).every(value => value &&
|
|
194
|
+
typeof value === 'object' &&
|
|
195
|
+
!Array.isArray(value) &&
|
|
196
|
+
Object.keys(value).length === 0);
|
|
197
|
+
};
|
|
198
|
+
export const formatDateTimeToAnalytics = (ts) => {
|
|
199
|
+
const d = new Date(ts);
|
|
200
|
+
return d?.toLocaleString(undefined, {
|
|
201
|
+
month: 'short',
|
|
202
|
+
day: 'numeric',
|
|
203
|
+
hour: '2-digit',
|
|
204
|
+
minute: '2-digit',
|
|
205
|
+
second: '2-digit',
|
|
206
|
+
});
|
|
207
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare const NetworkInspector: () => React.JSX.Element;
|
|
3
|
+
export default NetworkInspector;
|
|
4
|
+
export { setupNetworkLogger, clearNetworkLogs, subscribeNetworkLogs, } from './customHooks/networkLogger';
|
|
5
|
+
export { setupConsoleLogger, clearConsoleLogs, subscribeConsoleLogs, } from './customHooks/consoleLogger';
|
|
6
|
+
export { setupAnalyticsLogger, logAnalyticsEvent, subscribeAnalyticsEvents, clearAnalyticsEvents, } from './customHooks/analyticsLogger';
|
|
7
|
+
export { getWebViewLogs, getWebViewNavHistory, getWebViewHtml, getWebViewCss, getWebViewJs, getWebViewHtmlUrl, clearWebViewData, subscribeWebView, } from './customHooks/webViewLogger';
|