Include letterhead files in tenant archive
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
Build and Push Docker Images / build-website (push) Successful in 17s
Build and Push Docker Images / build-docs (push) Successful in 16s
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
Build and Push Docker Images / build-website (push) Successful in 17s
Build and Push Docker Images / build-docs (push) Successful in 16s
This commit is contained in:
@@ -265,6 +265,22 @@ const archiveEntryPathForFile = (path: string) => {
|
|||||||
return `files/${normalizedPath || "unnamed-file"}`
|
return `files/${normalizedPath || "unnamed-file"}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filenameFromPath = (path: string) => {
|
||||||
|
const filename = path
|
||||||
|
.replace(/\\/g, "/")
|
||||||
|
.split("/")
|
||||||
|
.filter(Boolean)
|
||||||
|
.pop()
|
||||||
|
|
||||||
|
if (!filename) return null
|
||||||
|
|
||||||
|
try {
|
||||||
|
return decodeURIComponent(filename)
|
||||||
|
} catch {
|
||||||
|
return filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const jsonBuffer = (value: unknown) => Buffer.from(`${JSON.stringify(value, null, 2)}\n`, "utf8")
|
const jsonBuffer = (value: unknown) => Buffer.from(`${JSON.stringify(value, null, 2)}\n`, "utf8")
|
||||||
|
|
||||||
export const buildTenantFullExport = async (
|
export const buildTenantFullExport = async (
|
||||||
@@ -329,11 +345,17 @@ export const buildTenantFullExport = async (
|
|||||||
tables.entitybankaccounts = decryptEntityBankAccountsForExport(tables.entitybankaccounts)
|
tables.entitybankaccounts = decryptEntityBankAccountsForExport(tables.entitybankaccounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileRows = tables.files || []
|
|
||||||
const files = []
|
const files = []
|
||||||
|
const filePaths = new Set<string>()
|
||||||
for (const file of fileRows) {
|
const addExportFile = async (file: {
|
||||||
if (!file.path) continue
|
id: string
|
||||||
|
path: string
|
||||||
|
name?: string | null
|
||||||
|
mimeType?: string | null
|
||||||
|
size?: number | null
|
||||||
|
}) => {
|
||||||
|
if (!file.path || filePaths.has(file.path)) return
|
||||||
|
filePaths.add(file.path)
|
||||||
|
|
||||||
const object = includeFileContents
|
const object = includeFileContents
|
||||||
? await loadObjectAsBase64(file.path)
|
? await loadObjectAsBase64(file.path)
|
||||||
@@ -350,7 +372,7 @@ export const buildTenantFullExport = async (
|
|||||||
files.push({
|
files.push({
|
||||||
id: file.id,
|
id: file.id,
|
||||||
path: file.path,
|
path: file.path,
|
||||||
name: file.name || null,
|
name: file.name || filenameFromPath(file.path),
|
||||||
mimeType: file.mimeType || null,
|
mimeType: file.mimeType || null,
|
||||||
size: file.size || null,
|
size: file.size || null,
|
||||||
contentBase64: object.contentBase64,
|
contentBase64: object.contentBase64,
|
||||||
@@ -359,6 +381,30 @@ export const buildTenantFullExport = async (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const file of tables.files || []) {
|
||||||
|
if (!file.path) continue
|
||||||
|
|
||||||
|
await addExportFile({
|
||||||
|
id: file.id,
|
||||||
|
path: file.path,
|
||||||
|
name: file.name || null,
|
||||||
|
mimeType: file.mimeType || null,
|
||||||
|
size: file.size || null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const letterhead of tables.letterheads || []) {
|
||||||
|
if (!letterhead.path) continue
|
||||||
|
|
||||||
|
await addExportFile({
|
||||||
|
id: `letterhead:${letterhead.id}`,
|
||||||
|
path: letterhead.path,
|
||||||
|
name: filenameFromPath(letterhead.path),
|
||||||
|
mimeType: "application/pdf",
|
||||||
|
size: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
format: "fedeo.tenant-full-export",
|
format: "fedeo.tenant-full-export",
|
||||||
version: 1,
|
version: 1,
|
||||||
@@ -384,7 +430,7 @@ export const createTenantFullExportArchive = async (
|
|||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
const filename = options.filename || `fedeo-tenant-${safeTenantName || tenantId}-${new Date().toISOString().slice(0, 10)}.fedeo-export.zip`
|
const filename = options.filename || `fedeo-tenant-${safeTenantName || tenantId}-${new Date().toISOString().slice(0, 10)}.fedeo-export.zip`
|
||||||
const storagePath = options.storagePath || `tenant-exports/${tenantId}/${Date.now()}-${filename}`
|
const storagePath = options.storagePath || `tenant-exports/${tenantId}/${Date.now()}-${filename}`
|
||||||
const fileRows = exportData.tables.files || []
|
const fileRows = exportData.files || []
|
||||||
const archive = archiver("zip", { zlib: { level: 6 } })
|
const archive = archiver("zip", { zlib: { level: 6 } })
|
||||||
const tempPath = path.join(os.tmpdir(), `fedeo-tenant-export-${tenantId}-${Date.now()}-${filename}`)
|
const tempPath = path.join(os.tmpdir(), `fedeo-tenant-export-${tenantId}-${Date.now()}-${filename}`)
|
||||||
const output = createWriteStream(tempPath)
|
const output = createWriteStream(tempPath)
|
||||||
@@ -523,7 +569,7 @@ const restoreArchiveFiles = async (
|
|||||||
let skipped = 0
|
let skipped = 0
|
||||||
const filesByPath = new Map((manifest.files || []).map((file) => [file.path, file]))
|
const filesByPath = new Map((manifest.files || []).map((file) => [file.path, file]))
|
||||||
|
|
||||||
for (const fileRow of exportData.tables.files || []) {
|
for (const fileRow of exportData.files || []) {
|
||||||
const originalPath = fileRow.path
|
const originalPath = fileRow.path
|
||||||
if (!originalPath) {
|
if (!originalPath) {
|
||||||
skipped += 1
|
skipped += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user