Throws on failure — callers decide whether a failed write is fatal.
(data: CacheData)
| 401 | |
| 402 | /** Throws on failure — callers decide whether a failed write is fatal. */ |
| 403 | private saveFile(data: CacheData): void { |
| 404 | // atomic write: exclusively create a temp file then rename over the target |
| 405 | const tmpPath = `${this.filePath}.tmp.${process.pid}.${randomBytes(4).toString('hex')}`; |
| 406 | fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600, flag: 'wx' }); |
| 407 | try { |
| 408 | fs.renameSync(tmpPath, this.filePath); |
| 409 | } catch (err) { |
| 410 | fs.rmSync(tmpPath, { force: true }); |
| 411 | throw err; |
| 412 | } |
| 413 | // explicit chmod in case rename preserved an existing file's mode |
| 414 | fs.chmodSync(this.filePath, 0o600); |
| 415 | } |
| 416 | |
| 417 | private pruneExpired(data: CacheData): CacheData { |
| 418 | const now = Date.now(); |
no test coverage detected