= ({ title, items }) => {
{items.map(({ name, value }, index) => (
- {name}: {value}
+ {name}:{' '}
+
+ {value}
+
))}
diff --git a/src/components/list/DropContainer.tsx b/src/components/list/DropContainer.tsx
index d3a02d3..5a3563d 100644
--- a/src/components/list/DropContainer.tsx
+++ b/src/components/list/DropContainer.tsx
@@ -10,6 +10,7 @@ import { createUseStyles } from 'react-jss';
import ContentOnlyItem from '../../models/ContentOnlyItem';
import { ItemType } from '../../models/types';
import TransactionItem from '../../models/TransactionItem';
+import { toast } from 'react-toastify';
const useStyles = createUseStyles({
dropZone: {
@@ -29,52 +30,55 @@ export const DropContainer: FC = ({ children }) => {
const [{ canDrop, isOver }, dropRef] = useDrop(
() => ({
accept: [NativeTypes.FILE],
- drop(item: { files: File[] }) {
+ async drop(item: { files: File[] }) {
const file = item.files[0];
- if (isFileSupported(file.name)) {
- parseFile(file).then(
- (log) => {
- if (log?.log?.entries) {
- try {
- setList(
- [
- new ContentOnlyItem({
- timestamp: new Date().getTime(),
- tag: 'NET LOGS',
- content: `Opened file "${file.name}"`
- }),
- ...log.log.entries.map(
- (request) => {
- let ItemContstructor;
- switch (request.comment) {
- case ItemType.ContentOnly:
- ItemContstructor = ContentOnlyItem;
- break;
- case ItemType.Transaction:
- ItemContstructor = TransactionItem;
- break;
- default:
- ItemContstructor = NetworkItem;
- }
- return ItemContstructor.fromJSON(
- request
- );
- }
- )
- ],
- false
- );
- } catch (e) {
- window.alert('Invalid har file');
+ if (!isFileSupported(file.name)) {
+ toast.error('Only json files are supported');
+ }
+ let log: Har | null = null;
+ const toastId = toast('Loading file...');
+ try {
+ log = await parseFile(file);
+ toast.dismiss(toastId);
+ } catch (e) {
+ toast.dismiss(toastId);
+ toast.error('Error parsing file');
+ }
+ if (!log) {
+ return;
+ }
+ if (!log?.log?.entries) {
+ toast.error('Invalid har file');
+ return;
+ }
+ try {
+ setList(
+ [
+ new ContentOnlyItem({
+ timestamp: new Date().getTime(),
+ tag: 'NET LOGS',
+ content: `Opened file "${file.name}"`
+ }),
+ ...log.log.entries.map((request) => {
+ let ItemConstructor;
+ switch (request.comment) {
+ case ItemType.ContentOnly:
+ ItemConstructor = ContentOnlyItem;
+ break;
+ case ItemType.Transaction:
+ ItemConstructor = TransactionItem;
+ break;
+ default:
+ ItemConstructor = NetworkItem;
}
- } else {
- window.alert('Invalid har file');
- }
- },
- (e) => window.alert(`Error parsing file ${e.message}`)
+ return ItemConstructor.fromJSON(request);
+ })
+ ],
+ false
);
- } else {
- window.alert('Only json files are supported');
+ } catch (e) {
+ console.log('Error occurred:', e);
+ toast.error('Invalid har file');
}
},
collect: (monitor) => ({
diff --git a/src/controllers/network.ts b/src/controllers/network.ts
index c55f1c3..c87bc8c 100644
--- a/src/controllers/network.ts
+++ b/src/controllers/network.ts
@@ -19,14 +19,28 @@ type TStore = {
setList: (newList: ItemList, isDynamic?: boolean) => void;
};
-export const useListStore = create((set) => ({
+export const useListStore = create((set, get) => ({
list: [],
isDynamic: true,
isPreserve: false,
mimeTypes: new Set(),
clear: () => set({ list: [], isDynamic: true, mimeTypes: new Set() }),
- setList: (newList: ItemList, isDynamic = true) =>
- set({ list: newList, isDynamic })
+ setList: (newList: ItemList, isDynamic = true) => {
+ const newState = {
+ list: newList,
+ isDynamic,
+ mimeTypes: new Set([...get().mimeTypes])
+ };
+ if (!isDynamic) {
+ newList.forEach((request) => {
+ const mimeType = request.toJSON().response.content.mimeType;
+ if (mimeType && !newState.mimeTypes.has(mimeType)) {
+ newState.mimeTypes.add(mimeType);
+ }
+ });
+ }
+ set(newState);
+ }
}));
class Network {
diff --git a/src/controllers/settings/profiles/default.ts b/src/controllers/settings/profiles/default.ts
index 4763f30..9961bf2 100644
--- a/src/controllers/settings/profiles/default.ts
+++ b/src/controllers/settings/profiles/default.ts
@@ -20,7 +20,10 @@ export const defaultProfile: IProfile = {
let params;
const postData = request.request.postData;
const method = request.request.method;
- if ((method === 'POST' || method === 'PATCH') && postData) {
+ if (
+ (method === 'POST' || method === 'PATCH' || method === 'PUT') &&
+ postData
+ ) {
if (postData.text) {
try {
params = JSON.parse(postData.text);
diff --git a/src/sandboxUtils.ts b/src/sandboxUtils.ts
index f838768..a3ed6fc 100644
--- a/src/sandboxUtils.ts
+++ b/src/sandboxUtils.ts
@@ -117,7 +117,14 @@ export async function wrapSandbox(): Promise {
window.chrome?.devtools.inspectedWindow.reload({});
break;
case 'download':
- downloadAsZip(data);
+ downloadAsZip(data).finally(() => {
+ postSandbox({
+ id,
+ type,
+ data: ''
+ });
+ resolve();
+ });
break;
default:
console.warn(`Unrecognized type ${type}`);
@@ -127,18 +134,20 @@ export async function wrapSandbox(): Promise {
});
}
-function downloadAsZip(dataString: string): void {
+function downloadAsZip(dataString: string): Promise {
const { fileName, data } = JSON.parse(dataString);
// const blob = new Blob([data], { type: 'application/json' });
const zip = new JSZip();
zip.file(`${fileName}.har`, data);
- zip.generateAsync({
- type: 'blob',
- compression: 'DEFLATE',
- compressionOptions: {
- level: 9
- }
- }).then((content) => {
- download(`${fileName}.netlogs.zip`, content);
- });
+ return zip
+ .generateAsync({
+ type: 'blob',
+ compression: 'DEFLATE',
+ compressionOptions: {
+ level: 9
+ }
+ })
+ .then((content) => {
+ download(`${fileName}.netlogs.zip`, content);
+ });
}
diff --git a/yarn.lock b/yarn.lock
index beaa683..b3663b0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8247,7 +8247,7 @@ number-is-nan@^1.0.0:
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
+ integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
object-copy@^0.1.0:
version "0.1.0"
@@ -9379,6 +9379,13 @@ react-textarea-autosize@^8.3.0:
use-composed-ref "^1.0.0"
use-latest "^1.0.0"
+react-toastify@9.1.3:
+ version "9.1.3"
+ resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff"
+ integrity sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==
+ dependencies:
+ clsx "^1.1.1"
+
react-universal-interface@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b"