mirror of
https://github.com/usebruno/bruno.git
synced 2025-06-24 22:11:38 +02:00
Now added the ability to import and export js and json values. changes made in item schema. (#2296)
* Now added the ability to import and export js values. changes made in item schema. * Improvements upon review * Fixes. * refactor: removed the copyRequest function and wrote the logic directly inside the copyItems function. * refactor: Update getBrunoJsonConfig function to remove unnecessary parameter * refactor: Update getBrunoJsonConfig function to remove unnecessary parameter and handle auth object dynamically * refactor: Update OAuth2 grantType handling in transformCollectionToSaveToExportAsFile function * refactor: Update getBrunoJsonConfig function to remove unnecessary async
This commit is contained in:
parent
4df78910f5
commit
4f115b06fb
@ -267,6 +267,10 @@ export const transformCollectionToSaveToExportAsFile = (collection, options = {}
|
|||||||
|
|
||||||
const copyItems = (sourceItems, destItems) => {
|
const copyItems = (sourceItems, destItems) => {
|
||||||
each(sourceItems, (si) => {
|
each(sourceItems, (si) => {
|
||||||
|
if (!isItemAFolder(si) && !isItemARequest(si) && si.type !== 'js') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const di = {
|
const di = {
|
||||||
uid: si.uid,
|
uid: si.uid,
|
||||||
type: si.type,
|
type: si.type,
|
||||||
@ -274,80 +278,109 @@ export const transformCollectionToSaveToExportAsFile = (collection, options = {}
|
|||||||
seq: si.seq
|
seq: si.seq
|
||||||
};
|
};
|
||||||
|
|
||||||
// if items is draft, then take data from draft to save
|
if (si.request) {
|
||||||
// The condition "!options.ignoreDraft" may appear confusing
|
di.request = {
|
||||||
// When saving a collection, this option allows the caller to specify to ignore any draft changes while still saving rest of the collection.
|
url: si.request.url,
|
||||||
// This is useful for performing rename request/collections while still leaving changes in draft not making its way into the indexeddb
|
method: si.request.method,
|
||||||
if (si.draft && !options.ignoreDraft) {
|
headers: copyHeaders(si.request.headers),
|
||||||
if (si.draft.request) {
|
params: copyQueryParams(si.request.params),
|
||||||
di.request = {
|
body: {
|
||||||
url: si.draft.request.url,
|
mode: si.request.body.mode,
|
||||||
method: si.draft.request.method,
|
json: si.request.body.json,
|
||||||
headers: copyHeaders(si.draft.request.headers),
|
text: si.request.body.text,
|
||||||
params: copyQueryParams(si.draft.request.params),
|
xml: si.request.body.xml,
|
||||||
body: {
|
graphql: si.request.body.graphql,
|
||||||
mode: si.draft.request.body.mode,
|
sparql: si.request.body.sparql,
|
||||||
json: si.draft.request.body.json,
|
formUrlEncoded: copyFormUrlEncodedParams(si.request.body.formUrlEncoded),
|
||||||
text: si.draft.request.body.text,
|
multipartForm: copyMultipartFormParams(si.request.body.multipartForm)
|
||||||
xml: si.draft.request.body.xml,
|
},
|
||||||
graphql: si.draft.request.body.graphql,
|
script: si.request.script,
|
||||||
sparql: si.draft.request.body.sparql,
|
vars: si.request.vars,
|
||||||
formUrlEncoded: copyFormUrlEncodedParams(si.draft.request.body.formUrlEncoded),
|
assertions: si.request.assertions,
|
||||||
multipartForm: copyMultipartFormParams(si.draft.request.body.multipartForm)
|
tests: si.request.tests
|
||||||
},
|
};
|
||||||
auth: {
|
|
||||||
mode: get(si.draft.request, 'auth.mode', 'none'),
|
|
||||||
basic: {
|
|
||||||
username: get(si.draft.request, 'auth.basic.username', ''),
|
|
||||||
password: get(si.draft.request, 'auth.basic.password', '')
|
|
||||||
},
|
|
||||||
bearer: {
|
|
||||||
token: get(si.draft.request, 'auth.bearer.token', '')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
script: si.draft.request.script,
|
|
||||||
vars: si.draft.request.vars,
|
|
||||||
assertions: si.draft.request.assertions,
|
|
||||||
tests: si.draft.request.tests
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (si.request) {
|
|
||||||
di.request = {
|
|
||||||
url: si.request.url,
|
|
||||||
method: si.request.method,
|
|
||||||
headers: copyHeaders(si.request.headers),
|
|
||||||
params: copyQueryParams(si.request.params),
|
|
||||||
body: {
|
|
||||||
mode: si.request.body.mode,
|
|
||||||
json: si.request.body.json,
|
|
||||||
text: si.request.body.text,
|
|
||||||
xml: si.request.body.xml,
|
|
||||||
graphql: si.request.body.graphql,
|
|
||||||
sparql: si.request.body.sparql,
|
|
||||||
formUrlEncoded: copyFormUrlEncodedParams(si.request.body.formUrlEncoded),
|
|
||||||
multipartForm: copyMultipartFormParams(si.request.body.multipartForm)
|
|
||||||
},
|
|
||||||
auth: {
|
|
||||||
mode: get(si.request, 'auth.mode', 'none'),
|
|
||||||
basic: {
|
|
||||||
username: get(si.request, 'auth.basic.username', ''),
|
|
||||||
password: get(si.request, 'auth.basic.password', '')
|
|
||||||
},
|
|
||||||
bearer: {
|
|
||||||
token: get(si.request, 'auth.bearer.token', '')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
script: si.request.script,
|
|
||||||
vars: si.request.vars,
|
|
||||||
assertions: si.request.assertions,
|
|
||||||
tests: si.request.tests
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (di.request && di.request.body.mode === 'json') {
|
// Handle auth object dynamically
|
||||||
di.request.body.json = replaceTabsWithSpaces(di.request.body.json);
|
di.request.auth = {
|
||||||
|
mode: get(si.request, 'auth.mode', 'none')
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (di.request.auth.mode) {
|
||||||
|
case 'awsv4':
|
||||||
|
di.request.auth.awsv4 = {
|
||||||
|
accessKeyId: get(si.request, 'auth.awsv4.accessKeyId', ''),
|
||||||
|
secretAccessKey: get(si.request, 'auth.awsv4.secretAccessKey', ''),
|
||||||
|
sessionToken: get(si.request, 'auth.awsv4.sessionToken', ''),
|
||||||
|
service: get(si.request, 'auth.awsv4.service', ''),
|
||||||
|
region: get(si.request, 'auth.awsv4.region', ''),
|
||||||
|
profileName: get(si.request, 'auth.awsv4.profileName', '')
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 'basic':
|
||||||
|
di.request.auth.basic = {
|
||||||
|
username: get(si.request, 'auth.basic.username', ''),
|
||||||
|
password: get(si.request, 'auth.basic.password', '')
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 'bearer':
|
||||||
|
di.request.auth.bearer = {
|
||||||
|
token: get(si.request, 'auth.bearer.token', '')
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 'digest':
|
||||||
|
di.request.auth.digest = {
|
||||||
|
username: get(si.request, 'auth.digest.username', ''),
|
||||||
|
password: get(si.request, 'auth.digest.password', '')
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 'oauth2':
|
||||||
|
let grantType = get(si.request, 'auth.oauth2.grantType', '');
|
||||||
|
switch (grantType) {
|
||||||
|
case 'password':
|
||||||
|
di.request.auth.oauth2 = {
|
||||||
|
grantType: grantType,
|
||||||
|
accessTokenUrl: get(si.request, 'auth.oauth2.accessTokenUrl', ''),
|
||||||
|
username: get(si.request, 'auth.oauth2.username', ''),
|
||||||
|
password: get(si.request, 'auth.oauth2.password', ''),
|
||||||
|
clientId: get(si.request, 'auth.oauth2.clientId', ''),
|
||||||
|
clientSecret: get(si.request, 'auth.oauth2.clientSecret', ''),
|
||||||
|
scope: get(si.request, 'auth.oauth2.scope', '')
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 'authorization_code':
|
||||||
|
di.request.auth.oauth2 = {
|
||||||
|
grantType: grantType,
|
||||||
|
callbackUrl: get(si.request, 'auth.oauth2.callbackUrl', ''),
|
||||||
|
authorizationUrl: get(si.request, 'auth.oauth2.authorizationUrl', ''),
|
||||||
|
accessTokenUrl: get(si.request, 'auth.oauth2.accessTokenUrl', ''),
|
||||||
|
clientId: get(si.request, 'auth.oauth2.clientId', ''),
|
||||||
|
clientSecret: get(si.request, 'auth.oauth2.clientSecret', ''),
|
||||||
|
scope: get(si.request, 'auth.oauth2.scope', ''),
|
||||||
|
pkce: get(si.request, 'auth.oauth2.pkce', false)
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 'client_credentials':
|
||||||
|
di.request.auth.oauth2 = {
|
||||||
|
grantType: grantType,
|
||||||
|
accessTokenUrl: get(si.request, 'auth.oauth2.accessTokenUrl', ''),
|
||||||
|
clientId: get(si.request, 'auth.oauth2.clientId', ''),
|
||||||
|
clientSecret: get(si.request, 'auth.oauth2.clientSecret', ''),
|
||||||
|
scope: get(si.request, 'auth.oauth2.scope', '')
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (si.type === 'js') {
|
||||||
|
di.fileContent = si.raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (di.request.body.mode === 'json') {
|
||||||
|
di.request.body.json = replaceTabsWithSpaces(di.request.body.json);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destItems.push(di);
|
destItems.push(di);
|
||||||
@ -369,8 +402,14 @@ export const transformCollectionToSaveToExportAsFile = (collection, options = {}
|
|||||||
collectionToSave.activeEnvironmentUid = collection.activeEnvironmentUid;
|
collectionToSave.activeEnvironmentUid = collection.activeEnvironmentUid;
|
||||||
collectionToSave.environments = collection.environments || [];
|
collectionToSave.environments = collection.environments || [];
|
||||||
|
|
||||||
copyItems(collection.items, collectionToSave.items);
|
collectionToSave.brunoConfig = cloneDeep(collection?.brunoConfig);
|
||||||
|
|
||||||
|
// delete proxy password if present
|
||||||
|
if (collectionToSave?.brunoConfig?.proxy?.auth?.password) {
|
||||||
|
delete collectionToSave.brunoConfig.proxy.auth.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
copyItems(collection.items, collectionToSave.items);
|
||||||
return collectionToSave;
|
return collectionToSave;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -428,6 +428,11 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
|||||||
parseCollectionItems(item.items, folderPath);
|
parseCollectionItems(item.items, folderPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Handle items of type 'js'
|
||||||
|
if (item.type === 'js') {
|
||||||
|
const filePath = path.join(currentPath, `${item.name}.js`);
|
||||||
|
fs.writeFileSync(filePath, item.raw);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -444,17 +449,29 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getBrunoJsonConfig = (collection) => {
|
||||||
|
let brunoConfig = collection.brunoConfig;
|
||||||
|
|
||||||
|
if (!brunoConfig) {
|
||||||
|
brunoConfig = {
|
||||||
|
version: '1',
|
||||||
|
name: collection.name,
|
||||||
|
type: 'collection',
|
||||||
|
ignore: ['node_modules', '.git']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return brunoConfig;
|
||||||
|
};
|
||||||
|
|
||||||
await createDirectory(collectionPath);
|
await createDirectory(collectionPath);
|
||||||
|
|
||||||
const uid = generateUidBasedOnHash(collectionPath);
|
const uid = generateUidBasedOnHash(collectionPath);
|
||||||
const brunoConfig = {
|
const brunoConfig = getBrunoJsonConfig(collection);
|
||||||
version: '1',
|
const stringifiedBrunoConfig = await stringifyJson(brunoConfig);
|
||||||
name: collectionName,
|
|
||||||
type: 'collection',
|
// Write the Bruno configuration to a file
|
||||||
ignore: ['node_modules', '.git']
|
await writeFile(path.join(collectionPath, 'bruno.json'), stringifiedBrunoConfig);
|
||||||
};
|
|
||||||
const content = await stringifyJson(brunoConfig);
|
|
||||||
await writeFile(path.join(collectionPath, 'bruno.json'), content);
|
|
||||||
|
|
||||||
mainWindow.webContents.send('main:collection-opened', collectionPath, uid, brunoConfig);
|
mainWindow.webContents.send('main:collection-opened', collectionPath, uid, brunoConfig);
|
||||||
ipcMain.emit('main:collection-opened', mainWindow, collectionPath, uid, brunoConfig);
|
ipcMain.emit('main:collection-opened', mainWindow, collectionPath, uid, brunoConfig);
|
||||||
|
@ -217,13 +217,21 @@ const requestSchema = Yup.object({
|
|||||||
|
|
||||||
const itemSchema = Yup.object({
|
const itemSchema = Yup.object({
|
||||||
uid: uidSchema,
|
uid: uidSchema,
|
||||||
type: Yup.string().oneOf(['http-request', 'graphql-request', 'folder']).required('type is required'),
|
type: Yup.string().oneOf(['http-request', 'graphql-request', 'folder', 'js']).required('type is required'),
|
||||||
seq: Yup.number().min(1),
|
seq: Yup.number().min(1),
|
||||||
name: Yup.string().min(1, 'name must be at least 1 character').required('name is required'),
|
name: Yup.string().min(1, 'name must be at least 1 character').required('name is required'),
|
||||||
request: requestSchema.when('type', {
|
request: requestSchema.when('type', {
|
||||||
is: (type) => ['http-request', 'graphql-request'].includes(type),
|
is: (type) => ['http-request', 'graphql-request'].includes(type),
|
||||||
then: (schema) => schema.required('request is required when item-type is request')
|
then: (schema) => schema.required('request is required when item-type is request')
|
||||||
}),
|
}),
|
||||||
|
fileContent: Yup.string().when('type', {
|
||||||
|
// If the type is 'js', the fileContent field is expected to be a string.
|
||||||
|
// This can include an empty string, indicating that the JS file may not have any content.
|
||||||
|
is: 'js',
|
||||||
|
then: Yup.string(),
|
||||||
|
// For all other types, the fileContent field is not required and can be null.
|
||||||
|
otherwise: Yup.string().nullable()
|
||||||
|
}),
|
||||||
items: Yup.lazy(() => Yup.array().of(itemSchema)),
|
items: Yup.lazy(() => Yup.array().of(itemSchema)),
|
||||||
filename: Yup.string().nullable(),
|
filename: Yup.string().nullable(),
|
||||||
pathname: Yup.string().nullable()
|
pathname: Yup.string().nullable()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user