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
45 changes: 19 additions & 26 deletions packages/bruno-lang/v2/src/bruToJson.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ const grammar = ohm.grammar(`Bru {

// Multiline text block surrounded by '''
multilinetextblockdelimiter = "'''"
multilinetextblock = multilinetextblockdelimiter (~multilinetextblockdelimiter any)* multilinetextblockdelimiter
multilinetextblock = multilinetextblockdelimiter (~multilinetextblockdelimiter any)* multilinetextblockdelimiter st* contenttypeannotation?
contenttypeannotation = "@contentType(" (~")" any)* ")"

// Dictionary Blocks
dictionary = st* "{" pairlist? tagend
Expand All @@ -65,7 +66,8 @@ const grammar = ohm.grammar(`Bru {
quoted_key_char = ~(quote_char | esc_quote_char | nl) any
quoted_key = disable_char? quote_char (esc_quote_char | quoted_key_char)* quote_char
key = keychar*
value = list | multilinetextblock | valuechar*
value = list | multilinetextblock | singlelinevalue
singlelinevalue = valuechar*

// Dictionary for Assert Block
assertdictionary = st* "{" assertpairlist? tagend
Expand Down Expand Up @@ -211,7 +213,7 @@ const mapRequestParams = (pairList = [], type) => {

const multipartExtractContentType = (pair) => {
if (_.isString(pair.value)) {
const match = pair.value.match(/^(.*?)\s*@contentType\((.*?)\)\s*$/);
const match = pair.value.match(/^(.*?)\s*@contentType\((.*?)\)\s*$/s);
if (match != null && match.length > 2) {
pair.value = match[1];
pair.contentType = match[2];
Expand All @@ -223,7 +225,7 @@ const multipartExtractContentType = (pair) => {

const fileExtractContentType = (pair) => {
if (_.isString(pair.value)) {
const match = pair.value.match(/^(.*?)\s*@contentType\((.*?)\)\s*$/);
const match = pair.value.match(/^(.*?)\s*@contentType\((.*?)\)\s*$/s);
if (match && match.length > 2) {
pair.value = match[1].trim();
pair.contentType = match[2].trim();
Expand Down Expand Up @@ -370,25 +372,6 @@ const sem = grammar.createSemantics().addAttribute('ast', {
key(chars) {
return chars.sourceString ? chars.sourceString.trim() : '';
},
value(chars) {
if (chars.ctorName === 'list') {
return chars.ast;
}
try {
let isMultiline = chars.sourceString?.startsWith(`'''`) && chars.sourceString?.endsWith(`'''`);
if (isMultiline) {
const multilineString = chars.sourceString?.replace(/^'''|'''$/g, '');
return multilineString
.split('\n')
.map((line) => line.slice(4))
.join('\n');
}
return chars.sourceString ? chars.sourceString.trim() : '';
} catch (err) {
console.error(err);
}
return chars.sourceString ? chars.sourceString.trim() : '';
},
assertdictionary(_1, _2, pairlist, _3) {
return pairlist.ast;
},
Expand Down Expand Up @@ -436,9 +419,19 @@ const sem = grammar.createSemantics().addAttribute('ast', {
multilinetextblockdelimiter(_) {
return '';
},
multilinetextblock(_1, content, _2) {
// Join all the content between the triple quotes and trim it
return content.sourceString.trim();
multilinetextblock(_1, content, _2, _3, contentType) {
const multilineString = content.sourceString
.split('\n')
.map((line) => line.slice(4))
.join('\n');

if (!contentType.sourceString) {
return multilineString;
}
return `${multilineString} ${contentType.sourceString}`;
},
singlelinevalue(chars) {
return chars.sourceString?.trim() || '';
},
_iter(...elements) {
return elements.map((e) => e.ast);
Expand Down
28 changes: 28 additions & 0 deletions packages/bruno-lang/v2/tests/bruToJson.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,5 +175,33 @@ vars:pre-request {
const output = parser(input);
expect(output).toEqual(expected);
});

it('parses multiline body parts with content type annotation', () => {
const input = `
body:multipart-form {
filePart: '''
Line1
Line2
''' @contentType(text/plain)
}
`;

const expected = {
body: {
multipartForm: [
{
name: 'filePart',
value: 'Line1\nLine2',
enabled: true,
type: 'text',
contentType: 'text/plain'
}
]
}
};

const output = parser(input);
expect(output).toEqual(expected);
});
});
});
4 changes: 4 additions & 0 deletions packages/bruno-tests/collection/echo/echo multipart.bru
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ post {

body:multipart-form {
foo: {"bar":"baz"} @contentType(application/json--test)
multiline: '''
"multiline-test"
''' @contentType(application/json--multiline--test)
form-data-key: {{form-data-key}}
form-data-stringified-object: {{form-data-stringified-object}}
file: @file(bruno.png)
Expand All @@ -21,6 +24,7 @@ assert {
res.body: contains form-data-value
res.body: contains {"foo":123}
res.body: contains Content-Type: application/json--test
res.body: contains Content-Type: application/json--multiline--test
}

script:pre-request {
Expand Down