forked from extern/bruno
feat: automagically migrate users of bru v1 to bru v2
This commit is contained in:
parent
6947860204
commit
f69332d9c3
@ -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) => {
|
const deleteUidsInEnvs = (envs) => {
|
||||||
each(envs, (env) => {
|
each(envs, (env) => {
|
||||||
delete env.uid;
|
delete env.uid;
|
||||||
@ -31,6 +56,8 @@ const exportCollection = (collection) => {
|
|||||||
delete collection.uid;
|
delete collection.uid;
|
||||||
deleteUidsInItems(collection.items);
|
deleteUidsInItems(collection.items);
|
||||||
deleteUidsInEnvs(collection.environments);
|
deleteUidsInEnvs(collection.environments);
|
||||||
|
transformItem(collection.items);
|
||||||
|
|
||||||
|
|
||||||
const fileName = `${collection.name}.json`;
|
const fileName = `${collection.name}.json`;
|
||||||
const fileBlob = new Blob([JSON.stringify(collection, null, 2)], { type: 'application/json' });
|
const fileBlob = new Blob([JSON.stringify(collection, null, 2)], { type: 'application/json' });
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import fileDialog from 'file-dialog';
|
import fileDialog from 'file-dialog';
|
||||||
import { BrunoError } from 'utils/common/error';
|
import { BrunoError } from 'utils/common/error';
|
||||||
import { validateSchema, updateUidsInCollection, hydrateSeqInCollection } from './common';
|
import { validateSchema, transformItemsInCollection, updateUidsInCollection, hydrateSeqInCollection } from './common';
|
||||||
|
|
||||||
const readFile = (files) => {
|
const readFile = (files) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -30,6 +30,7 @@ const importCollection = () => {
|
|||||||
.then(parseJsonCollection)
|
.then(parseJsonCollection)
|
||||||
.then(hydrateSeqInCollection)
|
.then(hydrateSeqInCollection)
|
||||||
.then(updateUidsInCollection)
|
.then(updateUidsInCollection)
|
||||||
|
.then(transformItemsInCollection)
|
||||||
.then(validateSchema)
|
.then(validateSchema)
|
||||||
.then((collection) => resolve(collection))
|
.then((collection) => resolve(collection))
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -30,6 +30,7 @@ export const updateUidsInCollection = (_collection) => {
|
|||||||
item.uid = uuid();
|
item.uid = uuid();
|
||||||
|
|
||||||
each(get(item, 'request.headers'), (header) => (header.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.params'), (param) => (param.uid = uuid()));
|
||||||
each(get(item, 'request.body.multipartForm'), (param) => (param.uid = uuid()));
|
each(get(item, 'request.body.multipartForm'), (param) => (param.uid = uuid()));
|
||||||
each(get(item, 'request.body.formUrlEncoded'), (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);
|
||||||
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;
|
return collection;
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ import get from 'lodash/get';
|
|||||||
import fileDialog from 'file-dialog';
|
import fileDialog from 'file-dialog';
|
||||||
import { uuid } from 'utils/common';
|
import { uuid } from 'utils/common';
|
||||||
import { BrunoError } from 'utils/common/error';
|
import { BrunoError } from 'utils/common/error';
|
||||||
import { validateSchema, hydrateSeqInCollection } from './common';
|
import { validateSchema, transformItemsInCollection, hydrateSeqInCollection } from './common';
|
||||||
|
|
||||||
const readFile = (files) => {
|
const readFile = (files) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -178,6 +178,7 @@ const importCollection = () => {
|
|||||||
fileDialog({ accept: 'application/json' })
|
fileDialog({ accept: 'application/json' })
|
||||||
.then(readFile)
|
.then(readFile)
|
||||||
.then(parsePostmanCollection)
|
.then(parsePostmanCollection)
|
||||||
|
.then(transformItemsInCollection)
|
||||||
.then(hydrateSeqInCollection)
|
.then(hydrateSeqInCollection)
|
||||||
.then(validateSchema)
|
.then(validateSchema)
|
||||||
.then((collection) => resolve(collection))
|
.then((collection) => resolve(collection))
|
||||||
|
@ -9,6 +9,13 @@ const {
|
|||||||
bruToJson,
|
bruToJson,
|
||||||
jsonToBru
|
jsonToBru
|
||||||
} = require('../bru');
|
} = require('../bru');
|
||||||
|
|
||||||
|
const {
|
||||||
|
isLegacyEnvFile,
|
||||||
|
migrateLegacyEnvFile,
|
||||||
|
isLegacyBruFile,
|
||||||
|
migrateLegacyBruFile
|
||||||
|
} = require('../bru/migrate');
|
||||||
const { itemSchema } = require('@usebruno/schema');
|
const { itemSchema } = require('@usebruno/schema');
|
||||||
const { uuid } = require('../utils/common');
|
const { uuid } = require('../utils/common');
|
||||||
const { getRequestUid } = require('../cache/requestUids');
|
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 = bruToEnvJson(bruContent);
|
||||||
file.data.name = basename.substring(0, basename.length - 4);
|
file.data.name = basename.substring(0, basename.length - 4);
|
||||||
file.data.uid = getRequestUid(pathname);
|
file.data.uid = getRequestUid(pathname);
|
||||||
@ -117,11 +130,11 @@ const add = async (win, pathname, collectionUid, collectionPath) => {
|
|||||||
console.log(`watcher add: ${pathname}`);
|
console.log(`watcher add: ${pathname}`);
|
||||||
|
|
||||||
if(isJsonEnvironmentConfig(pathname, collectionPath)) {
|
if(isJsonEnvironmentConfig(pathname, collectionPath)) {
|
||||||
// migrate old env json to bru file
|
|
||||||
try {
|
try {
|
||||||
const dirname = path.dirname(pathname);
|
const dirname = path.dirname(pathname);
|
||||||
const jsonStr = fs.readFileSync(pathname, 'utf8');
|
const bruContent = fs.readFileSync(pathname, 'utf8');
|
||||||
const jsonData = JSON.parse(jsonStr);
|
|
||||||
|
const jsonData = JSON.parse(bruContent);
|
||||||
|
|
||||||
const envDirectory = path.join(dirname, 'environments');
|
const envDirectory = path.join(dirname, 'environments');
|
||||||
if (!fs.existsSync(envDirectory)) {
|
if (!fs.existsSync(envDirectory)) {
|
||||||
@ -177,8 +190,14 @@ const add = async (win, pathname, collectionUid, collectionPath) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const bru = fs.readFileSync(pathname, 'utf8');
|
let bruContent = fs.readFileSync(pathname, 'utf8');
|
||||||
file.data = bruToJson(bru);
|
|
||||||
|
// migrate old bru format to new bru format
|
||||||
|
if(isLegacyBruFile(bruContent)) {
|
||||||
|
bruContent = await migrateLegacyBruFile(bruContent, pathname);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.data = bruToJson(bruContent);
|
||||||
hydrateRequestWithUuid(file.data, pathname);
|
hydrateRequestWithUuid(file.data, pathname);
|
||||||
win.webContents.send('main:collection-tree-updated', 'addFile', file);
|
win.webContents.send('main:collection-tree-updated', 'addFile', file);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const {
|
const {
|
||||||
bruToEnvJson: bruToEnvJsonV1,
|
|
||||||
envJsonToBru: envJsonToBruV1,
|
|
||||||
bruToJson: bruToJsonV1,
|
|
||||||
|
|
||||||
bruToJsonV2,
|
bruToJsonV2,
|
||||||
jsonToBruV2,
|
jsonToBruV2,
|
||||||
bruToEnvJsonV2,
|
bruToEnvJsonV2,
|
||||||
@ -56,7 +52,7 @@ const bruToJson = (bru) => {
|
|||||||
} else if(requestType === "graphql") {
|
} else if(requestType === "graphql") {
|
||||||
requestType = "graphql-request";
|
requestType = "graphql-request";
|
||||||
} else {
|
} else {
|
||||||
requestType = "http";
|
requestType = "http-request";
|
||||||
}
|
}
|
||||||
|
|
||||||
const sequence = _.get(json, "meta.seq")
|
const sequence = _.get(json, "meta.seq")
|
||||||
|
99
packages/bruno-electron/src/bru/migrate.js
Normal file
99
packages/bruno-electron/src/bru/migrate.js
Normal 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
|
||||||
|
};
|
@ -38,7 +38,7 @@ const grammar = ohm.grammar(`Bru {
|
|||||||
|
|
||||||
// Dictionary Blocks
|
// Dictionary Blocks
|
||||||
dictionary = st* "{" pairlist? tagend
|
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*
|
pair = st* key st* ":" st* value? st*
|
||||||
key = ~tagend validkey*
|
key = ~tagend validkey*
|
||||||
value = ~tagend validvalue*
|
value = ~tagend validvalue*
|
||||||
|
Loading…
Reference in New Issue
Block a user