Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
purrseus committed Jan 18, 2025
2 parents ee54c54 + e3ee6b7 commit cc58d2d
Show file tree
Hide file tree
Showing 24 changed files with 521 additions and 473 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 purrseus
Copyright (c) 2025 purrseus
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
Expand Down
16 changes: 16 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ function Button({ title, onPress }: { title: string; onPress: () => void }) {
export default function App() {
return (
<View style={styles.container}>
<Button
title="Fetch: Get pokemon"
onPress={() => {
fetch('https://pokeapi.co/api/v2/pokemon/ditto')
.then(res => res.json())
.then(console.log);
}}
/>

<Button
title="Fetch: Get posts"
onPress={() => {
Expand Down Expand Up @@ -42,6 +51,13 @@ export default function App() {
}}
/>

<Button
title="Axios: Get pokemon"
onPress={() => {
axios('https://pokeapi.co/api/v2/pokemon/ditto').then(console.log);
}}
/>

<Button
title="Axios: Get posts"
onPress={() => {
Expand Down
Binary file added src/assets/icons/arrow-left.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/beautify.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/contexts/MainContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface MainContextValue {
debuggerState: DebuggerState;
setDebuggerState: Updater<DebuggerState>;
networkInterceptor: ReturnType<typeof useNetworkInterceptor>;
logInterceptor: ReturnType<typeof useConsoleInterceptor>;
consoleInterceptor: ReturnType<typeof useConsoleInterceptor>;
}

const MainContext = createContext<MainContextValue | null>(null);
Expand Down
12 changes: 0 additions & 12 deletions src/core/data.ts

This file was deleted.

73 changes: 56 additions & 17 deletions src/core/utils.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
import type { HttpRequest } from '../types';
import { NetworkType, type HttpRequest, type WebSocketRequest } from '../types';

export const getNetworkUtils = (data: HttpRequest | WebSocketRequest) => {
const isHttp = data?.type !== NetworkType.WS;
const requestUrl = new URL(data.url);

const overviewShown = !!data.url;
const headersShown = isHttp && (!!data.requestHeaders || !!data.responseHeaders);
const requestShown = isHttp && (!!requestUrl.search || !!data.body);
const responseShown = isHttp && !!data.response;
const messagesShown = !isHttp && !!data.messages;

return {
isHttp,
requestUrl,
overviewShown,
headersShown,
requestShown,
responseShown,
messagesShown,
};
};

//#region metrics
export const getVerticalSafeMargin = (screenHeight: number) => screenHeight / 8;

export const limitChar = (value: any, limit = 5000) => {
const stringValue = typeof value === 'string' ? value : JSON.stringify(value ?? '');

return stringValue.length > limit
? `${stringValue.slice(0, limit)}\n---LIMITED TO ${limit} CHARACTERS---`
: stringValue;
};
export const clamp = (value: number, min: number, max: number) =>
Math.max(min, Math.min(max, value));

export const getHttpInterceptorId = () => {
const timestamp = Date.now().toString(36);
const randomNum = Math.random().toString(36).substring(2, 10);
return timestamp + randomNum;
};
//#endregion

export const clamp = (value: number, min: number, max: number) =>
Math.max(min, Math.min(max, value));
//#region formatters
export const limitChar = (value: any, limit = 5000) => {
const stringValue = typeof value === 'string' ? value : JSON.stringify(value ?? '');

export const keyValueToString = (key: string, value: any): string =>
`${key}: ${limitChar(value)}\n`;
return stringValue.length > limit
? `${stringValue.slice(0, limit)}\n---LIMITED TO ${limit} CHARACTERS---`
: stringValue;
};

export const keyValueToString = (
key: string,
value: any,
newLine: 'leading' | 'trailing' | null = 'trailing',
): string =>
`${newLine === 'leading' ? '\n' : ''}${key}: ${limitChar(value)}${newLine === 'trailing' ? '\n' : ''}`;

export const formatRequestMethod = (method?: string) => method ?? 'GET';

Expand All @@ -30,15 +58,23 @@ export const formatRequestDuration = (duration?: number) =>
export const formatRequestStatusCode = (statusCode?: number) => `${statusCode ?? 'pending'}`;

export const formatLogMessage = (type: string, values: any[]) => {
const message: string = values.reduce((pre, cur, index, array) => {
const isLastItem = index === array.length - 1;

return pre + limitChar(cur) + (isLastItem ? '' : ', ');
}, '');
const message: string = values.reduce(
(pre, cur, index) => pre + (!index ? '' : ', ') + limitChar(cur),
'',
);

return `${type.toUpperCase()}: ${message}`;
};

export const beautify = (data: any, beautified: boolean) => {
try {
const res = typeof data === 'string' ? JSON.parse(data) : data;
return beautified ? JSON.stringify(res, null, 2) : limitChar(res);
} catch (error) {
return limitChar(data);
}
};

export const convertToCurl = (
method: HttpRequest['method'],
url: HttpRequest['url'],
Expand All @@ -60,7 +96,9 @@ export const convertToCurl = (

return curlCommand;
};
//#endregion

//#region decorators
export function frozen(_target: Object) {
const descriptor: PropertyDescriptor = arguments[2];
descriptor.configurable = false;
Expand All @@ -81,3 +119,4 @@ export function singleton<T extends { new (...args: any[]): {} }>(constructor: T

return Singleton;
}
//#endregion
21 changes: 17 additions & 4 deletions src/hooks/useNetworkInterceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,15 @@ export default function useNetworkInterceptor({ autoEnabled }: NetworkIntercepto
setNetworkRequests((draft: NetworkRequests<HttpRequest>) => {
if (!draft.get(id)) return draft;

const currentHeaderLine = keyValueToString(header, value);
const requestHeaderNewLine: Parameters<typeof keyValueToString>[2] = draft.get(id)!
.requestHeadersString?.length
? 'leading'
: null;

const currentHeaderLine = keyValueToString(header, value, requestHeaderNewLine);

const fetchRequestHeaderLineRegex = RegExp(
keyValueToString(NETWORK_REQUEST_HEADER, NetworkType.Fetch),
keyValueToString(NETWORK_REQUEST_HEADER, NetworkType.Fetch, requestHeaderNewLine),
'gi',
);

Expand Down Expand Up @@ -163,7 +168,11 @@ export default function useNetworkInterceptor({ autoEnabled }: NetworkIntercepto
if (!draft.get(`${socketId}`)) return draft;

draft.get(`${socketId}`)!.messages ??= '';
draft.get(`${socketId}`)!.messages += keyValueToString('SENT', data);
draft.get(`${socketId}`)!.messages += keyValueToString(
'SENT',
data,
draft.get(`${socketId}`)!.messages?.length ? 'leading' : null,
);
});
};

Expand Down Expand Up @@ -195,7 +204,11 @@ export default function useNetworkInterceptor({ autoEnabled }: NetworkIntercepto
if (!draft.get(`${socketId}`)) return draft;

draft.get(`${socketId}`)!.messages ??= '';
draft.get(`${socketId}`)!.messages += keyValueToString('RECEIVED', message);
draft.get(`${socketId}`)!.messages += keyValueToString(
'RECEIVED',
message,
draft.get(`${socketId}`)!.messages?.length ? 'leading' : null,
);
});
};

Expand Down
6 changes: 5 additions & 1 deletion src/interceptors/FetchInterceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ export default class FetchInterceptor extends HttpInterceptor {
let responseHeaders: string = '';

for (const [headerKey, headerValue] of clonedResponseHeaders.entries()) {
responseHeaders += keyValueToString(headerKey, headerValue);
responseHeaders += keyValueToString(
headerKey,
headerValue,
responseHeaders.length ? 'leading' : null,
);
}

headerReceivedCallback?.(interceptionId, responseContentType, responseSize, responseHeaders);
Expand Down
1 change: 1 addition & 0 deletions src/theme/colors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const colors = Object.freeze({
black: '#000000',
red: '#ef4444',
green: '#22c55e',
gray: '#888888',
lightGray: '#AAAAAA',
});
Expand Down
3 changes: 3 additions & 0 deletions src/theme/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const icons = Object.freeze({
hide: require('../assets/icons/hide.png'),
move: require('../assets/icons/move.png'),
record: require('../assets/icons/record.png'),
share: require('../assets/icons/share.png'),
arrowLeft: require('../assets/icons/arrow-left.png'),
beautify: require('../assets/icons/beautify.png'),
});

export default icons;
18 changes: 17 additions & 1 deletion src/types/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { HttpRequest, LogMessage, WebSocketRequest } from '.';

export enum NetworkType {
XHR = 'xhr',
Fetch = 'fetch',
Expand All @@ -19,10 +21,24 @@ export interface NetworkRequest {
duration?: number;
}

export type NetworkTab = 'headers' | 'queryStringParameters' | 'body' | 'response' | 'messages';
export type DetailTab = 'overview' | 'headers' | 'request' | 'response' | 'messages' | 'logMessage';

export interface DebuggerState {
visibility: 'hidden' | 'bubble' | 'panel';
position: 'top' | 'bottom';
selectedPanel: DebuggerPanel | null;
detailsData:
| {
type: DebuggerPanel.Network;
data: HttpRequest | WebSocketRequest;
selectedTab: Exclude<DetailTab, 'logMessage'>;
beautified: boolean;
}
| {
type: DebuggerPanel.Console;
data: LogMessage;
selectedTab: Extract<DetailTab, 'logMessage'>;
beautified: boolean;
}
| null;
}
Loading

0 comments on commit cc58d2d

Please sign in to comment.