Skip to content

Commit 4ecb449

Browse files
rinaldo stevenazzirinaldo stevenazzi
authored andcommitted
WIP - add vercel configuration, improve typescript
1 parent 02a5c3a commit 4ecb449

File tree

7 files changed

+64
-63
lines changed

7 files changed

+64
-63
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ yarn-error.log
1313
.idea
1414

1515
#env
16-
.env
16+
.env
17+
18+
dist/
19+
.vercel

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
"name": "speed-puzzle-backend",
33
"version": "0.0.1",
44
"description": "speed puzzle backend",
5-
"main": "dist/index.js",
5+
"main": "src/api/index.ts",
6+
"type": "module",
67
"scripts": {
7-
"dev": "tsx watch src/index.ts",
8-
"build": "tsc -p tsconfig.json",
9-
"start": "node dist/index.js",
8+
"dev": "node src/api/index.ts",
9+
"build": "node -p tsconfig.json",
10+
"start": "node src/api/index.ts",
1011
"typecheck": "tsc -p tsconfig.json --noEmit",
1112
"test": "echo \"Error: no test specified\" && exit 1",
12-
"seed": "tsx src/scripts/seeder.ts"
13+
"seed": "node src/scripts/seeder.ts"
1314
},
1415
"dependencies": {
1516
"@faker-js/faker": "^9.9.0",

src/api/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// api/index.ts
2+
import app from "../index.ts";
3+
export default app;

src/controllers/Global.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import MongoDB from "../services/MongoDB";
2-
import Users, { User } from "../services/Users";
3-
import Scores from "../services/Scores";
4-
import EVENTS from "../constants/events";
1+
import MongoDB from "../services/MongoDB.ts";
2+
import Users from "../services/Users.ts";
3+
import type { User } from "../services/Users.ts";
4+
import Scores from "../services/Scores.ts";
5+
import EVENTS from "../constants/events.ts";
56
import type { Db, ObjectId } from "mongodb";
67

78
// Results using literal event types
@@ -134,9 +135,7 @@ export default class Global {
134135
/**
135136
* Top N scores with their associated user
136137
*/
137-
async getTopScores(
138-
limit = 10
139-
): Promise<
138+
async getTopScores(limit = 10): Promise<
140139
Array<{
141140
score: number;
142141
user: {

src/index.ts

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import express, { Request, Response } from "express";
1+
// src/index.ts
2+
import express from "express";
23
import http from "http";
34
import "dotenv/config";
4-
import Global from "./controllers/Global";
5-
import EVENTS from "./constants/events";
5+
import Global from "./controllers/Global.ts";
6+
import EVENTS from "./constants/events.ts";
67

78
const app = express();
89
const server = http.createServer(app);
9-
1010
const PORT = Number(process.env.API_PORT) || 3000;
1111

1212
const globalController = new Global();
@@ -18,36 +18,37 @@ globalController
1818
app.use(express.json());
1919

2020
app.get("/", (_req, res) => {
21+
console.log("GET /");
2122
res.send("<h1>Hello world</h1>");
2223
});
2324

24-
// --- Score check endpoint (schema-agnostic): checks against global min, does not persist ---
2525
app.post(
2626
"/score",
27-
async (req: Request<{}, {}, { score: number }>, res: Response) => {
27+
async (
28+
req: express.Request<{}, {}, { score: number }>,
29+
res: express.Response
30+
) => {
2831
try {
2932
const { score } = req.body;
3033
const result = await globalController.checkScore(score);
31-
if (result.message === EVENTS.SCORED) {
32-
return res.status(200).send();
33-
}
34-
return res.status(409).send();
34+
return result.message === EVENTS.SCORED
35+
? res.status(200).send()
36+
: res.status(409).send();
3537
} catch (e) {
3638
return res.status(406).send(e);
3739
}
3840
}
3941
);
4042

41-
// --- Create user aligned with mobile schema: { userName, password, score? } ---
4243
app.post(
4344
"/adduser",
4445
async (
45-
req: Request<
46+
req: express.Request<
4647
{},
4748
{},
4849
{ userName: string; password: string; score?: number }
4950
>,
50-
res: Response
51+
res: express.Response
5152
) => {
5253
try {
5354
const { userName, password, score } = req.body;
@@ -56,49 +57,39 @@ app.post(
5657
password,
5758
score,
5859
});
59-
60-
if (result.message === EVENTS.USER_ALREADY_EXIST) {
60+
if (result.message === EVENTS.USER_ALREADY_EXIST)
6161
return res.status(409).send("User Already Exist.");
62-
}
63-
if (result.message === EVENTS.USER_CREATED) {
62+
if (result.message === EVENTS.USER_CREATED)
6463
return res.status(200).json(result.list);
65-
}
6664
return res.send();
6765
} catch (e) {
68-
console.log("index - response 406");
6966
return res.status(406).send(e);
7067
}
7168
}
7269
);
7370

74-
// --- Add a score for a specific user ---
7571
app.post(
7672
"/users/:userName/scores",
7773
async (
78-
req: Request<{ userName: string }, {}, { value: number }>,
79-
res: Response
74+
req: express.Request<{ userName: string }, {}, { value: number }>,
75+
res: express.Response
8076
) => {
8177
try {
8278
const { userName } = req.params;
8379
const { value } = req.body;
84-
85-
if (typeof value !== "number") {
80+
if (typeof value !== "number")
8681
return res.status(400).send("value must be a number");
87-
}
88-
8982
const result = await globalController.addScoreForUser(userName, value);
90-
if (result.message === EVENTS.SCORED && result.created) {
91-
return res.status(201).json({ userId: result.userId, value });
92-
}
93-
return res.status(409).send();
83+
return result.message === EVENTS.SCORED && result.created
84+
? res.status(201).json({ userId: result.userId, value })
85+
: res.status(409).send();
9486
} catch (e) {
9587
return res.status(406).send(e);
9688
}
9789
}
9890
);
9991

100-
// --- Get all users (public) ---
101-
app.get("/users", async (_req: Request, res: Response) => {
92+
app.get("/users", async (_req, res) => {
10293
try {
10394
const list = await globalController.listUsersPublic();
10495
return res.status(200).json(list);
@@ -107,17 +98,18 @@ app.get("/users", async (_req: Request, res: Response) => {
10798
}
10899
});
109100

110-
// --- Get top N scores with user (default 10) ---
111101
app.get(
112102
"/scores/top",
113-
async (req: Request<{}, {}, {}, { limit?: string }>, res: Response) => {
103+
async (
104+
req: express.Request<{}, {}, {}, { limit?: string }>,
105+
res: express.Response
106+
) => {
114107
try {
115108
const raw = req.query.limit;
116109
const parsed = raw ? parseInt(raw, 10) : 10;
117110
const limit = Number.isFinite(parsed)
118111
? Math.min(Math.max(parsed, 1), 50)
119112
: 10;
120-
121113
const rows = await globalController.getTopScores(limit);
122114
return res.status(200).json(rows);
123115
} catch (e) {
@@ -126,6 +118,11 @@ app.get(
126118
}
127119
);
128120

129-
server.listen(PORT, () => {
130-
console.log(`Listening on ${PORT}`);
131-
});
121+
// ❗ run the HTTP listener only when NOT on Vercel
122+
// if (!process.env.VERCEL_ENV) {
123+
// console.log(`Listening on port ${PORT}`);
124+
server.listen(PORT, () => console.log(`Listening on ${PORT}`));
125+
// }
126+
127+
// ✅ expose the Express app for Vercel's /api entry
128+
export default app;

tsconfig.json

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
{
22
"compilerOptions": {
3-
"target": "ES2021",
4-
"module": "commonjs",
5-
"moduleResolution": "node",
6-
"rootDir": "src",
7-
"outDir": "dist",
8-
"strict": true,
9-
"esModuleInterop": true,
10-
"skipLibCheck": true,
11-
"resolveJsonModule": true
12-
},
13-
"include": ["src"],
14-
"exclude": ["dist"]
3+
"noEmit": true, // Optional - see note below
4+
"target": "esnext",
5+
"module": "nodenext",
6+
"rewriteRelativeImportExtensions": true,
7+
"erasableSyntaxOnly": true
8+
// "verbatimModuleSyntax": true
9+
}
1510
}

vercel.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"rewrites": [{ "source": "/(.*)", "destination": "/api" }]
3+
}

0 commit comments

Comments
 (0)