feat: automagically migrate users of bru v1 to bru v2

This commit is contained in:
Anoop M D 2023-02-07 01:19:32 +05:30
parent 6947860204
commit f69332d9c3
8 changed files with 187 additions and 15 deletions

View File

@ -19,6 +19,31 @@ const deleteUidsInItems = (items) => {
});
};
/**
* Some of the models in the app are not consistent with the Collection Json format
* This function is used to transform the models to the Collection Json format
*/
const transformItem = (items = []) => {
each(items, (item) => {
if (['http-request', 'graphql-request'].includes(item.type)) {
item.request.query = item.request.params;
delete item.request.params;
if(item.type === 'graphql-request') {
item.type = 'graphql';
}
if(item.type === 'http-request') {
item.type = 'http';
}
}
if (item.items && item.items.length) {
transformItem(item.items);
}
});
};
const deleteUidsInEnvs = (envs) => {
each(envs, (env) => {
delete env.uid;
@ -31,6 +56,8 @@ const exportCollection = (collection) => {
delete collection.uid;
deleteUidsInItems(collection.items);
deleteUidsInEnvs(collection.environments);
transformItem(collection.items);
const fileName = `${collection.name}.json`;
const fileBlob = new Blob([JSON.stringify(collection, null, 2)], { type: 'application/json' });

View File

@ -1,6 +1,6 @@
import fileDialog from 'file-dialog';
import { BrunoError } from 'utils/common/error';
import { validateSchema, updateUidsInCollection, hydrateSeqInCollection } from './common';
import { validateSchema, transformItemsInCollection, updateUidsInCollection, hydrateSeqInCollection } from './common';
const readFile = (files) => {
return new Promise((resolve, reject) => {
@ -30,6 +30,7 @@ const importCollection = () => {
.then(parseJsonCollection)
.then(hydrateSeqInCollection)
.then(updateUidsInCollection)
.then(transformItemsInCollection)
.then(validateSchema)
.then((collection) => resolve(collection))
.catch((err) => {

View File

@ -30,6 +30,7 @@ export const updateUidsInCollection = (_collection) => {
item.uid = uuid();
each(get(item, 'request.headers'), (header) => (header.uid = uuid()));
each(get(item, 'request.query'), (param) => (param.uid = uuid()));
each(get(item, 'request.params'), (param) => (param.uid = uuid()));
each(get(item, 'request.body.multipartForm'), (param) => (param.uid = uuid()));
each(get(item, 'request.body.formUrlEncoded'), (param) => (param.uid = uuid()));
@ -48,7 +49,35 @@ export const updateUidsInCollection = (_collection) => {
});
};
updateEnvUids(collection.environments);
updateEnvUids(collection.environments);
console.log(collection);
return collection;
};
// todo
// need to eventually get rid of supporting old collection app models
// 1. start with making request type a constant fetched from a single place
// 2. move references of param and replace it with query inside the app
export const transformItemsInCollection = (collection) => {
const transformItems = (items = []) => {
each(items, (item) => {
if (['http', 'graphql'].includes(item.type)) {
item.type = `${item.type}-request`;
if(item.request.query) {
item.request.params = item.request.query;
}
delete item.request.query;
}
if (item.items && item.items.length) {
transformItems(item.items);
}
});
};
transformItems(collection.items);
return collection;
};

View File

@ -3,7 +3,7 @@ import get from 'lodash/get';
import fileDialog from 'file-dialog';
import { uuid } from 'utils/common';
import { BrunoError } from 'utils/common/error';
import { validateSchema, hydrateSeqInCollection } from './common';
import { validateSchema, transformItemsInCollection, hydrateSeqInCollection } from './common';
const readFile = (files) => {
return new Promise((resolve, reject) => {
@ -178,6 +178,7 @@ const importCollection = () => {
fileDialog({ accept: 'application/json' })
.then(readFile)
.then(parsePostmanCollection)
.then(transformItemsInCollection)
.then(hydrateSeqInCollection)
.then(validateSchema)
.then((collection) => resolve(collection))

View File

@ -9,6 +9,13 @@ const {
bruToJson,
jsonToBru
} = require('../bru');
const {
isLegacyEnvFile,
migrateLegacyEnvFile,
isLegacyBruFile,
migrateLegacyBruFile
} = require('../bru/migrate');
const { itemSchema } = require('@usebruno/schema');
const { uuid } = require('../utils/common');
const { getRequestUid } = require('../cache/requestUids');
@ -55,7 +62,13 @@ const addEnvironmentFile = async (win, pathname, collectionUid) => {
},
};
const bruContent = fs.readFileSync(pathname, 'utf8');
let bruContent = fs.readFileSync(pathname, 'utf8');
// migrate old env json to bru file
if(isLegacyEnvFile(bruContent)) {
bruContent = await migrateLegacyEnvFile(bruContent, pathname);
}
file.data = bruToEnvJson(bruContent);
file.data.name = basename.substring(0, basename.length - 4);
file.data.uid = getRequestUid(pathname);
@ -117,11 +130,11 @@ const add = async (win, pathname, collectionUid, collectionPath) => {
console.log(`watcher add: ${pathname}`);
if(isJsonEnvironmentConfig(pathname, collectionPath)) {
// migrate old env json to bru file
try {
const dirname = path.dirname(pathname);
const jsonStr = fs.readFileSync(pathname, 'utf8');
const jsonData = JSON.parse(jsonStr);
const bruContent = fs.readFileSync(pathname, 'utf8');
const jsonData = JSON.parse(bruContent);
const envDirectory = path.join(dirname, 'environments');
if (!fs.existsSync(envDirectory)) {
@ -177,8 +190,14 @@ const add = async (win, pathname, collectionUid, collectionPath) => {
}
try {
const bru = fs.readFileSync(pathname, 'utf8');
file.data = bruToJson(bru);
let bruContent = fs.readFileSync(pathname, 'utf8');
// migrate old bru format to new bru format
if(isLegacyBruFile(bruContent)) {
bruContent = await migrateLegacyBruFile(bruContent, pathname);
}
file.data = bruToJson(bruContent);
hydrateRequestWithUuid(file.data, pathname);
win.webContents.send('main:collection-tree-updated', 'addFile', file);
} catch (err) {

View File

@ -1,9 +1,5 @@
const _ = require('lodash');
const {
bruToEnvJson: bruToEnvJsonV1,
envJsonToBru: envJsonToBruV1,
bruToJson: bruToJsonV1,
bruToJsonV2,
jsonToBruV2,
bruToEnvJsonV2,
@ -56,7 +52,7 @@ const bruToJson = (bru) => {
} else if(requestType === "graphql") {
requestType = "graphql-request";
} else {
requestType = "http";
requestType = "http-request";
}
const sequence = _.get(json, "meta.seq")

View File

@ -0,0 +1,99 @@
const {
bruToEnvJson: bruToEnvJsonV1,
bruToJson: bruToJsonV1,
jsonToBruV2,
envJsonToBruV2
} = require('@usebruno/lang');
const _ = require('lodash');
const { writeFile } = require('../utils/filesystem');
const isLegacyEnvFile = (bruContent = '') => {
bruContent = bruContent.trim();
let regex = /^vars[\s\S]*\/vars$/;
return regex.test(bruContent);
};
const migrateLegacyEnvFile = async (bruContent, pathname) => {
const envJson = bruToEnvJsonV1(bruContent);
const newBruContent = envJsonToBruV2(envJson);
await writeFile(pathname, newBruContent);
return newBruContent;
};
const isLegacyBruFile = (bruContent = '') => {
bruContent = bruContent.trim();
let lines = bruContent.split(/\r?\n/);
let hasName = false;
let hasMethod = false;
let hasUrl = false;
for (let line of lines) {
line = line.trim();
if (line.startsWith("name")) {
hasName = true;
} else if (line.startsWith("method")) {
hasMethod = true;
} else if (line.startsWith("url")) {
hasUrl = true;
}
}
return hasName && hasMethod && hasUrl;
};
const migrateLegacyBruFile = async (bruContent, pathname) => {
const json = bruToJsonV1(bruContent);
let type = _.get(json, 'type');
if (type === 'http-request') {
type = "http";
} else if (type === 'graphql-request') {
type = "graphql";
} else {
type = "http";
}
let script = {};
let legacyScript = _.get(json, 'request.script');
if(legacyScript && legacyScript.trim().length > 0) {
script = {
res: legacyScript
};
}
const bruJson = {
meta: {
name: _.get(json, 'name'),
type: type,
seq: _.get(json, 'seq'),
},
http: {
method: _.lowerCase(_.get(json, 'request.method')),
url: _.get(json, 'request.url'),
mode: _.get(json, 'request.body.mode', 'none')
},
query: _.get(json, 'request.params', []),
headers: _.get(json, 'request.headers', []),
body: _.get(json, 'request.body', {}),
script: script,
tests: _.get(json, 'request.tests', ''),
};
const newBruContent = jsonToBruV2(bruJson);
await writeFile(pathname, newBruContent);
return newBruContent;
}
module.exports = {
isLegacyEnvFile,
migrateLegacyEnvFile,
isLegacyBruFile,
migrateLegacyBruFile
};

View File

@ -38,7 +38,7 @@ const grammar = ohm.grammar(`Bru {
// Dictionary Blocks
dictionary = st* "{" pairlist? tagend
pairlist = optionalnl* pair (~tagend nl pair)* (~tagend space)*
pairlist = optionalnl* pair (~tagend stnl* pair)* (~tagend space)*
pair = st* key st* ":" st* value? st*
key = ~tagend validkey*
value = ~tagend validvalue*