(
options: { readonly now?: number; readonly dir?: string } = {},
)
| 37 | * `dir` is injectable for tests; production callers leave it as the default. |
| 38 | */ |
| 39 | export async function removeStaleFeedbackUploads( |
| 40 | options: { readonly now?: number; readonly dir?: string } = {}, |
| 41 | ): Promise<void> { |
| 42 | const now = options.now ?? Date.now(); |
| 43 | const dir = options.dir ?? join(getCacheDir(), 'feedback-uploads'); |
| 44 | const entries = await readdir(dir, { withFileTypes: true }).catch((error: unknown) => { |
| 45 | if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null; |
| 46 | throw error; |
| 47 | }); |
| 48 | if (entries === null) return; |
| 49 | |
| 50 | const cutoff = now - STALE_ARCHIVE_MAX_AGE_MS; |
| 51 | await Promise.all( |
| 52 | entries.map(async (entry) => { |
| 53 | if (!entry.isDirectory() && !entry.isSymbolicLink()) return; |
| 54 | const target = join(dir, entry.name); |
| 55 | const targetStat = await stat(target).catch(() => null); |
| 56 | if (targetStat === null || targetStat.mtimeMs >= cutoff) return; |
| 57 | await rm(target, { recursive: true, force: true }).catch(() => {}); |
| 58 | }), |
| 59 | ); |
| 60 | } |
| 61 | |
| 62 | async function createArchivePath(filename: string): Promise<string> { |
| 63 | await removeStaleFeedbackUploads(); |
no test coverage detected