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