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); }); });