diff --git a/packages/bruno-app/src/utils/curl/curl-to-json.js b/packages/bruno-app/src/utils/curl/curl-to-json.js index ea0ec2a05..a6239519e 100644 --- a/packages/bruno-app/src/utils/curl/curl-to-json.js +++ b/packages/bruno-app/src/utils/curl/curl-to-json.js @@ -183,7 +183,13 @@ const curlToJson = (curlCommand) => { if (request.query) { requestJson.queries = getQueries(request); - } else if (request.multipartUploads || request.isDataBinary) { + } else if (request.multipartUploads) { + requestJson.data = request.multipartUploads; + if (!requestJson.headers) { + requestJson.headers = {}; + } + requestJson.headers['Content-Type'] = 'multipart/form-data'; + } else if (request.isDataBinary) { Object.assign(requestJson, getFilesString(request)); } else if (typeof request.data === 'string' || typeof request.data === 'number') { Object.assign(requestJson, getDataString(request)); diff --git a/packages/bruno-app/src/utils/curl/parse-curl.js b/packages/bruno-app/src/utils/curl/parse-curl.js index 79db23672..afdc10395 100644 --- a/packages/bruno-app/src/utils/curl/parse-curl.js +++ b/packages/bruno-app/src/utils/curl/parse-curl.js @@ -37,7 +37,8 @@ const parseCurlCommand = (curlCommand) => { alias: { H: 'header', A: 'user-agent', - u: 'user' + u: 'user', + F: 'form' } }); @@ -95,17 +96,31 @@ const parseCurlCommand = (curlCommand) => { cookieString = parsedArguments.cookie; } let multipartUploads; - if (parsedArguments.F) { - multipartUploads = {}; - if (!Array.isArray(parsedArguments.F)) { - parsedArguments.F = [parsedArguments.F]; - } - parsedArguments.F.forEach((multipartArgument) => { - // input looks like key=value. value could be json or a file path prepended with an @ - const splitArguments = multipartArgument.split('=', 2); - const key = splitArguments[0]; - const value = splitArguments[1]; - multipartUploads[key] = value; + // Handle multipart form data specified via -F or --form flags + // Example: curl -F 'id=123' -F 'file=@/path/to/file.txt' + if (parsedArguments.F || parsedArguments.form) { + multipartUploads = []; + const formArgs = parsedArguments.F || parsedArguments.form; + const formArray = Array.isArray(formArgs) ? formArgs : [formArgs]; + + formArray.forEach((multipartArgument) => { + // Parse each form field using regex: + // - Group 1: Field name before = + // - Group 2: Value in quotes after = (for text fields) + // - Group 3: Value after @ (for file fields) + const match = multipartArgument.match(/^([^=]+)=(?:@?"([^"]*)"|([^@]*))?$/); + if (match) { + const key = match[1]; + const value = match[2] || match[3] || ''; + const isFile = multipartArgument.includes('@'); + + multipartUploads.push({ + name: key, + value: value, + type: isFile ? 'file' : 'text', + enabled: true + }); + } }); } if (cookieString) { diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index 776cca7d5..c7395e2ff 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -330,8 +330,9 @@ ${indentString(body.sparql)} } if (item.type === 'file') { - let filepaths = item.value || []; - let filestr = filepaths.join('|'); + const filepaths = Array.isArray(item.value) ? item.value : []; + const filestr = filepaths.join('|'); + const value = `@file(${filestr})`; return `${enabled}${item.name}: ${value}${contentType}`; }