/** Текущий формат архива проекта (новые сохранения). */ export const PROJECT_ZIP_EXTENSION = '.ttrpg.zip'; /** Устаревший формат — только открытие / импорт (вариант B). */ export const PROJECT_ZIP_EXTENSION_LEGACY = '.dnd.zip'; export function isProjectZipFileName(fileName: string): boolean { const lower = fileName.toLowerCase(); return lower.endsWith(PROJECT_ZIP_EXTENSION) || lower.endsWith(PROJECT_ZIP_EXTENSION_LEGACY); } export function isLegacyProjectZipFileName(fileName: string): boolean { return fileName.toLowerCase().endsWith(PROJECT_ZIP_EXTENSION_LEGACY); } export function projectZipFileNameFromBase(stem: string): string { return `${stem}${PROJECT_ZIP_EXTENSION}`; } /** Имя файла для сохранения/экспорта — всегда `.ttrpg.zip`. */ export function normalizeSaveProjectZipPath(filePath: string): string { const lower = filePath.toLowerCase(); if (lower.endsWith(PROJECT_ZIP_EXTENSION)) return filePath; if (lower.endsWith(PROJECT_ZIP_EXTENSION_LEGACY)) { return filePath.slice(0, -PROJECT_ZIP_EXTENSION_LEGACY.length) + PROJECT_ZIP_EXTENSION; } if (lower.endsWith('.zip')) { return filePath.replace(/\.zip$/iu, PROJECT_ZIP_EXTENSION); } return `${filePath}${PROJECT_ZIP_EXTENSION}`; } export function stripProjectZipExtension(fileName: string): string { const lower = fileName.toLowerCase(); if (lower.endsWith(PROJECT_ZIP_EXTENSION)) { return fileName.slice(0, -PROJECT_ZIP_EXTENSION.length); } if (lower.endsWith(PROJECT_ZIP_EXTENSION_LEGACY)) { return fileName.slice(0, -PROJECT_ZIP_EXTENSION_LEGACY.length); } return fileName; } export const PROJECT_ZIP_OPEN_DIALOG_FILTER: Electron.FileFilter = { name: 'Проект TTRPG (*.ttrpg.zip, *.dnd.zip)', extensions: ['ttrpg.zip', 'dnd.zip'], }; export const PROJECT_ZIP_SAVE_DIALOG_FILTER: Electron.FileFilter = { name: 'Проект TTRPG (*.ttrpg.zip)', extensions: ['ttrpg.zip'], };