Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
DeikuModder committed Nov 29, 2023
0 parents commit 881326b
Show file tree
Hide file tree
Showing 12 changed files with 2,276 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.http
index.html
98 changes: 98 additions & 0 deletions build/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const node_crypto_1 = __importDefault(require("node:crypto"));
const cors_1 = __importDefault(require("cors"));
const movies_json_1 = __importDefault(require("./src/movies.json"));
const movie_1 = require("./src/schemas/movie");
const moviesCollection = movies_json_1.default;
const PORT = process.env.PORT || 1235;
const app = (0, express_1.default)();
app.disable("x-powered-by");
//middleware that helps with cors error, and specifying the origins that has access to the api
app.use((0, cors_1.default)({
origin: (origin, callback) => {
const ACCEPTED_ORIGINS = [
"http://127.0.0.1:5500",
"http://localhost:1235",
"https://movies.com",
"https://midu.dev",
];
if (ACCEPTED_ORIGINS.includes(origin)) {
return callback(null, true);
}
if (!origin) {
return callback(null, true);
}
return callback(new Error("Not allowed by CORS"));
},
}));
app.use(express_1.default.json()); // for parsing application/json
app.get("/", (_req, res) => {
res.send("Hello Typescript!");
});
// will get all MOVIES resources
app.get("/movies", (req, res) => {
const { genre, page } = req.query; // for the movies endpoint this will get all queries
if (genre) {
const filteredMovies = moviesCollection.filter((movie) => movie.genre.some((g) => g.toLowerCase() === genre.toString().toLowerCase()));
return res.json(filteredMovies);
}
if (page) {
const movieIndex = page;
if (movieIndex > moviesCollection.length) {
return res.send(404).json({ message: "Movie not found" });
}
return res.json(moviesCollection[movieIndex]);
}
res.json(moviesCollection);
});
// get movie by its id
app.get("/movies/:id", (req, res) => {
const { id } = req.params; // express internally uses path-to-regexp
const movie = moviesCollection.find((movie) => movie.id === id);
movie ? res.json(movie) : res.status(404).send("Movie not found");
});
app.post("/movies", (req, res) => {
const result = (0, movie_1.validateMovie)(req.body);
if (!result.success) {
return res.status(400).json({ error: JSON.parse(result.error.message) });
}
const newMovie = Object.assign({ id: node_crypto_1.default.randomUUID() }, result.data);
// this wouldn't be REST, since we're storing data in the application memory
// the correct way to do it would be storing it in a database
moviesCollection.push(newMovie);
res.status(201).json(newMovie);
});
app.patch("/movies/:id", (req, res) => {
const result = (0, movie_1.validatePartialMovie)(req.body);
if (!result.success) {
return res.status(400).json({ error: JSON.parse(result.error.message) });
}
const { id } = req.params;
const movieIndex = moviesCollection.findIndex((movie) => movie.id === id);
if (movieIndex < 0) {
return res.status(404).json({ message: "Movie not found" });
}
const updateMovie = Object.assign(Object.assign({}, moviesCollection[movieIndex]), result.data);
moviesCollection[movieIndex] = updateMovie;
return res.json(updateMovie);
});
app.delete("/movies/:id", (req, res) => {
const { id } = req.params;
const movieIndex = moviesCollection.findIndex((movie) => movie.id === id);
if (movieIndex < 0) {
return res.status(404).json({ message: "Movie not found." });
}
moviesCollection.splice(movieIndex, 1);
return res.json({ message: "Movie deleted" });
});
app.use((_req, res) => {
res.status(404).send("404 not found");
});
app.listen(PORT, () => {
console.log(`server listening on http://localhost:${PORT}`);
});
152 changes: 152 additions & 0 deletions build/src/movies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
[
{
"id": "dcdd0fad-a94c-4810-8acc-5f108d3b18c3",
"title": "The Shawshank Redemption",
"year": 1994,
"director": "Frank Darabont",
"duration": 142,
"poster": "https://i.ebayimg.com/images/g/4goAAOSwMyBe7hnQ/s-l1200.webp",
"genre": ["Drama"],
"rate": 9.3
},
{
"id": "c8a7d63f-3b04-44d3-9d95-8782fd7dcfaf",
"title": "The Dark Knight",
"year": 2008,
"director": "Christopher Nolan",
"duration": 152,
"poster": "https://i.ebayimg.com/images/g/yokAAOSw8w1YARbm/s-l1200.jpg",
"genre": ["Action", "Crime", "Drama"],
"rate": 9.0
},
{
"id": "5ad1a235-0d9c-410a-b32b-220d91689a08",
"title": "Inception",
"year": 2010,
"director": "Christopher Nolan",
"duration": 148,
"poster": "https://m.media-amazon.com/images/I/91Rc8cAmnAL._AC_UF1000,1000_QL80_.jpg",
"genre": ["Action", "Adventure", "Sci-Fi"],
"rate": 8.8
},
{
"id": "241bf55d-b649-4109-af7c-0e6890ded3fc",
"title": "Pulp Fiction",
"year": 1994,
"director": "Quentin Tarantino",
"duration": 154,
"poster": "https://www.themoviedb.org/t/p/original/vQWk5YBFWF4bZaofAbv0tShwBvQ.jpg",
"genre": ["Crime", "Drama"],
"rate": 8.9
},
{
"id": "9e6106f0-848b-4810-a11a-3d832a5610f9",
"title": "Forrest Gump",
"year": 1994,
"director": "Robert Zemeckis",
"duration": 142,
"poster": "https://i.ebayimg.com/images/g/qR8AAOSwkvRZzuMD/s-l1600.jpg",
"genre": ["Drama", "Romance"],
"rate": 8.8
},
{
"id": "7e3fd5ab-60ff-4ae2-92b6-9597f0308d1",
"title": "Gladiator",
"year": 2000,
"director": "Ridley Scott",
"duration": 155,
"poster": "https://img.fruugo.com/product/0/60/14417600_max.jpg",
"genre": ["Action", "Adventure", "Drama"],
"rate": 8.5
},
{
"id": "c906673b-3948-4402-ac7f-73ac3a9e3105",
"title": "The Matrix",
"year": 1999,
"director": "Lana Wachowski",
"duration": 136,
"poster": "https://i.ebayimg.com/images/g/QFQAAOSwAQpfjaA6/s-l1200.jpg",
"genre": ["Action", "Sci-Fi"],
"rate": 8.7
},
{
"id": "b6e03689-cccd-478e-8565-d92f40813b13",
"title": "Interstellar",
"year": 2014,
"director": "Christopher Nolan",
"duration": 169,
"poster": "https://m.media-amazon.com/images/I/91obuWzA3XL._AC_UF1000,1000_QL80_.jpg",
"genre": ["Adventure", "Drama", "Sci-Fi"],
"rate": 8.6
},
{
"id": "aa391090-b938-42eb-b520-86ea0aa3917b",
"title": "The Lord of the Rings: The Return of the King",
"year": 2003,
"director": "Peter Jackson",
"duration": 201,
"poster": "https://i.ebayimg.com/images/g/0hoAAOSwe7peaMLW/s-l1600.jpg",
"genre": ["Action", "Adventure", "Drama"],
"rate": 8.9
},
{
"id": "2e6900e2-0b48-4fb6-ad48-09c7086e54fe",
"title": "The Lion King",
"year": 1994,
"director": "Roger Allers, Rob Minkoff",
"duration": 88,
"poster": "https://m.media-amazon.com/images/I/81BMmrwSFOL._AC_UF1000,1000_QL80_.jpg",
"genre": ["Animation", "Adventure", "Drama"],
"rate": 8.5
},
{
"id": "04986507-b3ed-442c-8ae7-4c5df804f896",
"title": "The Avengers",
"year": 2012,
"director": "Joss Whedon",
"duration": 143,
"poster": "https://img.fruugo.com/product/7/41/14532417_max.jpg",
"genre": ["Action", "Adventure", "Sci-Fi"],
"rate": 8.0
},
{
"id": "7d2832f8-c70a-410e-8963-4c93bf36cc9c",
"title": "Jurassic Park",
"year": 1993,
"director": "Steven Spielberg",
"duration": 127,
"poster": "https://vice-press.com/cdn/shop/products/Jurassic-Park-Editions-poster-florey.jpg?v=1654518755&width=1024",
"genre": ["Adventure", "Sci-Fi"],
"rate": 8.1
},
{
"id": "ccf36f2e-8566-47f7-912d-9f4647250bc7",
"title": "Titanic",
"year": 1997,
"director": "James Cameron",
"duration": 195,
"poster": "https://i.pinimg.com/originals/42/42/65/4242658e6f1b0d6322a4a93e0383108b.png",
"genre": ["Drama", "Romance"],
"rate": 7.8
},
{
"id": "8fb17ae1-bdfe-45e5-a871-4772d7e526b8",
"title": "The Social Network",
"year": 2010,
"director": "David Fincher",
"duration": 120,
"poster": "https://i.pinimg.com/originals/7e/37/b9/7e37b994b613e94cba64f307b1983e39.jpg",
"genre": ["Biography", "Drama"],
"rate": 7.7
},
{
"id": "6a360a18-c645-4b47-9a7b-2a71babbf3e0",
"title": "Avatar",
"year": 2009,
"director": "James Cameron",
"duration": 162,
"poster": "https://i.etsystatic.com/35681979/r/il/dfe3ba/3957859451/il_fullxfull.3957859451_h27r.jpg",
"genre": ["Action", "Adventure", "Fantasy"],
"rate": 7.8
}
]
46 changes: 46 additions & 0 deletions build/src/schemas/movie.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validatePartialMovie = exports.validateMovie = void 0;
const zod_1 = __importDefault(require("zod"));
// using zod package, this will make validations to ensure that client is passing the correct information
const movieSchema = zod_1.default.object({
title: zod_1.default.string({
invalid_type_error: "Movie title must be a string",
required_error: "Movie title is required",
}),
year: zod_1.default.number().int().min(1900).max(2024),
director: zod_1.default.string(),
duration: zod_1.default.number().int().positive(),
rate: zod_1.default.number().min(0).max(10).default(0),
poster: zod_1.default.string().url({
message: "Poster must be a valid url",
}),
genre: zod_1.default.array(zod_1.default.enum([
"Action",
"Adventure",
"Sci-Fi",
"Drama",
"Romance",
"Animation",
"Comedy",
"Biography",
"Crime",
"Documentary",
"Fantasy",
"Horror",
"Mystery",
"Thriller",
])),
});
function validateMovie(object) {
return movieSchema.safeParse(object);
}
exports.validateMovie = validateMovie;
// will make all properties optional
function validatePartialMovie(object) {
return movieSchema.partial().safeParse(object);
}
exports.validatePartialMovie = validatePartialMovie;
Loading

0 comments on commit 881326b

Please sign in to comment.