diff --git a/packages/bruno-app/src/components/RequestPane/WsBody/index.js b/packages/bruno-app/src/components/RequestPane/WsBody/index.js
index 3dc4ad833..09c31bfcf 100644
--- a/packages/bruno-app/src/components/RequestPane/WsBody/index.js
+++ b/packages/bruno-app/src/components/RequestPane/WsBody/index.js
@@ -38,7 +38,7 @@ const SingleWSMessage = ({
const preferences = useSelector(state => state.app.preferences);
const body = item.draft ? get(item, 'draft.request.body') : get(item, 'request.body');
- const { name, content, decoder } = message;
+ const { name, content, type } = message;
const [messageFormat, setMessageFormat] = useState(autoDetectLang(content));
const onUpdateMessageType = type => {
@@ -92,8 +92,8 @@ const SingleWSMessage = ({
= canClientSendMultipleMessages && body.ws.length > 1 ? `${isCollapsed ? '' : 'h-80'}` : 'h-full';
let codeType = messageFormat;
- if (TYPE_BY_DECODER[decoder]) {
- codeType = TYPE_BY_DECODER[decoder];
+ if (TYPE_BY_DECODER[type]) {
+ codeType = TYPE_BY_DECODER[type];
}
const codemirrorMode = {
@@ -110,6 +110,7 @@ const SingleWSMessage = ({
const currentMessages = [...(body.ws || [])];
currentMessages[index] = {
+ ...currentMessages[index],
name: name ? name : `message ${index + 1}`,
content: prettyBodyJson,
};
@@ -129,6 +130,7 @@ const SingleWSMessage = ({
const currentMessages = [...(body.ws || [])];
currentMessages[index] = {
+ ...currentMessages[index],
name: name ? name : `message ${index + 1}`,
content: prettyBodyXML,
};
@@ -270,9 +272,8 @@ const WSBody = ({ item, collection, handleRun }) => {
{body.ws
.filter((_, index) => canClientSendMultipleMessages || index === 0)
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
index 9c695b7aa..822414590 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
@@ -1466,6 +1466,10 @@ export const collectionsSlice = createSlice({
item.draft.request.body.grpc = action.payload.content;
break;
}
+ case 'ws': {
+ item.draft.request.body.ws = action.payload.content;
+ break;
+ }
}
}
}
diff --git a/packages/bruno-filestore/src/formats/bru/index.ts b/packages/bruno-filestore/src/formats/bru/index.ts
index 0be333c10..5b394a381 100644
--- a/packages/bruno-filestore/src/formats/bru/index.ts
+++ b/packages/bruno-filestore/src/formats/bru/index.ts
@@ -79,13 +79,15 @@ export const bruRequestToJson = (data: string | any, parsed: boolean = false): a
});
} else if (requestType === 'ws-request') {
transformedJson.request.auth.mode = _.get(json, 'ws.auth', 'none');
- const bodyFromBru = _.get(json, 'body') || {};
- transformedJson.request.body = {
+ transformedJson.request.body = _.get(json, 'body', {
mode: 'ws',
- ws: [
- bodyFromBru,
- ],
- };
+ ws: _.get(json, 'body.ws', [
+ {
+ name: 'message 1',
+ content: '{}'
+ }
+ ])
+ });
} else {
// For HTTP and GraphQL
(transformedJson.request as any).params = _.get(json, 'params', []);
@@ -182,11 +184,9 @@ export const jsonRequestToBru = (json: any): string => {
bruJson.ws = {
url: _.get(json, 'request.url'),
auth: _.get(json, 'request.auth.mode', 'none'),
+ body: _.get(json, 'request.body.mode', 'ws')
};
- const method = _.get(json, 'request.method');
- const methodType = _.get(json, 'request.methodType');
- if (method) bruJson.ws.method = method;
- if (methodType) bruJson.ws.methodType = methodType;
+
bruJson.body = _.get(json, 'request.body', {
mode: 'ws',
ws: _.get(json, 'request.body.ws', [
diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js
index 8b127c3dd..0dcc27e48 100644
--- a/packages/bruno-lang/v2/src/bruToJson.js
+++ b/packages/bruno-lang/v2/src/bruToJson.js
@@ -31,7 +31,7 @@ const { safeParseJson, outdentString } = require('./utils');
const grammar = ohm.grammar(`Bru {
BruFile = (meta | http | grpc | ws | query | params | headers | metadata | auths | bodies | varsandassert | script | tests | settings | docs)*
auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM | authOAuth2 | authwsse | authapikey | authOauth2Configs
- bodies = bodyjson | bodytext | bodyxml | bodysparql | bodygraphql | bodygraphqlvars | bodyforms | body | bodygrpc
+ bodies = bodyjson | bodytext | bodyxml | bodysparql | bodygraphql | bodygraphqlvars | bodyforms | body | bodygrpc | bodyws
bodyforms = bodyformurlencoded | bodymultipart | bodyfile
params = paramspath | paramsquery
@@ -131,7 +131,7 @@ const grammar = ohm.grammar(`Bru {
oauth2RefreshTokenReqQueryParams = "auth:oauth2:additional_params:refresh_token_req:queryparams" dictionary
oauth2RefreshTokenReqBody = "auth:oauth2:additional_params:refresh_token_req:body" dictionary
- body = "body" st* "{" nl* (pairlist|textblock) tagend
+ body = "body" st* "{" nl* textblock tagend
bodyjson = "body:json" st* "{" nl* textblock tagend
bodytext = "body:text" st* "{" nl* textblock tagend
bodyxml = "body:xml" st* "{" nl* textblock tagend
@@ -139,6 +139,7 @@ const grammar = ohm.grammar(`Bru {
bodygraphql = "body:graphql" st* "{" nl* textblock tagend
bodygraphqlvars = "body:graphql:vars" st* "{" nl* textblock tagend
bodygrpc = "body:grpc" dictionary
+ bodyws = "body:ws" dictionary
bodyformurlencoded = "body:form-urlencoded" dictionary
bodymultipart = "body:multipart-form" dictionary
@@ -820,18 +821,13 @@ const sem = grammar.createSemantics().addAttribute('ast', {
}
};
},
- body(_1, _2, _3, _4, content, _5) {
- if (Array.isArray(content.ast)) {
- return {
- body: mapPairListToKeyValPair([content.ast]),
- };
- }
+ body(_1, _2, _3, _4, textblock, _5) {
return {
http: {
body: 'json'
},
body: {
- json: outdentString(content.sourceString),
+ json: outdentString(textblock.sourceString),
}
};
},
@@ -979,6 +975,29 @@ const sem = grammar.createSemantics().addAttribute('ast', {
}]
}
};
+ },
+ bodyws(_1, dictionary) {
+ const pairs = mapPairListToKeyValPairs(dictionary.ast, false);
+ const namePair = _.find(pairs, { name: 'name' });
+ const contentPair = _.find(pairs, { name: 'content' });
+ const typePair = _.find(pairs, { name: 'type' });
+
+ const messageName = namePair ? namePair.value : '';
+ const messageContent = contentPair ? contentPair.value : '';
+ const messageTypeContent = typePair ? typePair.value : '';
+
+ return {
+ body: {
+ mode: 'ws',
+ ws: [
+ {
+ name: messageName,
+ type: messageTypeContent,
+ content: messageContent
+ }
+ ]
+ }
+ };
}
});
diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js
index ec2c8d2d3..e39770a72 100644
--- a/packages/bruno-lang/v2/src/jsonToBru.js
+++ b/packages/bruno-lang/v2/src/jsonToBru.js
@@ -102,10 +102,6 @@ const jsonToBru = (json) => {
bru += `ws {
url: ${ws.url}`;
- if (ws.method && ws.method.length) {
- bru += `
- method: ${ws.method}`;
- }
if (ws.body && ws.body.length) {
bru += `
@@ -615,6 +611,29 @@ ${indentString(body.sparql)}
}
}
+ if (body && body.ws) {
+ // Convert each ws message to a separate body:ws block
+ if (Array.isArray(body.ws)) {
+ body.ws.forEach(message => {
+ const { name, content, type = '' } = message;
+
+ bru += `body:ws {\n`;
+
+ bru += `${indentString(`name: ${getValueString(name)}`)}\n`;
+ if (type.length) {
+ bru += `${indentString(`type: ${getValueString(type)}`)}\n`;
+ }
+
+ // Convert content to JSON string if it's an object
+ let contentValue = typeof content === 'object' ? JSON.stringify(content, null, 2) : content || '{}';
+
+ // Wrap content with triple quotes for multiline support, without extra indentation
+ bru += `${indentString(`content: '''\n${indentString(contentValue)}\n'''`)}\n`;
+ bru += '}\n\n';
+ });
+ }
+ }
+
let reqvars = _.get(vars, 'req');
let resvars = _.get(vars, 'res');
if (reqvars && reqvars.length) {
diff --git a/tests/websockets/fixtures/collection/ws-test-request-with-headers.bru b/tests/websockets/fixtures/collection/ws-test-request-with-headers.bru
index 35a4fca39..f181d6479 100644
--- a/tests/websockets/fixtures/collection/ws-test-request-with-headers.bru
+++ b/tests/websockets/fixtures/collection/ws-test-request-with-headers.bru
@@ -13,7 +13,7 @@ headers {
Authorization: Dummy
}
-body {
+body:ws {
name: message 1
content: '''
{
diff --git a/tests/websockets/fixtures/collection/ws-test-request.bru b/tests/websockets/fixtures/collection/ws-test-request.bru
index b9267785a..50a6481d0 100644
--- a/tests/websockets/fixtures/collection/ws-test-request.bru
+++ b/tests/websockets/fixtures/collection/ws-test-request.bru
@@ -9,7 +9,7 @@ ws {
auth: inherit
}
-body {
+body:ws {
name: message 1
content: '''
{