Skip to content

Commit

Permalink
Add hacky GraphQL operation name display (#10610)
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson authored Jul 14, 2024
1 parent 4cc1d67 commit 59132a7
Showing 1 changed file with 60 additions and 3 deletions.
63 changes: 60 additions & 3 deletions src/ui/components/NetworkMonitor/NetworkMonitorListRow.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { CSSProperties, MouseEvent, useContext } from "react";
import { CSSProperties, MouseEvent, useContext, useEffect, useState } from "react";

import Icon from "replay-next/components/Icon";
import { SessionContext } from "replay-next/src/contexts/SessionContext";
import { useNag } from "replay-next/src/hooks/useNag";
import { networkRequestBodyCache } from "replay-next/src/suspense/NetworkRequestsCache";
import { ReplayClientContext } from "shared/client/ReplayClientContext";
import { Nag } from "shared/graphql/types";
import useNetworkContextMenu from "ui/components/NetworkMonitor/useNetworkContextMenu";
import { EnabledColumns } from "ui/components/NetworkMonitor/useNetworkMonitorColumns";
import { RequestSummary } from "ui/components/NetworkMonitor/utils";
import { RequestSummary, findHeader } from "ui/components/NetworkMonitor/utils";

import {
BodyPartsToUInt8Array,
Displayable,
RawToImageMaybe,
RawToUTF8,
StringToObjectMaybe,
URLEncodedToPlaintext,
} from "./content";
import styles from "./NetworkMonitorListRow.module.css";

export const LIST_ROW_HEIGHT = 26;
Expand Down Expand Up @@ -56,6 +66,21 @@ export function NetworkMonitorListRow({
}
}

function isLikelyGraphQLRequest(request: RequestSummary): boolean {
// TODO Hacky heuristic here, improve this?
return request.path.includes("graphql") || request.url.includes("graphql");
}

interface GraphqlOperationBody {
operationName: string;
variables: Record<string, unknown>;
query?: string;
}

function isGraphqlOperationBody(value: unknown): value is GraphqlOperationBody {
return typeof value === "object" && value !== null && "operationName" in value;
}

function RequestRow({
itemData,
request,
Expand All @@ -65,6 +90,7 @@ function RequestRow({
request: RequestSummary;
style: CSSProperties;
}) {
const [graphqlOperationName, setGraphqlOperationName] = useState<string | null>(null);
const {
columns,
currentTime,
Expand All @@ -74,6 +100,7 @@ function RequestRow({
selectedRequestId,
} = itemData;

const replayClient = useContext(ReplayClientContext);
const { duration: recordingDuration } = useContext(SessionContext);

const {
Expand Down Expand Up @@ -118,6 +145,36 @@ function RequestRow({

const [, dismissJumpToNetworkRequestNag] = useNag(Nag.JUMP_TO_NETWORK_REQUEST);

useEffect(() => {
async function getGraphqlOperationNameIfRelevant() {
if (isLikelyGraphQLRequest(request)) {
const reqBodyStreaming = await networkRequestBodyCache.readAsync(replayClient, request.id);

const value = reqBodyStreaming.value;

if (value) {
const raw = BodyPartsToUInt8Array(
value,
findHeader(request.requestHeaders, "content-type") || "unknown"
);

const displayable = StringToObjectMaybe(
URLEncodedToPlaintext(RawToUTF8(RawToImageMaybe(raw)))
);

if (displayable.as == Displayable.JSON) {
const { content } = displayable;
if (isGraphqlOperationBody(content)) {
setGraphqlOperationName(content.operationName);
}
}
}
}
}

getGraphqlOperationNameIfRelevant();
}, [path, replayClient, request]);

const seekToRequestWrapper = (request: RequestSummary) => {
seekToRequest(request);
dismissJumpToNetworkRequestNag(); // Replay Passport
Expand Down Expand Up @@ -168,7 +225,7 @@ function RequestRow({
)}
{columns.name && (
<div className={styles.Column} data-name="name">
{name}
{name} {graphqlOperationName && `(GraphQL: ${graphqlOperationName})`}
</div>
)}
{columns.method && (
Expand Down

0 comments on commit 59132a7

Please sign in to comment.