-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathattachment-storage.ts
More file actions
64 lines (55 loc) · 1.77 KB
/
Copy pathattachment-storage.ts
File metadata and controls
64 lines (55 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import fs from 'fs';
import os from 'os';
import path from 'path';
export interface AttachmentStorageSetup {
attachmentsDir: string;
uploadsDir: string;
stopEviction: () => void;
}
/**
* Prepare uploads/attachments directories and start periodic attachment eviction.
*/
export function initializeAttachmentStorage(dataDir: string): AttachmentStorageSetup {
const attachmentsDir = path.join(os.homedir(), '.relay', 'attachments');
if (!fs.existsSync(attachmentsDir)) {
fs.mkdirSync(attachmentsDir, { recursive: true });
}
const uploadsDir = path.join(dataDir, 'uploads');
if (!fs.existsSync(uploadsDir)) {
fs.mkdirSync(uploadsDir, { recursive: true });
}
const maxAgeMs = 7 * 24 * 60 * 60 * 1000;
const evictOldAttachments = async () => {
try {
const files = await fs.promises.readdir(attachmentsDir);
const now = Date.now();
let evictedCount = 0;
for (const file of files) {
const filePath = path.join(attachmentsDir, file);
try {
const stat = await fs.promises.stat(filePath);
if (stat.isFile() && now - stat.mtimeMs > maxAgeMs) {
await fs.promises.unlink(filePath);
evictedCount++;
}
} catch {
// Ignore per-file errors (deleted concurrently, permission changes, etc).
}
}
if (evictedCount > 0) {
console.log(`[dashboard] Evicted ${evictedCount} old attachment(s)`);
}
} catch (err) {
console.error('[dashboard] Failed to evict old attachments:', err);
}
};
void evictOldAttachments();
const evictionInterval = setInterval(() => {
void evictOldAttachments();
}, 60 * 60 * 1000);
return {
attachmentsDir,
uploadsDir,
stopEviction: () => clearInterval(evictionInterval),
};
}