generated from azures04/Base-REST-API
169 lines
5.6 KiB
JavaScript
169 lines
5.6 KiB
JavaScript
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 productsDataPath = path.join(process.cwd(), "data", "products")
|
|
|
|
fs.promises.exists = async function exists(path) {
|
|
try {
|
|
await fs.promises.access(path)
|
|
return true
|
|
} catch {
|
|
return false
|
|
}
|
|
};
|
|
|
|
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 getProductFiles(productName, platform) {
|
|
const finalPath = path.join(productsDataPath, productName, "files", platform)
|
|
const files = await fs.promises.readdir(finalPath, { recursive: true })
|
|
const productFilesIndex = { root: [] }
|
|
for (const file of files) {
|
|
const filePath = path.join(finalPath, file)
|
|
const fileMetadata = await fs.promises.stat(filePath)
|
|
|
|
if (!fileMetadata.isDirectory() && !filePath.endsWith(".brikcfg")) {
|
|
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
|
|
}
|
|
productFilesIndex.root.push(downloadObject)
|
|
}
|
|
}
|
|
return productFilesIndex
|
|
}
|
|
|
|
async function getFile(basePath, productName, productPlatform) {
|
|
try {
|
|
const fixedPath = path.join(productsDataPath, productName, "files", productPlatform, 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
|
|
}
|
|
}
|
|
}
|
|
|
|
async function canAccess(productName) {
|
|
const fixedPath = path.join(productsDataPath, productName, "files", ".brikcfg")
|
|
const fileState = await fs.promises.exists(fixedPath, fs.constants.F_OK)
|
|
if (!fileState) {
|
|
return { code: 200 }
|
|
}
|
|
|
|
try {
|
|
const brikConfig = JSON.parse(await fs.promises.readFile(fixedPath))
|
|
if (!brikConfig.public) {
|
|
throw new DefaultError(403, "Forbidden", "Locked resource.", "InsuffisentPrivilegeException")
|
|
}
|
|
return { code: 200 }
|
|
} catch (error) {
|
|
if (!error instanceof DefaultError) {
|
|
throw new DefaultError(500, "Please contact the maintener", "CONFIGURATION", "0x00")
|
|
}
|
|
throw error
|
|
}
|
|
|
|
}
|
|
|
|
async function getProduct(productName) {
|
|
const fixedPath = path.join(productsDataPath, productName, ".brikpkg")
|
|
const fileState = await fs.promises.exists(fixedPath, fs.constants.F_OK)
|
|
if (!fileState) {
|
|
throw new DefaultError(404, "Not found", "MissingDir", "NotFoundException")
|
|
}
|
|
|
|
try {
|
|
const brikPackage = JSON.parse(await fs.promises.readFile(fixedPath))
|
|
if (!brikPackage.public) {
|
|
throw new DefaultError(403, "Forbidden", "Locked resource.", "InsuffisentPrivilegeException")
|
|
}
|
|
return brikPackage
|
|
} catch (error) {
|
|
if (!error instanceof DefaultError) {
|
|
throw new DefaultError(500, "Please contact the maintener", "CONFIGURATION", "0x00")
|
|
}
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async function getProducts() {
|
|
const files = await fs.promises.readdir(path.join(productsDataPath), { recursive: false })
|
|
return files
|
|
}
|
|
|
|
async function getRequirementsForPlatform(productName, productPlatform) {
|
|
const fixedPath = path.join(productsDataPath, productName, "files", ".brikcfg")
|
|
if (!(await fs.promises.exists(fixedPath))) return []
|
|
|
|
const config = JSON.parse(await fs.promises.readFile(fixedPath, "utf8"))
|
|
|
|
const globalReqs = config.requirements?.global || []
|
|
const platformReqs = config.requirements?.[productPlatform] || []
|
|
|
|
return [...globalReqs, ...platformReqs]
|
|
}
|
|
|
|
async function getInstallerResources(productName) {
|
|
const fixedPath = path.join(productsDataPath, productName, "files", ".brikcfg")
|
|
if (!(await fs.promises.exists(fixedPath))) return []
|
|
|
|
const config = JSON.parse(await fs.promises.readFile(fixedPath, "utf8"))
|
|
return config["installerResources"]
|
|
}
|
|
|
|
async function getInstallerConfig(productName, productPlatform) {
|
|
const fixedPath = path.join(productsDataPath, productName, "files", ".brikcfg")
|
|
if (!(await fs.promises.exists(fixedPath))) return []
|
|
|
|
const config = JSON.parse(await fs.promises.readFile(fixedPath, "utf8"))
|
|
|
|
const globalReqs = config.configurations?.global || []
|
|
const platformReqs = config.configurations?.[productPlatform] || []
|
|
|
|
return { ...globalReqs, ...platformReqs }
|
|
}
|
|
|
|
module.exports = {
|
|
getFile,
|
|
canAccess,
|
|
getProduct,
|
|
getFileSha1,
|
|
getProducts,
|
|
getProductFiles,
|
|
getInstallerConfig,
|
|
getInstallerResources,
|
|
getRequirementsForPlatform
|
|
} |