( originalFile: string, backupFileName: string, originalStatsHint?: Stats, )
| 598 | * Exported for testing. |
| 599 | */ |
| 600 | export async function checkOriginFileChanged( |
| 601 | originalFile: string, |
| 602 | backupFileName: string, |
| 603 | originalStatsHint?: Stats, |
| 604 | ): Promise<boolean> { |
| 605 | const backupPath = resolveBackupPath(backupFileName) |
| 606 | |
| 607 | let originalStats: Stats | null = originalStatsHint ?? null |
| 608 | if (!originalStats) { |
| 609 | try { |
| 610 | originalStats = await stat(originalFile) |
| 611 | } catch (e: unknown) { |
| 612 | if (!isENOENT(e)) return true |
| 613 | } |
| 614 | } |
| 615 | let backupStats: Stats | null = null |
| 616 | try { |
| 617 | backupStats = await stat(backupPath) |
| 618 | } catch (e: unknown) { |
| 619 | if (!isENOENT(e)) return true |
| 620 | } |
| 621 | |
| 622 | return compareStatsAndContent(originalStats, backupStats, async () => { |
| 623 | try { |
| 624 | const [originalContent, backupContent] = await Promise.all([ |
| 625 | readFile(originalFile, 'utf-8'), |
| 626 | readFile(backupPath, 'utf-8'), |
| 627 | ]) |
| 628 | return originalContent !== backupContent |
| 629 | } catch { |
| 630 | // File deleted between stat and read -> treat as changed. |
| 631 | return true |
| 632 | } |
| 633 | }) |
| 634 | } |
| 635 | |
| 636 | /** |
| 637 | * Shared stat/content comparison logic for sync and async change checks. |
no test coverage detected