From 306c87fca2aa5c7792ffcb87f574c295b5d5c74a Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Sat, 29 Mar 2025 00:31:25 +0100 Subject: [PATCH] feat: Error handling middleware feat: Ability to get the db variable from everywhere with getDatabase function feat: Hello world when getting root url fix: Now mods model is able to communicate with db fix: fixed a syntax error in routes/mods.js file which caused sending two responses to the client --- package.json | 6 +- pnpm-lock.yaml | 234 ++++++++++++++++++++++++++++++++++++++- server.js | 14 ++- src/controllers/mods.js | 7 +- src/database/index.js | 17 ++- src/middleware/errors.js | 19 ++++ src/models/mod.js | 3 +- src/routes/mods.js | 2 +- src/routes/root.js | 10 ++ src/utils/AppError.js | 22 ++++ 10 files changed, 315 insertions(+), 19 deletions(-) create mode 100644 src/middleware/errors.js create mode 100644 src/routes/root.js create mode 100644 src/utils/AppError.js diff --git a/package.json b/package.json index bda8ae9..1622cf7 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "server.js", "scripts": { "start": "node server.js", + "start-auto": "pnpx nodemon server.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], @@ -12,7 +13,7 @@ "license": "ISC", "packageManager": "pnpm@10.5.2", "dependencies": { - "better-sqlite3": "^11.8.1", + "better-sqlite3": "^11.9.1", "express": "^4.21.2", "mysql": "^2.18.1" }, @@ -20,5 +21,8 @@ "onlyBuiltDependencies": [ "better-sqlite3" ] + }, + "devDependencies": { + "nodemon": "^3.1.9" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 279d16a..9604306 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,14 +9,18 @@ importers: .: dependencies: better-sqlite3: - specifier: ^11.8.1 - version: 11.8.1 + specifier: ^11.9.1 + version: 11.9.1 express: specifier: ^4.21.2 version: 4.21.2 mysql: specifier: ^2.18.1 version: 2.18.1 + devDependencies: + nodemon: + specifier: ^3.1.9 + version: 3.1.9 packages: @@ -24,18 +28,29 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - better-sqlite3@11.8.1: - resolution: {integrity: sha512-9BxNaBkblMjhJW8sMRZxnxVTRgbRmssZW0Oxc1MPBTfiR+WW21e2Mk4qu8CzrcZb1LwPCnFsfDEzq+SNcBU8eg==} + better-sqlite3@11.9.1: + resolution: {integrity: sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==} bignumber.js@9.0.0: resolution: {integrity: sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} @@ -46,6 +61,13 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -61,9 +83,16 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -90,6 +119,15 @@ packages: supports-color: optional: true + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -158,6 +196,10 @@ packages: file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + finalhandler@1.3.1: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} @@ -173,6 +215,11 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -187,10 +234,18 @@ packages: github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -210,6 +265,9 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -220,6 +278,22 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -255,6 +329,9 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -282,6 +359,15 @@ packages: resolution: {integrity: sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==} engines: {node: '>=10'} + nodemon@3.1.9: + resolution: {integrity: sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==} + engines: {node: '>=10'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -300,6 +386,10 @@ packages: path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + prebuild-install@7.1.3: resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} engines: {node: '>=10'} @@ -312,6 +402,9 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -338,6 +431,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -385,6 +482,10 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + sqlstring@2.3.1: resolution: {integrity: sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==} engines: {node: '>= 0.6'} @@ -403,6 +504,10 @@ packages: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + tar-fs@2.1.2: resolution: {integrity: sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==} @@ -410,10 +515,18 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -421,6 +534,9 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -446,17 +562,26 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + array-flatten@1.1.1: {} + balanced-match@1.0.2: {} + base64-js@1.5.1: {} - better-sqlite3@11.8.1: + better-sqlite3@11.9.1: dependencies: bindings: 1.5.0 prebuild-install: 7.1.3 bignumber.js@9.0.0: {} + binary-extensions@2.3.0: {} + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 @@ -484,6 +609,15 @@ snapshots: transitivePeerDependencies: - supports-color + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + buffer@5.7.1: dependencies: base64-js: 1.5.1 @@ -501,8 +635,22 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + chownr@1.1.4: {} + concat-map@0.0.1: {} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -519,6 +667,12 @@ snapshots: dependencies: ms: 2.0.0 + debug@4.4.0(supports-color@5.5.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + decompress-response@6.0.0: dependencies: mimic-response: 3.1.0 @@ -599,6 +753,10 @@ snapshots: file-uri-to-path@1.0.0: {} + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + finalhandler@1.3.1: dependencies: debug: 2.6.9 @@ -617,6 +775,9 @@ snapshots: fs-constants@1.0.0: {} + fsevents@2.3.3: + optional: true + function-bind@1.1.2: {} get-intrinsic@1.3.0: @@ -639,8 +800,14 @@ snapshots: github-from-package@0.0.0: {} + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + gopd@1.2.0: {} + has-flag@3.0.0: {} + has-symbols@1.1.0: {} hasown@2.0.2: @@ -661,12 +828,26 @@ snapshots: ieee754@1.2.1: {} + ignore-by-default@1.0.1: {} + inherits@2.0.4: {} ini@1.3.8: {} ipaddr.js@1.9.1: {} + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + isarray@1.0.0: {} math-intrinsics@1.1.0: {} @@ -687,6 +868,10 @@ snapshots: mimic-response@3.1.0: {} + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + minimist@1.2.8: {} mkdirp-classic@0.5.3: {} @@ -710,6 +895,21 @@ snapshots: dependencies: semver: 7.7.1 + nodemon@3.1.9: + dependencies: + chokidar: 3.6.0 + debug: 4.4.0(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.7.1 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + + normalize-path@3.0.0: {} + object-inspect@1.13.4: {} on-finished@2.4.1: @@ -724,6 +924,8 @@ snapshots: path-to-regexp@0.1.12: {} + picomatch@2.3.1: {} + prebuild-install@7.1.3: dependencies: detect-libc: 2.0.3 @@ -746,6 +948,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + pstree.remy@1.1.8: {} + pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -787,6 +991,10 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -860,6 +1068,10 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 + simple-update-notifier@2.0.0: + dependencies: + semver: 7.7.1 + sqlstring@2.3.1: {} statuses@2.0.1: {} @@ -874,6 +1086,10 @@ snapshots: strip-json-comments@2.0.1: {} + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + tar-fs@2.1.2: dependencies: chownr: 1.1.4 @@ -889,8 +1105,14 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + toidentifier@1.0.1: {} + touch@3.1.1: {} + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -900,6 +1122,8 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 + undefsafe@2.0.5: {} + unpipe@1.0.0: {} util-deprecate@1.0.2: {} diff --git a/server.js b/server.js index bfe5665..b076bd2 100644 --- a/server.js +++ b/server.js @@ -1,11 +1,13 @@ -// --- Define constants --- +// --- Imports --- const express = require("express"); const app = express(); const fs = require("fs"); const path = require("path"); -const { getDatabase } = require('./src/database/index'); +const { getDatabase, connectDatabase } = require('./src/database/index'); +const handleError = require('./src/middleware/errors'); +// --- Define constants --- const config_folder = "config"; const config_file_name = "config.json" @@ -34,13 +36,17 @@ const port = config.port || default_port; console.debug("Port: ", port); // Database connection -db = getDatabase(config.database); -db.connect(); +db = connectDatabase(config.database); // --- Routing --- +app.use("/", require("./src/routes/root")); app.use("/mods", require("./src/routes/mods")); +// -- Error handling --- + +app.use(handleError); + // --- Launch --- app.listen(port, () => { diff --git a/src/controllers/mods.js b/src/controllers/mods.js index e3ebec9..c855b80 100644 --- a/src/controllers/mods.js +++ b/src/controllers/mods.js @@ -5,10 +5,11 @@ async function getAllMods(req, res) { console.debug("Calling controller"); const query_result = await mod_service.getAllMods(); console.debug("Controller OK"); - return res.json(query_result); + res.json(query_result); } catch (error) { - return res.status(500).json({ error: error.message }); + console.debug("Error at controller"); + res.status(500).json({ error: error.message }); } } -module.exports = {getAllMods}; \ No newline at end of file +module.exports = { getAllMods }; \ No newline at end of file diff --git a/src/database/index.js b/src/database/index.js index 7dc3d40..5d3dcfa 100644 --- a/src/database/index.js +++ b/src/database/index.js @@ -1,15 +1,24 @@ const MySQLDatabase = require("./mysql"); const SQLiteDatabase = require("./sqlite"); -function getDatabase(config) { +let db; + +async function connectDatabase(config) { if (config.type === "mysql") { - return new MySQLDatabase(config); + db = new MySQLDatabase(config); } else if (config.type === "sqlite") { - return new SQLiteDatabase(config); + db = new SQLiteDatabase(config); } else { throw new Error("Invalid database type: ", config.type); } + + await db.connect(); + return db; +} + +function getDatabase() { + return db; } -module.exports = { getDatabase }; \ No newline at end of file +module.exports = { getDatabase, connectDatabase }; \ No newline at end of file diff --git a/src/middleware/errors.js b/src/middleware/errors.js new file mode 100644 index 0000000..4d416b4 --- /dev/null +++ b/src/middleware/errors.js @@ -0,0 +1,19 @@ +const AppError = require("../utils/AppError"); + +const handleError = (err, req, res, next) => { + // Send + if (err instanceof AppError) { + return res.status(err.statusCode).json({ + message: err.message, + status: err.status + }); + } + + // Default error + res.status(500).json({ + message: 'Internal server error', + status: 500 + }); +} + +module.exports = handleError; \ No newline at end of file diff --git a/src/models/mod.js b/src/models/mod.js index ae99115..65e55d8 100644 --- a/src/models/mod.js +++ b/src/models/mod.js @@ -1,4 +1,5 @@ -// const db = require("..."); +const { getDatabase } = require('../database/index'); +const db = getDatabase(); async function getAllMods() { console.debug("Calling model"); diff --git a/src/routes/mods.js b/src/routes/mods.js index 9c98f86..6624c8c 100644 --- a/src/routes/mods.js +++ b/src/routes/mods.js @@ -6,7 +6,7 @@ const router = express.Router(); // List mods router.get("/", async (req,res) => { console.debug("Accessing mods list"); - res.send(controller.getAllMods()); + controller.getAllMods(req,res); // res.send("No list yet"); }); diff --git a/src/routes/root.js b/src/routes/root.js new file mode 100644 index 0000000..5f77796 --- /dev/null +++ b/src/routes/root.js @@ -0,0 +1,10 @@ +const express = require("express"); +const controller = require("../controllers/mods"); + +const router = express.Router(); + +router.get('/', (res, req) => { + res.send("Hello there!"); +}); + +module.exports = router; \ No newline at end of file diff --git a/src/utils/AppError.js b/src/utils/AppError.js new file mode 100644 index 0000000..f50f4c9 --- /dev/null +++ b/src/utils/AppError.js @@ -0,0 +1,22 @@ +class AppError extends Error { + constructor(statusCode, message) { + super(message); + this.statusCode = statusCode; + + if (status_code.ToString().startsWith("4")) { + this.status = "fail"; + } else { + this.status = "error"; + } + } +} + +exports.tryCatch = (controller) => async (req, res, next) => { + try { + await controller(req, res, next); + } catch(err) { + next(err); + } +} + +module.exports = AppError; \ No newline at end of file