Skip to content

Commit

Permalink
Update dependency upgrades - non-major (#315)
Browse files Browse the repository at this point in the history
* Update dependency upgrades - non-major

* Refactor guest creation and update handlers

* Refactor guest creation and update handlers

* Move types

* Refactor getGuestsHandler

* Refactor guest handlers and move types

* Refactor guest handlers and move types

* Refactor getGuestsHandler

* Add ParamsDictionary

* Change guestList to guests

* Remove params in types

* Update request type

* Update index.ts

* Update index.ts

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Lukas Prochazka <[email protected]>
Co-authored-by: Karl Horky <[email protected]>
  • Loading branch information
3 people authored Aug 2, 2024
1 parent d591a14 commit 372f3b2
Show file tree
Hide file tree
Showing 3 changed files with 438 additions and 395 deletions.
311 changes: 198 additions & 113 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import express from 'express';
import express, { NextFunction, Request, Response } from 'express';
import type { ParamsDictionary } from 'express-serve-static-core';

const app = express();

Expand All @@ -14,138 +15,222 @@ type Guest = {

let id = 1;

const guestList: Guest[] = [];
const guests: Guest[] = [];

// Enable CORS
app.use(function allowCrossDomainRequests(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header(
app.use(function allowCrossDomainRequests(
request: Request,
response: Response,
next: NextFunction,
) {
response.header('Access-Control-Allow-Origin', '*');
response.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept',
);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
response.header(
'Access-Control-Allow-Methods',
'GET, POST, PUT, DELETE, OPTIONS',
);
next();
});

// Get endpoints
app.get('/', function rootHandler(req, res) {
res.json({
guests: `${req.protocol}://${req.get('host')}/guests/`,
});
});

// Get all guests
app.get('/guests', function getGuestsHandler(req, res) {
res.json(guestList);
});

// New guest
app.post('/guests', function postGuestsHandler(req, res) {
if (!req.body.firstName || !req.body.lastName) {
res.status(400).json({
errors: [
{ message: 'Request body missing a firstName or lastName property' },
],
app.get(
'/',
function rootHandler(
request: Request,
response: Response<{ guests: string }>,
) {
response.json({
guests: `${request.protocol}://${request.get('host')}/guests/`,
});
return;
}

if (Object.keys(req.body).length > 3) {
res.status(400).json({
errors: [
{
message:
'Request body contains more than firstName, lastName and deadline properties',
},
],
});
return;
}
},
);

const guest = {
id: String(id++),
firstName: req.body.firstName,
lastName: req.body.lastName,
...(req.body.deadline ? { deadline: req.body.deadline } : {}),
attending: false,
};
type GuestsResponseBodyGet = Guest[];

guestList.push(guest);
// Get all guests
app.get(
'/guests',
function getGuestsHandler(
request: Request,
response: Response<GuestsResponseBodyGet>,
) {
response.json(guests);
},
);

type GuestRequestBodyPost = {
firstName: string;
lastName: string;
deadline?: string;
};

res.json(guest);
});
type GuestResponseBodyPost =
| Guest
| {
errors: { message: string }[];
};

// New guest
app.post(
'/guests',
function postGuestsHandler(
request: Request<ParamsDictionary, GuestResponseBodyPost, GuestRequestBodyPost>,
response: Response<GuestResponseBodyPost>,
) {
if (!request.body.firstName || !request.body.lastName) {
response.status(400).json({
errors: [
{
message: 'Request body missing a firstName or lastName property',
},
],
});
return;
}

if (Object.keys(request.body).length > 3) {
response.status(400).json({
errors: [
{
message:
'Request body contains more than firstName, lastName and deadline properties',
},
],
});
return;
}

const guest = {
id: String(id++),
firstName: request.body.firstName,
lastName: request.body.lastName,
...(request.body.deadline ? { deadline: request.body.deadline } : {}),
attending: false,
};

guests.push(guest);

response.json(guest);
},
);

type GuestResponseBodyGet =
| Guest
| {
errors: { message: string }[];
};

// Get a single guest
app.get('/guests/:id', function getGuestHandler(req, res) {
const guest = guestList.find(
(currentGuest) => currentGuest.id === req.params.id,
);
app.get(
'/guests/:id',
function getGuestHandler(
request: Request<{ id: string }>,
response: Response<GuestResponseBodyGet>,
) {
const guest = guests.find(
(currentGuest) => currentGuest.id === request.params.id,
);

if (!guest) {
response.status(404).json({
errors: [{ message: `Guest ${request.params.id} not found` }],
});
return;
}
response.json(guest);
},
);

type GuestRequestBodyPut = {
firstName: string;
lastName: string;
deadline?: string;
attending: boolean;
};

if (!guest) {
res
.status(404)
.json({ errors: [{ message: `Guest ${req.params.id} not found` }] });
return;
}
res.json(guest);
});
type GuestResponseBodyPut =
| Guest
| {
errors: { message: string }[];
};

// Modify a single guest
app.put('/guests/:id', function putGuestHandler(req, res) {
const allowedKeys = ['firstName', 'lastName', 'deadline', 'attending'];
const difference = Object.keys(req.body).filter(
(key) => !allowedKeys.includes(key),
);

if (difference.length > 0) {
res.status(400).json({
errors: [
{
message: `Request body contains more than allowed properties (${allowedKeys.join(
', ',
)}). The request also contains these extra keys that are not allowed: ${difference.join(
', ',
)}`,
},
],
});
return;
}

const guest = guestList.find(
(currentGuest) => currentGuest.id === req.params.id,
);

if (!guest) {
res
.status(404)
.json({ errors: [{ message: `Guest ${req.params.id} not found` }] });
return;
}

if (req.body.firstName) guest.firstName = req.body.firstName;
if (req.body.lastName) guest.lastName = req.body.lastName;
if (req.body.deadline) guest.deadline = req.body.deadline;
if ('attending' in req.body) guest.attending = req.body.attending;
res.json(guest);
});
app.put(
'/guests/:id',
function putGuestHandler(
request: Request<{ id: string }, GuestResponseBodyPut, GuestRequestBodyPut>,
response: Response<GuestResponseBodyPut>,
) {
const allowedKeys = ['firstName', 'lastName', 'deadline', 'attending'];
const difference = Object.keys(request.body).filter(
(key) => !allowedKeys.includes(key),
);

if (difference.length > 0) {
response.status(400).json({
errors: [
{
message: `Request body contains more than allowed properties (${allowedKeys.join(
', ',
)}). The request also contains these extra keys that are not allowed: ${difference.join(
', ',
)}`,
},
],
});
return;
}

const guest = guests.find(
(currentGuest) => currentGuest.id === request.params.id,
);

if (!guest) {
response.status(404).json({
errors: [{ message: `Guest ${request.params.id} not found` }],
});
return;
}

if (request.body.firstName) guest.firstName = request.body.firstName;
if (request.body.lastName) guest.lastName = request.body.lastName;
if (request.body.deadline) guest.deadline = request.body.deadline;
if ('attending' in request.body) guest.attending = request.body.attending;
response.json(guest);
},
);

type GuestResponseBodyDelete =
| Guest
| {
errors: { message: string }[];
};

// Delete a single guest
app.delete('/guests/:id', function deleteGuestHandler(req, res) {
const guest = guestList.find(
(currentGuest) => currentGuest.id === req.params.id,
);

if (!guest) {
res
.status(404)
.json({ errors: [{ message: `Guest ${req.params.id} not found` }] });
return;
}

guestList.splice(guestList.indexOf(guest), 1);
res.json(guest);
});
app.delete(
'/guests/:id',
function deleteGuestHandler(
request: Request<{ id: string }>,
response: Response<GuestResponseBodyDelete>,
) {
const guest = guests.find(
(currentGuest) => currentGuest.id === request.params.id,
);

if (!guest) {
response.status(404).json({
errors: [{ message: `Guest ${request.params.id} not found` }],
});
return;
}

guests.splice(guests.indexOf(guest), 1);
response.json(guest);
},
);

app.listen(process.env.PORT || 4000, () => {
console.log('🚀 Guest list server started on http://localhost:4000');
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@
},
"dependencies": {
"@types/express": "4.17.21",
"@types/express-serve-static-core": "^4.19.5",
"express": "4.19.2",
"tsx": "4.16.2"
"tsx": "4.16.5"
},
"devDependencies": {
"@types/node": "22.0.3",
"eslint": "9.6.0",
"eslint-config-upleveled": "8.5.0",
"typescript": "5.5.3"
"eslint": "9.8.0",
"eslint-config-upleveled": "8.6.14",
"typescript": "5.5.4"
},
"engines": {
"node": ">=20.9.0"
},
"packageManager": "pnpm@9.5.0"
"packageManager": "pnpm@9.6.0"
}
Loading

0 comments on commit 372f3b2

Please sign in to comment.