(root: string, path: string)
| 193 | * root, or undefined if the file does not exist. |
| 194 | */ |
| 195 | export function getFileInfo(root: string, path: string): FileInfo | undefined { |
| 196 | const key = join(root, path); |
| 197 | let mtimeMs: number; |
| 198 | let size: number; |
| 199 | try { |
| 200 | const stat = statSync(key); |
| 201 | if (!stat.isFile()) return; // ignore non-files |
| 202 | accessSync(key, constants.R_OK); // verify that file is readable |
| 203 | mtimeMs = Math.floor((currentDate ?? stat.mtimeMs) as number); |
| 204 | size = stat.size; |
| 205 | } catch { |
| 206 | fileInfoCache.delete(key); // delete stale entry |
| 207 | return; // ignore missing, non-readable file |
| 208 | } |
| 209 | let entry = fileInfoCache.get(key); |
| 210 | if (!entry || entry.mtimeMs < mtimeMs) { |
| 211 | const contents = readFileSync(key); |
| 212 | const hash = createHash("sha256").update(contents).digest("hex"); |
| 213 | fileInfoCache.set(key, (entry = {mtimeMs, size, hash})); |
| 214 | } |
| 215 | return entry; |
| 216 | } |
| 217 | |
| 218 | // For testing only! |
| 219 | export function clearFileInfo(root: string, path: string): boolean { |
no test coverage detected