From 3cee9f85af67340fc986f73eef3661738e7e5e66 Mon Sep 17 00:00:00 2001 From: Ferdi-Cocelli Date: Fri, 5 Jun 2026 14:38:31 +0100 Subject: [PATCH] Fix broken task runner and improve readability medium solution The run category script expected filenames like 2-medium.ts but the actual task files are just named medium.ts. Updated the difficulty mapping to match the real filenames. The readability medium task uses top level await, which requires ESM. Added "type": "module" to package.json to enable this. Since the helper scripts (run category, decrypt) use require(), they've been renamed from .js to .cjs so Node treats them as CommonJS while the rest of the project runs as ESM. Also refactored the readability medium task itself by splitting the single compound assertion into three separate assertions with descriptive error messages, and destructured response.data to reduce repetition. Ferdi, Christian, Nathan, Henry --- package-lock.json | 2 +- package.json | 5 +- scripts/{decrypt.js => decrypt.cjs} | 150 +++++++++--------- scripts/{run-category.js => run-category.cjs} | 68 ++++---- tasks/readability/medium.ts | 9 +- 5 files changed, 117 insertions(+), 117 deletions(-) rename scripts/{decrypt.js => decrypt.cjs} (96%) rename scripts/{run-category.js => run-category.cjs} (90%) diff --git a/package-lock.json b/package-lock.json index bb4ff91..38a72bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "fqe-practice-day-workshop", + "name": "fqe-code-quality-workshop", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index fcf1765..423a512 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { + "type": "module", "scripts": { - "test": "node scripts/run-category.js", - "unlock-solution": "node scripts/decrypt.js" + "test": "node scripts/run-category.cjs", + "unlock-solution": "node scripts/decrypt.cjs" }, "dependencies": { "crypto": "^1.0.1", diff --git a/scripts/decrypt.js b/scripts/decrypt.cjs similarity index 96% rename from scripts/decrypt.js rename to scripts/decrypt.cjs index c8654b9..bf125d0 100644 --- a/scripts/decrypt.js +++ b/scripts/decrypt.cjs @@ -1,75 +1,75 @@ -const fs = require("fs"); -const crypto = require("crypto"); -const prompt = require("prompt-sync")({ sigint: true }); - -const algorithm = "aes-256-gcm"; - -function decrypt(data, password) { - const input = Buffer.from(data, "base64"); - - const salt = input.subarray(0, 16); - const iv = input.subarray(16, 28); - const tag = input.subarray(28, 44); - const text = input.subarray(44); - - const key = crypto.scryptSync(password, salt, 32); - - const decipher = crypto.createDecipheriv(algorithm, key, iv); - decipher.setAuthTag(tag); - - const decrypted = Buffer.concat([decipher.update(text), decipher.final()]); - return decrypted.toString("utf8"); -} - -const [, , category, difficulty] = process.argv; - -const map = { - easy: "easy", - medium: "medium", - hard: "hard", -}; - -const categoryOptions = [ - "additional", - "maintainability", - "readability", - "scalability", -]; - -// Is category parameter valid? -if (!category || !categoryOptions.includes(category)) { - console.error( - `Incorrect category flag\n\nExample usage: 'npm run unlock-solution maintainability easy'\n\nOptions are: ${categoryOptions.join(", ")}`, - ); - process.exit(1); -} - -// Is difficulty parameter valid? -const difficultyOptions = Object.keys(map); -if (!difficulty || !difficultyOptions.includes(difficulty)) { - console.error( - `Incorrect category flag\n\nexample usage: 'npm run unlock-solution maintainability easy'\n\nOptions are: ${difficultyOptions.join(", ")}`, - ); - process.exit(1); -} - -const filePath = `solutions/${category}/${map[difficulty]}.ts.enc`; - -if (!fs.existsSync(filePath)) { - console.error("File not found:", filePath); - process.exit(1); -} - -const password = prompt("Enter decryption password: "); - -const encrypted = fs.readFileSync(filePath, "utf8"); - -try { - const decrypted = decrypt(encrypted, password.trim().toLowerCase()); - fs.writeFileSync(filePath.replace(".ts.enc", ".ts"), decrypted); - fs.unlinkSync(filePath); - fs.del; -} catch (e) { - console.error("Wrong decryption password..."); - process.exit(0); -} +const fs = require("fs"); +const crypto = require("crypto"); +const prompt = require("prompt-sync")({ sigint: true }); + +const algorithm = "aes-256-gcm"; + +function decrypt(data, password) { + const input = Buffer.from(data, "base64"); + + const salt = input.subarray(0, 16); + const iv = input.subarray(16, 28); + const tag = input.subarray(28, 44); + const text = input.subarray(44); + + const key = crypto.scryptSync(password, salt, 32); + + const decipher = crypto.createDecipheriv(algorithm, key, iv); + decipher.setAuthTag(tag); + + const decrypted = Buffer.concat([decipher.update(text), decipher.final()]); + return decrypted.toString("utf8"); +} + +const [, , category, difficulty] = process.argv; + +const map = { + easy: "easy", + medium: "medium", + hard: "hard", +}; + +const categoryOptions = [ + "additional", + "maintainability", + "readability", + "scalability", +]; + +// Is category parameter valid? +if (!category || !categoryOptions.includes(category)) { + console.error( + `Incorrect category flag\n\nExample usage: 'npm run unlock-solution maintainability easy'\n\nOptions are: ${categoryOptions.join(", ")}`, + ); + process.exit(1); +} + +// Is difficulty parameter valid? +const difficultyOptions = Object.keys(map); +if (!difficulty || !difficultyOptions.includes(difficulty)) { + console.error( + `Incorrect category flag\n\nexample usage: 'npm run unlock-solution maintainability easy'\n\nOptions are: ${difficultyOptions.join(", ")}`, + ); + process.exit(1); +} + +const filePath = `solutions/${category}/${map[difficulty]}.ts.enc`; + +if (!fs.existsSync(filePath)) { + console.error("File not found:", filePath); + process.exit(1); +} + +const password = prompt("Enter decryption password: "); + +const encrypted = fs.readFileSync(filePath, "utf8"); + +try { + const decrypted = decrypt(encrypted, password.trim().toLowerCase()); + fs.writeFileSync(filePath.replace(".ts.enc", ".ts"), decrypted); + fs.unlinkSync(filePath); + fs.del; +} catch (e) { + console.error("Wrong decryption password..."); + process.exit(0); +} diff --git a/scripts/run-category.js b/scripts/run-category.cjs similarity index 90% rename from scripts/run-category.js rename to scripts/run-category.cjs index 9d6d2ff..680e9be 100644 --- a/scripts/run-category.js +++ b/scripts/run-category.cjs @@ -1,34 +1,34 @@ -const { execSync } = require("child_process"); - -const category = process.argv[2]; -const difficulty = process.argv[3]; - -const map = { - easy: "1-easy", - medium: "2-medium", - hard: "3-hard", -}; - -// Is category parameter valid? -const categoryOptions = ["maintainability", "readability", "scalability"]; -if (!category || !categoryOptions.includes(category)) { - console.error( - `Incorrect category flag\n\nExample usage: 'npm run test maintainability easy'\n\nOptions are: ${categoryOptions.join(", ")}`, - ); - process.exit(1); -} - -// Is difficulty parameter valid? -const difficultyOptions = Object.keys(map); -if (!difficulty || !difficultyOptions.includes(difficulty)) { - console.error( - `Incorrect category flag\n\nexample usage: 'npm run test maintainability easy'\n\nOptions are: ${difficultyOptions.join(", ")}`, - ); - process.exit(1); -} - -const file = `tasks/${category}/${map[difficulty]}.ts`; - -execSync(`npx tsx ${file}`, { - stdio: "inherit", -}); +const { execSync } = require("child_process"); + +const category = process.argv[2]; +const difficulty = process.argv[3]; + +const map = { + easy: "easy", + medium: "medium", + hard: "hard", +}; + +// Is category parameter valid? +const categoryOptions = ["maintainability", "readability", "scalability"]; +if (!category || !categoryOptions.includes(category)) { + console.error( + `Incorrect category flag\n\nExample usage: 'npm run test maintainability easy'\n\nOptions are: ${categoryOptions.join(", ")}`, + ); + process.exit(1); +} + +// Is difficulty parameter valid? +const difficultyOptions = Object.keys(map); +if (!difficulty || !difficultyOptions.includes(difficulty)) { + console.error( + `Incorrect category flag\n\nexample usage: 'npm run test maintainability easy'\n\nOptions are: ${difficultyOptions.join(", ")}`, + ); + process.exit(1); +} + +const file = `tasks/${category}/${map[difficulty]}.ts`; + +execSync(`npx tsx ${file}`, { + stdio: "inherit", +}); diff --git a/tasks/readability/medium.ts b/tasks/readability/medium.ts index 8df9ba9..412e103 100644 --- a/tasks/readability/medium.ts +++ b/tasks/readability/medium.ts @@ -11,9 +11,8 @@ import assert from "node:assert"; */ const response = await api.get("/user/1"); +const { roles, status, profile } = response.data; -assert( - response.data.roles.includes("admin") && - response.data.status === "active" && - response.data.profile.completed === true, -); +assert(roles.includes("admin"), "Expected user to have admin role"); +assert(status === "active", "Expected user status to be active"); +assert(profile.completed === true, "Expected user profile to be complete");