From d5da5c4e3ed99d2befe30087821a14767f962a00 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Sat, 22 Mar 2025 13:50:07 +0000 Subject: [PATCH 1/6] add typescript + remove redundant code --- controllers/armies-controller.js | 22 ---------------------- package.json | 3 ++- pnpm-lock.yaml | 9 +++++++++ 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/controllers/armies-controller.js b/controllers/armies-controller.js index 9c17267..e4f6392 100644 --- a/controllers/armies-controller.js +++ b/controllers/armies-controller.js @@ -3,28 +3,6 @@ const dayjs = require("dayjs"); const crypto = require("crypto"); const { completedArmiesBattleFormatting } = require("../utils/ArrayMethods"); -// const pool = database.client.pool; - -// database.on("query", (builder) => { -// console.log("Army Controller to be executed", builder.sql); -// console.log("Army Controller Pool Used on Start", pool.numUsed()); -// console.log("Army Controller Pool Used on Start", pool.numPendingAcquires()); - -// console.log("Army Controller Pool Free on Start", pool.numFree()); -// }); - -// database.on("query-response", (response, builder) => { -// console.log("Army Controller Query executed successfully:", builder.sql); -// console.log("Army Controller Pool Used on response", pool.numUsed()); -// console.log("Army Controller Pool Free on response", pool.numFree()); -// }); - -// database.on("query-error", (error, builder) => { -// console.error("Error executing query:", builder.sql, error); -// console.log("Army Controller Error Pool Used on error", pool.numUsed()); -// console.log("Army Controller Error Pool Free on error", pool.numFree()); -// }); - const armyCountFn = (array) => { const returnArray = []; array.forEach((army) => { diff --git a/package.json b/package.json index 338c2f9..3170db0 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "jsonwebtoken": "^9.0.2", "knex": "^3.1.0", "mysql2": "^3.9.2", - "nodemailer": "^6.9.8" + "nodemailer": "^6.9.8", + "typescript": "^5.8.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29898be..c5a3dad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: nodemailer: specifier: ^6.9.8 version: 6.9.8 + typescript: + specifier: ^5.8.2 + version: 5.8.2 packages: @@ -837,6 +840,12 @@ packages: mime-types: 2.1.35 dev: false + /typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} From 2304516565c58cfed373a15fe37ec80e71a572b7 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Sat, 22 Mar 2025 13:50:43 +0000 Subject: [PATCH 2/6] move army controllers into modules folder --- controllers/{ => modules/armies}/armies-controller.js | 6 ++++-- routes/armies-routes.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) rename controllers/{ => modules/armies}/armies-controller.js (98%) diff --git a/controllers/armies-controller.js b/controllers/modules/armies/armies-controller.js similarity index 98% rename from controllers/armies-controller.js rename to controllers/modules/armies/armies-controller.js index e4f6392..ab4a78a 100644 --- a/controllers/armies-controller.js +++ b/controllers/modules/armies/armies-controller.js @@ -1,7 +1,9 @@ -const database = require("../database/db"); +const database = require("../../../database/db"); const dayjs = require("dayjs"); const crypto = require("crypto"); -const { completedArmiesBattleFormatting } = require("../utils/ArrayMethods"); +const { + completedArmiesBattleFormatting, +} = require("../../../utils/ArrayMethods"); const armyCountFn = (array) => { const returnArray = []; diff --git a/routes/armies-routes.js b/routes/armies-routes.js index 62c5093..221717e 100644 --- a/routes/armies-routes.js +++ b/routes/armies-routes.js @@ -15,7 +15,7 @@ const { getAllUserArmies, insertNewArmy, getArmyInfo, -} = require("../controllers/armies-controller"); +} = require("../controllers/modules/armies/armies-controller"); const { headerAuth, adminAuth } = require("../middleware/auth"); require("dotenv").config(); From 732e979671a762090c29466293c7048c879050dc Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Sat, 22 Mar 2025 14:10:48 +0000 Subject: [PATCH 3/6] add army type and create armyCountFn in helpers --- ...ies-controller.js => armies-controller.ts} | 33 +++---------------- controllers/modules/armies/helpers.ts | 23 +++++++++++++ types/armies.ts | 14 ++++++++ 3 files changed, 42 insertions(+), 28 deletions(-) rename controllers/modules/armies/{armies-controller.js => armies-controller.ts} (94%) create mode 100644 controllers/modules/armies/helpers.ts create mode 100644 types/armies.ts diff --git a/controllers/modules/armies/armies-controller.js b/controllers/modules/armies/armies-controller.ts similarity index 94% rename from controllers/modules/armies/armies-controller.js rename to controllers/modules/armies/armies-controller.ts index ab4a78a..b5aff1f 100644 --- a/controllers/modules/armies/armies-controller.js +++ b/controllers/modules/armies/armies-controller.ts @@ -1,31 +1,8 @@ -const database = require("../../../database/db"); -const dayjs = require("dayjs"); -const crypto = require("crypto"); -const { - completedArmiesBattleFormatting, -} = require("../../../utils/ArrayMethods"); - -const armyCountFn = (array) => { - const returnArray = []; - array.forEach((army) => { - let armyBool = false; - for (let i = 0; i < returnArray.length; i++) { - if ( - returnArray[i].id === army.id && - returnArray[i].name === army.name && - returnArray[i].known_as === army.known_as - ) { - armyBool = true; - returnArray[i].count++; - } - } - if (armyBool !== true) { - returnArray.push({ count: 1, ...army }); - } - }); - - return returnArray; -}; +import database from "../../../database/db"; +import dayjs from "dayjs"; +import crypto from "crypto"; +import { completedArmiesBattleFormatting } from "../../../utils/ArrayMethods"; +import { armyCountFn } from "./helpers"; const updateArmyField = async (armyID, fieldName, newValue) => { try { diff --git a/controllers/modules/armies/helpers.ts b/controllers/modules/armies/helpers.ts new file mode 100644 index 0000000..c29c845 --- /dev/null +++ b/controllers/modules/armies/helpers.ts @@ -0,0 +1,23 @@ +import { Army, CountedArmy } from "../../../types/armies"; + +export const armyCountFn = (array: Army[]) => { + const returnArray: CountedArmy[] = []; + array.forEach((army) => { + let armyBool = false; + for (let i = 0; i < returnArray.length; i++) { + if ( + returnArray[i].id === army.id && + returnArray[i].name === army.name && + returnArray[i].known_as === army.known_as + ) { + armyBool = true; + returnArray[i].count++; + } + } + if (armyBool !== true) { + returnArray.push({ count: 1, ...army }); + } + }); + + return returnArray; +}; diff --git a/types/armies.ts b/types/armies.ts new file mode 100644 index 0000000..3447546 --- /dev/null +++ b/types/armies.ts @@ -0,0 +1,14 @@ +export interface Army { + name: string; + army_id: string; + id: string; + known_as: string; + ranking: string; + emblem?: string; + emblem_id?: string; + type?: "fantasy" | "40k"; +} + +export interface CountedArmy extends Army { + count: number; +} From 6399315643d02def09e67ffc4cf0425d062ad76e Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Sat, 22 Mar 2025 14:21:59 +0000 Subject: [PATCH 4/6] refine addNEwArmyRanking --- .../modules/armies/armies-controller.ts | 40 +++++++------------ controllers/modules/armies/helpers.ts | 22 +++++++++- types/armies.ts | 18 +++++++-- 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/controllers/modules/armies/armies-controller.ts b/controllers/modules/armies/armies-controller.ts index b5aff1f..eb3ea46 100644 --- a/controllers/modules/armies/armies-controller.ts +++ b/controllers/modules/armies/armies-controller.ts @@ -2,7 +2,8 @@ import database from "../../../database/db"; import dayjs from "dayjs"; import crypto from "crypto"; import { completedArmiesBattleFormatting } from "../../../utils/ArrayMethods"; -import { armyCountFn } from "./helpers"; +import { armyCountFn, getRankAndPosition } from "./helpers"; +import { Army, ArmyRank } from "../../../types/armies"; const updateArmyField = async (armyID, fieldName, newValue) => { try { @@ -21,15 +22,15 @@ const fetchOneArmy = async (req, res) => { const id = req.params.id; try { - const armyObj = await database("armies").where({ id: id }).first(); + const army: Army = await database("armies").where({ id: id }).first(); - if (!armyObj) { + if (!army) { return res .status(400) .send("We cannot find the army you are looking for"); } - res.status(200).send(armyObj); + res.status(200).send(army); } catch (error) { console.error(error); res.status(400).send("We cannot process your request right now"); @@ -38,47 +39,34 @@ const fetchOneArmy = async (req, res) => { const addNewArmyRanking = async (req, res) => { const armyID = req.params.id; - const { newRank } = req.body; + const { newRank: newRankScore } = req.body; - if (!newRank) { + if (!newRankScore) { return res.status(400).send("Please add the new rank to the request body"); } - const armyObj = await database("armies").where({ id: armyID }).first(); + const army = await database("armies").where({ id: armyID }).first(); - if (!armyObj) { + if (!army) { return res.status(400).send(`Can't find the army with ID: ${armyID}`); } try { - const subquery = database("rank") - .join("armies", "rank.army_id", "=", "armies.id") - .select("army_id", "date", "ranking") - .rowNumber("rn", { column: "date", order: "desc" }, "army_id") - .where({ "armies.type": armyObj.type }) - .as("ranks"); - - const query = database(subquery) - .select("army_id", "date", "ranking", "rn") - .where("rn", 1) - .orderBy("ranking", "desc"); - - const currentRankPosition = - (await query).findIndex((ranking) => ranking.army_id === armyID) + 1; + const currentRankPosition = await getRankAndPosition(army.type, armyID); const date = Date.now(); - const newRankObj = { + const newRank: ArmyRank = { date: dayjs(date).format("YYYY-MM-DD HH:mm:ss"), id: crypto.randomUUID(), army_id: armyID, - ranking: newRank, + ranking: newRankScore, prev_ranking: currentRankPosition, }; - await database("rank").insert(newRankObj); + await database("rank").insert(newRank); - res.status(200).send(newRankObj); + res.status(200).send(newRank); } catch (error) { console.error(error); res.status(400).send("Unable to update the rank"); diff --git a/controllers/modules/armies/helpers.ts b/controllers/modules/armies/helpers.ts index c29c845..459527f 100644 --- a/controllers/modules/armies/helpers.ts +++ b/controllers/modules/armies/helpers.ts @@ -1,4 +1,5 @@ -import { Army, CountedArmy } from "../../../types/armies"; +import { Army, ArmyId, ArmyType, CountedArmy } from "../../../types/armies"; +import database from "../../../database/db"; export const armyCountFn = (array: Army[]) => { const returnArray: CountedArmy[] = []; @@ -21,3 +22,22 @@ export const armyCountFn = (array: Army[]) => { return returnArray; }; + +export const getRankAndPosition = async (type: ArmyType, armyID: ArmyId) => { + const subquery = database("rank") + .join("armies", "rank.army_id", "=", "armies.id") + .select("army_id", "date", "ranking") + .rowNumber("rn", { column: "date", order: "desc" }, "army_id") + .where({ "armies.type": type }) + .as("ranks"); + + const query = database(subquery) + .select("army_id", "date", "ranking", "rn") + .where("rn", 1) + .orderBy("ranking", "desc"); + + const currentRankPosition = + (await query).findIndex((ranking) => ranking.army_id === armyID) + 1; + + return currentRankPosition; +}; diff --git a/types/armies.ts b/types/armies.ts index 3447546..bbd77bd 100644 --- a/types/armies.ts +++ b/types/armies.ts @@ -1,14 +1,26 @@ +export type ArmyId = string; +export type UserId = string; +export type ArmyType = "fantasy" | "40k"; + export interface Army { name: string; - army_id: string; - id: string; + army_id: ArmyId; + id: UserId; known_as: string; ranking: string; emblem?: string; emblem_id?: string; - type?: "fantasy" | "40k"; + type?: ArmyType; } export interface CountedArmy extends Army { count: number; } + +export interface ArmyRank { + date: string; + id: string; + army_id: string; + ranking: string; + prev_ranking: number; +} From 7691316fd019334fe95142c8223e2e5fbe6059ff Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Sat, 22 Mar 2025 14:24:42 +0000 Subject: [PATCH 5/6] refine getAllArmies --- controllers/modules/armies/armies-controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/modules/armies/armies-controller.ts b/controllers/modules/armies/armies-controller.ts index eb3ea46..37ef10a 100644 --- a/controllers/modules/armies/armies-controller.ts +++ b/controllers/modules/armies/armies-controller.ts @@ -75,8 +75,8 @@ const addNewArmyRanking = async (req, res) => { const getAllArmies = async (req, res) => { try { - const armyArray = await database("armies").select("*"); - res.status(200).send(armyArray); + const armies: Army[] = await database("armies").select("*"); + res.status(200).send(armies); } catch (error) { console.error(error); res.status(400).send(error); From e6efd20a9daf3c2b9ea68a9cb23b2fd4842a43d6 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Sat, 22 Mar 2025 15:19:59 +0000 Subject: [PATCH 6/6] beginnings of TS transition and ESM --- .gitignore | 3 +- controllers/battles-controller.js | 6 +- .../modules/armies/armies-controller.ts | 22 +- controllers/rankings-controllers.js | 2 +- controllers/users-controllers.js | 10 +- database/db.js | 4 +- index.js | 30 +- knexfile.js | 27 +- middleware/auth.js | 10 +- package.json | 13 +- pnpm-lock.yaml | 154 ++++++- routes/armies-routes.js | 43 +- routes/battles-routes.js | 401 +++++++++--------- routes/rankings-routes.js | 22 +- routes/users-routes.js | 78 ++-- tsconfig.json | 12 + types/armies.ts | 6 +- utils/ArrayMethods.js | 6 +- utils/Auth.js | 8 +- 19 files changed, 514 insertions(+), 343 deletions(-) create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index 32c96c1..1a3d55f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .env -/node_modules \ No newline at end of file +/node_modules +/dist \ No newline at end of file diff --git a/controllers/battles-controller.js b/controllers/battles-controller.js index 4b39ea9..52335ac 100644 --- a/controllers/battles-controller.js +++ b/controllers/battles-controller.js @@ -1,7 +1,7 @@ const crypto = require("crypto"); const jwt = require("jsonwebtoken"); -const database = require("../database/db"); +const database = require("../database/db").default; const dayjs = require("dayjs"); const { battleFormatting, @@ -11,8 +11,8 @@ const { upcomingBattleFormattingLimited, completedBattleFormatting, formatOneBattle, -} = require("../utils/ArrayMethods"); -const { getTokenProfile } = require("../utils/Auth"); +} = require("../utils/ArrayMethods").default; +const { getTokenProfile } = require("../utils/Auth").default; const pool = database.client.pool; diff --git a/controllers/modules/armies/armies-controller.ts b/controllers/modules/armies/armies-controller.ts index 37ef10a..13b0f2b 100644 --- a/controllers/modules/armies/armies-controller.ts +++ b/controllers/modules/armies/armies-controller.ts @@ -3,7 +3,7 @@ import dayjs from "dayjs"; import crypto from "crypto"; import { completedArmiesBattleFormatting } from "../../../utils/ArrayMethods"; import { armyCountFn, getRankAndPosition } from "./helpers"; -import { Army, ArmyRank } from "../../../types/armies"; +import { Army, ArmyRank, CountedArmy } from "../../../types/armies"; const updateArmyField = async (armyID, fieldName, newValue) => { try { @@ -97,24 +97,26 @@ const getAllUserArmies = async (req, res) => { .select("army_id", "armies.name", "armies.type", "armies.emblem") .as("battleArray"); - const maxCountArray = []; + console.log(battleArray); + + const userArmies = []; battleArray.forEach((army) => { - const targetObj = maxCountArray.find( - (targetArmy) => targetArmy.army_id === army.army_id + const target = userArmies.find( + (targetArmy: Army) => targetArmy.army_id === army.army_id ); - if (!targetObj) { - maxCountArray.push(army); - } else if (targetObj) { - const targetIndex = maxCountArray.findIndex( + if (!target) { + userArmies.push(army); + } else if (target) { + const targetIndex = userArmies.findIndex( (targetArmy) => targetArmy.army_id === army.army_id ); - maxCountArray[targetIndex].count = army.count; + userArmies[targetIndex].count = army.count; } }); - res.status(200).send(maxCountArray); + res.status(200).send(userArmies); } catch (error) { console.error(error); res.status(400).send(error); diff --git a/controllers/rankings-controllers.js b/controllers/rankings-controllers.js index 87670f7..7d83dcf 100644 --- a/controllers/rankings-controllers.js +++ b/controllers/rankings-controllers.js @@ -1,4 +1,4 @@ -const database = require("../database/db"); +const database = require("../database/db").default; // const pool = database.client.pool; diff --git a/controllers/users-controllers.js b/controllers/users-controllers.js index 17fe6d8..4389c9e 100644 --- a/controllers/users-controllers.js +++ b/controllers/users-controllers.js @@ -1,11 +1,9 @@ -const database = require("../database/db"); +const database = require("../database/db").default; const bcrypt = require("bcryptjs"); const jwt = require("jsonwebtoken"); -const { - completedBattleFormatting, - userCompletedBattleFormatting, -} = require("../utils/ArrayMethods"); -const { verifyToken, getTokenProfile } = require("../utils/Auth"); +const { completedBattleFormatting, userCompletedBattleFormatting } = + require("../utils/ArrayMethods").default; +const { verifyToken, getTokenProfile } = require("../utils/Auth").default; const { armyCountFn } = require("./armies-controller"); // const pool = database.client.pool; diff --git a/database/db.js b/database/db.js index 8cfe768..3899db2 100644 --- a/database/db.js +++ b/database/db.js @@ -1,3 +1,3 @@ -const config = require("../knexfile"); +import config from "../knexfile.js"; -module.exports = require("knex")(config); +export default require("knex")(config); diff --git a/index.js b/index.js index 3fdde63..0480ee8 100644 --- a/index.js +++ b/index.js @@ -1,35 +1,27 @@ -const express = require("express"); +import express, { json } from "express"; +import { cors } from "cors"; const app = express(); -const cors = require("cors"); const knex = require("knex")(require("./knexfile")); require("dotenv").config(); -app.use(express.json()); +app.use(json()); app.use(cors()); const PORT = process.env.PORT || 8080; -const userRoutes = require("./routes/users-routes"); -const battlesRoutes = require("./routes/battles-routes"); -const rankingsRoutes = require("./routes/rankings-routes"); -const armiesRoutes = require("./routes/armies-routes"); - -const pool = knex.client.pool; - -// app.use("/", (req, res, next) => { -// console.log("Index File Pool in Use", pool.numUsed()); -// console.log("Index File Pool free", pool.numFree()); -// next(); -// }); +import battleRouter from "./routes/battles-routes.js"; +import rankingRouter from "./routes/rankings-routes.js"; +import userRouter from "./routes/users-routes.js"; +import armyRouter from "./routes/armies-routes.js"; app.get("/", (req, res) => { res.send("Hello World"); }); -app.use("/users", userRoutes); -app.use("/battles", battlesRoutes); -app.use("/rankings", rankingsRoutes); -app.use("/armies", armiesRoutes); +app.use("/users", userRouter); +app.use("/battles", battleRouter); +app.use("/rankings", rankingRouter); +app.use("/armies", armyRouter); app.listen(PORT, () => { console.log(`running at ${process.env.BASE_URL}${PORT}`); }); diff --git a/knexfile.js b/knexfile.js index 8a10dce..7f6e915 100644 --- a/knexfile.js +++ b/knexfile.js @@ -1,18 +1,15 @@ require("dotenv").config(); -module.exports = { - client: "mysql2", - connection: { - host: process.env.DB_HOST, - database: process.env.DB_NAME, - user: process.env.DB_USER, - password: process.env.DB_PASSWORD, - charset: "utf8", - }, - pool: { - min: 2, // Minimum number of connections in the pool - max: 10, // Maximum number of connections in the pool - idleTimeoutMillis: 1000, - }, - debugger: true, +export const client = "mysql2"; +export const connection = { + host: process.env.DB_HOST, + database: process.env.DB_NAME, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + charset: "utf8", +}; +export const pool = { + min: 2, // Minimum number of connections in the pool + max: 10, // Maximum number of connections in the pool + idleTimeoutMillis: 1000, }; diff --git a/middleware/auth.js b/middleware/auth.js index f10ff29..081826a 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -1,5 +1,5 @@ -const jwt = require("jsonwebtoken"); -const knex = require("knex")(require("../knexfile")); +import { verify } from "jsonwebtoken"; +import knex from "knex"; const headerAuth = async (req, res, next) => { if (!req.headers.authorization) { @@ -9,7 +9,7 @@ const headerAuth = async (req, res, next) => { const authToken = req.headers.authorization.split(" ")[1]; try { - const decodedToken = jwt.verify(authToken, process.env.JWT_KEY); + const decodedToken = verify(authToken, process.env.JWT_KEY); const userID = decodedToken.id; const profile = await knex("users").where({ id: userID }).first(); @@ -30,7 +30,7 @@ const adminAuth = async (req, res, next) => { const authToken = req.headers.authorization.split(" ")[1]; try { - const decodedToken = jwt.verify(authToken, process.env.JWT_KEY); + const decodedToken = verify(authToken, process.env.JWT_KEY); const userID = decodedToken.id; const profile = await knex("users").where({ id: userID }).first(); @@ -47,4 +47,4 @@ const adminAuth = async (req, res, next) => { } }; -module.exports = { headerAuth, adminAuth }; +export default { headerAuth, adminAuth }; diff --git a/package.json b/package.json index 3170db0..c4691a7 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,12 @@ "version": "1.0.0", "description": "", "main": "index.js", + "type": "module", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc", "start": "node index.js", + "dev": "node --loader ts-node/esm index.js", + "test": "echo \"Error: no test specified\" && exit 1", "migrate": "knex migrate:latest", "rollback": " knex migrate:rollback", "knex": "knex" @@ -22,7 +25,13 @@ "jsonwebtoken": "^9.0.2", "knex": "^3.1.0", "mysql2": "^3.9.2", - "nodemailer": "^6.9.8", + "node": "^20.19.0", + "nodemailer": "^6.9.8" + }, + "devDependencies": { + "@types/cors": "^2.8.17", + "@types/node": "^22.13.11", + "ts-node": "^10.9.2", "typescript": "^5.8.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5a3dad..1eebb01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,15 +32,80 @@ dependencies: mysql2: specifier: ^3.9.2 version: 3.9.2 + node: + specifier: ^20.19.0 + version: 20.19.0 nodemailer: specifier: ^6.9.8 version: 6.9.8 + +devDependencies: + '@types/cors': + specifier: ^2.8.17 + version: 2.8.17 + '@types/node': + specifier: ^22.13.11 + version: 22.13.11 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@22.13.11)(typescript@5.8.2) typescript: specifier: ^5.8.2 version: 5.8.2 packages: + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /@tsconfig/node10@1.0.11: + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/cors@2.8.17: + resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + dependencies: + '@types/node': 22.13.11 + dev: true + + /@types/node@22.13.11: + resolution: {integrity: sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==} + dependencies: + undici-types: 6.20.0 + dev: true + /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -49,6 +114,23 @@ packages: negotiator: 0.6.3 dev: false + /acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + dependencies: + acorn: 8.14.1 + dev: true + + /acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: false @@ -140,6 +222,10 @@ packages: vary: 1.1.2 dev: false + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + /crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} dev: false @@ -186,6 +272,11 @@ packages: engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dev: false + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + /dotenv@16.3.2: resolution: {integrity: sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==} engines: {node: '>=12'} @@ -541,6 +632,10 @@ packages: engines: {node: '>=16.14'} dev: false + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + /math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -616,6 +711,19 @@ packages: engines: {node: '>= 0.6'} dev: false + /node-bin-setup@1.1.3: + resolution: {integrity: sha512-opgw9iSCAzT2+6wJOETCpeRYAQxSopqQ2z+N6BXwIMsQQ7Zj5M8MaafQY8JMlolRR6R1UXg2WmhKp0p9lSOivg==} + dev: false + + /node@20.19.0: + resolution: {integrity: sha512-upEH46DT6+wF3J8Q7tnmB8Kh0m+xYcBdaIluOxjR9ZnM5lpabfZIBfXNYWUxOhxTQLu23J4MiNXkUOeFHPrqdA==} + engines: {npm: '>=5.0.0'} + hasBin: true + requiresBuild: true + dependencies: + node-bin-setup: 1.1.3 + dev: false + /nodemailer@6.9.8: resolution: {integrity: sha512-cfrYUk16e67Ks051i4CntM9kshRYei1/o/Gi8K1d+R34OIs21xdFnW7Pt7EucmVKA0LKtqUGNcjMZ7ehjl49mQ==} engines: {node: '>=6.0.0'} @@ -832,6 +940,37 @@ packages: engines: {node: '>=0.6'} dev: false + /ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.13.11 + acorn: 8.14.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.8.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -844,7 +983,11 @@ packages: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} hasBin: true - dev: false + dev: true + + /undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + dev: true /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} @@ -856,7 +999,16 @@ packages: engines: {node: '>= 0.4.0'} dev: false + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} dev: false + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true diff --git a/routes/armies-routes.js b/routes/armies-routes.js index 221717e..cf33dd7 100644 --- a/routes/armies-routes.js +++ b/routes/armies-routes.js @@ -1,11 +1,12 @@ -const express = require("express"); -const database = require("../database/db"); -const router = express.Router(); -const crypto = require("crypto"); -const dayjs = require("dayjs"); -const jwt = require("jsonwebtoken"); - -const { +import { Router } from "express"; +import database from "../database/db.js"; +import crypto from "crypto"; +import dayjs from "dayjs"; +import jwt from "jsonwebtoken"; + +const armyRouter = Router(); + +import { updateArmyField, addNewArmyRanking, fetchOneArmy, @@ -15,16 +16,16 @@ const { getAllUserArmies, insertNewArmy, getArmyInfo, -} = require("../controllers/modules/armies/armies-controller"); -const { headerAuth, adminAuth } = require("../middleware/auth"); +} from "../controllers/modules/armies/armies-controller.ts"; + +import { headerAuth, adminAuth } from "../middleware/auth.js"; require("dotenv").config(); -const pool = database.client.pool; -router.route("/all").get(getAllArmies); -router.route("/all/:id").get(getAllUserArmies); +armyRouter.route("/all").get(getAllArmies); +armyRouter.route("/all/:id").get(getAllUserArmies); -router.route("/create").post(headerAuth, async (req, res) => { +armyRouter.route("/create").post(headerAuth, async (req, res) => { try { const { name, type, emblemName, emblemID } = req.body; @@ -81,9 +82,9 @@ router.route("/create").post(headerAuth, async (req, res) => { } }); -router.route("/army/:id").get(fetchOneArmy); +armyRouter.route("/army/:id").get(fetchOneArmy); -router.route("/:id/update").patch(headerAuth, async (req, res) => { +armyRouter.route("/:id/update").patch(headerAuth, async (req, res) => { const armyID = req.params.id; const { name, type, userId } = req.body; @@ -113,10 +114,10 @@ router.route("/:id/update").patch(headerAuth, async (req, res) => { } }); -router.route("/:id/ranking").post(adminAuth, addNewArmyRanking); +armyRouter.route("/:id/ranking").post(adminAuth, addNewArmyRanking); -router.route("/:id/nemesis").get(getArmyNemesis); -router.route("/:id/ally").get(getArmyAlly); -router.route("/:id/info").get(getArmyInfo); +armyRouter.route("/:id/nemesis").get(getArmyNemesis); +armyRouter.route("/:id/ally").get(getArmyAlly); +armyRouter.route("/:id/info").get(getArmyInfo); -module.exports = router; +export default armyRouter; diff --git a/routes/battles-routes.js b/routes/battles-routes.js index 2159347..2180ac3 100644 --- a/routes/battles-routes.js +++ b/routes/battles-routes.js @@ -1,15 +1,12 @@ -const express = require("express"); -const database = require("../database/db"); -const router = express.Router(); -const crypto = require("crypto"); -const dayjs = require("dayjs"); -const cors = require("cors"); - -const jwt = require("jsonwebtoken"); +import { Router } from "express"; +import database, { transaction } from "../database/db.js"; +import { randomUUID } from "crypto"; +import dayjs from "dayjs"; require("dotenv").config(); +const battleRouter = Router(); -const { +import { singleToMultiCombatantUpdate, deleteCombatantTeam, addCombatant, @@ -39,10 +36,10 @@ const { multiplayerMapping, deleteCreateNewRank, fetchUsersLastFiveBattles, -} = require("../controllers/battles-controller"); -const { headerAuth, adminAuth } = require("../middleware/auth"); +} from "../controllers/battles-controller.js"; +import { headerAuth, adminAuth } from "../middleware/auth.js"; -router.route("/create").post(headerAuth, async (req, res) => { +battleRouter.route("/create").post(headerAuth, async (req, res) => { let { points_size, battle_type, @@ -78,15 +75,15 @@ router.route("/create").post(headerAuth, async (req, res) => { if (date === "unspecified") { date = dayjs().format("YYYY-MM-DD HH:mm:ss"); } - const playerOneID = crypto.randomUUID(); - const playerTwoID = crypto.randomUUID(); + const playerOneID = randomUUID(); + const playerTwoID = randomUUID(); if (player_type === "single") { const playerOne = { id: playerOneID, army_id: player_1[0].army_id }; const playerTwo = { id: playerTwoID, army_id: player_2[0].army_id }; const newBattleObj = { - id: crypto.randomUUID(), + id: randomUUID(), date: dayjs(date).format("YYYY-MM-DD"), player_type, battle_type, @@ -100,7 +97,7 @@ router.route("/create").post(headerAuth, async (req, res) => { }; try { - await database.transaction(async (trx) => { + await transaction(async (trx) => { await trx("combatants").insert([playerOne, playerTwo]); await trx("battles").insert(newBattleObj); }); @@ -116,7 +113,7 @@ router.route("/create").post(headerAuth, async (req, res) => { } else if (player_type === "multi") { try { const newBattleObj = { - id: crypto.randomUUID(), + id: randomUUID(), date: dayjs(date).format("YYYY-MM-DD"), player_type, battle_type, @@ -131,7 +128,7 @@ router.route("/create").post(headerAuth, async (req, res) => { const playerOneMapped = multiplayerMapping(player_1, playerOneID); const playerTwoMapped = multiplayerMapping(player_2, playerTwoID); - await database.transaction(async (trx) => { + await transaction(async (trx) => { await trx("combatants").insert([ ...playerOneMapped, ...playerTwoMapped, @@ -147,45 +144,47 @@ router.route("/create").post(headerAuth, async (req, res) => { } }); -router.route("/all").get(fetchAllBattles); -router.route("/upcoming").get(fetchUpcomingBattles); -router.route("/upcoming/5").get(fetchFiveUpcomingBattles); -router.route("/completed").get(fetchCompletedBattles); -router.route("/completed/5").get(fetchFiveCompletedBattles); -router.route("/:id").get(fetchOneBattle); -router.route("/:id/win/percent").get(fetchUsersWinPercent); -router.route("/:id/win/count").get(fetchUsersWinCount); -router.route("/:id/all").get(fetchAllUsersBattles); -router.route("/:id/all/count").get(fetchAllUsersBattlesCount); -router.route("/user/upcoming").get(fetchUsersUpcomingBattles); -router.route("/user/completed").get(fetchUsersCompletedBattles); -router.route("/user/last/5").get(fetchUsersLastFiveBattles); -router.route("/:id/upcoming/count").get(fetchUsersUpcomingBattlesCount); -router.route("/:id/completed").get(fetchUsersCompletedBattles); -router.route("/:id/completed/count").get(fetchUsersCompletedBattlesCount); - -router.route("/:id/edit/pointsize").patch(headerAuth, async (req, res) => { - const battleID = req.params.id; - const { points_size } = req.body; - const oldPointsSize = await database("battles") - .where({ id: battleID }) - .first() - .select("points_size"); - try { - await database("battles") +battleRouter.route("/all").get(fetchAllBattles); +battleRouter.route("/upcoming").get(fetchUpcomingBattles); +battleRouter.route("/upcoming/5").get(fetchFiveUpcomingBattles); +battleRouter.route("/completed").get(fetchCompletedBattles); +battleRouter.route("/completed/5").get(fetchFiveCompletedBattles); +battleRouter.route("/:id").get(fetchOneBattle); +battleRouter.route("/:id/win/percent").get(fetchUsersWinPercent); +battleRouter.route("/:id/win/count").get(fetchUsersWinCount); +battleRouter.route("/:id/all").get(fetchAllUsersBattles); +battleRouter.route("/:id/all/count").get(fetchAllUsersBattlesCount); +battleRouter.route("/user/upcoming").get(fetchUsersUpcomingBattles); +battleRouter.route("/user/completed").get(fetchUsersCompletedBattles); +battleRouter.route("/user/last/5").get(fetchUsersLastFiveBattles); +battleRouter.route("/:id/upcoming/count").get(fetchUsersUpcomingBattlesCount); +battleRouter.route("/:id/completed").get(fetchUsersCompletedBattles); +battleRouter.route("/:id/completed/count").get(fetchUsersCompletedBattlesCount); + +battleRouter + .route("/:id/edit/pointsize") + .patch(headerAuth, async (req, res) => { + const battleID = req.params.id; + const { points_size } = req.body; + const oldPointsSize = await database("battles") .where({ id: battleID }) - .update({ points_size: points_size }); - res - .status(200) - .send( - `Points Size has been updated from ${oldPointsSize.points_size} to ${points_size}` - ); - } catch (error) { - console.error(error); - res.status(400).send("Issue with altering points size in the database"); - } -}); -router.route("/:id/edit/scenario").patch(headerAuth, async (req, res) => { + .first() + .select("points_size"); + try { + await database("battles") + .where({ id: battleID }) + .update({ points_size: points_size }); + res + .status(200) + .send( + `Points Size has been updated from ${oldPointsSize.points_size} to ${points_size}` + ); + } catch (error) { + console.error(error); + res.status(400).send("Issue with altering points size in the database"); + } + }); +battleRouter.route("/:id/edit/scenario").patch(headerAuth, async (req, res) => { const battleID = req.params.id; const { scenario } = req.body; const oldScenario = await database("battles") @@ -206,7 +205,7 @@ router.route("/:id/edit/scenario").patch(headerAuth, async (req, res) => { res.status(400).send("Issue with altering scenario in the database"); } }); -router.route("/:id/edit/date").patch(headerAuth, async (req, res) => { +battleRouter.route("/:id/edit/date").patch(headerAuth, async (req, res) => { const battleID = req.params.id; const { date } = req.body; @@ -230,7 +229,7 @@ router.route("/:id/edit/date").patch(headerAuth, async (req, res) => { res.status(400).send("Issue with altering date in the database"); } }); -router.route("/:id/edit/start").patch(headerAuth, async (req, res) => { +battleRouter.route("/:id/edit/start").patch(headerAuth, async (req, res) => { const battleID = req.params.id; const { start } = req.body; @@ -248,7 +247,7 @@ router.route("/:id/edit/start").patch(headerAuth, async (req, res) => { res.status(400).send("Issue with altering Start Time in the database"); } }); -router.route("/:id/edit/finish").patch(headerAuth, async (req, res) => { +battleRouter.route("/:id/edit/finish").patch(headerAuth, async (req, res) => { const battleID = req.params.id; const { finish } = req.body; @@ -270,7 +269,7 @@ router.route("/:id/edit/finish").patch(headerAuth, async (req, res) => { res.status(400).send("Issue with altering Finish Time in the database"); } }); -router.route("/:id/edit/table").patch(headerAuth, async (req, res) => { +battleRouter.route("/:id/edit/table").patch(headerAuth, async (req, res) => { const battleID = req.params.id; const { table } = req.body; @@ -288,7 +287,7 @@ router.route("/:id/edit/table").patch(headerAuth, async (req, res) => { res.status(400).send("Issue with altering Table in the database"); } }); -router.route("/:id/edit/gametype").patch(headerAuth, async (req, res) => { +battleRouter.route("/:id/edit/gametype").patch(headerAuth, async (req, res) => { const battleID = req.params.id; const { battle_type, player_type } = req.body; @@ -354,152 +353,160 @@ router.route("/:id/edit/gametype").patch(headerAuth, async (req, res) => { ); } }); -router.route("/:id/edit/combatants").patch(headerAuth, async (req, res) => { - const battleID = req.params.id; - const { player_1, player_2 } = req.body; - - const battleToChange = await database("battles") - .where({ id: battleID }) - .first(); - - if (!battleToChange) { - return res - .status(400) - .send("Unable to locate the battle you are looking for"); - } +battleRouter + .route("/:id/edit/combatants") + .patch(headerAuth, async (req, res) => { + const battleID = req.params.id; + const { player_1, player_2 } = req.body; - const prevPlayerOneID = battleToChange.player_1_id; - const prevPlayerTwoID = battleToChange.player_2_id; - - if ( - battleToChange.player_type === "single" && - (player_1.length > 1) | (player_2.length > 1) - ) { - try { - const teamOneID = crypto.randomUUID(); - const teamTwoID = crypto.randomUUID(); + const battleToChange = await database("battles") + .where({ id: battleID }) + .first(); - const teamOneArray = await singleToMultiCombatantUpdate( - player_1, - prevPlayerOneID, - teamOneID - ); - const teamTwoArray = await singleToMultiCombatantUpdate( - player_2, - prevPlayerTwoID, - teamTwoID - ); + if (!battleToChange) { + return res + .status(400) + .send("Unable to locate the battle you are looking for"); + } - await database("battles") - .where({ id: battleID }) - .update({ player_type: "multi" }); + const prevPlayerOneID = battleToChange.player_1_id; + const prevPlayerTwoID = battleToChange.player_2_id; - await database("battles") - .where({ id: battleID }) - .update({ player_1_id: teamOneID, player_2_id: teamTwoID }); + if ( + battleToChange.player_type === "single" && + (player_1.length > 1) | (player_2.length > 1) + ) { + try { + const teamOneID = randomUUID(); + const teamTwoID = randomUUID(); + + const teamOneArray = await singleToMultiCombatantUpdate( + player_1, + prevPlayerOneID, + teamOneID + ); + const teamTwoArray = await singleToMultiCombatantUpdate( + player_2, + prevPlayerTwoID, + teamTwoID + ); - res.status(200).send({ - message: "Teams successfully Update", - teamOne: teamOneArray, - teamTwo: teamTwoArray, - }); - } catch (error) { - console.error(error); - res.status(400).send("Unable to update teams"); - } - } else if ( - battleToChange.player_type === "single" && - player_1.length === 1 && - player_2.length === 1 - ) { - try { - if (player_1.id !== prevPlayerOneID) { - await database("combatants") - .where({ id: prevPlayerOneID }) - .update({ army_id: player_1[0].army_id }); + await database("battles") + .where({ id: battleID }) + .update({ player_type: "multi" }); + + await database("battles") + .where({ id: battleID }) + .update({ player_1_id: teamOneID, player_2_id: teamTwoID }); + + res.status(200).send({ + message: "Teams successfully Update", + teamOne: teamOneArray, + teamTwo: teamTwoArray, + }); + } catch (error) { + console.error(error); + res.status(400).send("Unable to update teams"); } - if (player_2.id !== prevPlayerTwoID) { - await database("combatants") - .where({ id: prevPlayerTwoID }) - .update({ army_id: player_2[0].army_id }); + } else if ( + battleToChange.player_type === "single" && + player_1.length === 1 && + player_2.length === 1 + ) { + try { + if (player_1.id !== prevPlayerOneID) { + await database("combatants") + .where({ id: prevPlayerOneID }) + .update({ army_id: player_1[0].army_id }); + } + if (player_2.id !== prevPlayerTwoID) { + await database("combatants") + .where({ id: prevPlayerTwoID }) + .update({ army_id: player_2[0].army_id }); + } + + res.status(200).send({ + message: "Successfully updated the combatants", + player_1, + player_2, + }); + } catch (error) { + console.error(error); + res.status(400).send("Unable to update the combatants"); } + } else if ( + battleToChange.player_type === "multi" && + player_1.length === 1 && + player_2.length === 1 + ) { + const playerOneID = randomUUID(); + const playerTwoID = randomUUID(); - res.status(200).send({ - message: "Successfully updated the combatants", - player_1, - player_2, - }); - } catch (error) { - console.error(error); - res.status(400).send("Unable to update the combatants"); - } - } else if ( - battleToChange.player_type === "multi" && - player_1.length === 1 && - player_2.length === 1 - ) { - const playerOneID = crypto.randomUUID(); - const playerTwoID = crypto.randomUUID(); - - try { - await database("battles") - .where({ id: battleID }) - .update({ player_type: "single" }); - - await deleteCombatantTeam(battleToChange.player_1_id); - await deleteCombatantTeam(battleToChange.player_2_id); - - const playerOneObj = await addCombatant(player_1[0].army_id, playerOneID); - const playerTwoObj = await addCombatant(player_2[0].army_id, playerTwoID); + try { + await database("battles") + .where({ id: battleID }) + .update({ player_type: "single" }); - await assignNewCombatant(battleID, playerOneID, 1); - await assignNewCombatant(battleID, playerTwoID, 2); + await deleteCombatantTeam(battleToChange.player_1_id); + await deleteCombatantTeam(battleToChange.player_2_id); - res.status(200).send({ - message: "Combatants have been successfully update", - player_1: playerOneObj, - player_2: playerTwoObj, - }); - } catch (error) { - console.error(error); - res.status(400).send("Unable to update the battle"); - } - } else if ( - battleToChange.player_type === "multi" && - player_1.length > 1 && - player_2.length > 1 - ) { - const playerOneID = crypto.randomUUID(); - const playerTwoID = crypto.randomUUID(); + const playerOneObj = await addCombatant( + player_1[0].army_id, + playerOneID + ); + const playerTwoObj = await addCombatant( + player_2[0].army_id, + playerTwoID + ); - try { - await deleteCombatantTeam(battleToChange.player_1_id); - await deleteCombatantTeam(battleToChange.player_2_id); + await assignNewCombatant(battleID, playerOneID, 1); + await assignNewCombatant(battleID, playerTwoID, 2); + + res.status(200).send({ + message: "Combatants have been successfully update", + player_1: playerOneObj, + player_2: playerTwoObj, + }); + } catch (error) { + console.error(error); + res.status(400).send("Unable to update the battle"); + } + } else if ( + battleToChange.player_type === "multi" && + player_1.length > 1 && + player_2.length > 1 + ) { + const playerOneID = randomUUID(); + const playerTwoID = randomUUID(); - const teamOneArray = await multiplayerdatabaseInsert( - player_1, - playerOneID - ); - const teamTwoArray = await multiplayerdatabaseInsert( - player_2, - playerTwoID - ); + try { + await deleteCombatantTeam(battleToChange.player_1_id); + await deleteCombatantTeam(battleToChange.player_2_id); - await assignNewCombatant(battleID, playerOneID, 1); - await assignNewCombatant(battleID, playerTwoID, 2); + const teamOneArray = await multiplayerdatabaseInsert( + player_1, + playerOneID + ); + const teamTwoArray = await multiplayerdatabaseInsert( + player_2, + playerTwoID + ); - res.status(200).send({ - message: "Teams have been updated", - team_1: teamOneArray, - team_2: teamTwoArray, - }); - } catch (error) { - console.error(error); - res.status(400).send("Unable to update teams"); + await assignNewCombatant(battleID, playerOneID, 1); + await assignNewCombatant(battleID, playerTwoID, 2); + + res.status(200).send({ + message: "Teams have been updated", + team_1: teamOneArray, + team_2: teamTwoArray, + }); + } catch (error) { + console.error(error); + res.status(400).send("Unable to update teams"); + } } - } -}); -router.route("/:id/edit/points_1").patch(headerAuth, async (req, res) => { + }); +battleRouter.route("/:id/edit/points_1").patch(headerAuth, async (req, res) => { const { points } = req.body; const battleID = req.params.id; @@ -528,7 +535,7 @@ router.route("/:id/edit/points_1").patch(headerAuth, async (req, res) => { res.status(400).send("Unable to update the battle"); } }); -router.route("/:id/edit/points_2").patch(headerAuth, async (req, res) => { +battleRouter.route("/:id/edit/points_2").patch(headerAuth, async (req, res) => { const { points } = req.body; const battleID = req.params.id; @@ -558,7 +565,7 @@ router.route("/:id/edit/points_2").patch(headerAuth, async (req, res) => { } }); -router.route("/:id/delete").delete(adminAuth, async (req, res) => { +battleRouter.route("/:id/delete").delete(adminAuth, async (req, res) => { const battleID = req.params.id; const battleObj = await database("battles").where({ id: battleID }).first(); try { @@ -573,7 +580,7 @@ router.route("/:id/delete").delete(adminAuth, async (req, res) => { } }); -router.route("/:id/submit").post(headerAuth, async (req, res) => { +battleRouter.route("/:id/submit").post(headerAuth, async (req, res) => { const battleID = req.params.id; const battleObj = await database("battles").where({ id: battleID }).first(); @@ -730,7 +737,7 @@ router.route("/:id/submit").post(headerAuth, async (req, res) => { } }); -router.route("/:id/resubmit").post(adminAuth, async (req, res) => { +battleRouter.route("/:id/resubmit").post(adminAuth, async (req, res) => { const battleID = req.params.id; const battleObj = await database("battles").where({ id: battleID }).first(); @@ -919,4 +926,4 @@ router.route("/:id/resubmit").post(adminAuth, async (req, res) => { } }); -module.exports = router; +export default battleRouter; diff --git a/routes/rankings-routes.js b/routes/rankings-routes.js index 5e92c0a..aefcccb 100644 --- a/routes/rankings-routes.js +++ b/routes/rankings-routes.js @@ -1,14 +1,14 @@ -const express = require("express"); -const database = require("../database/db"); +import { Router } from "express"; +import { client } from "../database/db.js"; -const { +import { fetchAllRankings, fetchTopFiveRanking, fetchOneRanking, fetchAllArmyRankings, -} = require("../controllers/rankings-controllers"); -const router = express.Router(); -const pool = database.client.pool; +} from "../controllers/rankings-controllers.js"; +const rankingRouter = Router(); +const pool = client.pool; // database.on("query", (builder) => { // console.log("Ranking Routes to be executed", builder.sql); // console.log("Ranking Routes Pool Used on Start", pool.numUsed()); @@ -29,8 +29,8 @@ const pool = database.client.pool; // console.log("Ranking Routes Error Pool Free on error", pool.numFree()); // }); -router.route("/all").get(fetchAllRankings); -router.route("/top5").get(fetchTopFiveRanking); -router.route("/:id").get(fetchOneRanking); -router.route("/:id/all").get(fetchAllArmyRankings); -module.exports = router; +rankingRouter.route("/all").get(fetchAllRankings); +rankingRouter.route("/top5").get(fetchTopFiveRanking); +rankingRouter.route("/:id").get(fetchOneRanking); +rankingRouter.route("/:id/all").get(fetchAllArmyRankings); +export default rankingRouter; diff --git a/routes/users-routes.js b/routes/users-routes.js index d4bbcc8..25e14fc 100644 --- a/routes/users-routes.js +++ b/routes/users-routes.js @@ -1,12 +1,11 @@ -const express = require("express"); -const bcrypt = require("bcryptjs"); -const jwt = require("jsonwebtoken"); -const database = require("../database/db"); -const crypto = require("crypto"); -const router = express.Router(); -const nodemailer = require("nodemailer"); -const { adminAuth, headerAuth } = require("../middleware/auth"); -const { +import { Router } from "express"; +import { hashSync, compareSync } from "bcryptjs"; +import { sign } from "jsonwebtoken"; +import database from "../database/db.js"; +import { randomUUID } from "crypto"; +import { createTransport } from "nodemailer"; +import { adminAuth, headerAuth } from "../middleware/auth.js"; +import { getAllUsers, getOneUser, getUserNemesis, @@ -14,9 +13,10 @@ const { getOneOtherUser, getUserInfo, getOneUserWithToken, -} = require("../controllers/users-controllers"); -const { verifyToken } = require("../utils/Auth"); +} from "../controllers/users-controllers.js"; +import { verifyToken } from "../utils/Auth.js"; +const userRouter = Router(); require("dotenv").config(); const baseURL = `${process.env.BASE_URL}${process.env.PORT}`; @@ -43,7 +43,7 @@ const clientURL = `${process.env.CLIENT_URL}`; // console.log("User Routes Error Pool Free on error", pool.numFree()); // }); -const transport = nodemailer.createTransport({ +const transport = createTransport({ host: "live.smtp.mailtrap.io", port: 587, auth: { @@ -52,7 +52,7 @@ const transport = nodemailer.createTransport({ }, }); -router.route("/register").post(async (req, res) => { +userRouter.route("/register").post(async (req, res) => { const { first_name, last_name, known_as, email, password, user_emblem } = req.body; @@ -85,10 +85,10 @@ router.route("/register").post(async (req, res) => { ); } - const hashedPassword = bcrypt.hashSync(password); + const hashedPassword = hashSync(password); const newUser = { - id: crypto.randomUUID(), + id: randomUUID(), first_name, last_name, known_as, @@ -107,7 +107,7 @@ router.route("/register").post(async (req, res) => { } }); -router.route("/login").post(async (req, res) => { +userRouter.route("/login").post(async (req, res) => { const { email, password } = req.body; if (!email | !password) { @@ -121,13 +121,13 @@ router.route("/login").post(async (req, res) => { return res.status(400).send("User has not been found"); } - const isPasswordCorrect = bcrypt.compareSync(password, user.password); + const isPasswordCorrect = compareSync(password, user.password); if (!isPasswordCorrect) { return res.status(400).send("Invalid Password"); } - const token = jwt.sign( + const token = sign( { id: user.id, email: user.email }, process.env.JWT_KEY, { expiresIn: "24h" } @@ -139,9 +139,9 @@ router.route("/login").post(async (req, res) => { } }); -router.route("/forgot-password").post(async (req, res) => { +userRouter.route("/forgot-password").post(async (req, res) => { const { email } = req.body; - const resetToken = crypto.randomUUID(); + const resetToken = randomUUID(); try { const user = await database("users").where({ email: email }).first(); @@ -177,7 +177,7 @@ router.route("/forgot-password").post(async (req, res) => { } }); -router.route("/reset/:token").patch(async (req, res) => { +userRouter.route("/reset/:token").patch(async (req, res) => { const { password } = req.body; if (!password) { @@ -192,7 +192,7 @@ router.route("/reset/:token").patch(async (req, res) => { return res.status(400).send("Invalid user ID in request parameters"); } - const hashedPassword = bcrypt.hashSync(password); + const hashedPassword = hashSync(password); try { const userToChange = await database("users") @@ -212,7 +212,7 @@ router.route("/reset/:token").patch(async (req, res) => { } }); -router.route("/:id/admin").patch(adminAuth, async (req, res) => { +userRouter.route("/:id/admin").patch(adminAuth, async (req, res) => { const id = req.params.id; try { @@ -231,7 +231,7 @@ router.route("/:id/admin").patch(adminAuth, async (req, res) => { } }); -router.route("/:id/deactivate").patch(adminAuth, async (req, res) => { +userRouter.route("/:id/deactivate").patch(adminAuth, async (req, res) => { const id = req.params.id; try { @@ -250,7 +250,7 @@ router.route("/:id/deactivate").patch(adminAuth, async (req, res) => { } }); -router.route("/:id/user").patch(adminAuth, async (req, res) => { +userRouter.route("/:id/user").patch(adminAuth, async (req, res) => { const id = req.params.id; try { @@ -269,7 +269,7 @@ router.route("/:id/user").patch(adminAuth, async (req, res) => { } }); -router.route("/:id/edit/first_name").patch(headerAuth, async (req, res) => { +userRouter.route("/:id/edit/first_name").patch(headerAuth, async (req, res) => { const { first_name } = req.body; const id = req.params.id; @@ -296,7 +296,7 @@ router.route("/:id/edit/first_name").patch(headerAuth, async (req, res) => { } }); -router.route("/:id/edit/last_name").patch(headerAuth, async (req, res) => { +userRouter.route("/:id/edit/last_name").patch(headerAuth, async (req, res) => { const { last_name } = req.body; const id = req.params.id; @@ -323,7 +323,7 @@ router.route("/:id/edit/last_name").patch(headerAuth, async (req, res) => { } }); -router.route("/:id/edit/email").patch(headerAuth, async (req, res) => { +userRouter.route("/:id/edit/email").patch(headerAuth, async (req, res) => { const { email } = req.body; const id = req.params.id; @@ -350,7 +350,7 @@ router.route("/:id/edit/email").patch(headerAuth, async (req, res) => { } }); -router.route("/:id/edit/known_as").patch(headerAuth, async (req, res) => { +userRouter.route("/:id/edit/known_as").patch(headerAuth, async (req, res) => { const { known_as } = req.body; const id = req.params.id; @@ -379,7 +379,7 @@ router.route("/:id/edit/known_as").patch(headerAuth, async (req, res) => { } }); -router.route("/rankings").get(headerAuth, async (req, res) => { +userRouter.route("/rankings").get(headerAuth, async (req, res) => { const authToken = req.headers.authorization.split(" ")[1]; const decodedToken = verifyToken(authToken); @@ -441,19 +441,19 @@ router.route("/rankings").get(headerAuth, async (req, res) => { } }); -router.route("/all").get(getAllUsers); +userRouter.route("/all").get(getAllUsers); -router.route("/one").get(getOneUser); +userRouter.route("/one").get(getOneUser); -router.route("/one/:id").get(getOneOtherUser); +userRouter.route("/one/:id").get(getOneOtherUser); -router.route("/nemesis").get(getUserNemesis); -router.route("/ally").get(getUserAlly); +userRouter.route("/nemesis").get(getUserNemesis); +userRouter.route("/ally").get(getUserAlly); -router.route("/token").get(getOneUserWithToken); +userRouter.route("/token").get(getOneUserWithToken); -router.route("/user/info").get(getUserInfo); -router.route("/user/authenticate/:token").get((req, res) => { +userRouter.route("/user/info").get(getUserInfo); +userRouter.route("/user/authenticate/:token").get((req, res) => { const token = req.params.token; const response = verifyToken(token); @@ -464,4 +464,4 @@ router.route("/user/authenticate/:token").get((req, res) => { return res.status(401).send(false); } }); -module.exports = router; +export default userRouter; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8a4476d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "esModuleInterop": true, + "outDir": "./dist", + "strict": true + }, + "include": ["**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/types/armies.ts b/types/armies.ts index bbd77bd..b359416 100644 --- a/types/armies.ts +++ b/types/armies.ts @@ -5,9 +5,9 @@ export type ArmyType = "fantasy" | "40k"; export interface Army { name: string; army_id: ArmyId; - id: UserId; - known_as: string; - ranking: string; + id?: string; + known_as?: string; + ranking?: string; emblem?: string; emblem_id?: string; type?: ArmyType; diff --git a/utils/ArrayMethods.js b/utils/ArrayMethods.js index 1727e70..4556c7f 100644 --- a/utils/ArrayMethods.js +++ b/utils/ArrayMethods.js @@ -1,5 +1,5 @@ -const database = require("../database/db"); -const dayjs = require("dayjs"); +import database from "../database/db"; +import dayjs from "dayjs"; // const pool = database.client.pool; @@ -987,7 +987,7 @@ const singleBattlePlayerFormatting = async (battle) => { return newBattleObj; }; -module.exports = { +export default { singleBattlePlayerFormatting, completedBattleFormattingLimited, completedBattleFormatting, diff --git a/utils/Auth.js b/utils/Auth.js index ca67d9e..dc18f96 100644 --- a/utils/Auth.js +++ b/utils/Auth.js @@ -1,8 +1,8 @@ -const jwt = require("jsonwebtoken"); -const database = require("../database/db"); +import { verify } from "jsonwebtoken"; +import database from "../database/db"; const verifyToken = (authToken) => { - const decodedToken = jwt.verify(authToken, process.env.JWT_KEY); + const decodedToken = verify(authToken, process.env.JWT_KEY); if (!decodedToken) { return null; } @@ -20,4 +20,4 @@ const getTokenProfile = async (id) => { } }; -module.exports = { verifyToken, getTokenProfile }; +export default { verifyToken, getTokenProfile };