feat: use confluence real file names

This commit is contained in:
Philipinho
2026-03-28 10:23:29 +00:00
parent 795b79c2a2
commit a5360ad341
2 changed files with 34 additions and 3 deletions
@@ -190,13 +190,32 @@ export class ImportAttachmentService {
} }
} }
// Build a map from resolved archive path → real filename from Confluence
// metadata. Confluence Server archives often store files under numeric IDs
// (e.g. "attachments/65601/65602") instead of the original filename.
const pageDir = path.dirname(pageRelativePath);
const attachmentNameByRelPath = new Map<string, string>();
for (const attachment of pageAttachments) {
const relPath = resolveRelativeAttachmentPath(
attachment.href,
pageDir,
attachmentCandidates,
);
if (relPath && attachment.fileName) {
attachmentNameByRelPath.set(relPath, attachment.fileName);
}
}
const uploadOnce = (relPath: string) => { const uploadOnce = (relPath: string) => {
const abs = attachmentCandidates.get(relPath)!; const abs = attachmentCandidates.get(relPath)!;
const attachmentId = v7(); const attachmentId = v7();
const ext = path.extname(abs);
const realName = attachmentNameByRelPath.get(relPath);
const baseName = realName || path.basename(abs);
const ext = path.extname(baseName);
const fileNameWithExt = const fileNameWithExt =
sanitizeFileName(path.basename(abs, ext)) + ext.toLowerCase(); sanitizeFileName(path.basename(baseName, ext)) + ext.toLowerCase();
const storageFilePath = `${getAttachmentFolderPath( const storageFilePath = `${getAttachmentFolderPath(
AttachmentType.File, AttachmentType.File,
@@ -240,7 +259,6 @@ export class ImportAttachmentService {
return fresh; return fresh;
}; };
const pageDir = path.dirname(pageRelativePath);
const $ = load(html); const $ = load(html);
// image // image
@@ -41,6 +41,15 @@ export function resolveRelativeAttachmentPath(
'ImportUtils', 'ImportUtils',
); );
} }
// Confluence Server uses "/download/attachments/..." in HTML but the ZIP
// stores files under "attachments/...". Strip the "download/" prefix so
// the path can match candidates from the archive.
const confluenceStripped = mainRel.replace(
/^download\/attachments\//,
'attachments/',
);
const fallback = path const fallback = path
.normalize(path.join(pageDir, mainRel)) .normalize(path.join(pageDir, mainRel))
.split(path.sep) .split(path.sep)
@@ -49,9 +58,13 @@ export function resolveRelativeAttachmentPath(
if (attachmentCandidates.has(mainRel)) { if (attachmentCandidates.has(mainRel)) {
return mainRel; return mainRel;
} }
if (confluenceStripped !== mainRel && attachmentCandidates.has(confluenceStripped)) {
return confluenceStripped;
}
if (attachmentCandidates.has(fallback)) { if (attachmentCandidates.has(fallback)) {
return fallback; return fallback;
} }
return null; return null;
} }