mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-14 19:31:30 +00:00
fix(cli): preserve request item type during import and fail on unsupported types (#7207)
* fix(cli): preserve request type when importing collections * fix(cli): fail fast on unsupported imported item types * fix(cli): force BRU format when writing imported files * chore: apply code rabbit fixes * chore: adress review comment - keep changes minimal * add additional test to test bru folder format * agree with coderabbit, error handling is required --------- Co-authored-by: Ramesh Sunkara <rs@rsunkara.com>
This commit is contained in:
@@ -11,6 +11,7 @@ const FORMAT_CONFIG = {
|
||||
yml: { ext: '.yml', collectionFile: 'opencollection.yml', folderFile: 'folder.yml' },
|
||||
bru: { ext: '.bru', collectionFile: 'collection.bru', folderFile: 'folder.bru' }
|
||||
};
|
||||
const REQUEST_ITEM_TYPES = ['http-request', 'graphql-request'];
|
||||
|
||||
const getCollectionFormat = (collectionPath) => {
|
||||
if (fs.existsSync(path.join(collectionPath, 'opencollection.yml'))) return 'yml';
|
||||
@@ -499,7 +500,7 @@ const processCollectionItems = async (items = [], currentPath) => {
|
||||
if (item.seq) {
|
||||
item.root.meta.seq = item.seq;
|
||||
}
|
||||
const folderContent = await stringifyFolder(item.root);
|
||||
const folderContent = stringifyFolder(item.root, { format: 'bru' });
|
||||
safeWriteFileSync(folderBruFilePath, folderContent);
|
||||
}
|
||||
|
||||
@@ -507,17 +508,16 @@ const processCollectionItems = async (items = [], currentPath) => {
|
||||
if (item.items && item.items.length) {
|
||||
await processCollectionItems(item.items, folderPath);
|
||||
}
|
||||
} else if (['http-request', 'graphql-request'].includes(item.type)) {
|
||||
} else if (REQUEST_ITEM_TYPES.includes(item.type)) {
|
||||
// Create request file
|
||||
let sanitizedFilename = sanitizeName(item?.filename || `${item.name}.bru`);
|
||||
if (!sanitizedFilename.endsWith('.bru')) {
|
||||
sanitizedFilename += '.bru';
|
||||
}
|
||||
|
||||
// Convert JSON to BRU format based on the item type
|
||||
let type = item.type === 'http-request' ? 'http' : 'graphql';
|
||||
const bruJson = {
|
||||
type: type,
|
||||
// Keep schema item type so filestore can stringify request correctly
|
||||
type: item.type,
|
||||
name: item.name,
|
||||
seq: typeof item.seq === 'number' ? item.seq : 1,
|
||||
tags: item.tags || [],
|
||||
@@ -538,8 +538,10 @@ const processCollectionItems = async (items = [], currentPath) => {
|
||||
};
|
||||
|
||||
// Convert to BRU format and write to file
|
||||
const content = await stringifyRequest(bruJson);
|
||||
const content = stringifyRequest(bruJson, { format: 'bru' });
|
||||
safeWriteFileSync(path.join(currentPath, sanitizedFilename), content);
|
||||
} else {
|
||||
throw new Error(`Unsupported item type: ${item.type}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { describe, it, expect, afterEach } = require('@jest/globals');
|
||||
const { parseRequest, parseFolder } = require('@usebruno/filestore');
|
||||
const { createCollectionFromBrunoObject } = require('../../../src/utils/collection');
|
||||
|
||||
describe('createCollectionFromBrunoObject', () => {
|
||||
let outputDir;
|
||||
const createOutputDir = () => {
|
||||
outputDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bruno-cli-import-'));
|
||||
return outputDir;
|
||||
};
|
||||
const parseBruRequestFromPath = (filePath) => parseRequest(fs.readFileSync(filePath, 'utf8'), { format: 'bru' });
|
||||
const parseBruFolderFromPath = (filePath) => parseFolder(fs.readFileSync(filePath, 'utf8'), { format: 'bru' });
|
||||
|
||||
afterEach(() => {
|
||||
if (outputDir && fs.existsSync(outputDir)) {
|
||||
fs.rmSync(outputDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it('writes http and graphql requests from imported collection items', async () => {
|
||||
createOutputDir();
|
||||
|
||||
await createCollectionFromBrunoObject(
|
||||
{
|
||||
name: 'imported-collection',
|
||||
items: [
|
||||
{
|
||||
type: 'http-request',
|
||||
name: 'Get Users',
|
||||
filename: 'get-users.bru',
|
||||
seq: 1,
|
||||
request: {
|
||||
method: 'GET',
|
||||
url: 'https://api.example.com/users'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'graphql-request',
|
||||
name: 'Get Viewer',
|
||||
filename: 'get-viewer.bru',
|
||||
seq: 2,
|
||||
request: {
|
||||
method: 'POST',
|
||||
url: 'https://api.example.com/graphql',
|
||||
body: {
|
||||
mode: 'graphql',
|
||||
graphql: {
|
||||
query: 'query { viewer { id } }',
|
||||
variables: '{}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
outputDir
|
||||
);
|
||||
|
||||
const httpPath = path.join(outputDir, 'get-users.bru');
|
||||
const graphqlPath = path.join(outputDir, 'get-viewer.bru');
|
||||
|
||||
expect(fs.existsSync(httpPath)).toBe(true);
|
||||
expect(fs.existsSync(graphqlPath)).toBe(true);
|
||||
|
||||
const httpRequest = parseBruRequestFromPath(httpPath);
|
||||
const graphqlRequest = parseBruRequestFromPath(graphqlPath);
|
||||
|
||||
expect(httpRequest).toHaveProperty('type', 'http-request');
|
||||
expect(httpRequest).toHaveProperty('request.method', 'GET');
|
||||
expect(graphqlRequest).toHaveProperty('type', 'graphql-request');
|
||||
expect(graphqlRequest).toHaveProperty('request.method', 'POST');
|
||||
});
|
||||
|
||||
it('writes folder.bru in bru format', async () => {
|
||||
createOutputDir();
|
||||
|
||||
await createCollectionFromBrunoObject(
|
||||
{
|
||||
name: 'folder-collection',
|
||||
items: [
|
||||
{
|
||||
type: 'folder',
|
||||
name: 'Users',
|
||||
seq: 3,
|
||||
root: {
|
||||
meta: { name: 'Users' }
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'http-request',
|
||||
name: 'List Users',
|
||||
filename: 'list-users.bru',
|
||||
seq: 1,
|
||||
request: {
|
||||
method: 'GET',
|
||||
url: 'https://api.example.com/users'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
outputDir
|
||||
);
|
||||
|
||||
const folderPath = path.join(outputDir, 'Users');
|
||||
const folderBruPath = path.join(folderPath, 'folder.bru');
|
||||
const nestedRequestPath = path.join(folderPath, 'list-users.bru');
|
||||
|
||||
expect(fs.existsSync(folderBruPath)).toBe(true);
|
||||
expect(fs.existsSync(nestedRequestPath)).toBe(true);
|
||||
|
||||
const folder = parseBruFolderFromPath(folderBruPath);
|
||||
const nestedRequest = parseBruRequestFromPath(nestedRequestPath);
|
||||
|
||||
expect(folder).toHaveProperty('meta.name', 'Users');
|
||||
expect(folder).toHaveProperty('meta.seq', 3);
|
||||
expect(nestedRequest).toHaveProperty('type', 'http-request');
|
||||
expect(nestedRequest).toHaveProperty('request.method', 'GET');
|
||||
});
|
||||
|
||||
it('throws for unsupported item types', async () => {
|
||||
createOutputDir();
|
||||
|
||||
await expect(
|
||||
createCollectionFromBrunoObject(
|
||||
{
|
||||
name: 'invalid-item-type-collection',
|
||||
items: [
|
||||
{
|
||||
type: 'unsupported-type',
|
||||
name: 'Unsupported'
|
||||
}
|
||||
]
|
||||
},
|
||||
outputDir
|
||||
)
|
||||
).rejects.toThrow('Unsupported item type: unsupported-type');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user