const fs = require("node:fs") const path = require("node:path") const crypto = require("node:crypto") const { DefaultError } = require("../errors/errors") const { pipeline } = require("node:stream/promises") const gameDataPath = path.join(process.cwd(), "data", "products") function normalizePath($path) { return $path.split(path.win32.sep).join(path.posix.sep) } async function getFileSha1(filePath) { const hash = crypto.createHash("sha1") const readStream = fs.createReadStream(filePath) try { await pipeline(readStream, hash) return hash.digest("hex") } catch (error) { throw new Error(`Error when calculating SHA-1 hash: ${error.message}`); } } async function getGameFiles() { const files = await fs.promises.readdir(gameDataPath, { recursive: true }) const gameFilesIndex = { root: [] } for (const file of files) { const filePath = path.join(gameDataPath, file) const fileMetadata = await fs.promises.stat(filePath) if (!fileMetadata.isDirectory()) { const normalizedFilePath = normalizePath(file) const artifact = { path: normalizedFilePath, sha1: await getFileSha1(filePath), size: fileMetadata.size, url: (process.env.BASE_POINT || "") + normalizedFilePath } const downloadObject = { downloads: { artifact, }, name: path.parse(normalizedFilePath).base } gameFilesIndex.root.push(downloadObject) } } return gameFilesIndex } async function getFile(basePath) { try { const fixedPath = path.join(gameDataPath, decodeURI(basePath)) const fileMetadata = await fs.promises.stat(fixedPath) if (fileMetadata.isDirectory()) { throw new DefaultError(409, "Can't download a directory", "", "NotDownloadableException") } return { code: 200, path: fixedPath } } catch (error) { if (error.code == "ENOENT") { throw new DefaultError(404, "File not found", "", "NotFoundException") } else { throw error } } } module.exports = { getFile, getFileSha1, getGameFiles }