fix(export): omit unselected folders from filtered v5 export

Previously every folder was exported even when none of its requests were selected.
This commit is contained in:
George He committed 2026-10-30 11:41:02 +08:00
1 parent 95ba903d66
commit 545aa3dfd1
2 files changed
+74 -2

No files matched your search

@@ -369,6 +369,62 @@ spec:
expect(parsed.collection[0].name).toBe('Request 1');
});
it('omits folders that contain no selected requests', async () => {
const workspace = await services.workspace.create({
_id: 'wrk_folder_filter',
name: 'Folder Filter Workspace',
parentId: 'proj_test',
scope: 'collection',
});
await services.environment.create({
_id: 'env_folder_filter',
name: 'Base Env',
parentId: workspace._id,
data: {},
});
const keptOuter = await services.requestGroup.create({
_id: 'fld_kept_outer',
name: 'Kept',
parentId: workspace._id,
});
const keptInner = await services.requestGroup.create({
_id: 'fld_kept_inner',
name: 'Inner',
parentId: keptOuter._id,
});
const skipped = await services.requestGroup.create({
_id: 'fld_skipped',
name: 'Skipped',
parentId: workspace._id,
});
const selected = await services.request.create({
_id: 'req_selected',
name: 'Selected',
parentId: keptInner._id,
url: 'https://api.example.com/selected',
method: 'GET',
});
await services.request.create({
_id: 'req_unselected',
name: 'Unselected',
parentId: skipped._id,
url: 'https://api.example.com/unselected',
method: 'GET',
});
const result = await getInsomniaV5DataExport({
workspaceId: workspace._id,
includePrivateEnvironments: false,
requestIds: [selected._id],
});
const parsed = YAML.parse(result);
expect(parsed.collection).toHaveLength(1);
expect(parsed.collection[0].name).toBe('Kept');
expect(parsed.collection[0].children[0].name).toBe('Inner');
expect(parsed.collection[0].children[0].children[0].name).toBe('Selected');
});
it('handles design workspace correctly', async () => {
const workspace = await services.workspace.create({
_id: 'wrk_design_test',
+18 -2
View File
@@ -1085,6 +1085,19 @@ export async function getInsomniaV5DataExport({
exportableResources.filter(models.webSocketPayload.isWebSocketPayload).map(payload => [payload.parentId, payload]),
);
// When exporting a subset of requests, only keep the folders that contain at least one of them
const requestGroupIdsToKeep = new Set<string>();
if (requestIds && requestIds.length > 0) {
const parentIdById = new Map(exportableResources.map(resource => [resource._id, resource.parentId]));
for (const requestId of requestIds) {
let parentId = parentIdById.get(requestId);
while (parentId && !requestGroupIdsToKeep.has(parentId)) {
requestGroupIdsToKeep.add(parentId);
parentId = parentIdById.get(parentId);
}
}
}
/**
* Recursively builds a collection structure from flat resource list
* This function converts the flat list of resources into a hierarchical structure
@@ -1103,10 +1116,13 @@ export async function getInsomniaV5DataExport({
// Filter resources based on requestIds filter and parent relationship
resources
.filter(resource => {
// Include all request groups, or filter by requestIds if specified
if (!requestIds || requestIds.length === 0 || models.requestGroup.isRequestGroup(resource)) {
// Include everything, or filter by requestIds if specified (folders are kept only if they contain a selected request)
if (!requestIds || requestIds.length === 0) {
return true;
}
if (models.requestGroup.isRequestGroup(resource)) {
return requestGroupIdsToKeep.has(resource._id);
}
return requestIds.includes(resource._id);
})