From 17365b0d63acadab6083a31fc33335ec770ff261 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Fri, 7 Feb 2025 14:44:27 +0530 Subject: [PATCH] wip: abstracting parse and stringify operations --- packages/bruno-electron/src/app/watcher.js | 24 +- .../src/{ => filestore}/bru/index.js | 291 +++++++++--------- .../src/{ => filestore}/bru/workers/index.js | 0 .../bru/workers/scripts/bru-to-json.js | 0 .../bru/workers/scripts/json-to-bru.js | 0 .../bruno-electron/src/filestore/index.js | 69 +++++ 6 files changed, 224 insertions(+), 160 deletions(-) rename packages/bruno-electron/src/{ => filestore}/bru/index.js (63%) rename packages/bruno-electron/src/{ => filestore}/bru/workers/index.js (100%) rename packages/bruno-electron/src/{ => filestore}/bru/workers/scripts/bru-to-json.js (100%) rename packages/bruno-electron/src/{ => filestore}/bru/workers/scripts/json-to-bru.js (100%) create mode 100644 packages/bruno-electron/src/filestore/index.js diff --git a/packages/bruno-electron/src/app/watcher.js b/packages/bruno-electron/src/app/watcher.js index b2b60fd55..8333cef9e 100644 --- a/packages/bruno-electron/src/app/watcher.js +++ b/packages/bruno-electron/src/app/watcher.js @@ -5,6 +5,16 @@ const chokidar = require('chokidar'); const { hasBruExtension, isWSLPath, normalizeAndResolvePath, normalizeWslPath, sizeInMB } = require('../utils/filesystem'); const { bruToEnvJson, bruToJson, bruToJsonViaWorker ,collectionBruToJson } = require('../bru'); const { dotenvToJson } = require('@usebruno/lang'); +const { + parseRequest, + stringifyRequest, + parseCollection, + stringifyCollection, + parseFolder, + stringifyFolder, + parseEnvironment, + stringifyEnvironment +} = require('../filestore'); const { uuid } = require('../utils/common'); const { getRequestUid } = require('../cache/requestUids'); @@ -80,7 +90,7 @@ const addEnvironmentFile = async (win, pathname, collectionUid, collectionPath) let bruContent = fs.readFileSync(pathname, 'utf8'); - file.data = await bruToEnvJson(bruContent); + file.data = await parseEnvironment(bruContent, { format: 'bru' }); file.data.name = basename.substring(0, basename.length - 4); file.data.uid = getRequestUid(pathname); @@ -209,8 +219,7 @@ const add = async (win, pathname, collectionUid, collectionPath, useWorkerThread try { let bruContent = fs.readFileSync(pathname, 'utf8'); - file.data = await collectionBruToJson(bruContent); - + file.data = await parseCollection(bruContent, { format: 'bru' }); hydrateBruCollectionFileWithUuid(file.data); win.webContents.send('main:collection-tree-updated', 'addFile', file); return; @@ -234,8 +243,7 @@ const add = async (win, pathname, collectionUid, collectionPath, useWorkerThread try { let bruContent = fs.readFileSync(pathname, 'utf8'); - file.data = await collectionBruToJson(bruContent); - + file.data = await parseFolder(bruContent, { format: 'bru' }); hydrateBruCollectionFileWithUuid(file.data); win.webContents.send('main:collection-tree-updated', 'addFile', file); return; @@ -259,7 +267,7 @@ const add = async (win, pathname, collectionUid, collectionPath, useWorkerThread // If worker thread is not used, we can directly parse the file if (!useWorkerThread) { try { - file.data = await bruToJson(bruContent); + file.data = await parseRequest(bruContent, { format: 'bru' }); file.partial = false; file.loading = false; file.size = sizeInMB(fileStats?.size); @@ -279,7 +287,7 @@ const add = async (win, pathname, collectionUid, collectionPath, useWorkerThread type: 'http-request' }; - const metaJson = await bruToJson(parseBruFileMeta(bruContent), true); + const metaJson = await parseRequest(parseBruFileMeta(bruContent), { format: 'bru' }); file.data = metaJson; file.partial = true; file.loading = false; @@ -296,7 +304,7 @@ const add = async (win, pathname, collectionUid, collectionPath, useWorkerThread win.webContents.send('main:collection-tree-updated', 'addFile', file); // This is to update the file info in the UI - file.data = await bruToJsonViaWorker(bruContent); + file.data = await parseRequest(bruContent, { format: 'bru', useWorker: true }); file.partial = false; file.loading = false; hydrateRequestWithUuid(file.data, pathname); diff --git a/packages/bruno-electron/src/bru/index.js b/packages/bruno-electron/src/filestore/bru/index.js similarity index 63% rename from packages/bruno-electron/src/bru/index.js rename to packages/bruno-electron/src/filestore/bru/index.js index a641a95a7..c7dcd387d 100644 --- a/packages/bruno-electron/src/bru/index.js +++ b/packages/bruno-electron/src/filestore/bru/index.js @@ -4,116 +4,31 @@ const { jsonToBruV2, bruToEnvJsonV2, envJsonToBruV2, - collectionBruToJson: _collectionBruToJson, - jsonToCollectionBru: _jsonToCollectionBru + collectionBruToJson, + jsonToCollectionBru } = require('@usebruno/lang'); const BruParserWorker = require('./workers'); const bruParserWorker = new BruParserWorker(); -const collectionBruToJson = async (data, parsed = false) => { - try { - const json = parsed ? data : _collectionBruToJson(data); - - const transformedJson = { - request: { - headers: _.get(json, 'headers', []), - auth: _.get(json, 'auth', {}), - script: _.get(json, 'script', {}), - vars: _.get(json, 'vars', {}), - tests: _.get(json, 'tests', '') - }, - docs: _.get(json, 'docs', '') - }; - - // add meta if it exists - // this is only for folder bru file - // in the future, all of this will be replaced by standard bru lang - if (json.meta) { - transformedJson.meta = { - name: json.meta.name - }; - } - - return transformedJson; - } catch (error) { - return Promise.reject(error); - } -}; - -const jsonToCollectionBru = async (json, isFolder) => { - try { - const collectionBruJson = { - headers: _.get(json, 'request.headers', []), - script: { - req: _.get(json, 'request.script.req', ''), - res: _.get(json, 'request.script.res', '') - }, - vars: { - req: _.get(json, 'request.vars.req', []), - res: _.get(json, 'request.vars.res', []) - }, - tests: _.get(json, 'request.tests', ''), - docs: _.get(json, 'docs', '') - }; - - // add meta if it exists - // this is only for folder bru file - // in the future, all of this will be replaced by standard bru lang - if (json?.meta) { - collectionBruJson.meta = { - name: json.meta.name - }; - } - - if (!isFolder) { - collectionBruJson.auth = _.get(json, 'request.auth', {}); - } - - return _jsonToCollectionBru(collectionBruJson); - } catch (error) { - return Promise.reject(error); - } -}; - -const bruToEnvJson = async (bru) => { - try { - const json = bruToEnvJsonV2(bru); - - // the app env format requires each variable to have a type - // this need to be evaluated and safely removed - // i don't see it being used in schema validation - if (json && json.variables && json.variables.length) { - _.each(json.variables, (v) => (v.type = 'text')); - } - - return json; - } catch (error) { - return Promise.reject(error); - } -}; - -const envJsonToBru = async (json) => { - try { - const bru = envJsonToBruV2(json); - return bru; - } catch (error) { - return Promise.reject(error); - } -}; - /** * The transformer function for converting a BRU file to JSON. * * We map the json response from the bru lang and transform it into the DSL * format that the app uses * - * @param {string} data The BRU file content. + * @param {string} bru The BRU file content. * @returns {object} The JSON representation of the BRU file. */ -const bruToJson = (data, parsed = false) => { +const parseRequest = async (bru, options = {}) => { try { - const json = parsed ? data : bruToJsonV2(data); + let json; + + if(options.useWorker) { + json = await bruParserWorker?.bruToJson(data); + } else { + json = bruToJsonV2(bru); + } let requestType = _.get(json, 'meta.type'); if (requestType === 'http') { @@ -153,15 +68,6 @@ const bruToJson = (data, parsed = false) => { } }; -const bruToJsonViaWorker = async (data) => { - try { - const json = await bruParserWorker?.bruToJson(data); - return bruToJson(json, true); - } catch (e) { - return Promise.reject(e); - } -}; - /** * The transformer function for converting a JSON to BRU file. * @@ -171,7 +77,7 @@ const bruToJsonViaWorker = async (data) => { * @param {object} json The JSON representation of the BRU file. * @returns {string} The BRU file content. */ -const jsonToBru = async (json) => { +const stringifyRequest = async (json, options = {}) => { let type = _.get(json, 'type'); if (type === 'http-request') { type = 'http'; @@ -208,59 +114,140 @@ const jsonToBru = async (json) => { docs: _.get(json, 'request.docs', '') }; - const bru = jsonToBruV2(bruJson); - return bru; + if(options.useWorker) { + return await bruParserWorker?.jsonToBru(bruJson); + } else { + return jsonToBruV2(bruJson); + } }; -const jsonToBruViaWorker = async (json) => { - let type = _.get(json, 'type'); - if (type === 'http-request') { - type = 'http'; - } else if (type === 'graphql-request') { - type = 'graphql'; - } else { - type = 'http'; +const parseCollection = async (bru) => { + try { + const json = collectionBruToJson(bru); + + const transformedJson = { + request: { + headers: _.get(json, 'headers', []), + auth: _.get(json, 'auth', {}), + script: _.get(json, 'script', {}), + vars: _.get(json, 'vars', {}), + tests: _.get(json, 'tests', '') + }, + docs: _.get(json, 'docs', '') + }; + + return transformedJson; + } catch (error) { + return Promise.reject(error); } +}; - const sequence = _.get(json, 'seq'); - const bruJson = { - meta: { - name: _.get(json, 'name'), - type: type, - seq: !isNaN(sequence) ? Number(sequence) : 1 - }, - http: { - method: _.lowerCase(_.get(json, 'request.method')), - url: _.get(json, 'request.url'), - auth: _.get(json, 'request.auth.mode', 'none'), - body: _.get(json, 'request.body.mode', 'none') - }, - params: _.get(json, 'request.params', []), - headers: _.get(json, 'request.headers', []), - auth: _.get(json, 'request.auth', {}), - body: _.get(json, 'request.body', {}), - script: _.get(json, 'request.script', {}), - vars: { - req: _.get(json, 'request.vars.req', []), - res: _.get(json, 'request.vars.res', []) - }, - assertions: _.get(json, 'request.assertions', []), - tests: _.get(json, 'request.tests', ''), - docs: _.get(json, 'request.docs', '') - }; +const stringifyCollection = async (json) => { + try { + const collectionBruJson = { + headers: _.get(json, 'request.headers', []), + auth: _.get(json, 'request.auth', {}), + script: { + req: _.get(json, 'request.script.req', ''), + res: _.get(json, 'request.script.res', '') + }, + vars: { + req: _.get(json, 'request.vars.req', []), + res: _.get(json, 'request.vars.res', []) + }, + tests: _.get(json, 'request.tests', ''), + docs: _.get(json, 'docs', '') + }; - const bru = await bruParserWorker?.jsonToBru(bruJson) - return bru; + return jsonToCollectionBru(collectionBruJson); + } catch (error) { + return Promise.reject(error); + } +}; + +const parseFolder = async (bru) => { + try { + const json = collectionBruToJson(bru); + + const transformedJson = { + meta: { + name: _.get(json, 'meta.name') + }, + request: { + headers: _.get(json, 'headers', []), + auth: _.get(json, 'auth', {}), + script: _.get(json, 'script', {}), + vars: _.get(json, 'vars', {}), + tests: _.get(json, 'tests', '') + }, + docs: _.get(json, 'docs', '') + }; + + return transformedJson; + } catch (error) { + return Promise.reject(error); + } +}; + +const stringifyFolder = async (json) => { + try { + const folderBruJson = { + meta: { + name: _.get(json, 'meta.name') + }, + headers: _.get(json, 'request.headers', []), + script: { + req: _.get(json, 'request.script.req', ''), + res: _.get(json, 'request.script.res', '') + }, + vars: { + req: _.get(json, 'request.vars.req', []), + res: _.get(json, 'request.vars.res', []) + }, + tests: _.get(json, 'request.tests', ''), + docs: _.get(json, 'docs', '') + }; + + return jsonToCollectionBru(folderBruJson); + } catch (error) { + return Promise.reject(error); + } +}; + +const parseEnvironment = async (bru) => { + try { + const json = bruToEnvJsonV2(bru); + + // the app env format requires each variable to have a type + // this need to be evaluated and safely removed + // i don't see it being used in schema validation + if (json && json.variables && json.variables.length) { + _.each(json.variables, (v) => (v.type = 'text')); + } + + return json; + } catch (error) { + return Promise.reject(error); + } +}; + +const stringifyEnvironment = async (json) => { + try { + const bru = envJsonToBruV2(json); + return bru; + } catch (error) { + return Promise.reject(error); + } }; module.exports = { - bruToJson, - bruToJsonViaWorker, - jsonToBru, - bruToEnvJson, - envJsonToBru, - collectionBruToJson, - jsonToCollectionBru, - jsonToBruViaWorker + parseRequest, + stringifyRequest, + parseCollection, + stringifyCollection, + parseFolder, + stringifyFolder, + parseEnvironment, + stringifyEnvironment }; diff --git a/packages/bruno-electron/src/bru/workers/index.js b/packages/bruno-electron/src/filestore/bru/workers/index.js similarity index 100% rename from packages/bruno-electron/src/bru/workers/index.js rename to packages/bruno-electron/src/filestore/bru/workers/index.js diff --git a/packages/bruno-electron/src/bru/workers/scripts/bru-to-json.js b/packages/bruno-electron/src/filestore/bru/workers/scripts/bru-to-json.js similarity index 100% rename from packages/bruno-electron/src/bru/workers/scripts/bru-to-json.js rename to packages/bruno-electron/src/filestore/bru/workers/scripts/bru-to-json.js diff --git a/packages/bruno-electron/src/bru/workers/scripts/json-to-bru.js b/packages/bruno-electron/src/filestore/bru/workers/scripts/json-to-bru.js similarity index 100% rename from packages/bruno-electron/src/bru/workers/scripts/json-to-bru.js rename to packages/bruno-electron/src/filestore/bru/workers/scripts/json-to-bru.js diff --git a/packages/bruno-electron/src/filestore/index.js b/packages/bruno-electron/src/filestore/index.js new file mode 100644 index 000000000..1f1c172fd --- /dev/null +++ b/packages/bruno-electron/src/filestore/index.js @@ -0,0 +1,69 @@ +import { + parseRequest as bruParseRequest, + stringifyRequest as bruStringifyRequest, + parseFolder as bruParseFolder, + stringifyFolder as bruStringifyFolder, + parseCollection as bruParseCollection, + stringifyCollection as bruStringifyCollection, + parseEnvironment as bruParseEnvironment, + stringifyEnvironment as bruStringifyEnvironment +} from './bru'; + +const parseRequest = (bru, options = {}) => { + if (options.format === 'bru') { + return bruParseRequest(bru); + } +}; + +const stringifyRequest = (json, options = {}) => { + if (options.format === 'bru') { + return bruStringifyRequest(json); + } +}; + +const parseFolder = (bru, options = {}) => { + if (options.format === 'bru') { + return bruParseFolder(bru); + } +}; + +const stringifyFolder = (json, options = {}) => { + if (options.format === 'bru') { + return bruStringifyFolder(json); + } +}; + +const parseCollection = (bru, options = {}) => { + if (options.format === 'bru') { + return bruParseCollection(bru); + } +}; + +const stringifyCollection = (json, options = {}) => { + if (options.format === 'bru') { + return bruStringifyCollection(json); + } +}; + +const parseEnvironment = (bru, options = {}) => { + if (options.format === 'bru') { + return bruParseEnvironment(bru); + } +}; + +const stringifyEnvironment = (json, options = {}) => { + if (options.format === 'bru') { + return bruStringifyEnvironment(json); + } +}; + +module.exports = { + parseRequest, + stringifyRequest, + parseFolder, + stringifyFolder, + parseCollection, + stringifyCollection, + parseEnvironment, + stringifyEnvironment +}; \ No newline at end of file