diff --git a/packages/bruno-electron/src/app/collections.js b/packages/bruno-electron/src/app/collections.js index 66c40ff2..d8c5716b 100644 --- a/packages/bruno-electron/src/app/collections.js +++ b/packages/bruno-electron/src/app/collections.js @@ -16,28 +16,30 @@ const configSchema = Yup.object({ name: Yup.string().nullable().max(256, 'name must be 256 characters or less'), type: Yup.string().oneOf(['collection']).required('type is required'), version: Yup.string().oneOf(['1']).required('type is required') -}).noUnknown(true).strict(); +}) + .noUnknown(true) + .strict(); const readConfigFile = async (pathname) => { try { const jsonData = fs.readFileSync(pathname, 'utf8'); return JSON.parse(jsonData); - } catch(err) { - return Promise.reject(new Error("Unable to parse json in bruno.json")); + } catch (err) { + return Promise.reject(new Error('Unable to parse json in bruno.json')); } -} +}; const validateSchema = async (config) => { try { await configSchema.validate(config); - } catch(err) { - return Promise.reject(new Error("bruno.json format is invalid")); + } catch (err) { + return Promise.reject(new Error('bruno.json format is invalid')); } }; const getCollectionConfigFile = async (pathname) => { const configFilePath = path.join(pathname, 'bruno.json'); - if (!fs.existsSync(configFilePath)){ + if (!fs.existsSync(configFilePath)) { throw new Error(`The collection is not valid (bruno.json not found)`); } @@ -45,7 +47,7 @@ const getCollectionConfigFile = async (pathname) => { await validateSchema(config); return config; -} +}; const openCollectionDialog = async (win, watcher) => { const { filePaths } = await dialog.showOpenDialog(win, { @@ -60,20 +62,18 @@ const openCollectionDialog = async (win, watcher) => { console.error(`[ERROR] Cannot open unknown folder: "${resolvedPath}"`); } } -} +}; const openCollection = async (win, watcher, collectionPath, options = {}) => { - if(!watcher.hasWatcher(collectionPath)) { + if (!watcher.hasWatcher(collectionPath)) { try { - const { - name - } = await getCollectionConfigFile(collectionPath); - const uid = generateUidBasedOnHash(collectionPath); + const { name } = await getCollectionConfigFile(collectionPath); + const uid = generateUidBasedOnHash(collectionPath); win.webContents.send('main:collection-opened', collectionPath, uid, name); ipcMain.emit('main:collection-opened', win, collectionPath, uid); - } catch(err) { - if(!options.dontSendDisplayErrors) { + } catch (err) { + if (!options.dontSendDisplayErrors) { win.webContents.send('main:display-error', { error: err.message || 'An error occured while opening the local collection' }); diff --git a/packages/bruno-electron/src/app/last-opened-collections.js b/packages/bruno-electron/src/app/last-opened-collections.js index 88867a41..546b73b5 100644 --- a/packages/bruno-electron/src/app/last-opened-collections.js +++ b/packages/bruno-electron/src/app/last-opened-collections.js @@ -18,8 +18,8 @@ class LastOpenedCollections { add(collectionPath) { const collections = this.store.get('lastOpenedCollections') || []; - if(isDirectory(collectionPath)) { - if(!collections.includes(collectionPath)) { + if (isDirectory(collectionPath)) { + if (!collections.includes(collectionPath)) { collections.push(collectionPath); this.store.set('lastOpenedCollections', collections); } @@ -29,8 +29,8 @@ class LastOpenedCollections { remove(collectionPath) { let collections = this.store.get('lastOpenedCollections') || []; - if(collections.includes(collectionPath)) { - collections = _.filter(collections, c => c !== collectionPath); + if (collections.includes(collectionPath)) { + collections = _.filter(collections, (c) => c !== collectionPath); this.store.set('lastOpenedCollections', collections); } } @@ -38,6 +38,6 @@ class LastOpenedCollections { removeAll() { return this.store.set('lastOpenedCollections', []); } -}; +} module.exports = LastOpenedCollections; diff --git a/packages/bruno-electron/src/app/menu-template.js b/packages/bruno-electron/src/app/menu-template.js index 9156092b..2e3beb82 100644 --- a/packages/bruno-electron/src/app/menu-template.js +++ b/packages/bruno-electron/src/app/menu-template.js @@ -6,7 +6,7 @@ const template = [ submenu: [ { label: 'Open Local Collection', - click () { + click() { ipcMain.emit('main:open-collection'); } }, @@ -14,40 +14,35 @@ const template = [ ] }, { - label: 'Edit', - submenu: [ - { role: 'undo'}, - { role: 'redo'}, - { type: 'separator'}, - { role: 'cut'}, - { role: 'copy'}, - { role: 'paste'} + label: 'Edit', + submenu: [ + { role: 'undo' }, + { role: 'redo' }, + { type: 'separator' }, + { role: 'cut' }, + { role: 'copy' }, + { role: 'paste' } ] }, { - label: 'View', - submenu: [ - { role: 'toggledevtools'}, - { type: 'separator'}, - { role: 'resetzoom'}, - { role: 'zoomin'}, - { role: 'zoomout'}, - { type: 'separator'}, - { role: 'togglefullscreen'} + label: 'View', + submenu: [ + { role: 'toggledevtools' }, + { type: 'separator' }, + { role: 'resetzoom' }, + { role: 'zoomin' }, + { role: 'zoomout' }, + { type: 'separator' }, + { role: 'togglefullscreen' } ] }, { - role: 'window', - submenu: [ - { role: 'minimize'}, - { role: 'close'} - ] + role: 'window', + submenu: [{ role: 'minimize' }, { role: 'close' }] }, { role: 'help', - submenu: [ - { label: 'Learn More'} - ] + submenu: [{ label: 'Learn More' }] } ]; diff --git a/packages/bruno-electron/src/app/preferences.js b/packages/bruno-electron/src/app/preferences.js index b72385fa..f1b86b0f 100644 --- a/packages/bruno-electron/src/app/preferences.js +++ b/packages/bruno-electron/src/app/preferences.js @@ -2,7 +2,7 @@ * The preferences are stored in the browser local storage. * When the app is started, an IPC message is published from the renderer process to set the preferences. * The electron process uses this module to get the preferences. - * + * * { * request: { * sslVerification: boolean @@ -14,11 +14,11 @@ let preferences = {}; const getPreferences = () => { return preferences; -} +}; const setPreferences = (newPreferences) => { preferences = newPreferences; -} +}; module.exports = { getPreferences, diff --git a/packages/bruno-electron/src/app/watcher.js b/packages/bruno-electron/src/app/watcher.js index 988b00bf..6edd0b61 100644 --- a/packages/bruno-electron/src/app/watcher.js +++ b/packages/bruno-electron/src/app/watcher.js @@ -3,19 +3,9 @@ const fs = require('fs'); const path = require('path'); const chokidar = require('chokidar'); const { hasJsonExtension, hasBruExtension, writeFile } = require('../utils/filesystem'); -const { - bruToEnvJson, - envJsonToBru, - bruToJson, - jsonToBru -} = require('../bru'); +const { bruToEnvJson, envJsonToBru, bruToJson, jsonToBru } = require('../bru'); -const { - isLegacyEnvFile, - migrateLegacyEnvFile, - isLegacyBruFile, - migrateLegacyBruFile -} = require('../bru/migrate'); +const { isLegacyEnvFile, migrateLegacyEnvFile, isLegacyBruFile, migrateLegacyBruFile } = require('../bru/migrate'); const { itemSchema } = require('@usebruno/schema'); const { uuid } = require('../utils/common'); const { getRequestUid } = require('../cache/requestUids'); @@ -46,16 +36,16 @@ const hydrateRequestWithUuid = (request, pathname) => { const bodyFormUrlEncoded = _.get(request, 'request.body.formUrlEncoded', []); const bodyMultipartForm = _.get(request, 'request.body.multipartForm', []); - params.forEach((param) => param.uid = uuid()); - headers.forEach((header) => header.uid = uuid()); - requestVars.forEach((variable) => variable.uid = uuid()); - responseVars.forEach((variable) => variable.uid = uuid()); - assertions.forEach((assertion) => assertion.uid = uuid()); - bodyFormUrlEncoded.forEach((param) => param.uid = uuid()); - bodyMultipartForm.forEach((param) => param.uid = uuid()); + params.forEach((param) => (param.uid = uuid())); + headers.forEach((header) => (header.uid = uuid())); + requestVars.forEach((variable) => (variable.uid = uuid())); + responseVars.forEach((variable) => (variable.uid = uuid())); + assertions.forEach((assertion) => (assertion.uid = uuid())); + bodyFormUrlEncoded.forEach((param) => (param.uid = uuid())); + bodyMultipartForm.forEach((param) => (param.uid = uuid())); return request; -} +}; const addEnvironmentFile = async (win, pathname, collectionUid) => { try { @@ -65,13 +55,13 @@ const addEnvironmentFile = async (win, pathname, collectionUid) => { collectionUid, pathname, name: basename - }, + } }; let bruContent = fs.readFileSync(pathname, 'utf8'); // migrate old env json to bru file - if(isLegacyEnvFile(bruContent)) { + if (isLegacyEnvFile(bruContent)) { bruContent = await migrateLegacyEnvFile(bruContent, pathname); } @@ -79,10 +69,10 @@ const addEnvironmentFile = async (win, pathname, collectionUid) => { file.data.name = basename.substring(0, basename.length - 4); file.data.uid = getRequestUid(pathname); - _.each(_.get(file, 'data.variables', []), (variable) => variable.uid = uuid()); + _.each(_.get(file, 'data.variables', []), (variable) => (variable.uid = uuid())); win.webContents.send('main:collection-tree-updated', 'addEnvironmentFile', file); } catch (err) { - console.error(err) + console.error(err); } }; @@ -101,14 +91,14 @@ const changeEnvironmentFile = async (win, pathname, collectionUid) => { file.data = bruToEnvJson(bruContent); file.data.name = basename.substring(0, basename.length - 4); file.data.uid = getRequestUid(pathname); - _.each(_.get(file, 'data.variables', []), (variable) => variable.uid = uuid()); + _.each(_.get(file, 'data.variables', []), (variable) => (variable.uid = uuid())); // we are reusing the addEnvironmentFile event itself // this is because the uid of the pathname remains the same // and the collection tree will be able to update the existing environment win.webContents.send('main:collection-tree-updated', 'addEnvironmentFile', file); } catch (err) { - console.error(err) + console.error(err); } }; @@ -118,24 +108,24 @@ const unlinkEnvironmentFile = async (win, pathname, collectionUid) => { meta: { collectionUid, pathname, - name: path.basename(pathname), + name: path.basename(pathname) }, data: { uid: getRequestUid(pathname), - name: path.basename(pathname).substring(0, path.basename(pathname).length - 4), + name: path.basename(pathname).substring(0, path.basename(pathname).length - 4) } }; win.webContents.send('main:collection-tree-updated', 'unlinkEnvironmentFile', file); } catch (err) { - console.error(err) + console.error(err); } }; const add = async (win, pathname, collectionUid, collectionPath) => { console.log(`watcher add: ${pathname}`); - if(isJsonEnvironmentConfig(pathname, collectionPath)) { + if (isJsonEnvironmentConfig(pathname, collectionPath)) { try { const dirname = path.dirname(pathname); const bruContent = fs.readFileSync(pathname, 'utf8'); @@ -147,7 +137,7 @@ const add = async (win, pathname, collectionUid, collectionPath) => { fs.mkdirSync(envDirectory); } - for(const env of jsonData) { + for (const env of jsonData) { const bruEnvFilename = path.join(envDirectory, `${env.name}.bru`); const bruContent = envJsonToBru(env); await writeFile(bruEnvFilename, bruContent); @@ -161,12 +151,12 @@ const add = async (win, pathname, collectionUid, collectionPath) => { return; } - if(isBruEnvironmentConfig(pathname, collectionPath)) { + if (isBruEnvironmentConfig(pathname, collectionPath)) { return addEnvironmentFile(win, pathname, collectionUid); } // migrate old json files to bru - if(hasJsonExtension(pathname)) { + if (hasJsonExtension(pathname)) { try { const json = fs.readFileSync(pathname, 'utf8'); const jsonData = JSON.parse(json); @@ -178,7 +168,7 @@ const add = async (win, pathname, collectionUid, collectionPath) => { const re = /(.*)\.json$/; const subst = `$1.bru`; const bruFilename = pathname.replace(re, subst); - + await writeFile(bruFilename, content); await fs.unlinkSync(pathname); } catch (err) { @@ -186,20 +176,20 @@ const add = async (win, pathname, collectionUid, collectionPath) => { } } - if(hasBruExtension(pathname)) { + if (hasBruExtension(pathname)) { const file = { meta: { collectionUid, pathname, - name: path.basename(pathname), + name: path.basename(pathname) } - } + }; try { let bruContent = fs.readFileSync(pathname, 'utf8'); // migrate old bru format to new bru format - if(isLegacyBruFile(bruContent)) { + if (isLegacyBruFile(bruContent)) { bruContent = await migrateLegacyBruFile(bruContent, pathname); } @@ -207,7 +197,7 @@ const add = async (win, pathname, collectionUid, collectionPath) => { hydrateRequestWithUuid(file.data, pathname); win.webContents.send('main:collection-tree-updated', 'addFile', file); } catch (err) { - console.error(err) + console.error(err); } } }; @@ -215,7 +205,7 @@ const add = async (win, pathname, collectionUid, collectionPath) => { const addDirectory = (win, pathname, collectionUid, collectionPath) => { const envDirectory = path.join(collectionPath, 'environments'); - if(pathname === envDirectory) { + if (pathname === envDirectory) { return; } @@ -223,44 +213,43 @@ const addDirectory = (win, pathname, collectionUid, collectionPath) => { meta: { collectionUid, pathname, - name: path.basename(pathname), + name: path.basename(pathname) } }; win.webContents.send('main:collection-tree-updated', 'addDir', directory); }; const change = async (win, pathname, collectionUid, collectionPath) => { - if(isBruEnvironmentConfig(pathname, collectionPath)) { + if (isBruEnvironmentConfig(pathname, collectionPath)) { return changeEnvironmentFile(win, pathname, collectionUid); } - if(hasBruExtension(pathname)) { + if (hasBruExtension(pathname)) { try { const file = { meta: { collectionUid, pathname, - name: path.basename(pathname), + name: path.basename(pathname) } }; - + const bru = fs.readFileSync(pathname, 'utf8'); file.data = bruToJson(bru); hydrateRequestWithUuid(file.data, pathname); win.webContents.send('main:collection-tree-updated', 'change', file); } catch (err) { - console.error(err) + console.error(err); } } - }; const unlink = (win, pathname, collectionUid, collectionPath) => { - if(isBruEnvironmentConfig(pathname, collectionPath)) { + if (isBruEnvironmentConfig(pathname, collectionPath)) { return unlinkEnvironmentFile(win, pathname, collectionUid); } - if(hasBruExtension(pathname)) { + if (hasBruExtension(pathname)) { const file = { meta: { collectionUid, @@ -270,12 +259,12 @@ const unlink = (win, pathname, collectionUid, collectionPath) => { }; win.webContents.send('main:collection-tree-updated', 'unlink', file); } -} +}; const unlinkDir = (win, pathname, collectionUid, collectionPath) => { const envDirectory = path.join(collectionPath, 'environments'); - if(pathname === envDirectory) { + if (pathname === envDirectory) { return; } @@ -287,15 +276,15 @@ const unlinkDir = (win, pathname, collectionUid, collectionPath) => { } }; win.webContents.send('main:collection-tree-updated', 'unlinkDir', directory); -} +}; class Watcher { - constructor () { + constructor() { this.watchers = {}; } - addWatcher (win, watchPath, collectionUid) { - if(this.watchers[watchPath]) { + addWatcher(win, watchPath, collectionUid) { + if (this.watchers[watchPath]) { this.watchers[watchPath].close(); } @@ -309,7 +298,7 @@ class Watcher { const watcher = chokidar.watch(watchPath, { ignoreInitial: false, usePolling: false, - ignored: path => ["node_modules", ".git", "bruno.json"].some(s => path.includes(s)), + ignored: (path) => ['node_modules', '.git', 'bruno.json'].some((s) => path.includes(s)), persistent: true, ignorePermissionErrors: true, awaitWriteFinish: { @@ -318,28 +307,28 @@ class Watcher { }, depth: 20 }); - + watcher - .on('add', pathname => add(win, pathname, collectionUid, watchPath)) - .on('addDir', pathname => addDirectory(win, pathname, collectionUid, watchPath)) - .on('change', pathname => change(win, pathname, collectionUid, watchPath)) - .on('unlink', pathname => unlink(win, pathname, collectionUid, watchPath)) - .on('unlinkDir', pathname => unlinkDir(win, pathname, collectionUid, watchPath)) - - self.watchers[watchPath] = watcher; + .on('add', (pathname) => add(win, pathname, collectionUid, watchPath)) + .on('addDir', (pathname) => addDirectory(win, pathname, collectionUid, watchPath)) + .on('change', (pathname) => change(win, pathname, collectionUid, watchPath)) + .on('unlink', (pathname) => unlink(win, pathname, collectionUid, watchPath)) + .on('unlinkDir', (pathname) => unlinkDir(win, pathname, collectionUid, watchPath)); + + self.watchers[watchPath] = watcher; }, 100); } - hasWatcher (watchPath) { + hasWatcher(watchPath) { return this.watchers[watchPath]; } - removeWatcher (watchPath, win) { - if(this.watchers[watchPath]) { + removeWatcher(watchPath, win) { + if (this.watchers[watchPath]) { this.watchers[watchPath].close(); this.watchers[watchPath] = null; } } -}; +} -module.exports = Watcher; +module.exports = Watcher; diff --git a/packages/bruno-electron/src/bru/index.js b/packages/bruno-electron/src/bru/index.js index 402ac043..6b1d73cd 100644 --- a/packages/bruno-electron/src/bru/index.js +++ b/packages/bruno-electron/src/bru/index.js @@ -1,10 +1,5 @@ const _ = require('lodash'); -const { - bruToJsonV2, - jsonToBruV2, - bruToEnvJsonV2, - envJsonToBruV2 -} = require('@usebruno/lang'); +const { bruToJsonV2, jsonToBruV2, bruToEnvJsonV2, envJsonToBruV2 } = require('@usebruno/lang'); const { each } = require('lodash'); const bruToEnvJson = (bru) => { @@ -14,15 +9,15 @@ const bruToEnvJson = (bru) => { // the app env format requires each variable to have a type // this need to be evaulated 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"); + if (json && json.variables && json.variables.length) { + each(json.variables, (v) => (v.type = 'text')); } return json; } catch (error) { return Promise.reject(e); } -} +}; const envJsonToBru = (json) => { try { @@ -31,14 +26,14 @@ const envJsonToBru = (json) => { } catch (error) { return Promise.reject(e); } -} +}; /** * 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 users - * + * * @param {string} bru The BRU file content. * @returns {object} The JSON representation of the BRU file. */ @@ -46,35 +41,35 @@ const bruToJson = (bru) => { try { const json = bruToJsonV2(bru); - let requestType = _.get(json, "meta.type"); - if(requestType === "http") { - requestType = "http-request" - } else if(requestType === "graphql") { - requestType = "graphql-request"; + let requestType = _.get(json, 'meta.type'); + if (requestType === 'http') { + requestType = 'http-request'; + } else if (requestType === 'graphql') { + requestType = 'graphql-request'; } else { - requestType = "http-request"; + requestType = 'http-request'; } - const sequence = _.get(json, "meta.seq") + const sequence = _.get(json, 'meta.seq'); const transformedJson = { - "type": requestType, - "name": _.get(json, "meta.name"), - "seq": !isNaN(sequence) ? Number(sequence) : 1, - "request": { - "method": _.upperCase(_.get(json, "http.method")), - "url": _.get(json, "http.url"), - "params": _.get(json, "query", []), - "headers": _.get(json, "headers", []), - "body": _.get(json, "body", {}), - "script": _.get(json, "script", {}), - "vars": _.get(json, "vars", {}), - "assertions": _.get(json, "assertions", []), - "tests": _.get(json, "tests", "") + type: requestType, + name: _.get(json, 'meta.name'), + seq: !isNaN(sequence) ? Number(sequence) : 1, + request: { + method: _.upperCase(_.get(json, 'http.method')), + url: _.get(json, 'http.url'), + params: _.get(json, 'query', []), + headers: _.get(json, 'headers', []), + body: _.get(json, 'body', {}), + script: _.get(json, 'script', {}), + vars: _.get(json, 'vars', {}), + assertions: _.get(json, 'assertions', []), + tests: _.get(json, 'tests', '') } }; - transformedJson.request.body.mode = _.get(json, "http.body", "none"); + transformedJson.request.body.mode = _.get(json, 'http.body', 'none'); return transformedJson; } catch (e) { @@ -83,28 +78,28 @@ const bruToJson = (bru) => { }; /** * The transformer function for converting a JSON to BRU file. - * + * * We map the json response from the app and transform it into the DSL * format that the bru lang understands - * + * * @param {object} json The JSON representation of the BRU file. * @returns {string} The BRU file content. */ const jsonToBru = (json) => { let type = _.get(json, 'type'); if (type === 'http-request') { - type = "http"; + type = 'http'; } else if (type === 'graphql-request') { - type = "graphql"; + type = 'graphql'; } else { - type = "http"; + type = 'http'; } const bruJson = { meta: { name: _.get(json, 'name'), type: type, - seq: _.get(json, 'seq'), + seq: _.get(json, 'seq') }, http: { method: _.lowerCase(_.get(json, 'request.method')), @@ -120,7 +115,7 @@ const jsonToBru = (json) => { res: _.get(json, 'request.vars.res', []) }, assertions: _.get(json, 'request.assertions', []), - tests: _.get(json, 'request.tests', ''), + tests: _.get(json, 'request.tests', '') }; return jsonToBruV2(bruJson); @@ -130,5 +125,5 @@ module.exports = { bruToJson, jsonToBru, bruToEnvJson, - envJsonToBru, + envJsonToBru }; diff --git a/packages/bruno-electron/src/bru/migrate.js b/packages/bruno-electron/src/bru/migrate.js index b98ccf9c..a74dc2fd 100644 --- a/packages/bruno-electron/src/bru/migrate.js +++ b/packages/bruno-electron/src/bru/migrate.js @@ -34,15 +34,15 @@ const isLegacyBruFile = (bruContent = '') => { for (let line of lines) { line = line.trim(); - if (line.startsWith("name")) { + if (line.startsWith('name')) { hasName = true; - } else if (line.startsWith("method")) { + } else if (line.startsWith('method')) { hasMethod = true; - } else if (line.startsWith("url")) { + } else if (line.startsWith('url')) { hasUrl = true; } } - + return hasName && hasMethod && hasUrl; }; @@ -51,16 +51,16 @@ const migrateLegacyBruFile = async (bruContent, pathname) => { let type = _.get(json, 'type'); if (type === 'http-request') { - type = "http"; + type = 'http'; } else if (type === 'graphql-request') { - type = "graphql"; + type = 'graphql'; } else { - type = "http"; + type = 'http'; } let script = {}; let legacyScript = _.get(json, 'request.script'); - if(legacyScript && legacyScript.trim().length > 0) { + if (legacyScript && legacyScript.trim().length > 0) { script = { res: legacyScript }; @@ -70,7 +70,7 @@ const migrateLegacyBruFile = async (bruContent, pathname) => { meta: { name: _.get(json, 'name'), type: type, - seq: _.get(json, 'seq'), + seq: _.get(json, 'seq') }, http: { method: _.lowerCase(_.get(json, 'request.method')), @@ -81,7 +81,7 @@ const migrateLegacyBruFile = async (bruContent, pathname) => { headers: _.get(json, 'request.headers', []), body: _.get(json, 'request.body', {}), script: script, - tests: _.get(json, 'request.tests', ''), + tests: _.get(json, 'request.tests', '') }; const newBruContent = jsonToBruV2(bruJson); @@ -89,11 +89,11 @@ const migrateLegacyBruFile = async (bruContent, pathname) => { await writeFile(pathname, newBruContent); return newBruContent; -} +}; module.exports = { isLegacyEnvFile, migrateLegacyEnvFile, isLegacyBruFile, migrateLegacyBruFile -}; \ No newline at end of file +}; diff --git a/packages/bruno-electron/src/cache/requestUids.js b/packages/bruno-electron/src/cache/requestUids.js index 0a166b41..55f7fc29 100644 --- a/packages/bruno-electron/src/cache/requestUids.js +++ b/packages/bruno-electron/src/cache/requestUids.js @@ -2,7 +2,7 @@ * we maintain a cache of request uids to ensure that we * preserve the same uid for a request even when the request * moves to a different location - * + * * In the past, we used to generate unique ids based on the * pathname of the request, but we faced problems when implementing * functionality where the user can move the request to a different diff --git a/packages/bruno-electron/src/index.js b/packages/bruno-electron/src/index.js index d04d9895..e3aaae71 100644 --- a/packages/bruno-electron/src/index.js +++ b/packages/bruno-electron/src/index.js @@ -35,8 +35,8 @@ app.on('ready', async () => { webPreferences: { nodeIntegration: true, contextIsolation: true, - preload: path.join(__dirname, "preload.js") - }, + preload: path.join(__dirname, 'preload.js') + } }); const url = isDev @@ -50,7 +50,7 @@ app.on('ready', async () => { mainWindow.loadURL(url); watcher = new Watcher(); - mainWindow.webContents.on('new-window', function(e, url) { + mainWindow.webContents.on('new-window', function (e, url) { e.preventDefault(); require('electron').shell.openExternal(url); }); diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js index d5b2f5fe..fd8975d2 100644 --- a/packages/bruno-electron/src/ipc/collection.js +++ b/packages/bruno-electron/src/ipc/collection.js @@ -2,11 +2,7 @@ const _ = require('lodash'); const fs = require('fs'); const path = require('path'); const { ipcMain } = require('electron'); -const { - envJsonToBru, - bruToJson, - jsonToBru -} = require('../bru'); +const { envJsonToBru, bruToJson, jsonToBru } = require('../bru'); const { isValidPathname, @@ -21,7 +17,7 @@ const { stringifyJson } = require('../utils/common'); const { openCollectionDialog, openCollection } = require('../app/collections'); const { generateUidBasedOnHash } = require('../utils/common'); const { moveRequestUid, deleteRequestUid } = require('../cache/requestUids'); -const { setPreferences } = require("../app/preferences"); +const { setPreferences } = require('../app/preferences'); const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollections) => { // browse directory @@ -36,35 +32,38 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection }); // create collection - ipcMain.handle('renderer:create-collection', async (event, collectionName, collectionFolderName, collectionLocation) => { - try { - const dirPath = path.join(collectionLocation, collectionFolderName); - if (fs.existsSync(dirPath)){ - throw new Error(`collection: ${dirPath} already exists`); + ipcMain.handle( + 'renderer:create-collection', + async (event, collectionName, collectionFolderName, collectionLocation) => { + try { + const dirPath = path.join(collectionLocation, collectionFolderName); + if (fs.existsSync(dirPath)) { + throw new Error(`collection: ${dirPath} already exists`); + } + + if (!isValidPathname(dirPath)) { + throw new Error(`collection: invalid pathname - ${dir}`); + } + + await createDirectory(dirPath); + + const uid = generateUidBasedOnHash(dirPath); + const content = await stringifyJson({ + version: '1', + name: collectionName, + type: 'collection' + }); + await writeFile(path.join(dirPath, 'bruno.json'), content); + + mainWindow.webContents.send('main:collection-opened', dirPath, uid, collectionName); + ipcMain.emit('main:collection-opened', mainWindow, dirPath, uid); + + return; + } catch (error) { + return Promise.reject(error); } - - if(!isValidPathname(dirPath)) { - throw new Error(`collection: invalid pathname - ${dir}`); - } - - await createDirectory(dirPath); - - const uid = generateUidBasedOnHash(dirPath); - const content = await stringifyJson({ - version: '1', - name: collectionName, - type: 'collection' - }); - await writeFile(path.join(dirPath, 'bruno.json'), content); - - mainWindow.webContents.send('main:collection-opened', dirPath, uid, collectionName); - ipcMain.emit('main:collection-opened', mainWindow, dirPath, uid); - - return; - } catch (error) { - return Promise.reject(error); } - }); + ); // rename collection ipcMain.handle('renderer:rename-collection', async (event, newName, collectionPathname) => { @@ -94,7 +93,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection // new request ipcMain.handle('renderer:new-request', async (event, pathname, request) => { try { - if (fs.existsSync(pathname)){ + if (fs.existsSync(pathname)) { throw new Error(`path: ${pathname} already exists`); } @@ -108,7 +107,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection // save request ipcMain.handle('renderer:save-request', async (event, pathname, request) => { try { - if (!fs.existsSync(pathname)){ + if (!fs.existsSync(pathname)) { throw new Error(`path: ${pathname} does not exist`); } @@ -123,12 +122,12 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection ipcMain.handle('renderer:create-environment', async (event, collectionPathname, name) => { try { const envDirPath = path.join(collectionPathname, 'environments'); - if (!fs.existsSync(envDirPath)){ + if (!fs.existsSync(envDirPath)) { await createDirectory(envDirPath); } const envFilePath = path.join(envDirPath, `${name}.bru`); - if (fs.existsSync(envFilePath)){ + if (fs.existsSync(envFilePath)) { throw new Error(`environment: ${envFilePath} already exists`); } @@ -145,12 +144,12 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection ipcMain.handle('renderer:save-environment', async (event, collectionPathname, environment) => { try { const envDirPath = path.join(collectionPathname, 'environments'); - if (!fs.existsSync(envDirPath)){ + if (!fs.existsSync(envDirPath)) { await createDirectory(envDirPath); } const envFilePath = path.join(envDirPath, `${environment.name}.bru`); - if (!fs.existsSync(envFilePath)){ + if (!fs.existsSync(envFilePath)) { throw new Error(`environment: ${envFilePath} does not exist`); } @@ -166,12 +165,12 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection try { const envDirPath = path.join(collectionPathname, 'environments'); const envFilePath = path.join(envDirPath, `${environmentName}.bru`); - if (!fs.existsSync(envFilePath)){ + if (!fs.existsSync(envFilePath)) { throw new Error(`environment: ${envFilePath} does not exist`); } const newEnvFilePath = path.join(envDirPath, `${newName}.bru`); - if (fs.existsSync(newEnvFilePath)){ + if (fs.existsSync(newEnvFilePath)) { throw new Error(`environment: ${newEnvFilePath} already exists`); } @@ -186,7 +185,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection try { const envDirPath = path.join(collectionPathname, 'environments'); const envFilePath = path.join(envDirPath, `${environmentName}.bru`); - if (!fs.existsSync(envFilePath)){ + if (!fs.existsSync(envFilePath)) { throw new Error(`environment: ${envFilePath} does not exist`); } @@ -199,18 +198,18 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection // rename item ipcMain.handle('renderer:rename-item', async (event, oldPath, newPath, newName) => { try { - if (!fs.existsSync(oldPath)){ + if (!fs.existsSync(oldPath)) { throw new Error(`path: ${oldPath} does not exist`); } - if (fs.existsSync(newPath)){ + if (fs.existsSync(newPath)) { throw new Error(`path: ${oldPath} already exists`); } // if its directory, rename and return - if(isDirectory(oldPath)) { + if (isDirectory(oldPath)) { const bruFilesAtSource = await searchForBruFiles(oldPath); - for(let bruFile of bruFilesAtSource) { + for (let bruFile of bruFilesAtSource) { const newBruFilePath = bruFile.replace(oldPath, newPath); moveRequestUid(bruFile, newBruFilePath); } @@ -218,7 +217,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } const isBru = hasBruExtension(oldPath); - if(!isBru) { + if (!isBru) { throw new Error(`path: ${oldPath} is not a bru file`); } @@ -241,8 +240,8 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection // new folder ipcMain.handle('renderer:new-folder', async (event, pathname) => { try { - if (!fs.existsSync(pathname)){ - fs.mkdirSync(pathname); + if (!fs.existsSync(pathname)) { + fs.mkdirSync(pathname); } else { return Promise.reject(new Error('The directory already exists')); } @@ -254,20 +253,20 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection // delete file/folder ipcMain.handle('renderer:delete-item', async (event, pathname, type) => { try { - if(type === 'folder') { - if(!fs.existsSync(pathname)) { + if (type === 'folder') { + if (!fs.existsSync(pathname)) { return Promise.reject(new Error('The directory does not exist')); } // delete the request uid mappings const bruFilesAtSource = await searchForBruFiles(pathname); - for(let bruFile of bruFilesAtSource) { + for (let bruFile of bruFilesAtSource) { deleteRequestUid(bruFile); } - fs.rmSync(pathname, { recursive: true, force: true}); + fs.rmSync(pathname, { recursive: true, force: true }); } else if (['http-request', 'graphql-request'].includes(type)) { - if(!fs.existsSync(pathname)) { + if (!fs.existsSync(pathname)) { return Promise.reject(new Error('The file does not exist')); } @@ -283,13 +282,13 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection }); ipcMain.handle('renderer:open-collection', () => { - if(watcher && mainWindow) { + if (watcher && mainWindow) { openCollectionDialog(mainWindow, watcher); } }); ipcMain.handle('renderer:remove-collection', async (event, collectionPath) => { - if(watcher && mainWindow) { + if (watcher && mainWindow) { console.log(`watcher stopWatching: ${collectionPath}`); watcher.removeWatcher(collectionPath, mainWindow); lastOpenedCollections.remove(collectionPath); @@ -301,13 +300,13 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection let collectionName = collection.name; let collectionPath = path.join(collectionLocation, collectionName); - if (fs.existsSync(collectionPath)){ + if (fs.existsSync(collectionPath)) { throw new Error(`collection: ${collectionPath} already exists`); } // Recursive function to parse the collection items and create files/folders const parseCollectionItems = (items = [], currentPath) => { - items.forEach(item => { + items.forEach((item) => { if (['http-request', 'graphql-request'].includes(item.type)) { const content = jsonToBru(item); const filePath = path.join(currentPath, `${item.name}.bru`); @@ -317,7 +316,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection const folderPath = path.join(currentPath, item.name); fs.mkdirSync(folderPath); - if(item.items && item.items.length) { + if (item.items && item.items.length) { parseCollectionItems(item.items, folderPath); } } @@ -326,11 +325,11 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection const parseEnvironments = (environments = [], collectionPath) => { const envDirPath = path.join(collectionPath, 'environments'); - if(!fs.existsSync(envDirPath)){ + if (!fs.existsSync(envDirPath)) { fs.mkdirSync(envDirPath); } - environments.forEach(env => { + environments.forEach((env) => { const content = envJsonToBru(env); const filePath = path.join(envDirPath, `${env.name}.bru`); fs.writeFileSync(filePath, content); @@ -355,7 +354,6 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection // create folder and files based on collection await parseCollectionItems(collection.items, collectionPath); await parseEnvironments(collection.environments, collectionPath); - } catch (error) { return Promise.reject(error); } @@ -363,11 +361,11 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection ipcMain.handle('renderer:resequence-items', async (event, itemsToResequence) => { try { - for(let item of itemsToResequence) { + for (let item of itemsToResequence) { const bru = fs.readFileSync(item.pathname, 'utf8'); const jsonData = bruToJson(bru); - if(jsonData.seq !== item.seq) { + if (jsonData.seq !== item.seq) { jsonData.seq = item.seq; const content = jsonToBru(jsonData); await writeFile(item.pathname, content); @@ -397,17 +395,17 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection const folderName = path.basename(folderPath); const newFolderPath = path.join(destinationPath, folderName); - if(!fs.existsSync(folderPath)) { + if (!fs.existsSync(folderPath)) { throw new Error(`folder: ${folderPath} does not exist`); } - if(fs.existsSync(newFolderPath)) { + if (fs.existsSync(newFolderPath)) { throw new Error(`folder: ${newFolderPath} already exists`); } const bruFilesAtSource = await searchForBruFiles(folderPath); - for(let bruFile of bruFilesAtSource) { + for (let bruFile of bruFilesAtSource) { const newBruFilePath = bruFile.replace(folderPath, newFolderPath); moveRequestUid(bruFile, newBruFilePath); } @@ -422,9 +420,9 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection // reload last opened collections const lastOpened = lastOpenedCollections.getAll(); - if(lastOpened && lastOpened.length) { - for(let collectionPath of lastOpened) { - if(isDirectory(collectionPath)) { + if (lastOpened && lastOpened.length) { + for (let collectionPath of lastOpened) { + if (isDirectory(collectionPath)) { openCollection(mainWindow, watcher, collectionPath, { dontSendDisplayErrors: true }); @@ -440,7 +438,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection const registerMainEventHandlers = (mainWindow, watcher, lastOpenedCollections) => { ipcMain.on('main:open-collection', () => { - if(watcher && mainWindow) { + if (watcher && mainWindow) { openCollectionDialog(mainWindow, watcher); } }); @@ -449,12 +447,11 @@ const registerMainEventHandlers = (mainWindow, watcher, lastOpenedCollections) = watcher.addWatcher(win, pathname, uid); lastOpenedCollections.add(pathname); }); - -} +}; const registerCollectionsIpc = (mainWindow, watcher, lastOpenedCollections) => { registerRendererEventHandlers(mainWindow, watcher, lastOpenedCollections); registerMainEventHandlers(mainWindow, watcher, lastOpenedCollections); -} +}; module.exports = registerCollectionsIpc; diff --git a/packages/bruno-electron/src/ipc/network/helper.js b/packages/bruno-electron/src/ipc/network/helper.js index 6be61ea9..d4e49688 100644 --- a/packages/bruno-electron/src/ipc/network/helper.js +++ b/packages/bruno-electron/src/ipc/network/helper.js @@ -1,8 +1,4 @@ -const { - each, - filter -} = require('lodash'); - +const { each, filter } = require('lodash'); const sortCollection = (collection) => { const items = collection.items || []; diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 6a80ccbc..4858d61d 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -12,7 +12,7 @@ const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../util const { uuid } = require('../../utils/common'); const interpolateVars = require('./interpolate-vars'); const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper'); -const { getPreferences } = require('../../app/preferences'); +const { getPreferences } = require('../../app/preferences'); // override the default escape function to prevent escaping Mustache.escape = function (value) { @@ -45,7 +45,7 @@ const getEnvVars = (environment = {}) => { const envVars = {}; each(variables, (variable) => { - if(variable.enabled) { + if (variable.enabled) { envVars[variable.name] = Mustache.escape(variable.value); } }); @@ -53,19 +53,19 @@ const getEnvVars = (environment = {}) => { return { ...envVars, __name__: environment.name - } + }; }; const getSize = (data) => { - if(!data) { + if (!data) { return 0; } - if(typeof data === 'string') { + if (typeof data === 'string') { return Buffer.byteLength(data, 'utf8'); } - if(typeof data === 'object') { + if (typeof data === 'object') { return Buffer.byteLength(JSON.stringify(data), 'utf8'); } @@ -74,219 +74,197 @@ const getSize = (data) => { const registerNetworkIpc = (mainWindow) => { // handler for sending http request - ipcMain.handle('send-http-request', async (event, item, collectionUid, collectionPath, environment, collectionVariables) => { - const cancelTokenUid = uuid(); - const requestUid = uuid(); + ipcMain.handle( + 'send-http-request', + async (event, item, collectionUid, collectionPath, environment, collectionVariables) => { + const cancelTokenUid = uuid(); + const requestUid = uuid(); - const onConsoleLog = (type, args) => { - console[type](...args); + const onConsoleLog = (type, args) => { + console[type](...args); - mainWindow.webContents.send('main:console-log', { - type, - args - }); - }; - - mainWindow.webContents.send('main:run-request-event', { - type: 'request-queued', - requestUid, - collectionUid, - itemUid: item.uid, - cancelTokenUid - }); - - const _request = item.draft ? item.draft.request : item.request; - const request = prepareRequest(_request); - const envVars = getEnvVars(environment); - - try { - // make axios work in node using form data - // reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427 - if(request.headers && request.headers['content-type'] === 'multipart/form-data') { - const form = new FormData(); - forOwn(request.data, (value, key) => { - form.append(key, value); + mainWindow.webContents.send('main:console-log', { + type, + args }); - extend(request.headers, form.getHeaders()); - request.data = form; - } + }; - const cancelToken = axios.CancelToken.source(); - request.cancelToken = cancelToken.token; - saveCancelToken(cancelTokenUid, cancelToken); - - // run pre-request vars - const preRequestVars = get(request, 'vars.req', []); - if(preRequestVars && preRequestVars.length) { - const varsRuntime = new VarsRuntime(); - const result = varsRuntime.runPreRequestVars(preRequestVars, request, envVars, collectionVariables, collectionPath); - - mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, - requestUid, - collectionUid - }); - } - - // run pre-request script - const requestScript = get(request, 'script.req'); - if(requestScript && requestScript.length) { - const scriptRuntime = new ScriptRuntime(); - const result = await scriptRuntime.runRequestScript(requestScript, request, envVars, collectionVariables, collectionPath, onConsoleLog); - - mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, - requestUid, - collectionUid - }); - } - - interpolateVars(request, envVars, collectionVariables); - - // stringify the request url encoded params - if(request.headers['content-type'] === 'application/x-www-form-urlencoded') { - request.data = qs.stringify(request.data); - } - - // todo: - // i have no clue why electron can't send the request object - // without safeParseJSON(safeStringifyJSON(request.data)) mainWindow.webContents.send('main:run-request-event', { - type: 'request-sent', - requestSent: { - url: request.url, - method: request.method, - headers: request.headers, - data: safeParseJSON(safeStringifyJSON(request.data)) - }, + type: 'request-queued', + requestUid, collectionUid, itemUid: item.uid, - requestUid, cancelTokenUid }); - const preferences = getPreferences(); - const sslVerification = get(preferences, 'request.sslVerification', true); - const httpsAgentRequestFields = {}; - if(!sslVerification) { - httpsAgentRequestFields['rejectUnauthorized'] = false; - } - else { - const cacertArray = [preferences['cacert'], process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS]; - cacertFile = cacertArray.find(el => el); - if(cacertFile && cacertFile.length > 1) { - try { - const fs = require('fs'); - caCrt = fs.readFileSync(cacertFile); - httpsAgentRequestFields['ca'] = caCrt; - } catch(err) { - console.log('Error reading CA cert file:' + cacertFile, err); + const _request = item.draft ? item.draft.request : item.request; + const request = prepareRequest(_request); + const envVars = getEnvVars(environment); + + try { + // make axios work in node using form data + // reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427 + if (request.headers && request.headers['content-type'] === 'multipart/form-data') { + const form = new FormData(); + forOwn(request.data, (value, key) => { + form.append(key, value); + }); + extend(request.headers, form.getHeaders()); + request.data = form; + } + + const cancelToken = axios.CancelToken.source(); + request.cancelToken = cancelToken.token; + saveCancelToken(cancelTokenUid, cancelToken); + + // run pre-request vars + const preRequestVars = get(request, 'vars.req', []); + if (preRequestVars && preRequestVars.length) { + const varsRuntime = new VarsRuntime(); + const result = varsRuntime.runPreRequestVars( + preRequestVars, + request, + envVars, + collectionVariables, + collectionPath + ); + + mainWindow.webContents.send('main:script-environment-update', { + envVariables: result.envVariables, + collectionVariables: result.collectionVariables, + requestUid, + collectionUid + }); + } + + // run pre-request script + const requestScript = get(request, 'script.req'); + if (requestScript && requestScript.length) { + const scriptRuntime = new ScriptRuntime(); + const result = await scriptRuntime.runRequestScript( + requestScript, + request, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); + + mainWindow.webContents.send('main:script-environment-update', { + envVariables: result.envVariables, + collectionVariables: result.collectionVariables, + requestUid, + collectionUid + }); + } + + interpolateVars(request, envVars, collectionVariables); + + // stringify the request url encoded params + if (request.headers['content-type'] === 'application/x-www-form-urlencoded') { + request.data = qs.stringify(request.data); + } + + // todo: + // i have no clue why electron can't send the request object + // without safeParseJSON(safeStringifyJSON(request.data)) + mainWindow.webContents.send('main:run-request-event', { + type: 'request-sent', + requestSent: { + url: request.url, + method: request.method, + headers: request.headers, + data: safeParseJSON(safeStringifyJSON(request.data)) + }, + collectionUid, + itemUid: item.uid, + requestUid, + cancelTokenUid + }); + + const preferences = getPreferences(); + const sslVerification = get(preferences, 'request.sslVerification', true); + const httpsAgentRequestFields = {}; + if (!sslVerification) { + httpsAgentRequestFields['rejectUnauthorized'] = false; + } else { + const cacertArray = [preferences['cacert'], process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS]; + cacertFile = cacertArray.find((el) => el); + if (cacertFile && cacertFile.length > 1) { + try { + const fs = require('fs'); + caCrt = fs.readFileSync(cacertFile); + httpsAgentRequestFields['ca'] = caCrt; + } catch (err) { + console.log('Error reading CA cert file:' + cacertFile, err); + } } } - } - if(Object.keys(httpsAgentRequestFields).length > 0) { - request.httpsAgent = new https.Agent({ - ...httpsAgentRequestFields - }); - } + if (Object.keys(httpsAgentRequestFields).length > 0) { + request.httpsAgent = new https.Agent({ + ...httpsAgentRequestFields + }); + } - const response = await axios(request); + const response = await axios(request); - // run post-response vars - const postResponseVars = get(request, 'vars.res', []); - if(postResponseVars && postResponseVars.length) { - const varsRuntime = new VarsRuntime(); - const result = varsRuntime.runPostResponseVars(postResponseVars, request, response, envVars, collectionVariables, collectionPath); + // run post-response vars + const postResponseVars = get(request, 'vars.res', []); + if (postResponseVars && postResponseVars.length) { + const varsRuntime = new VarsRuntime(); + const result = varsRuntime.runPostResponseVars( + postResponseVars, + request, + response, + envVars, + collectionVariables, + collectionPath + ); - mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, - requestUid, - collectionUid - }); - } + mainWindow.webContents.send('main:script-environment-update', { + envVariables: result.envVariables, + collectionVariables: result.collectionVariables, + requestUid, + collectionUid + }); + } - // run post-response script - const responseScript = get(request, 'script.res'); - if(responseScript && responseScript.length) { - const scriptRuntime = new ScriptRuntime(); - const result = await scriptRuntime.runResponseScript(responseScript, request, response, envVars, collectionVariables, collectionPath, onConsoleLog); + // run post-response script + const responseScript = get(request, 'script.res'); + if (responseScript && responseScript.length) { + const scriptRuntime = new ScriptRuntime(); + const result = await scriptRuntime.runResponseScript( + responseScript, + request, + response, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); - mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, - requestUid, - collectionUid - }); - } + mainWindow.webContents.send('main:script-environment-update', { + envVariables: result.envVariables, + collectionVariables: result.collectionVariables, + requestUid, + collectionUid + }); + } - // run assertions - const assertions = get(request, 'assertions'); - if(assertions && assertions.length) { - const assertRuntime = new AssertRuntime(); - const results = assertRuntime.runAssertions(assertions, request, response, envVars, collectionVariables, collectionPath); - - mainWindow.webContents.send('main:run-request-event', { - type: 'assertion-results', - results: results, - itemUid: item.uid, - requestUid, - collectionUid - }); - } - - // run tests - const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests'); - if(testFile && testFile.length) { - const testRuntime = new TestRuntime(); - const testResults = testRuntime.runTests(testFile, request, response, envVars, collectionVariables, collectionPath, onConsoleLog); - - mainWindow.webContents.send('main:run-request-event', { - type: 'test-results', - results: testResults.results, - itemUid: item.uid, - requestUid, - collectionUid - }); - - mainWindow.webContents.send('main:script-environment-update', { - envVariables: testResults.envVariables, - collectionVariables: testResults.collectionVariables, - requestUid, - collectionUid - }); - } - - deleteCancelToken(cancelTokenUid); - - return { - status: response.status, - statusText: response.statusText, - headers: response.headers, - data: response.data - }; - } catch (error) { - // todo: better error handling - // need to convey the error to the UI - // and need not be always a network error - deleteCancelToken(cancelTokenUid); - - if (axios.isCancel(error)) { - let error = new Error("Request cancelled"); - error.isCancel = true; - return Promise.reject(error); - } - - if(error && error.response) { // run assertions const assertions = get(request, 'assertions'); - if(assertions && assertions.length) { + if (assertions && assertions.length) { const assertRuntime = new AssertRuntime(); - const results = assertRuntime.runAssertions(assertions, request, error.response, envVars, collectionVariables, collectionPath); - + const results = assertRuntime.runAssertions( + assertions, + request, + response, + envVars, + collectionVariables, + collectionPath + ); + mainWindow.webContents.send('main:run-request-event', { type: 'assertion-results', results: results, @@ -295,13 +273,21 @@ const registerNetworkIpc = (mainWindow) => { collectionUid }); } - + // run tests const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests'); - if(testFile && testFile.length) { + if (testFile && testFile.length) { const testRuntime = new TestRuntime(); - const testResults = testRuntime.runTests(testFile, request, error.response, envVars, collectionVariables, collectionPath, onConsoleLog); - + const testResults = testRuntime.runTests( + testFile, + request, + response, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); + mainWindow.webContents.send('main:run-request-event', { type: 'test-results', results: testResults.results, @@ -317,27 +303,101 @@ const registerNetworkIpc = (mainWindow) => { collectionUid }); } - - return { - status: error.response.status, - statusText: error.response.statusText, - headers: error.response.headers, - data: error.response.data - } - }; - return Promise.reject(error); + deleteCancelToken(cancelTokenUid); + + return { + status: response.status, + statusText: response.statusText, + headers: response.headers, + data: response.data + }; + } catch (error) { + // todo: better error handling + // need to convey the error to the UI + // and need not be always a network error + deleteCancelToken(cancelTokenUid); + + if (axios.isCancel(error)) { + let error = new Error('Request cancelled'); + error.isCancel = true; + return Promise.reject(error); + } + + if (error && error.response) { + // run assertions + const assertions = get(request, 'assertions'); + if (assertions && assertions.length) { + const assertRuntime = new AssertRuntime(); + const results = assertRuntime.runAssertions( + assertions, + request, + error.response, + envVars, + collectionVariables, + collectionPath + ); + + mainWindow.webContents.send('main:run-request-event', { + type: 'assertion-results', + results: results, + itemUid: item.uid, + requestUid, + collectionUid + }); + } + + // run tests + const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests'); + if (testFile && testFile.length) { + const testRuntime = new TestRuntime(); + const testResults = testRuntime.runTests( + testFile, + request, + error.response, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); + + mainWindow.webContents.send('main:run-request-event', { + type: 'test-results', + results: testResults.results, + itemUid: item.uid, + requestUid, + collectionUid + }); + + mainWindow.webContents.send('main:script-environment-update', { + envVariables: testResults.envVariables, + collectionVariables: testResults.collectionVariables, + requestUid, + collectionUid + }); + } + + return { + status: error.response.status, + statusText: error.response.statusText, + headers: error.response.headers, + data: error.response.data + }; + } + + return Promise.reject(error); + } } - }); + ); ipcMain.handle('cancel-http-request', async (event, cancelTokenUid) => { return new Promise((resolve, reject) => { - if(cancelTokenUid && cancelTokens[cancelTokenUid]) { + if (cancelTokenUid && cancelTokens[cancelTokenUid]) { cancelTokens[cancelTokenUid].cancel(); deleteCancelToken(cancelTokenUid); resolve(); } else { - reject(new Error("cancel token not found")); + reject(new Error('cancel token not found')); } }); }); @@ -350,7 +410,7 @@ const registerNetworkIpc = (mainWindow) => { const preferences = getPreferences(); const sslVerification = get(preferences, 'request.sslVerification', true); - if(!sslVerification) { + if (!sslVerification) { request.httpsAgent = new https.Agent({ rejectUnauthorized: false }); @@ -365,240 +425,208 @@ const registerNetworkIpc = (mainWindow) => { data: response.data }; } catch (error) { - if(error.response) { + if (error.response) { return { status: error.response.status, statusText: error.response.statusText, headers: error.response.headers, data: error.response.data - } - }; + }; + } return Promise.reject(error); } }); - ipcMain.handle('renderer:run-collection-folder', async (event, folder, collection, environment, collectionVariables, recursive) => { - const collectionUid = collection.uid; - const collectionPath = collection.pathname; - const folderUid = folder ? folder.uid : null; + ipcMain.handle( + 'renderer:run-collection-folder', + async (event, folder, collection, environment, collectionVariables, recursive) => { + const collectionUid = collection.uid; + const collectionPath = collection.pathname; + const folderUid = folder ? folder.uid : null; - const onConsoleLog = (type, args) => { - console[type](...args); + const onConsoleLog = (type, args) => { + console[type](...args); - mainWindow.webContents.send('main:console-log', { - type, - args - }); - }; - - if(!folder) { - folder = collection; - } - - mainWindow.webContents.send('main:run-folder-event', { - type: 'testrun-started', - isRecursive: recursive, - collectionUid, - folderUid - }); - - try { - const envVars = getEnvVars(environment); - let folderRequests = []; - - if(recursive) { - let sortedFolder = sortFolder(folder); - folderRequests = getAllRequestsInFolderRecursively(sortedFolder); - } else { - each(folder.items, (item) => { - if(item.request) { - folderRequests.push(item); - } + mainWindow.webContents.send('main:console-log', { + type, + args }); + }; - // sort requests by seq property - folderRequests.sort((a, b) => { - return a.seq - b.seq; - }); + if (!folder) { + folder = collection; } - for(let item of folderRequests) { - const itemUid = item.uid; - const eventData = { - collectionUid, - folderUid, - itemUid - }; + mainWindow.webContents.send('main:run-folder-event', { + type: 'testrun-started', + isRecursive: recursive, + collectionUid, + folderUid + }); - let timeStart; - let timeEnd; + try { + const envVars = getEnvVars(environment); + let folderRequests = []; - mainWindow.webContents.send('main:run-folder-event', { - type: 'request-queued', - ...eventData - }); + if (recursive) { + let sortedFolder = sortFolder(folder); + folderRequests = getAllRequestsInFolderRecursively(sortedFolder); + } else { + each(folder.items, (item) => { + if (item.request) { + folderRequests.push(item); + } + }); - const _request = item.draft ? item.draft.request : item.request; - const request = prepareRequest(_request); + // sort requests by seq property + folderRequests.sort((a, b) => { + return a.seq - b.seq; + }); + } - try { - // make axios work in node using form data - // reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427 - if(request.headers && request.headers['content-type'] === 'multipart/form-data') { - const form = new FormData(); - forOwn(request.data, (value, key) => { - form.append(key, value); - }); - extend(request.headers, form.getHeaders()); - request.data = form; - } + for (let item of folderRequests) { + const itemUid = item.uid; + const eventData = { + collectionUid, + folderUid, + itemUid + }; - // run pre-request vars - const preRequestVars = get(request, 'vars.req', []); - if(preRequestVars && preRequestVars.length) { - const varsRuntime = new VarsRuntime(); - varsRuntime.runPreRequestVars(preRequestVars, request, envVars, collectionVariables, collectionPath); - } + let timeStart; + let timeEnd; - // run pre-request script - const requestScript = get(request, 'script.req'); - if(requestScript && requestScript.length) { - const scriptRuntime = new ScriptRuntime(); - const result = await scriptRuntime.runRequestScript(requestScript, request, envVars, collectionVariables, collectionPath, onConsoleLog); - - mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, - collectionUid - }); - } - - // interpolate variables inside request - interpolateVars(request, envVars, collectionVariables); - - // todo: - // i have no clue why electron can't send the request object - // without safeParseJSON(safeStringifyJSON(request.data)) mainWindow.webContents.send('main:run-folder-event', { - type: 'request-sent', - requestSent: { - url: request.url, - method: request.method, - headers: request.headers, - data: safeParseJSON(safeStringifyJSON(request.data)) - }, + type: 'request-queued', ...eventData }); - const preferences = getPreferences(); - const sslVerification = get(preferences, 'request.sslVerification', true); + const _request = item.draft ? item.draft.request : item.request; + const request = prepareRequest(_request); - if(!sslVerification) { - request.httpsAgent = new https.Agent({ - rejectUnauthorized: false - }); - } + try { + // make axios work in node using form data + // reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427 + if (request.headers && request.headers['content-type'] === 'multipart/form-data') { + const form = new FormData(); + forOwn(request.data, (value, key) => { + form.append(key, value); + }); + extend(request.headers, form.getHeaders()); + request.data = form; + } - // send request - timeStart = Date.now(); - const response = await axios(request); - timeEnd = Date.now(); + // run pre-request vars + const preRequestVars = get(request, 'vars.req', []); + if (preRequestVars && preRequestVars.length) { + const varsRuntime = new VarsRuntime(); + varsRuntime.runPreRequestVars(preRequestVars, request, envVars, collectionVariables, collectionPath); + } - // run post-response vars - const postResponseVars = get(request, 'vars.res', []); - if(postResponseVars && postResponseVars.length) { - const varsRuntime = new VarsRuntime(); - const result = varsRuntime.runPostResponseVars(postResponseVars, request, response, envVars, collectionVariables, collectionPath); + // run pre-request script + const requestScript = get(request, 'script.req'); + if (requestScript && requestScript.length) { + const scriptRuntime = new ScriptRuntime(); + const result = await scriptRuntime.runRequestScript( + requestScript, + request, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); - mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, - collectionUid - }); - } + mainWindow.webContents.send('main:script-environment-update', { + envVariables: result.envVariables, + collectionVariables: result.collectionVariables, + collectionUid + }); + } - // run response script - const responseScript = get(request, 'script.res'); - if(responseScript && responseScript.length) { - const scriptRuntime = new ScriptRuntime(); - const result = await scriptRuntime.runResponseScript(responseScript, request, response, envVars, collectionVariables, collectionPath, onConsoleLog); - - mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, - collectionUid - }); - } - - // run assertions - const assertions = get(item, 'request.assertions'); - if(assertions && assertions.length) { - const assertRuntime = new AssertRuntime(); - const results = assertRuntime.runAssertions(assertions, request, response, envVars, collectionVariables, collectionPath); + // interpolate variables inside request + interpolateVars(request, envVars, collectionVariables); + // todo: + // i have no clue why electron can't send the request object + // without safeParseJSON(safeStringifyJSON(request.data)) mainWindow.webContents.send('main:run-folder-event', { - type: 'assertion-results', - assertionResults: results, - itemUid: item.uid, - collectionUid - }); - } - - // run tests - const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests'); - if(testFile && testFile.length) { - const testRuntime = new TestRuntime(); - const testResults = testRuntime.runTests(testFile, request, response, envVars, collectionVariables, collectionPath, onConsoleLog); - - mainWindow.webContents.send('main:run-folder-event', { - type: 'test-results', - testResults: testResults.results, + type: 'request-sent', + requestSent: { + url: request.url, + method: request.method, + headers: request.headers, + data: safeParseJSON(safeStringifyJSON(request.data)) + }, ...eventData }); - mainWindow.webContents.send('main:script-environment-update', { - envVariables: testResults.envVariables, - collectionVariables: testResults.collectionVariables, - collectionUid - }); - } + const preferences = getPreferences(); + const sslVerification = get(preferences, 'request.sslVerification', true); - mainWindow.webContents.send('main:run-folder-event', { - type: 'response-received', - ...eventData, - responseReceived: { - status: response.status, - statusText: response.statusText, - headers: Object.entries(response.headers), - duration: timeEnd - timeStart, - size: response.headers['content-length'] || getSize(response.data), - data: response.data, + if (!sslVerification) { + request.httpsAgent = new https.Agent({ + rejectUnauthorized: false + }); } - }); - } catch (error) { - let responseReceived = {}; - let duration = 0; - if(timeStart && timeEnd) { - duration = timeEnd - timeStart; - } + // send request + timeStart = Date.now(); + const response = await axios(request); + timeEnd = Date.now(); - if(error && error.response) { - responseReceived = { - status: error.response.status, - statusText: error.response.statusText, - headers: Object.entries(error.response.headers), - duration: duration, - size: error.response.headers['content-length'] || getSize(error.response.data), - data: error.response.data, + // run post-response vars + const postResponseVars = get(request, 'vars.res', []); + if (postResponseVars && postResponseVars.length) { + const varsRuntime = new VarsRuntime(); + const result = varsRuntime.runPostResponseVars( + postResponseVars, + request, + response, + envVars, + collectionVariables, + collectionPath + ); + + mainWindow.webContents.send('main:script-environment-update', { + envVariables: result.envVariables, + collectionVariables: result.collectionVariables, + collectionUid + }); + } + + // run response script + const responseScript = get(request, 'script.res'); + if (responseScript && responseScript.length) { + const scriptRuntime = new ScriptRuntime(); + const result = await scriptRuntime.runResponseScript( + responseScript, + request, + response, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); + + mainWindow.webContents.send('main:script-environment-update', { + envVariables: result.envVariables, + collectionVariables: result.collectionVariables, + collectionUid + }); } // run assertions const assertions = get(item, 'request.assertions'); - if(assertions && assertions.length) { + if (assertions && assertions.length) { const assertRuntime = new AssertRuntime(); - const results = assertRuntime.runAssertions(assertions, request, error.response, envVars, collectionVariables, collectionPath); + const results = assertRuntime.runAssertions( + assertions, + request, + response, + envVars, + collectionVariables, + collectionPath + ); mainWindow.webContents.send('main:run-folder-event', { type: 'assertion-results', @@ -610,9 +638,17 @@ const registerNetworkIpc = (mainWindow) => { // run tests const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests'); - if(testFile && testFile.length) { + if (testFile && testFile.length) { const testRuntime = new TestRuntime(); - const testResults = testRuntime.runTests(testFile, request, error.response, envVars, collectionVariables, collectionPath, onConsoleLog); + const testResults = testRuntime.runTests( + testFile, + request, + response, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); mainWindow.webContents.send('main:run-folder-event', { type: 'test-results', @@ -627,38 +663,117 @@ const registerNetworkIpc = (mainWindow) => { }); } - // if we get a response from the server, we consider it as a success mainWindow.webContents.send('main:run-folder-event', { type: 'response-received', + ...eventData, + responseReceived: { + status: response.status, + statusText: response.statusText, + headers: Object.entries(response.headers), + duration: timeEnd - timeStart, + size: response.headers['content-length'] || getSize(response.data), + data: response.data + } + }); + } catch (error) { + let responseReceived = {}; + let duration = 0; + + if (timeStart && timeEnd) { + duration = timeEnd - timeStart; + } + + if (error && error.response) { + responseReceived = { + status: error.response.status, + statusText: error.response.statusText, + headers: Object.entries(error.response.headers), + duration: duration, + size: error.response.headers['content-length'] || getSize(error.response.data), + data: error.response.data + }; + + // run assertions + const assertions = get(item, 'request.assertions'); + if (assertions && assertions.length) { + const assertRuntime = new AssertRuntime(); + const results = assertRuntime.runAssertions( + assertions, + request, + error.response, + envVars, + collectionVariables, + collectionPath + ); + + mainWindow.webContents.send('main:run-folder-event', { + type: 'assertion-results', + assertionResults: results, + itemUid: item.uid, + collectionUid + }); + } + + // run tests + const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests'); + if (testFile && testFile.length) { + const testRuntime = new TestRuntime(); + const testResults = testRuntime.runTests( + testFile, + request, + error.response, + envVars, + collectionVariables, + collectionPath, + onConsoleLog + ); + + mainWindow.webContents.send('main:run-folder-event', { + type: 'test-results', + testResults: testResults.results, + ...eventData + }); + + mainWindow.webContents.send('main:script-environment-update', { + envVariables: testResults.envVariables, + collectionVariables: testResults.collectionVariables, + collectionUid + }); + } + + // if we get a response from the server, we consider it as a success + mainWindow.webContents.send('main:run-folder-event', { + type: 'response-received', + error: error ? error.message : 'An error occurred while running the request', + responseReceived: responseReceived, + ...eventData + }); + + continue; + } + + mainWindow.webContents.send('main:run-folder-event', { + type: 'error', error: error ? error.message : 'An error occurred while running the request', responseReceived: responseReceived, ...eventData }); - - continue; } - - mainWindow.webContents.send('main:run-folder-event', { - type: 'error', - error: error ? error.message : 'An error occurred while running the request', - responseReceived: responseReceived, - ...eventData - }); } - } - mainWindow.webContents.send('main:run-folder-event', { - type: 'testrun-ended', - collectionUid, - folderUid - }); - } catch (error) { - mainWindow.webContents.send('main:run-folder-event', { - type: 'error', - error - }); + mainWindow.webContents.send('main:run-folder-event', { + type: 'testrun-ended', + collectionUid, + folderUid + }); + } catch (error) { + mainWindow.webContents.send('main:run-folder-event', { + type: 'error', + error + }); + } } - }); + ); }; module.exports = registerNetworkIpc; diff --git a/packages/bruno-electron/src/ipc/network/interpolate-vars.js b/packages/bruno-electron/src/ipc/network/interpolate-vars.js index 8e54430c..8c90e00a 100644 --- a/packages/bruno-electron/src/ipc/network/interpolate-vars.js +++ b/packages/bruno-electron/src/ipc/network/interpolate-vars.js @@ -6,9 +6,9 @@ Mustache.escape = function (value) { return value; }; -const interpolateVars = (request, envVars = {}, collectionVariables ={}) => { +const interpolateVars = (request, envVars = {}, collectionVariables = {}) => { const interpolate = (str) => { - if(!str || !str.length || typeof str !== "string") { + if (!str || !str.length || typeof str !== 'string') { return str; } @@ -27,29 +27,27 @@ const interpolateVars = (request, envVars = {}, collectionVariables ={}) => { request.headers[key] = interpolate(value); }); - if(request.headers["content-type"] === "application/json") { - if(typeof request.data === "object") { + if (request.headers['content-type'] === 'application/json') { + if (typeof request.data === 'object') { try { let parsed = JSON.stringify(request.data); parsed = interpolate(parsed); request.data = JSON.parse(parsed); - } catch (err) { - } + } catch (err) {} } - if(typeof request.data === "string") { - if(request.data.length) { + if (typeof request.data === 'string') { + if (request.data.length) { request.data = interpolate(request.data); } } - } else if(request.headers["content-type"] === "application/x-www-form-urlencoded") { - if(typeof request.data === "object") { + } else if (request.headers['content-type'] === 'application/x-www-form-urlencoded') { + if (typeof request.data === 'object') { try { let parsed = JSON.stringify(request.data); parsed = interpolate(parsed); request.data = JSON.parse(parsed); - } catch (err) { - } + } catch (err) {} } } else { request.data = interpolate(request.data); diff --git a/packages/bruno-electron/src/ipc/network/prepare-gql-introspection-request.js b/packages/bruno-electron/src/ipc/network/prepare-gql-introspection-request.js index b096e53c..a36666e3 100644 --- a/packages/bruno-electron/src/ipc/network/prepare-gql-introspection-request.js +++ b/packages/bruno-electron/src/ipc/network/prepare-gql-introspection-request.js @@ -7,8 +7,8 @@ Mustache.escape = function (value) { }; const prepareGqlIntrospectionRequest = (endpoint, envVars) => { - if(endpoint && endpoint.length) { - endpoint = Mustache.render(endpoint, envVars); + if (endpoint && endpoint.length) { + endpoint = Mustache.render(endpoint, envVars); } const introspectionQuery = getIntrospectionQuery(); const queryParams = { @@ -19,7 +19,7 @@ const prepareGqlIntrospectionRequest = (endpoint, envVars) => { method: 'POST', url: endpoint, headers: { - 'Accept': 'application/json', + Accept: 'application/json', 'Content-Type': 'application/json' }, data: JSON.stringify(queryParams) diff --git a/packages/bruno-electron/src/preload.js b/packages/bruno-electron/src/preload.js index bac807f6..4bfe2216 100644 --- a/packages/bruno-electron/src/preload.js +++ b/packages/bruno-electron/src/preload.js @@ -3,7 +3,7 @@ const { ipcRenderer, contextBridge } = require('electron'); contextBridge.exposeInMainWorld('ipcRenderer', { invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args), on: (channel, handler) => { - // Deliberately strip event as it includes `sender` + // Deliberately strip event as it includes `sender` const subscription = (event, ...args) => handler(...args); ipcRenderer.on(channel, subscription); @@ -11,4 +11,4 @@ contextBridge.exposeInMainWorld('ipcRenderer', { ipcRenderer.removeListener(channel, subscription); }; } -}); \ No newline at end of file +}); diff --git a/packages/bruno-electron/src/utils/cancel-token.js b/packages/bruno-electron/src/utils/cancel-token.js index aa1a1de3..50cc8390 100644 --- a/packages/bruno-electron/src/utils/cancel-token.js +++ b/packages/bruno-electron/src/utils/cancel-token.js @@ -2,11 +2,11 @@ const cancelTokens = {}; const saveCancelToken = (uid, axiosRequest) => { cancelTokens[uid] = axiosRequest; -} +}; const deleteCancelToken = (uid) => { delete cancelTokens[uid]; -} +}; module.exports = { cancelTokens, diff --git a/packages/bruno-electron/src/utils/common.js b/packages/bruno-electron/src/utils/common.js index 39324fed..d85d137d 100644 --- a/packages/bruno-electron/src/utils/common.js +++ b/packages/bruno-electron/src/utils/common.js @@ -4,7 +4,7 @@ const { customAlphabet } = require('nanoid'); const uuid = () => { // https://github.com/ai/nanoid/blob/main/url-alphabet/index.js const urlAlphabet = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLFGQZbfghjklqvwyzrict'; - const customNanoId = customAlphabet (urlAlphabet, 21); + const customNanoId = customAlphabet(urlAlphabet, 21); return customNanoId(); }; @@ -12,18 +12,18 @@ const uuid = () => { const stringifyJson = async (str) => { try { return JSON.stringify(str, null, 2); - } catch(err) { + } catch (err) { return Promise.reject(err); } -} +}; const parseJson = async (obj) => { try { return JSON.parse(obj); - } catch(err) { + } catch (err) { return Promise.reject(err); } -} +}; const simpleHash = (str) => { let hash = 0; @@ -39,7 +39,7 @@ const generateUidBasedOnHash = (str) => { const hash = simpleHash(str); return `${hash}`.padEnd(21, '0'); -} +}; module.exports = { uuid, diff --git a/packages/bruno-electron/src/utils/filesystem.js b/packages/bruno-electron/src/utils/filesystem.js index 33e64ee3..daf6eaf6 100644 --- a/packages/bruno-electron/src/utils/filesystem.js +++ b/packages/bruno-electron/src/utils/filesystem.js @@ -4,7 +4,7 @@ const fsPromises = require('fs/promises'); const { dialog } = require('electron'); const isValidPathname = require('is-valid-path'); -const exists = async p => { +const exists = async (p) => { try { await fsPromises.access(p); return true; @@ -13,7 +13,7 @@ const exists = async p => { } }; -const isSymbolicLink = filepath => { +const isSymbolicLink = (filepath) => { try { return fs.existsSync(filepath) && fs.lstatSync(filepath).isSymbolicLink(); } catch (_) { @@ -21,7 +21,7 @@ const isSymbolicLink = filepath => { } }; -const isFile = filepath => { +const isFile = (filepath) => { try { return fs.existsSync(filepath) && fs.lstatSync(filepath).isFile(); } catch (_) { @@ -29,7 +29,7 @@ const isFile = filepath => { } }; -const isDirectory = dirPath => { +const isDirectory = (dirPath) => { try { return fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory(); } catch (_) { @@ -37,14 +37,14 @@ const isDirectory = dirPath => { } }; -const normalizeAndResolvePath = pathname => { +const normalizeAndResolvePath = (pathname) => { if (isSymbolicLink(pathname)) { const absPath = path.dirname(pathname); const targetPath = path.resolve(absPath, fs.readlinkSync(pathname)); if (isFile(targetPath) || isDirectory(targetPath)) { return path.resolve(targetPath); } - console.error(`Cannot resolve link target "${pathname}" (${targetPath}).`) + console.error(`Cannot resolve link target "${pathname}" (${targetPath}).`); return ''; } return path.resolve(pathname); @@ -53,29 +53,29 @@ const normalizeAndResolvePath = pathname => { const writeFile = async (pathname, content) => { try { fs.writeFileSync(pathname, content, { - encoding: "utf8" + encoding: 'utf8' }); } catch (err) { return Promise.reject(err); } }; -const hasJsonExtension = filename => { - if (!filename || typeof filename !== 'string') return false - return ['json'].some(ext => filename.toLowerCase().endsWith(`.${ext}`)) -} +const hasJsonExtension = (filename) => { + if (!filename || typeof filename !== 'string') return false; + return ['json'].some((ext) => filename.toLowerCase().endsWith(`.${ext}`)); +}; -const hasBruExtension = filename => { - if (!filename || typeof filename !== 'string') return false - return ['bru'].some(ext => filename.toLowerCase().endsWith(`.${ext}`)) -} +const hasBruExtension = (filename) => { + if (!filename || typeof filename !== 'string') return false; + return ['bru'].some((ext) => filename.toLowerCase().endsWith(`.${ext}`)); +}; const createDirectory = async (dir) => { - if(!dir) { + if (!dir) { throw new Error(`directory: path is null`); } - if (fs.existsSync(dir)){ + if (fs.existsSync(dir)) { throw new Error(`directory: ${dir} already exists`); } @@ -108,7 +108,7 @@ const searchForFiles = (dir, extension) => { } } return results; -} +}; const searchForBruFiles = (dir) => { return searchForFiles(dir, '.bru');