From d51a4cbafc050414650f8864b3ee316416f455fb Mon Sep 17 00:00:00 2001 From: azures04 Date: Tue, 27 Jan 2026 06:00:28 +0100 Subject: [PATCH] Create productsFileService.js --- services/productsFileService.js | 72 +++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 services/productsFileService.js diff --git a/services/productsFileService.js b/services/productsFileService.js new file mode 100644 index 0000000..c0b10c6 --- /dev/null +++ b/services/productsFileService.js @@ -0,0 +1,72 @@ +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 +} \ No newline at end of file