Skip to content

Commit b442b6b

Browse files
committed
fix: detect file modifications using hashes
1 parent ebfdeef commit b442b6b

3 files changed

Lines changed: 21 additions & 9 deletions

File tree

server/utils/compare.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { diff as semverDiff } from 'semver'
2-
import type {
3-
PackageFileTree,
4-
DependencyChange,
5-
FileChange,
6-
CompareResponse,
7-
} from '#shared/types'
2+
import type { PackageFileTree, DependencyChange, FileChange, CompareResponse } from '#shared/types'
83

94
/** Maximum number of files to include in comparison */
105
const MAX_FILES_COMPARE = 1000
@@ -34,6 +29,17 @@ export function compareFileTrees(
3429
const fromFiles = flattenTree(fromTree)
3530
const toFiles = flattenTree(toTree)
3631

32+
const hasChanged = (fromNode: PackageFileTree, toNode: PackageFileTree): boolean => {
33+
// Prefer strong hash comparison when both hashes are available
34+
if (fromNode.hash && toNode.hash) return fromNode.hash !== toNode.hash
35+
// Fallback to size comparison if hashes are missing
36+
if (typeof fromNode.size === 'number' && typeof toNode.size === 'number') {
37+
return fromNode.size !== toNode.size
38+
}
39+
// If we lack comparable signals, assume unchanged
40+
return false
41+
}
42+
3743
const added: FileChange[] = []
3844
const removed: FileChange[] = []
3945
const modified: FileChange[] = []
@@ -58,8 +64,7 @@ export function compareFileTrees(
5864
newSize: toNode.size,
5965
})
6066
} else if (fromNode.type === 'file') {
61-
// Check if modified (size changed)
62-
if (fromNode.size !== toNode.size) {
67+
if (hasChanged(fromNode, toNode)) {
6368
modified.push({
6469
path,
6570
type: 'modified',
@@ -135,7 +140,11 @@ export function compareDependencies(
135140
const cleanTo = toVersion.replace(/^[\^~>=<]+/, '')
136141
const diffResult = semverDiff(cleanFrom, cleanTo)
137142
if (diffResult) {
138-
if (diffResult === 'premajor' || diffResult === 'preminor' || diffResult === 'prepatch') {
143+
if (
144+
diffResult === 'premajor' ||
145+
diffResult === 'preminor' ||
146+
diffResult === 'prepatch'
147+
) {
139148
semverDiffType = 'prerelease'
140149
} else if (['major', 'minor', 'patch', 'prerelease'].includes(diffResult)) {
141150
semverDiffType = diffResult as 'major' | 'minor' | 'patch' | 'prerelease'

server/utils/file-tree.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export function convertToFileTree(
5050
name: node.name,
5151
path,
5252
type: 'file',
53+
hash: node.hash,
5354
size: node.size,
5455
})
5556
}

shared/types/npm-registry.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ export interface PackageFileTree {
298298
path: string
299299
/** Node type */
300300
type: 'file' | 'directory'
301+
/** File hash (only for files) */
302+
hash?: string
301303
/** File size in bytes (only for files) */
302304
size?: number
303305
/** Child nodes (only for directories) */

0 commit comments

Comments
 (0)