diff --git a/apps/server/src/integrations/export/export.controller.ts b/apps/server/src/integrations/export/export.controller.ts index 0fc5fb96..1ce3f8c8 100644 --- a/apps/server/src/integrations/export/export.controller.ts +++ b/apps/server/src/integrations/export/export.controller.ts @@ -61,7 +61,7 @@ export class ExportController { await this.pageAccessService.validateCanView(page, user); - const zipFileStream = await this.exportService.exportPages( + const result = await this.exportService.exportPages( dto.pageId, dto.format, dto.includeAttachments, @@ -83,15 +83,29 @@ export class ExportController { }, }); - const fileName = sanitize(page.title || 'untitled') + '.zip'; + if (result.type === 'file') { + const ext = getExportExtension(dto.format); + const fileName = sanitize(page.title || 'untitled') + ext; + const contentType = getMimeType(path.extname(fileName)); - res.headers({ - 'Content-Type': 'application/zip', - 'Content-Disposition': - 'attachment; filename="' + encodeURIComponent(fileName) + '"', - }); + res.headers({ + 'Content-Type': contentType, + 'Content-Disposition': + 'attachment; filename="' + encodeURIComponent(fileName) + '"', + }); - res.send(zipFileStream); + res.send(result.content); + } else { + const fileName = sanitize(page.title || 'untitled') + '.zip'; + + res.headers({ + 'Content-Type': 'application/zip', + 'Content-Disposition': + 'attachment; filename="' + encodeURIComponent(fileName) + '"', + }); + + res.send(result.stream); + } } @UseGuards(JwtAuthGuard) diff --git a/apps/server/src/integrations/export/export.service.ts b/apps/server/src/integrations/export/export.service.ts index 4e1350f3..d93f9ba0 100644 --- a/apps/server/src/integrations/export/export.service.ts +++ b/apps/server/src/integrations/export/export.service.ts @@ -150,6 +150,13 @@ export class ExportService { // set to null to make export of pages with parentId work pages[parentPageIndex].parentPageId = null; + const isSinglePage = pages.length === 1 && !includeAttachments; + + if (isSinglePage) { + const pageContent = await this.exportPage(format, pages[0], true); + return { type: 'file' as const, content: pageContent, page: pages[0] }; + } + const tree = buildTree(pages as Page[]); const baseUrl = await this.getWorkspaceBaseUrl(pages[0].workspaceId); @@ -170,7 +177,7 @@ export class ExportService { compression: 'DEFLATE', }); - return zipFile; + return { type: 'zip' as const, stream: zipFile, page: pages[0] }; } async exportSpace(