67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
import { MODEL_EXTENSIONS } from './constants'
|
|
import type { FileChange, PushFile } from './types'
|
|
|
|
interface DiffResult {
|
|
fileChanges: Map<string, FileChange>
|
|
changedFilesToPush: PushFile[]
|
|
deletedFileNames: string[]
|
|
deletePaths: string[]
|
|
}
|
|
|
|
/**
|
|
* Classify each file as new, changed, or unchanged by comparing against
|
|
* the remote file map.
|
|
*
|
|
* Rules:
|
|
* - Models: always re-pushed,
|
|
* but marked as 'unchanged' in the commit message when the folder already
|
|
* exists (we keep the current behavior of always delivering the model file).
|
|
* - Textures: compared by size (not compressed, reliable).
|
|
* - Orphan remote files: classified as deletions.
|
|
*/
|
|
export function classifyFileChanges(
|
|
filesToPush: PushFile[],
|
|
remoteFileMap: Map<string, number>,
|
|
folderPath: string,
|
|
): DiffResult {
|
|
const fileChanges = new Map<string, FileChange>()
|
|
const changedFilesToPush: PushFile[] = []
|
|
|
|
for (const f of filesToPush) {
|
|
const filename = f.path.split('/').pop() ?? ''
|
|
const ext = filename.slice(filename.lastIndexOf('.')).toLowerCase()
|
|
const isModel = MODEL_EXTENSIONS.has(ext)
|
|
|
|
if (isModel) {
|
|
const remoteSize = remoteFileMap.get(filename.toLowerCase())
|
|
fileChanges.set(filename.toLowerCase(), remoteSize === undefined ? 'new' : 'unchanged')
|
|
changedFilesToPush.push(f)
|
|
} else {
|
|
const localSize = Buffer.from(f.contentBase64, 'base64').length
|
|
const remoteSize = remoteFileMap.get(filename.toLowerCase())
|
|
|
|
if (remoteSize === undefined) {
|
|
fileChanges.set(filename.toLowerCase(), 'new')
|
|
changedFilesToPush.push(f)
|
|
} else if (remoteSize !== localSize) {
|
|
fileChanges.set(filename.toLowerCase(), 'changed')
|
|
changedFilesToPush.push(f)
|
|
} else {
|
|
fileChanges.set(filename.toLowerCase(), 'unchanged')
|
|
}
|
|
}
|
|
}
|
|
|
|
const newFileNames = new Set(filesToPush.map((f) => (f.path.split('/').pop() ?? '').toLowerCase()))
|
|
const deletedFileNames: string[] = []
|
|
const deletePaths: string[] = []
|
|
for (const [name] of remoteFileMap) {
|
|
if (!newFileNames.has(name)) {
|
|
deletedFileNames.push(name)
|
|
deletePaths.push(`${folderPath}/${name}`)
|
|
}
|
|
}
|
|
|
|
return { fileChanges, changedFilesToPush, deletedFileNames, deletePaths }
|
|
}
|