index.ts
import express from "express";
import { listItems, addItem, completeItem } from './routes';
// Configure and start the HTTP server.
const port = 8088;
const app = express();
app.get("/api/list", listItems);
app.post("/api/add", addItem);
app.post("/api/complete", completeItem);
app.listen(port, () => console.log(`Server listening on ${port}`));
routes.ts
import { Request, Response } from "express";
// Description of an individual item in the list.
type Item = {
name: string,
completedAt: number // < 0 if not completed
};
// List of items on the todo list.
// RI: no two items have the same name
const items: Item[] = [];
// Returns a list of all items that are uncompleted or were completed less than
// 5 seconds ago.
export function listItems(_: Request, res: Response) {
const now = Date.now();
const remaining: {name: string, completed: boolean}[] = [];
for (const item of items) {
if (item.completedAt < 0) {
remaining.push({name: item.name, completed: false});
} else if (now - item.completedAt <= 5000) {
remaining.push({name: item.name, completed: true});
} else {
// skip this because it was completed too long ago
}
}
res.send(remaining);
}
// Add the item to the list.
export function addItem(req: Request, res: Response) {
const name = req.query.name;
if (name === undefined || typeof name !== 'string') {
res.status(400).send("missing 'name' parameter");
return;
}
const index = findByName(name);
if (index < 0) {
items.push({name, completedAt: -1});
res.send("added");
} else {
const item = items[index];
if (item.completedAt >= 0) {
item.completedAt = -1; // no longer removed
res.send("re-added");
} else {
res.send("already exists");
}
}
}
// Marks the given item as completed.
export function completeItem(req: Request, res: Response) {
const name = req.query.name;
if (name === undefined || typeof name !== 'string') {
res.status(400).send("missing 'name' parameter");
return;
}
const index = findByName(name);
if (index < 0 || items[index].completedAt >= 0) {
res.status(400).send(`no item called "${name}"`);
return;
}
const item = items[index];
item.completedAt = Date.now();
res.send("completed");
}
// Returns the index of the item with the given name or -1 if none exists.
function findByName(name: string): number {
for (let i = 0; i < items.length; i++) {
if (items[i].name === name)
return i;
}
return -1;
}
Full Code