Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 95 additions & 84 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions packages/bruno-app/src/components/CodeEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ class CodeEditor extends React.Component {
},
'Shift-Tab': 'indentLess',
'Ctrl-Space': (cm) => {
showRootHints(cm, this.props.showHintsFor);
showRootHints(cm, this.props.showHintsFor, this.props.protocol);
},
'Cmd-Space': (cm) => {
showRootHints(cm, this.props.showHintsFor);
showRootHints(cm, this.props.showHintsFor, this.props.protocol);
},
'Ctrl-Y': 'foldAll',
'Cmd-Y': 'foldAll',
Expand Down Expand Up @@ -255,6 +255,7 @@ class CodeEditor extends React.Component {
// Setup AutoComplete Helper for all modes
const autoCompleteOptions = {
showHintsFor: this.props.showHintsFor,
protocol: this.props.protocol,
getAllVariables: getAllVariablesHandler
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import ResponsiveTabs from 'ui/ResponsiveTabs';
import StyledWrapper from './StyledWrapper';
import { hasEffectiveAuth } from 'utils/auth';
import { AUTH_MODES_GRPC } from 'utils/common/constants';
import Script from 'components/RequestPane/Script';
import Tests from 'components/RequestPane/Tests';

const GrpcRequestPane = ({ item, collection, handleRun }) => {
const dispatch = useDispatch();
Expand Down Expand Up @@ -46,6 +48,12 @@ const GrpcRequestPane = ({ item, collection, handleRun }) => {
case 'docs': {
return <Documentation item={item} collection={collection} />;
}
case 'scripts': {
return <Script protocol="grpc" item={item} collection={collection} />;
}
case 'tests': {
return <Tests item={item} collection={collection} protocol="grpc" />;
}
default: {
return <div className="mt-4">404 | Not found</div>;
}
Expand All @@ -55,6 +63,10 @@ const GrpcRequestPane = ({ item, collection, handleRun }) => {
const body = getPropertyFromDraftOrRequest(item, 'request.body');
const headers = getPropertyFromDraftOrRequest(item, 'request.headers');
const docs = getPropertyFromDraftOrRequest(item, 'request.docs');
const script = getPropertyFromDraftOrRequest(item, 'request.script');
const tests = getPropertyFromDraftOrRequest(item, 'request.tests');
Comment on lines +66 to +67

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Guard the Scripts indicator against missing request.script, and memoize it on script content.

getPropertyFromDraftOrRequest() defaults to null, so Line 119 will throw on any gRPC request that does not have a request.script object yet. The same block also omits script from the useMemo deps, so the dot can stay stale after edits.

Minimal fix
-  const script = getPropertyFromDraftOrRequest(item, 'request.script');
+  const script = getPropertyFromDraftOrRequest(item, 'request.script', {});
...
       {
         key: 'scripts',
         label: 'Scripts',
         indicator: (script.req || script.stream || script.res) ? (hasScriptError ? <StatusDot type="error" /> : <StatusDot />) : null
       },
...
-  }, [grpcMessagesCount, isClientStreaming, activeHeadersLength, hasAuth, tests, hasTestError, docs, item.preRequestScriptErrorMessage, item.onMessageScriptErrorMessage, item.postResponseScriptErrorMessage]);
+  }, [grpcMessagesCount, isClientStreaming, activeHeadersLength, hasAuth, script.req, script.stream, script.res, tests, hasTestError, docs, item.preRequestScriptErrorMessage, item.onMessageScriptErrorMessage, item.postResponseScriptErrorMessage]);

Also applies to: 117-127

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bruno-app/src/components/RequestPane/GrpcRequestPane/index.js`
around lines 66 - 67, The Scripts indicator in GrpcRequestPane is using
request.script without guarding against the null default returned by
getPropertyFromDraftOrRequest(), so it can crash on gRPC requests that have no
script yet. Update the indicator logic around the existing script/tests handling
in GrpcRequestPane to safely check for a script object before reading its
content, and include script in the useMemo dependency list so the indicator
recomputes when script content changes. Use the existing symbols
getPropertyFromDraftOrRequest, script, and useMemo to locate the block.

const hasTestError = item.testScriptErrorMessage;

const itemAuthMode = item.draft?.request?.auth?.mode ?? item.request?.auth?.mode ?? item.root?.request?.auth?.mode;
const hasAuth = useMemo(
() => hasEffectiveAuth(collection, item, AUTH_MODES_GRPC),
Expand All @@ -68,6 +80,7 @@ const GrpcRequestPane = ({ item, collection, handleRun }) => {
const isClientStreaming = request.methodType === 'client-streaming' || request.methodType === 'bidi-streaming';

const allTabs = useMemo(() => {
const hasScriptError = item.preRequestScriptErrorMessage || item.onMessageScriptErrorMessage || item.postResponseScriptErrorMessage;
const getMessageIndicator = () => {
if (grpcMessagesCount > 0) {
return isClientStreaming ? (
Expand Down Expand Up @@ -99,9 +112,19 @@ const GrpcRequestPane = ({ item, collection, handleRun }) => {
key: 'docs',
label: 'Docs',
indicator: docs && docs.length > 0 ? <StatusDot type="default" /> : null
},
{
key: 'scripts',
label: 'Scripts',
indicator: (script.req || script.stream || script.res) ? (hasScriptError ? <StatusDot type="error" /> : <StatusDot />) : null
},
{
key: 'tests',
label: 'Tests',
indicator: tests && tests.length > 0 ? hasTestError ? <StatusDot type="error" /> : <StatusDot type="default" /> : null
}
];
}, [grpcMessagesCount, isClientStreaming, activeHeadersLength, hasAuth, docs]);
}, [grpcMessagesCount, isClientStreaming, activeHeadersLength, hasAuth, tests, hasTestError, docs, item.preRequestScriptErrorMessage, item.onMessageScriptErrorMessage, item.postResponseScriptErrorMessage]);

// Initialize tab to 'body' if no tab is currently set
useEffect(() => {
Expand Down
Loading
Loading