From ff33af92b76407b3447387abe2553c2beeb45acd Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Fri, 2 May 2025 18:07:07 +0200 Subject: [PATCH] Implemented most of the modService functions and made various fixes in mod model --- src/models/mod.js | 73 ++++++++++++------ src/services/modService.js | 150 ++++++++++++++++++++++++++++++------- 2 files changed, 177 insertions(+), 46 deletions(-) diff --git a/src/models/mod.js b/src/models/mod.js index 759116d..0794436 100644 --- a/src/models/mod.js +++ b/src/models/mod.js @@ -14,23 +14,40 @@ async function getModByName(name) { } -async function getFullModInfos(name) { +async function getModFullInfos(name) { // Query const base_infos = db.query(`SELECT * FROM Mods WHERE name = ?`, [name]); const other_infos = db.query(`SELECT full_description, license, links, creation_date FROM ModInfos WHERE name = ?`, [name]); + const tags = getModTags(name); // Merge - const res = {...await base_infos, ...await other_infos}; + const res = {...await base_infos, ...await other_infos, ...tags}; return res; } -async function exists(name) { - return db.exists("Mods", "name", name); +async function getAllVersions(mod_name) { + return await db.query("SELECT * FROM ModVersions WHERE mod = ?", [mod_name]); } +async function getVersionByNumber(mod_name, version_number) { + return await db.query(`SELECT * FROM ModVersions + WHERE mod = ? + AND version_number = ?;`, + [mod_name, version_number]); +} + +async function getVersion(mod_name, version_number, game_version, platform, environment) { + return await db.query(`SELECT * FROM ModVersions + WHERE mod = ? + AND version_number = ? + AND game_version = ? + AND platform = ? + AND environment = ?;`, + [mod_name, version_number, game_version, platform, environment]); +} // --- Create --- @@ -65,20 +82,20 @@ async function createMod(name, display_name, author, description, mod_infos) { return; } -async function addVersion(version_number, channel, changelog, release_date, game_version, platform, environment, url) { +async function addVersion(mod, version_number, channel, changelog, release_date, game_version, platform, environment, url) { - await db.prepare(`INSERT INTO ModVersions (version_number, channel, changelog, release_date, game_version, platform, url) - VALUES (?, ?, ?, ?, ?, ?, ?);`, - [version_number, channel, changelog, release_date, game_version, platform, url]); + await db.prepare(`INSERT INTO ModVersions (mod, version_number, channel, changelog, release_date, game_version, environment, platform, url) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);`, + [mod, version_number, channel, changelog, release_date, game_version, environment, platform, url]); return; } -async function addTags(tags) { +async function addTags(mod, tags) { // Add asynchronously - const promises = tags.map(async (mod) => { - db.query(`INSERT INTO UserFavoriteMods (username, mod) - VALUES (?, ?);`, - [username, mod]); + const promises = tags.map(async (tag) => { + db.query(`INSERT INTO ModTags (mod, tag) + VALUES (?, ?);`, + [mod, tag]); }); await Promise.all(promises); @@ -111,22 +128,21 @@ async function deleteMod(name) { return; } -async function deleteVersion(name, version_number, channel, game_version, platform, environment) { - await db.prepare(`DELETE FROM ModVersions WHERE name = ? +async function deleteVersion(name, version_number, game_version, platform, environment) { + await db.prepare(`DELETE FROM ModVersions WHERE mod = ? AND version_number = ? - AND channel = ? AND game_version = ? AND platform = ? AND environment = ?;`, - [name, version_number, channel, game_version, platform, environment]); + [name, version_number, game_version, platform, environment]); return; } -async function deleteTags(tags) { +async function deleteTags(mod, tags) { // Remove asynchronously - const promises = tags.map(async (mod) => { - db.query(`DELETE FROM UserFavoriteMods - WHERE username = ? AND mod = ?;`, [username, mod]); + const promises = tags.map(async (tag) => { + db.query(`DELETE FROM ModTags + WHERE mod = ? AND tag = ?;`, [mod, tag]); }); await Promise.all(promises); @@ -146,10 +162,25 @@ async function updateModInfosAttribute(name, attribute, value) { return; } +async function ModExists(name) { + return db.exists("Mods", "name", name); +} + +async function containsVersion(name, version_number, game_version, platform, environment) { + throw new AppError(501, "Not implemented"); + // return db.exists("Mods", "name", name); +} + +async function containsTag(name, tag) { + throw new AppError(501, "Not implemented"); + // return db.exists("Mods", "name", name); +} + // --- Exports --- module.exports = { getAllMods, getModByName, getFullModInfos, + getAllModVersions, getVersionByNumber, getVersion, createMod, addVersion, addTags, updateMod, deleteMod, deleteVersion, deleteTags, diff --git a/src/services/modService.js b/src/services/modService.js index 739b217..56b9a70 100644 --- a/src/services/modService.js +++ b/src/services/modService.js @@ -4,49 +4,149 @@ const { validateModData } = require("../utils/validate_legacy"); const { mdToHtml } = require("../utils/convert"); const { sanitizeModData } = require("../utils/sanitize"); + +// --- Get --- + async function getAllMods() { return model.getAllMods(); } async function getModByName(name) { - return model.getModByName(name); + const res = model.getModByName(name); + if (res.length == 0) { + throw new AppError(404, "Cannot find mod with this name", "Not found"); + } + return res[0]; } -async function createMod(mod_data) { +async function getFullModInfos(name) { + const res = model.getFullModInfos(name); + if (res.length == 0) { + throw new AppError(404, "Cannot find mod with this name", "Not found"); + } + return res[0]; +} + +async function getModVersion(infos) { + const { mod, version_number, game_version, platform, environment} = infos; + const res = model.getModVersion(mod, version_number, game_version, platform, environment); + if (res.length == 0) { + throw new AppError(404, "Cannot find mod with this name", "Not found"); + } + return res[0]; +} + + +// --- Create --- + +async function createMod(mod_data, author) { // Check body validity - await validateModData(mod_data); + //TODO + console.warn("Skipping validity checks for createMod"); + // await validateModData(mod_data); - // Check authenticity - //TODO no auth provider + // Generate data + const { name, display_name, description, mod_infos } = mod_data; + mod_infos.full_description = await mdToHtml(mod_infos.full_description); // Convert + await sanitizeModData(mod_data); // Sanitize - // Convert - mod_data.otherInfos.description = await mdToHtml(mod_data.otherInfos.description); - mod_data.otherInfos.changelogs = await mdToHtml(mod_data.otherInfos.changelogs); - - // Sanitize - await sanitizeModData(mod_data); - - - - console.debug("Passed validity checks"); - model.createMod(mod_data); - return; + // Write changes to database + model.createMod(name, display_name, author, description, mod_data); + + // Return + return getModByName(name); } +async function addVersion(version_data) { + + // Validate + //TODO + console.warn("Skipping validity checks for addVersion"); + + // Generate data + const { mod_name, version_number, channel, changelog, game_version, + platform, environment, url } = version_data; // Split + changelog = await mdToHtml(changelog); // Convert + await sanitizeModData(mod_data); // Sanitize + const release_date = (new Date()).toLocaleDateString(); + + // Write changes + await model.addVersion(mod_name, version_number, channel, changelog, + release_date, game_version, platform, environment, url); // Database + + // Return + return await model.getModVersion(mod_name, version_number, game_version, platform, environment ); +} + +async function addTags(mod, tags) { + + // Validate + //TODO + console.warn("Skipping validity checks for addTags"); + + // Write changes + await model.addTags(mod, tags); + + // Return + const { tags } = await model.getFullModInfos(mod); + return { "mod": mod, "tags": tags}; + +} + +// --- Update --- + +async function updateMod(diff_data) { + //TODO + throw new AppError(501, "Not implemented"); +} + + + +// Delete + async function deleteMod(name) { // Check existence - const exists = await model.exists(name); - if (!exists) { - throw new AppError(404, "Not found: Cannot find mod with this name"); + const mod = await model.getModByName(name); + + // Authorize + // TODO move outside of this function + if (mod.author != mod.user) { + throw new AppError(403, "You don't have the necessary permissions to execute this action", "Forbidden"); } - // Check authenticity - //TODO no auth provider + // Write changes to database + await model.deleteMod(name); - model.deleteMod(name); - return; + // Return + return mod; } -module.exports = { getAllMods, getModByName, createMod, deleteMod }; \ No newline at end of file +async function deleteVersion(version_infos) { + + // Validate + // TODO + + // Generate data + const res = await getModVersion(version_infos); + const { mod, version_number, game_version, platform, environment} = version_infos; + + // Write changes to db + await model.deleteVersion(mod, version_number, game_version, platform, environment); + + // Return + return res; + + +} + +async function deleteTags(tags) { + + // Check existence +} + +module.exports = { getAllMods, getModByName, getFullModInfos, + createMod, addTags, addVersion, + updateMod, + deleteMod, deleteTags, deleteVersion }; \ No newline at end of file