diff --git a/packages/bruno-lang/v2/src/index.js b/packages/bruno-lang/v2/src/index.js
index 3863060d..ae10df89 100644
--- a/packages/bruno-lang/v2/src/index.js
+++ b/packages/bruno-lang/v2/src/index.js
@@ -2,7 +2,9 @@ const ohm = require("ohm-js");
const _ = require('lodash');
const grammar = ohm.grammar(`Bru {
- BruFile = (script | test | headersdisabled | headers)*
+ BruFile = (script | test | querydisabled | query | headersdisabled | headers | bodies )*
+ bodies = bodyjson | bodytext | bodyxml | bodygraphql | bodygraphqlvars | bodyforms
+ bodyforms = bodyformurlencodeddisabled | bodyformurlencoded | bodymultipartdisabled | bodymultipart
nl = "\\r"? "\\n"
st = " " | "\\t"
tagend = nl "}"
@@ -12,12 +14,26 @@ const grammar = ohm.grammar(`Bru {
headers = "headers" pairblock
headersdisabled = "headers:disabled" pairblock
+ query = "query" pairblock
+ querydisabled = "query:disabled" pairblock
+
pairblock = st* "{" pairlist? tagend
pairlist = nl* pair (~tagend nl pair)* (~tagend space)*
pair = st* key st* ":" st* value? st*
key = ~tagend validkey*
value = ~tagend validvalue*
+ bodyjson = "body:json" st* "{" nl* textblock tagend
+ bodytext = "body:text" st* "{" nl* textblock tagend
+ bodyxml = "body:xml" st* "{" nl* textblock tagend
+ bodygraphql = "body:graphql" st* "{" nl* textblock tagend
+ bodygraphqlvars = "body:graphql:vars" st* "{" nl* textblock tagend
+
+ bodyformurlencoded = "body:form-urlencoded" pairblock
+ bodyformurlencodeddisabled = "body:form-urlencoded:disabled" pairblock
+ bodymultipart = "body:multipart-form" pairblock
+ bodymultipartdisabled = "body:multipart-form:disabled" pairblock
+
script = "script" st* "{" nl* textblock tagend
test = "test" st* "{" textblock tagend
@@ -56,6 +72,16 @@ const sem = grammar.createSemantics().addAttribute('ast', {
return _.mergeWith(result, item, concatArrays);
}, {});
},
+ query(_1, pairblock) {
+ return {
+ query: mapPairListToKeyValPairs(pairblock.ast)
+ };
+ },
+ querydisabled(_1, pairblock) {
+ return {
+ query: mapPairListToKeyValPairs(pairblock.ast, false)
+ };
+ },
headers(_1, pairblock) {
return {
headers: mapPairListToKeyValPairs(pairblock.ast)
@@ -83,6 +109,73 @@ const sem = grammar.createSemantics().addAttribute('ast', {
value(chars) {
return chars.sourceString ? chars.sourceString.trim() : '';
},
+ bodyformurlencoded(_1, pairblock) {
+ return {
+ body: {
+ formUrlEncoded: mapPairListToKeyValPairs(pairblock.ast)
+ }
+ };
+ },
+ bodyformurlencodeddisabled(_1, pairblock) {
+ return {
+ body: {
+ formUrlEncoded: mapPairListToKeyValPairs(pairblock.ast, false)
+ }
+ };
+ },
+ bodymultipart(_1, pairblock) {
+ return {
+ body: {
+ multipartForm: mapPairListToKeyValPairs(pairblock.ast)
+ }
+ };
+ },
+ bodymultipartdisabled(_1, pairblock) {
+ return {
+ body: {
+ multipartForm: mapPairListToKeyValPairs(pairblock.ast, false)
+ }
+ };
+ },
+ bodyjson(_1, _2, _3, _4, textblock, _5) {
+ return {
+ body: {
+ json: textblock.sourceString
+ }
+ };
+ },
+ bodytext(_1, _2, _3, _4, textblock, _5) {
+ return {
+ body: {
+ text: textblock.sourceString
+ }
+ };
+ },
+ bodyxml(_1, _2, _3, _4, textblock, _5) {
+ return {
+ body: {
+ xml: textblock.sourceString
+ }
+ };
+ },
+ bodygraphql(_1, _2, _3, _4, textblock, _5) {
+ return {
+ body: {
+ graphql: {
+ query: textblock.sourceString
+ }
+ }
+ };
+ },
+ bodygraphqlvars(_1, _2, _3, _4, textblock, _5) {
+ return {
+ body: {
+ graphql: {
+ variables: textblock.sourceString
+ }
+ }
+ };
+ },
script(_1, _2, _3, _4, textblock, _5) {
return {
script: textblock.sourceString
diff --git a/packages/bruno-lang/v2/tests/index.spec.js b/packages/bruno-lang/v2/tests/index.spec.js
index d260d8b5..ad9e3bfb 100644
--- a/packages/bruno-lang/v2/tests/index.spec.js
+++ b/packages/bruno-lang/v2/tests/index.spec.js
@@ -3,6 +3,15 @@ const parser = require("../src/index");
describe("parser", () => {
it("should parse the bru file", () => {
const input = `
+query {
+ apiKey: secret
+ numbers: 998877665
+}
+
+query:disabled {
+ message: hello
+}
+
headers {
content-type: application/json
Authorization: Bearer 123
@@ -12,6 +21,58 @@ headers:disabled {
transaction-id: {{transactionId}}
}
+body:form-urlencoded {
+ apikey: secret
+ numbers: +91998877665
+}
+
+body:form-urlencoded:disabled {
+ message: hello
+}
+
+body:multipart-form {
+ apikey: secret
+ numbers: +91998877665
+}
+
+body:multipart-form:disabled {
+ message: hello
+}
+
+body:json {
+ {
+ "hello": "world"
+ }
+}
+
+body:text {
+ This is a text body
+}
+
+body:xml {
+
+ John
+ 30
+
+}
+
+body:graphql {
+ {
+ launchesPast {
+ launch_site {
+ site_name
+ }
+ launch_success
+ }
+ }
+}
+
+body:graphql:vars {
+ {
+ "limit": 5
+ }
+}
+
script {
function onResponse(request, response) {
expect(response.status).to.equal(200);
@@ -21,6 +82,19 @@ script {
const output = parser(input);
const expected = {
+ "query": [{
+ "name": "apiKey",
+ "value": "secret",
+ "enabled": true
+ }, {
+ "name": "numbers",
+ "value": "998877665",
+ "enabled": true
+ }, {
+ "name": "message",
+ "value": "hello",
+ "enabled": false
+ }],
"headers": [
{
"name": "content-type",
@@ -38,9 +112,53 @@ script {
"enabled": false
}
],
+ "body": {
+ "json": " {\n \"hello\": \"world\"\n }",
+ "text": " This is a text body",
+ "xml": " \n John\n 30\n ",
+ "graphql": {
+ "query": " {\n launchesPast {\n launch_site {\n site_name\n }\n launch_success\n }\n }",
+ "variables": " {\n \"limit\": 5\n }"
+ },
+ "formUrlEncoded": [
+ {
+ "name": "apikey",
+ "value": "secret",
+ "enabled": true
+ },
+ {
+ "name": "numbers",
+ "value": "+91998877665",
+ "enabled": true
+ },
+ {
+ "name": "message",
+ "value": "hello",
+ "enabled": false
+ }
+ ],
+ "multipartForm": [
+ {
+ "name": "apikey",
+ "value": "secret",
+ "enabled": true
+ },
+ {
+ "name": "numbers",
+ "value": "+91998877665",
+ "enabled": true
+ },
+ {
+ "name": "message",
+ "value": "hello",
+ "enabled": false
+ }
+ ]
+ },
"script": " function onResponse(request, response) {\n expect(response.status).to.equal(200);\n }"
}
+ // console.log(JSON.stringify(output, null, 2));
expect(output).toEqual(expected);
});
});