feat: integrating app with the bru lang

This commit is contained in:
Anoop M D 2023-01-17 02:00:58 +05:30
parent 23076b41c6
commit b6c3205474
9 changed files with 131 additions and 44 deletions

View File

@ -1,5 +1,5 @@
module.exports = {
reactStrictMode: true,
reactStrictMode: false,
publicRuntimeConfig: {
CI: process.env.CI,
PLAYWRIGHT: process.env.PLAYWRIGHT

View File

@ -30,7 +30,7 @@ const Collections = ({ searchText }) => {
? collectionToDisplay.map((c) => {
return (
<DndProvider backend={HTML5Backend} key={c.uid}>
<Collection searchText={searchText} collection={c} />;
<Collection searchText={searchText} collection={c} />
</DndProvider>
);
})

View File

@ -1,3 +1,4 @@
import reckon from 'reckonjs';
import get from 'lodash/get';
import each from 'lodash/each';
import find from 'lodash/find';
@ -413,7 +414,6 @@ export const interpolateEnvironmentVars = (item, variables) => {
};
request.url = interpolate(request.url);
console.log(request.url);
each(request.headers, (header) => {
header.value = interpolate(header.value);

View File

@ -14,7 +14,7 @@ export const isLocalCollection = (collection) => {
};
export const resolveRequestFilename = (name) => {
return `${trim(name)}.json`;
return `${trim(name)}.bru`;
};
export const getSubdirectoriesFromRoot = (rootPath, pathname) => {

View File

@ -13,6 +13,8 @@
"pack-app": "electron-builder --dir"
},
"dependencies": {
"@usebruno/bruno-lang": "0.1.0",
"@usebruno/schema": "0.1.0",
"axios": "^0.26.0",
"chokidar": "^3.5.3",
"electron-is-dev": "^2.0.0",

View File

@ -1,7 +1,14 @@
const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const { hasJsonExtension } = require('../utils/filesystem');
const { hasJsonExtension, hasBruExtension, writeFile } = require('../utils/filesystem');
const {
bruToJson,
jsonToBru
} = require('@usebruno/bruno-lang');
const { itemSchema } = require('@usebruno/schema');
const { generateUidBasedOnHash, uuid } = require('../utils/common');
const isEnvironmentConfig = (pathname, collectionPath) => {
const dirname = path.dirname(pathname);
@ -10,6 +17,22 @@ const isEnvironmentConfig = (pathname, collectionPath) => {
return dirname === collectionPath && basename === 'environments.json';
}
const hydrateRequestWithUuid = (request, pathname) => {
request.uid = generateUidBasedOnHash(pathname);
const params = _.get(request, 'request.params', []);
const headers = _.get(request, 'request.headers', []);
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());
bodyFormUrlEncoded.forEach((param) => param.uid = uuid());
bodyMultipartForm.forEach((param) => param.uid = uuid());
return request;
}
const addEnvironmentFile = async (win, pathname, collectionUid) => {
try {
const file = {
@ -71,7 +94,30 @@ const add = async (win, pathname, collectionUid, collectionPath) => {
if(isEnvironmentConfig(pathname, collectionPath)) {
return addEnvironmentFile(win, pathname, collectionUid);
}
}
// migrate old json files to bru
if(hasJsonExtension(pathname)) {
try {
const json = fs.readFileSync(pathname, 'utf8');
const jsonData = JSON.parse(json);
await itemSchema.validate(jsonData);
const content = jsonToBru(jsonData);
const re = /(.*)\.json$/;
const subst = `$1.bru`;
const bruFilename = pathname.replace(re, subst);
await writeFile(bruFilename, content);
await fs.unlinkSync(pathname);
} catch (err) {
// do nothing
}
}
if(hasBruExtension(pathname)) {
const file = {
meta: {
collectionUid,
@ -81,8 +127,9 @@ const add = async (win, pathname, collectionUid, collectionPath) => {
}
try {
const jsonData = fs.readFileSync(pathname, 'utf8');
file.data = JSON.parse(jsonData);
const bru = fs.readFileSync(pathname, 'utf8');
file.data = bruToJson(bru);
hydrateRequestWithUuid(file.data, pathname);
win.webContents.send('main:collection-tree-updated', 'addFile', file);
} catch (err) {
console.error(err)
@ -104,25 +151,30 @@ const addDirectory = (win, pathname, collectionUid) => {
const change = async (win, pathname, collectionUid, collectionPath) => {
console.log(`watcher change: ${pathname}`);
try {
if(isEnvironmentConfig(pathname, collectionPath)) {
return changeEnvironmentFile(win, pathname, collectionUid);
}
const file = {
meta: {
collectionUid,
pathname,
name: path.basename(pathname),
}
};
const jsonData = fs.readFileSync(pathname, 'utf8');
file.data = await JSON.parse(jsonData);
win.webContents.send('main:collection-tree-updated', 'change', file);
} catch (err) {
console.error(err)
if(isEnvironmentConfig(pathname, collectionPath)) {
return changeEnvironmentFile(win, pathname, collectionUid);
}
if(hasBruExtension(pathname)) {
try {
const file = {
meta: {
collectionUid,
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)
}
}
};
const unlink = (win, pathname, collectionUid, collectionPath) => {
@ -130,19 +182,19 @@ const unlink = (win, pathname, collectionUid, collectionPath) => {
return unlinkEnvironmentFile(win, pathname, collectionUid);
}
console.log(`watcher unlink: ${pathname}`);
const file = {
meta: {
collectionUid,
pathname,
name: path.basename(pathname)
}
};
win.webContents.send('main:collection-tree-updated', 'unlink', file);
if(hasBruExtension(pathname)) {
const file = {
meta: {
collectionUid,
pathname,
name: path.basename(pathname)
}
};
win.webContents.send('main:collection-tree-updated', 'unlink', file);
}
}
const unlinkDir = (win, pathname, collectionUid) => {
console.log(`watcher unlinkDir: ${pathname}`);
const directory = {
meta: {
collectionUid,
@ -163,6 +215,11 @@ class Watcher {
this.watchers[watchPath].close();
}
// todo
// enable this in a future release
// once we can confirm all older json based files have been auto migrated to .bru format
// watchPath = path.join(watchPath, '**/*.bru');
const self = this;
setTimeout(() => {
const watcher = chokidar.watch(watchPath, {

View File

@ -2,15 +2,19 @@ const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const { ipcMain } = require('electron');
const {
jsonToBru,
bruToJson,
} = require('@usebruno/bruno-lang');
const {
isValidPathname,
writeFile,
hasJsonExtension,
hasBruExtension,
isDirectory,
browseDirectory,
createDirectory
} = require('../utils/filesystem');
const { uuid, stringifyJson, parseJson } = require('../utils/common');
const { uuid, stringifyJson } = require('../utils/common');
const { openCollectionDialog, openCollection } = require('../app/collections');
const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollections) => {
@ -64,7 +68,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
throw new Error(`path: ${pathname} already exists`);
}
const content = await stringifyJson(request);
const content = jsonToBru(request);
await writeFile(pathname, content);
} catch (error) {
return Promise.reject(error);
@ -78,7 +82,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
throw new Error(`path: ${pathname} does not exist`);
}
const content = await stringifyJson(request);
const content = jsonToBru(request);
await writeFile(pathname, content);
} catch (error) {
return Promise.reject(error);
@ -112,18 +116,18 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
return fs.renameSync(oldPath, newPath);
}
const isJson = hasJsonExtension(oldPath);
if(!isJson) {
throw new Error(`path: ${oldPath} is not a json file`);
const isBru = hasBruExtension(oldPath);
if(!isBru) {
throw new Error(`path: ${oldPath} is not a bru file`);
}
// update name in file and save new copy, then delete old copy
const data = fs.readFileSync(oldPath, 'utf8');
const jsonData = await parseJson(data);
const jsonData = bruToJson(data);
jsonData.name = newName;
const content = await stringifyJson(jsonData);
const content = jsonToBru(jsonData);
await writeFile(newPath, content);
await fs.unlinkSync(oldPath);
} catch (error) {

View File

@ -25,8 +25,26 @@ const parseJson = async (obj) => {
}
}
const simpleHash = (str) => {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash &= hash; // Convert to 32bit integer
}
return new Uint32Array([hash])[0].toString(36);
};
const generateUidBasedOnHash = (str) => {
const hash = simpleHash(str);
return `${hash}`.padEnd(21, '0');
}
module.exports = {
uuid,
stringifyJson,
parseJson
parseJson,
simpleHash,
generateUidBasedOnHash
};

View File

@ -65,6 +65,11 @@ const hasJsonExtension = filename => {
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 createDirectory = async (dir) => {
if(!dir) {
throw new Error(`directory: path is null`);
@ -99,6 +104,7 @@ module.exports = {
normalizeAndResolvePath,
writeFile,
hasJsonExtension,
hasBruExtension,
createDirectory,
browseDirectory
};