feat: initialize Express application with middleware and routes

- Set up Express application in src/app.ts with CORS, JSON parsing, and logging.
- Implement health check route.
- Add authentication, product, and order routes.
- Create error handling middleware for centralized error management.

feat: add authentication middleware with placeholder endpoints

- Implement /register and /login routes in src/middleware/auth.middleware.ts with 501 status responses.

feat: create error handling middleware

- Add error handling middleware in src/middleware/error.middleware.ts to manage errors and send appropriate responses.

feat: implement server startup logic

- Create server entry point in src/server.ts to connect to the database and start the Express server.

feat: add JWT utility functions for token signing and verification

- Implement JWT signing and verification functions in src/utils/jwt.ts with payload interface for user roles.
This commit is contained in:
2026-01-12 23:24:43 +03:00
parent 9e65d2f2d5
commit 95c24b9925
7 changed files with 386 additions and 64 deletions
+8 -1
View File
@@ -18,18 +18,25 @@
"license": "ISC",
"packageManager": "[email protected]",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^17.2.3",
"express": "^5.2.1",
"mongoose": "^9.1.3"
"express-rate-limit": "^8.2.1",
"mongoose": "^9.1.3",
"morgan": "^1.10.1"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@eslint/json": "^0.14.0",
"@eslint/markdown": "^7.5.1",
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/jsonwebtoken": "^9.0.10",
"@types/morgan": "^1.9.10",
"@types/node": "^25.0.6",
"eslint": "^9.39.2",
"globals": "^17.0.0",
"jsonwebtoken": "^9.0.3",
"nodemon": "^3.1.11",
"prettier": "^3.7.4",
"ts-node": "^10.9.2",
+282 -63
View File
@@ -8,15 +8,24 @@ importers:
.:
dependencies:
cors:
specifier: ^2.8.5
version: 2.8.5
dotenv:
specifier: ^17.2.3
version: 17.2.3
express:
specifier: ^5.2.1
version: 5.2.1
express-rate-limit:
specifier: ^8.2.1
version: 8.2.1([email protected])
mongoose:
specifier: ^9.1.3
version: 9.1.3
morgan:
specifier: ^1.10.1
version: 1.10.1
devDependencies:
'@eslint/js':
specifier: ^9.39.2
@@ -27,9 +36,18 @@ importers:
'@eslint/markdown':
specifier: ^7.5.1
version: 7.5.1
'@types/cors':
specifier: ^2.8.19
version: 2.8.19
'@types/express':
specifier: ^5.0.6
version: 5.0.6
'@types/jsonwebtoken':
specifier: ^9.0.10
version: 9.0.10
'@types/morgan':
specifier: ^1.9.10
version: 1.9.10
'@types/node':
specifier: ^25.0.6
version: 25.0.6
@@ -39,6 +57,9 @@ importers:
globals:
specifier: ^17.0.0
version: 17.0.0
jsonwebtoken:
specifier: ^9.0.3
version: 9.0.3
nodemon:
specifier: ^3.1.11
version: 3.1.11
@@ -53,7 +74,7 @@ importers:
version: 5.9.3
typescript-eslint:
specifier: ^8.52.0
version: 8.52.0([email protected])([email protected])
version: 8.53.0([email protected])([email protected])
packages:
@@ -158,6 +179,9 @@ packages:
'@types/[email protected]':
resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
'@types/[email protected]':
resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==}
'@types/[email protected]':
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
@@ -176,9 +200,15 @@ packages:
'@types/[email protected]':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/[email protected]':
resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==}
'@types/[email protected]':
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
'@types/[email protected]':
resolution: {integrity: sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA==}
'@types/[email protected]':
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
@@ -206,63 +236,63 @@ packages:
'@types/[email protected]':
resolution: {integrity: sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==}
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@typescript-eslint/parser': ^8.52.0
'@typescript-eslint/parser': ^8.53.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/[email protected]2.0':
resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==}
'@typescript-eslint/[email protected]3.0':
resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
[email protected]:
@@ -303,6 +333,10 @@ packages:
[email protected]:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
[email protected]:
resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
engines: {node: '>= 0.8'}
[email protected]:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
@@ -325,6 +359,9 @@ packages:
resolution: {integrity: sha512-Kwc6Wh4lQ5OmkqqKhYGKIuELXl+EPYSCObVE6bWsp1T/cGkOCBN0I8wF/T44BiuhHyNi1mmKVPXk60d41xZ7kw==}
engines: {node: '>=20.19.0'}
[email protected]:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
[email protected]:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
@@ -381,6 +418,10 @@ packages:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
[email protected]:
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
engines: {node: '>= 0.10'}
[email protected]:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
@@ -388,6 +429,14 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
[email protected]:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
[email protected]:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
@@ -426,6 +475,9 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
[email protected]:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
[email protected]:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@@ -502,6 +554,12 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
[email protected]:
resolution: {integrity: sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==}
engines: {node: '>= 16'}
peerDependencies:
express: '>= 4.11'
[email protected]:
resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
engines: {node: '>= 18'}
@@ -647,6 +705,10 @@ packages:
[email protected]:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
[email protected]:
resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==}
engines: {node: '>= 12'}
[email protected]:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
@@ -686,6 +748,16 @@ packages:
[email protected]:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
[email protected]:
resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==}
engines: {node: '>=12', npm: '>=6'}
[email protected]:
resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
[email protected]:
resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
[email protected]:
resolution: {integrity: sha512-RKhaOBSPN8L7y4yAgNhDT2602G5FD6QbOIISbjN9D6mjHPeqeg7K+EB5IGSU5o81/X2Gzm3ICnAvQW3x3OP8HA==}
engines: {node: '>=18.0.0'}
@@ -701,9 +773,30 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
[email protected]:
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
[email protected]:
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
[email protected]:
resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
[email protected]:
resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==}
[email protected]:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
[email protected]:
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
[email protected]:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
[email protected]:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
[email protected]:
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
@@ -901,6 +994,10 @@ packages:
resolution: {integrity: sha512-vIKt/qjdgXt0C/75g8/ROLY+o5rrVsjqwmo1C9qpGYIpJQI9KLZjuBXJTyL+8RXH2cGFumADCd7PIE3mry3ibw==}
engines: {node: '>=20.19.0'}
[email protected]:
resolution: {integrity: sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==}
engines: {node: '>= 0.8.0'}
[email protected]:
resolution: {integrity: sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==}
engines: {node: '>=4.0.0'}
@@ -909,6 +1006,9 @@ packages:
resolution: {integrity: sha512-b2KQNsmgtkscfeDgkYMcWGn9vZI9YoXh802VDEwE6qc50zxBFQ0Oo8ROkawbPAsXCY1/Z1yp0MagqsZStPWJjw==}
engines: {node: '>=20.19.0'}
[email protected]:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
[email protected]:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -928,14 +1028,26 @@ packages:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
[email protected]:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
[email protected]:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
[email protected]:
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
engines: {node: '>= 0.8'}
[email protected]:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
[email protected]:
resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==}
engines: {node: '>= 0.8'}
[email protected]:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
@@ -1022,6 +1134,12 @@ packages:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
[email protected]:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
[email protected]:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
[email protected]:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
@@ -1139,8 +1257,8 @@ packages:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'}
[email protected]2.0:
resolution: {integrity: sha512-atlQQJ2YkO4pfTVQmQ+wvYQwexPDOIgo+RaVcD7gHgzy/IQA+XTyuxNM9M9TVXvttkF7koBHmcwisKdOAf2EcA==}
[email protected]3.0:
resolution: {integrity: sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -1330,6 +1448,10 @@ snapshots:
dependencies:
'@types/node': 25.0.6
'@types/[email protected]':
dependencies:
'@types/node': 25.0.6
'@types/[email protected]':
dependencies:
'@types/ms': 2.1.0
@@ -1353,10 +1475,19 @@ snapshots:
'@types/[email protected]': {}
'@types/[email protected]':
dependencies:
'@types/ms': 2.1.0
'@types/node': 25.0.6
'@types/[email protected]':
dependencies:
'@types/unist': 3.0.3
'@types/[email protected]':
dependencies:
'@types/node': 25.0.6
'@types/[email protected]': {}
'@types/[email protected]':
@@ -1384,14 +1515,14 @@ snapshots:
dependencies:
'@types/webidl-conversions': 7.0.3
'@typescript-eslint/[email protected]2.0(@typescript-eslint/[email protected]2.0([email protected])([email protected]))([email protected])([email protected])':
'@typescript-eslint/[email protected]3.0(@typescript-eslint/[email protected]3.0([email protected])([email protected]))([email protected])([email protected])':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 8.52.0([email protected])([email protected])
'@typescript-eslint/scope-manager': 8.52.0
'@typescript-eslint/type-utils': 8.52.0([email protected])([email protected])
'@typescript-eslint/utils': 8.52.0([email protected])([email protected])
'@typescript-eslint/visitor-keys': 8.52.0
'@typescript-eslint/parser': 8.53.0([email protected])([email protected])
'@typescript-eslint/scope-manager': 8.53.0
'@typescript-eslint/type-utils': 8.53.0([email protected])([email protected])
'@typescript-eslint/utils': 8.53.0([email protected])([email protected])
'@typescript-eslint/visitor-keys': 8.53.0
eslint: 9.39.2
ignore: 7.0.5
natural-compare: 1.4.0
@@ -1400,41 +1531,41 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]2.0([email protected])([email protected])':
'@typescript-eslint/[email protected]3.0([email protected])([email protected])':
dependencies:
'@typescript-eslint/scope-manager': 8.52.0
'@typescript-eslint/types': 8.52.0
'@typescript-eslint/typescript-estree': 8.52.0([email protected])
'@typescript-eslint/visitor-keys': 8.52.0
'@typescript-eslint/scope-manager': 8.53.0
'@typescript-eslint/types': 8.53.0
'@typescript-eslint/typescript-estree': 8.53.0([email protected])
'@typescript-eslint/visitor-keys': 8.53.0
debug: 4.4.3([email protected])
eslint: 9.39.2
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]2.0([email protected])':
'@typescript-eslint/[email protected]3.0([email protected])':
dependencies:
'@typescript-eslint/tsconfig-utils': 8.52.0([email protected])
'@typescript-eslint/types': 8.52.0
'@typescript-eslint/tsconfig-utils': 8.53.0([email protected])
'@typescript-eslint/types': 8.53.0
debug: 4.4.3([email protected])
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]2.0':
'@typescript-eslint/[email protected]3.0':
dependencies:
'@typescript-eslint/types': 8.52.0
'@typescript-eslint/visitor-keys': 8.52.0
'@typescript-eslint/types': 8.53.0
'@typescript-eslint/visitor-keys': 8.53.0
'@typescript-eslint/[email protected]2.0([email protected])':
'@typescript-eslint/[email protected]3.0([email protected])':
dependencies:
typescript: 5.9.3
'@typescript-eslint/[email protected]2.0([email protected])([email protected])':
'@typescript-eslint/[email protected]3.0([email protected])([email protected])':
dependencies:
'@typescript-eslint/types': 8.52.0
'@typescript-eslint/typescript-estree': 8.52.0([email protected])
'@typescript-eslint/utils': 8.52.0([email protected])([email protected])
'@typescript-eslint/types': 8.53.0
'@typescript-eslint/typescript-estree': 8.53.0([email protected])
'@typescript-eslint/utils': 8.53.0([email protected])([email protected])
debug: 4.4.3([email protected])
eslint: 9.39.2
ts-api-utils: 2.4.0([email protected])
@@ -1442,14 +1573,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]2.0': {}
'@typescript-eslint/[email protected]3.0': {}
'@typescript-eslint/[email protected]2.0([email protected])':
'@typescript-eslint/[email protected]3.0([email protected])':
dependencies:
'@typescript-eslint/project-service': 8.52.0([email protected])
'@typescript-eslint/tsconfig-utils': 8.52.0([email protected])
'@typescript-eslint/types': 8.52.0
'@typescript-eslint/visitor-keys': 8.52.0
'@typescript-eslint/project-service': 8.53.0([email protected])
'@typescript-eslint/tsconfig-utils': 8.53.0([email protected])
'@typescript-eslint/types': 8.53.0
'@typescript-eslint/visitor-keys': 8.53.0
debug: 4.4.3([email protected])
minimatch: 9.0.5
semver: 7.7.3
@@ -1459,20 +1590,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]2.0([email protected])([email protected])':
'@typescript-eslint/[email protected]3.0([email protected])([email protected])':
dependencies:
'@eslint-community/eslint-utils': 4.9.1([email protected])
'@typescript-eslint/scope-manager': 8.52.0
'@typescript-eslint/types': 8.52.0
'@typescript-eslint/typescript-estree': 8.52.0([email protected])
'@typescript-eslint/scope-manager': 8.53.0
'@typescript-eslint/types': 8.53.0
'@typescript-eslint/typescript-estree': 8.53.0([email protected])
eslint: 9.39.2
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]2.0':
'@typescript-eslint/[email protected]3.0':
dependencies:
'@typescript-eslint/types': 8.52.0
'@typescript-eslint/types': 8.53.0
eslint-visitor-keys: 4.2.1
[email protected]:
@@ -1512,6 +1643,10 @@ snapshots:
[email protected]: {}
[email protected]:
dependencies:
safe-buffer: 5.1.2
[email protected]: {}
[email protected]:
@@ -1543,6 +1678,8 @@ snapshots:
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]:
@@ -1594,6 +1731,11 @@ snapshots:
[email protected]: {}
[email protected]:
dependencies:
object-assign: 4.1.1
vary: 1.1.2
[email protected]: {}
[email protected]:
@@ -1602,6 +1744,10 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
[email protected]:
dependencies:
ms: 2.0.0
[email protected]([email protected]):
dependencies:
ms: 2.1.3
@@ -1632,6 +1778,10 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
[email protected]:
dependencies:
safe-buffer: 5.2.1
[email protected]: {}
[email protected]: {}
@@ -1718,6 +1868,11 @@ snapshots:
[email protected]: {}
[email protected]([email protected]):
dependencies:
express: 5.2.1
ip-address: 10.0.1
[email protected]:
dependencies:
accepts: 2.0.0
@@ -1878,6 +2033,8 @@ snapshots:
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]:
@@ -1906,6 +2063,30 @@ snapshots:
[email protected]: {}
[email protected]:
dependencies:
jws: 4.0.1
lodash.includes: 4.3.0
lodash.isboolean: 3.0.3
lodash.isinteger: 4.0.4
lodash.isnumber: 3.0.3
lodash.isplainobject: 4.0.6
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
semver: 7.7.3
[email protected]:
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
[email protected]:
dependencies:
jwa: 2.0.1
safe-buffer: 5.2.1
[email protected]: {}
[email protected]:
@@ -1921,8 +2102,22 @@ snapshots:
dependencies:
p-locate: 5.0.0
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
@@ -2290,10 +2485,22 @@ snapshots:
- snappy
- socks
[email protected]:
dependencies:
basic-auth: 2.0.1
debug: 2.6.9
depd: 2.0.0
on-finished: 2.3.0
on-headers: 1.1.0
transitivePeerDependencies:
- supports-color
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
@@ -2315,12 +2522,20 @@ snapshots:
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]:
dependencies:
ee-first: 1.1.1
[email protected]:
dependencies:
ee-first: 1.1.1
[email protected]: {}
[email protected]:
dependencies:
wrappy: 1.0.2
@@ -2400,6 +2615,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
@@ -2536,12 +2755,12 @@ snapshots:
media-typer: 1.1.0
mime-types: 3.0.2
[email protected]2.0([email protected])([email protected]):
[email protected]3.0([email protected])([email protected]):
dependencies:
'@typescript-eslint/eslint-plugin': 8.52.0(@typescript-eslint/[email protected]2.0([email protected])([email protected]))([email protected])([email protected])
'@typescript-eslint/parser': 8.52.0([email protected])([email protected])
'@typescript-eslint/typescript-estree': 8.52.0([email protected])
'@typescript-eslint/utils': 8.52.0([email protected])([email protected])
'@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/[email protected]3.0([email protected])([email protected]))([email protected])([email protected])
'@typescript-eslint/parser': 8.53.0([email protected])([email protected])
'@typescript-eslint/typescript-estree': 8.53.0([email protected])
'@typescript-eslint/utils': 8.53.0([email protected])([email protected])
eslint: 9.39.2
typescript: 5.9.3
transitivePeerDependencies:
+31
View File
@@ -0,0 +1,31 @@
import express from "express";
import type { Application } from "express";
import cors from "cors";
import morgan from "morgan";
import { errorHandler } from "./middleware/error.middleware";
import authRoutes from "./routes/auth.routes";
import productRoutes from "./routes/product.routes";
import orderRoutes from "./routes/order.routes";
const app: Application = express();
//global middleware
app.use(cors());
app.use(express.json());
app.use(morgan("dev"));
// health check route
app.get("/health", (req, res) => {
res.status(200).json({ status: "OK" });
});
// routes
app.use("/auth", authRoutes);
app.use("/products", productRoutes);
app.use("/orders", orderRoutes);
// error handling middleware
app.use(errorHandler);
export default app;
+13
View File
@@ -0,0 +1,13 @@
import { Router } from "express";
const router = Router();
router.post("/register", (_req, res) => {
res.status(501).json({ message: "Register endpoint not implemented yet." });
});
router.post("/login", (_req, res) => {
res.status(501).json({ message: "Login endpoint not implemented yet." });
});
export default router;
+18
View File
@@ -0,0 +1,18 @@
import type { Request, Response, NextFunction } from "express";
export function errorHandler(
err: any,
_req: Request,
res: Response,
_next: NextFunction,
) {
console.error(err);
const statusCode = err.statusCode ?? 500;
const message = err.message ?? "Internal Server Error";
res.status(statusCode).json({
error: {
message,
},
});
}
+13
View File
@@ -0,0 +1,13 @@
import app from "./app.js";
import { env } from "./config/env.js";
import { connectDB } from "./config/db.js";
async function startServer() {
await connectDB();
app.listen(env.port, () => {
console.log(`Server is running on port ${env.port}`);
});
}
startServer();
+21
View File
@@ -0,0 +1,21 @@
import * as jwt from "jsonwebtoken";
import { env } from "../config/env.js";
export interface JwtPayload {
sub: string;
role: "admin" | "customer";
}
export function signToken(payload: JwtPayload): string {
return jwt.sign(
payload,
env.jwtSecret.secret as jwt.Secret,
{
expiresIn: env.jwtSecret.expiresIn,
} as jwt.SignOptions,
);
}
export function verifyToken(token: string): JwtPayload {
return jwt.verify(token, env.jwtSecret.secret as jwt.Secret) as JwtPayload;
}