48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
export type { FileInfo, Manifest } from '@types'
|
|
|
|
import type { FileInfo, Manifest } from '@types'
|
|
import { loadGitignore } from '@gitignore'
|
|
import { createHash } from 'crypto'
|
|
import { readdirSync, readFileSync, statSync } from 'fs'
|
|
import { join, relative } from 'path'
|
|
|
|
export function computeHash(content: Buffer | string): string {
|
|
return createHash('sha256').update(content).digest('hex')
|
|
}
|
|
|
|
export function generateManifest(appPath: string, appName: string): Manifest {
|
|
const files: Record<string, FileInfo> = {}
|
|
const gitignore = loadGitignore(appPath)
|
|
|
|
function walkDir(dir: string) {
|
|
const entries = readdirSync(dir, { withFileTypes: true })
|
|
|
|
for (const entry of entries) {
|
|
const fullPath = join(dir, entry.name)
|
|
const relativePath = relative(appPath, fullPath)
|
|
|
|
if (gitignore.shouldExclude(relativePath)) continue
|
|
|
|
if (entry.isDirectory()) {
|
|
walkDir(fullPath)
|
|
} else if (entry.isFile()) {
|
|
const content = readFileSync(fullPath)
|
|
const stats = statSync(fullPath)
|
|
|
|
files[relativePath] = {
|
|
hash: computeHash(content),
|
|
mtime: stats.mtime.toISOString(),
|
|
size: stats.size,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
walkDir(appPath)
|
|
|
|
return {
|
|
name: appName,
|
|
files,
|
|
}
|
|
}
|