diff --git a/backend/src/utils/files.ts b/backend/src/utils/files.ts new file mode 100644 index 0000000..9e91d6d --- /dev/null +++ b/backend/src/utils/files.ts @@ -0,0 +1,39 @@ +import path from 'node:path'; +import { env } from '../config/env.js'; +import type { FileRecord } from '../types.js'; +import { getPreviewMeta } from './preview.js'; +import { downloadUrl as gdriveDownloadUrl } from './gdrive.js'; + +export function sanitizeFilename(name: string) { + const base = path.basename(name || 'file'); + const cleaned = base + // eslint-disable-next-line no-control-regex + .replace(/[\x00-\x1f\x7f]/g, '') // strip control characters + .replace(/[^\w.()\s-]+/g, '-') + .replace(/\s+/g, ' ') + .trim(); + return cleaned || 'file'; +} + +export function fileToApi(file: FileRecord) { + const shareLink = `${env.publicAppUrl.replace(/\/$/, '')}/preview/${file.linkId}`; + const preview = getPreviewMeta(file); + return { + id: file.id, + linkId: file.linkId, + name: file.originalName, + size: file.sizeBytes, + type: file.mimeType, + uploader: file.uploader, + uploadedAt: file.createdAt, + expiresAt: file.expiresAt, + views: file.views, + downloads: file.downloads, + link: shareLink, + downloadUrl: gdriveDownloadUrl(file.gdriveId), + preview: { + ...preview, + url: preview.available ? `/api/v1/links/${file.linkId}/preview` : null, + }, + }; +}