From b75baf57ba6623abf5ca0f94be2555bd4342965b Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Sat, 14 Jan 2023 20:16:09 +0530 Subject: [PATCH] feat: bruno lang parse .bru file --- packages/bruno-lang/src/index.js | 91 ++++++++++--------- packages/bruno-lang/src/params-tag.js | 54 +++++++++++ .../bruno-lang/tests/fixtures/request.bru | 12 +++ .../{src => tests}/inline-tag.spec.js | 2 +- packages/bruno-lang/tests/parser.spec.js | 40 ++++++++ 5 files changed, 154 insertions(+), 45 deletions(-) create mode 100644 packages/bruno-lang/src/params-tag.js create mode 100644 packages/bruno-lang/tests/fixtures/request.bru rename packages/bruno-lang/{src => tests}/inline-tag.spec.js (97%) create mode 100644 packages/bruno-lang/tests/parser.spec.js diff --git a/packages/bruno-lang/src/index.js b/packages/bruno-lang/src/index.js index 175d54a03..90d99f67d 100644 --- a/packages/bruno-lang/src/index.js +++ b/packages/bruno-lang/src/index.js @@ -1,48 +1,51 @@ -const bruToJson = (input) => { +const { + sepBy, + regex, + many, + choice, + anyChar +} = require("arcsecond"); + +const inlineTag = require('./inline-tag'); +const paramsTag = require('./params-tag'); + +const bruToJson = (fileContents) => { + const newline = regex(/^\r?\n/); + const line = inlineTag; + const lines = many(line); + // const parser = sepBy(newline)(lines); + + let parser = choice([ + sepBy(newline)(lines), + paramsTag + ]); + + parser = many(choice([ + inlineTag, + paramsTag, + anyChar + ])); + + const parsed = parser + .run(fileContents) + .result + .reduce((acc, item) => { + return { + ...acc, + ...item + }; + }, {}); + + return { + ver: parsed.ver, + type: parsed.type, + name: parsed.name, + method: parsed.method, + url: parsed.url, + params: parsed.params + } }; -const a = { - "ver": "1.0", - "type": "http-request", - "name": "Send Bulk SMS", - "method": "GET", - "url": "https://api.textlocal.in/bulk_json?apiKey=secret=&numbers=919988776655&message=hello&sender=600010", - - "params": [{ - "enabled": true, - "key": "apiKey", - "value": "secret" - }, { - "enabled": true, - "key": "numbers", - "value": "998877665" - }, { - "enabled": true, - "key": "message", - "value": "hello" - }], - "headers": [{ - "enabled": true, - "key": "Content-Type", - "value": "application/json" - }, { - "enabled": true, - "key": "Accept-Language", - "value": "en-US,en;q=0.9,hi;q=0.8" - }, { - "enabled": false, - "key": "transaction-id", - "value": "{{transactionId}}" - }], - "body": { - "mode": "json", - "json": "{\n \"apikey: \"secret\",\n \"numbers: \"+91998877665\",\n \"data: {\n \"sender: \"TXTLCL\",\n \"messages: [{\n \"numbers: \"+91998877665\",\n \"message: \"Hello World\"\n }]\n }\n}", - "graphql": "{\n launchesPast {\n launch_site {\n site_name\n }\n launch_success\n }\n}", - } -} - - - -export { +module.exports = { bruToJson }; \ No newline at end of file diff --git a/packages/bruno-lang/src/params-tag.js b/packages/bruno-lang/src/params-tag.js new file mode 100644 index 000000000..a87c3a34f --- /dev/null +++ b/packages/bruno-lang/src/params-tag.js @@ -0,0 +1,54 @@ +const { + sequenceOf, + whitespace, + optionalWhitespace, + choice, + endOfInput, + everyCharUntil, + between, + digit, + many, + regex, + sepBy +} = require("arcsecond"); + +const newline = regex(/^\r?\n/); +const newLineOrEndOfInput = choice([newline, endOfInput]); + +const begin = sequenceOf([ + regex(/^params[^\S\r\n]*/), + newline +]); + +const end = sequenceOf([ + regex(/^\/params[^\S\r\n]*/), + newLineOrEndOfInput +]); +const key = everyCharUntil(whitespace); +const value = everyCharUntil(whitespace); + +const line = sequenceOf([ + optionalWhitespace, + digit, + whitespace, + key, + whitespace, + value, + newLineOrEndOfInput +]).map(([_, enabled, __, key, ___, value]) => { + return { + "enabled": enabled, + "key": key, + "value": value + }; +}); + +const lines = many(line); +const paramsLines = sepBy(newline)(lines); +const paramsTag = between(begin)(end)(paramsLines).map(([params]) => { + return { + params + }; +}); + +module.exports = paramsTag; diff --git a/packages/bruno-lang/tests/fixtures/request.bru b/packages/bruno-lang/tests/fixtures/request.bru new file mode 100644 index 000000000..4bd08096b --- /dev/null +++ b/packages/bruno-lang/tests/fixtures/request.bru @@ -0,0 +1,12 @@ +ver 1.0 +type http-request +name Send Bulk SMS +method GET +url https://api.textlocal.in/bulk_json?apiKey=secret=&numbers=919988776655&message=hello&sender=600010 +body-mode json + +params + 1 apiKey secret + 1 numbers 998877665 + 1 message hello +/params \ No newline at end of file diff --git a/packages/bruno-lang/src/inline-tag.spec.js b/packages/bruno-lang/tests/inline-tag.spec.js similarity index 97% rename from packages/bruno-lang/src/inline-tag.spec.js rename to packages/bruno-lang/tests/inline-tag.spec.js index 6a5311577..05b5db0a0 100644 --- a/packages/bruno-lang/src/inline-tag.spec.js +++ b/packages/bruno-lang/tests/inline-tag.spec.js @@ -1,4 +1,4 @@ -const inlineTag = require('./inline-tag'); +const inlineTag = require('../src/inline-tag'); const { sepBy, char, diff --git a/packages/bruno-lang/tests/parser.spec.js b/packages/bruno-lang/tests/parser.spec.js new file mode 100644 index 000000000..0a171bde1 --- /dev/null +++ b/packages/bruno-lang/tests/parser.spec.js @@ -0,0 +1,40 @@ +const fs = require('fs'); +const path = require('path'); + +const { + bruToJson +} = require('../src'); + +describe('bruToJson', () => { + it('should parse .bru file contents', () => { + const requestFile = fs.readFileSync(path.join(__dirname, 'fixtures', 'request.bru'), 'utf8'); + const result = bruToJson(requestFile); + + expect(result).toEqual({ + "ver": "1.0", + "type": "http-request", + "name": "Send Bulk SMS", + "method": "GET", + "url": "https://api.textlocal.in/bulk_json?apiKey=secret=&numbers=919988776655&message=hello&sender=600010", + "params": [ + { + "enabled": "1", + "key": "apiKey", + "value": "secret" + }, + { + "enabled": "1", + "key": "numbers", + "value": "998877665" + }, + { + "enabled": "1", + "key": "message", + "value": "hello" + } + ] + }); + }); +}); + +