mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-01 00:24:08 +00:00
* feat: Add Default Sample Collection On First Launch * feat(initial-load): add attribute for app readiness --------- Co-authored-by: Bijin Bruno <bijin@usebruno.com>
129 lines
4.8 KiB
JavaScript
129 lines
4.8 KiB
JavaScript
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const { ipcMain } = require('electron');
|
|
const { sanitizeName, createDirectory, writeFile, safeWriteFileSync, getCollectionStats } = require('./filesystem');
|
|
const { generateUidBasedOnHash, stringifyJson } = require('./common');
|
|
const { stringifyRequestViaWorker, stringifyCollection, stringifyEnvironment, stringifyFolder } = require('@usebruno/filestore');
|
|
|
|
/**
|
|
* Recursively find a unique folder name by appending incremental numbers
|
|
*/
|
|
async function findUniqueFolderName(baseName, collectionLocation, counter = 0) {
|
|
const folderName = counter === 0 ? baseName : `${baseName} - ${counter}`;
|
|
const collectionPath = path.join(collectionLocation, sanitizeName(folderName));
|
|
|
|
if (fs.existsSync(collectionPath)) {
|
|
return findUniqueFolderName(baseName, collectionLocation, counter + 1);
|
|
}
|
|
|
|
return folderName;
|
|
}
|
|
|
|
/**
|
|
* Import a collection - shared logic used by both IPC handler and onboarding service
|
|
*/
|
|
async function importCollection(collection, collectionLocation, mainWindow, lastOpenedCollections, uniqueFolderName = null) {
|
|
// Use provided unique folder name or use collection name
|
|
let folderName = uniqueFolderName ? sanitizeName(uniqueFolderName) : sanitizeName(collection.name);
|
|
let collectionPath = path.join(collectionLocation, folderName);
|
|
|
|
if (fs.existsSync(collectionPath)) {
|
|
throw new Error(`collection: ${collectionPath} already exists`);
|
|
}
|
|
|
|
// Recursive function to parse the collection items and create files/folders
|
|
const parseCollectionItems = async (items = [], currentPath) => {
|
|
for (const item of items) {
|
|
if (['http-request', 'graphql-request', 'grpc-request'].includes(item.type)) {
|
|
let sanitizedFilename = sanitizeName(item.filename || `${item.name}.bru`);
|
|
const content = await stringifyRequestViaWorker(item);
|
|
const filePath = path.join(currentPath, sanitizedFilename);
|
|
safeWriteFileSync(filePath, content);
|
|
}
|
|
if (item.type === 'folder') {
|
|
let sanitizedFolderName = sanitizeName(item.filename || item.name);
|
|
const folderPath = path.join(currentPath, sanitizedFolderName);
|
|
fs.mkdirSync(folderPath);
|
|
|
|
if (item.root?.meta?.name) {
|
|
const folderBruFilePath = path.join(folderPath, 'folder.bru');
|
|
item.root.meta.seq = item.seq;
|
|
const folderContent = await stringifyFolder(item.root);
|
|
safeWriteFileSync(folderBruFilePath, folderContent);
|
|
}
|
|
|
|
if (item.items && item.items.length) {
|
|
await parseCollectionItems(item.items, folderPath);
|
|
}
|
|
}
|
|
// Handle items of type 'js'
|
|
if (item.type === 'js') {
|
|
let sanitizedFilename = sanitizeName(item.filename || `${item.name}.js`);
|
|
const filePath = path.join(currentPath, sanitizedFilename);
|
|
safeWriteFileSync(filePath, item.fileContent);
|
|
}
|
|
}
|
|
};
|
|
|
|
const parseEnvironments = async (environments = [], collectionPath) => {
|
|
const envDirPath = path.join(collectionPath, 'environments');
|
|
if (!fs.existsSync(envDirPath)) {
|
|
fs.mkdirSync(envDirPath);
|
|
}
|
|
|
|
for (const env of environments) {
|
|
const content = await stringifyEnvironment(env);
|
|
let sanitizedEnvFilename = sanitizeName(`${env.name}.bru`);
|
|
const filePath = path.join(envDirPath, sanitizedEnvFilename);
|
|
safeWriteFileSync(filePath, content);
|
|
}
|
|
};
|
|
|
|
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);
|
|
|
|
const uid = generateUidBasedOnHash(collectionPath);
|
|
let brunoConfig = getBrunoJsonConfig(collection);
|
|
const stringifiedBrunoConfig = await stringifyJson(brunoConfig);
|
|
|
|
// Write the Bruno configuration to a file
|
|
await writeFile(path.join(collectionPath, 'bruno.json'), stringifiedBrunoConfig);
|
|
|
|
const collectionContent = await stringifyCollection(collection.root);
|
|
await writeFile(path.join(collectionPath, 'collection.bru'), collectionContent);
|
|
|
|
const { size, filesCount } = await getCollectionStats(collectionPath);
|
|
brunoConfig.size = size;
|
|
brunoConfig.filesCount = filesCount;
|
|
|
|
mainWindow.webContents.send('main:collection-opened', collectionPath, uid, brunoConfig);
|
|
ipcMain.emit('main:collection-opened', mainWindow, collectionPath, uid, brunoConfig);
|
|
|
|
lastOpenedCollections.add(collectionPath);
|
|
|
|
// create folder and files based on collection
|
|
await parseCollectionItems(collection.items, collectionPath);
|
|
await parseEnvironments(collection.environments, collectionPath);
|
|
|
|
return { collectionPath, uid, brunoConfig };
|
|
}
|
|
|
|
module.exports = {
|
|
importCollection,
|
|
findUniqueFolderName
|
|
};
|