diff --git a/src/app.ts b/src/app.ts index f69ff38..1497a38 100644 --- a/src/app.ts +++ b/src/app.ts @@ -4,7 +4,8 @@ import jwt from "jsonwebtoken" import cors from "cors" import cookieParser from "cookie-parser" -import sessionRouter from "./routers/session" +import sessionRouter from "./routers/session.js" +import paintingsRouter from "./routers/paintings.js" import { getJwtSecret } from "./utils/jwt.js" @@ -31,7 +32,12 @@ const appRouterGet: RequestHandler = (req, res) => { function initEnvVariables(): void { dotenv.config() - const varsToCheck = ["API_PORT", "FRONT_ORIGIN"] + const varsToCheck = [ + "API_PORT", + "FRONT_ORIGIN", + "JWT_SECRET", + "PARISMUSEES_SECRET", + ] varsToCheck.forEach((varName) => { const variable = process.env[varName] @@ -57,6 +63,7 @@ export function initServer(): express.Express { appRouter.get("/", appRouterGet) appRouter.use("/session/", sessionRouter) + appRouter.use("/paintings/", paintingsRouter) app.use("/v1/", appRouter) diff --git a/src/assets/paintingsUUID.json b/src/assets/paintingsUUID.json new file mode 100644 index 0000000..e03dc12 --- /dev/null +++ b/src/assets/paintingsUUID.json @@ -0,0 +1,38 @@ +{ + "paintings": [ + "3ed35487-0e9b-4068-a10a-2a533cc25b82", + "fea98ea1-2e1b-4c1e-9d55-aa52629619c6", + "bbd92851-7714-41ac-b541-a29b440af61d", + "7cc7e2c5-7ff8-4280-8c33-5e31415af60a", + "445e2c90-c5f4-42a2-abff-c936e2fa9a4e", + "e9573d7a-2b60-4eb7-b9e7-601a706e7bb7", + "95ae6d3a-a7ac-4004-afe3-826badda0c0a", + "9dbd6daf-e763-4df0-832a-c06c9ab525ab", + "b6cdca9f-f549-4561-a456-2fce0d850ab9", + "78a53d20-657f-4e95-b4e2-cfd0cc60d8cb", + "8621cfe3-287e-4e48-a3f4-3a8152c7cab0", + "63ef19bb-33d2-4dc5-b00f-213b9983c014", + "7acf7dd5-9c51-4836-8b56-36c643241e7e", + "5e47c316-4357-4a93-beb9-0f809f242686", + "b6cceae7-4399-4f39-87af-9580ac305b46", + "38955ff8-98fe-41da-adfe-616730d824f7", + "0177cb88-79c4-42c4-ac08-101a868b6826", + "9141320d-1959-44d9-9d9b-1d532bea44cf", + "c0646fe8-4feb-458b-91f9-561f38f5dcba", + "abc00ff4-1449-4952-b778-b6f2aac19df3", + "75c6c920-a3b1-4c30-9af5-96e324ce436b", + "6ac31138-ba35-473b-a594-e86f1188af10", + "be7c291e-d1b7-4050-9db0-584f6e7c364e", + "5f83d5df-b018-4464-9a3f-8c816c7f5443", + "4c88b58a-df5d-4379-ac94-4a4caf1e0f3d", + "4cde562e-aa57-444f-bd6a-3484a17649ef", + "e12191f0-29d4-4959-b1a2-9c3144b29d15", + "47021061-2873-4863-b2ac-d7b54d62b6e3", + "04f3bb58-3e9f-4ba8-9686-399b0e0b5bb2", + "fd62e962-0e81-41e8-be72-2b36c84a47df", + "3e2bf978-c15c-4f59-ae5c-8e211a802bd2", + "94713e84-0613-41b4-9869-cd34ba3e6d71", + "19d2347d-0dfd-402c-8d51-82a1c59fc2e4", + "cbdbed57-4f7e-4b99-a395-60e04c2b4219" + ] +} \ No newline at end of file diff --git a/src/routers/paintings.ts b/src/routers/paintings.ts new file mode 100644 index 0000000..a99f9f4 --- /dev/null +++ b/src/routers/paintings.ts @@ -0,0 +1,78 @@ +import { PrismaClient } from "@prisma/client" +import express, { RequestHandler } from "express" +import { z } from "zod" +import { getPaintingQuery } from "../utils/queries.js" + +import fs from "fs" + +const paintingsRouter = express.Router() +// const prisma = new PrismaClient() + +const paintingParser = z + .object({ + uuid: z.string(), + }) + .required() + +const randomParser = z + .object({ + limit: z.coerce.number().max(10), + }) + .required() + +async function fetchPainting(uuid: string): Promise { + return new Promise((resolve, reject) => { + fetch("https://apicollections.parismusees.paris.fr/graphql", { + method: "POST", + headers: { + "auth-token": process.env.PARISMUSEES_SECRET as string, + }, + body: JSON.stringify({ query: getPaintingQuery(uuid) }), + }) + .then((res) => res.json()) + .then((data) => resolve(data)) + .catch((err) => reject(err)) + }) +} + +const paintingRouterGet: RequestHandler = async (req, res) => { + const parsedPainting = paintingParser.safeParse(req.params) + if (!parsedPainting.success) { + res.status(400).send({ message: "Please provide valid painting UUID." }) + return + } + + const painting = await fetchPainting(parsedPainting.data.uuid) + res.send({ painting }) +} + +const paintingRouterGetRandoms: RequestHandler = async (req, res) => { + const parsedPainting = randomParser.safeParse(req.params) + if (!parsedPainting.success) { + res.status(400).send({ + message: "Please provide valid paintings limit.", + issues: parsedPainting.error.issues, + }) + return + } + + const paintingsUUIDs = JSON.parse( + fs.readFileSync("src/assets/paintingsUUID.json", "utf8") + ) + const randomUUIDs = paintingsUUIDs.paintings + .sort(() => Math.random() - 0.5) + .slice(0, parsedPainting.data.limit) + + const paintings = [] + for (const uuid of randomUUIDs) { + const painting = await fetchPainting(uuid) + paintings.push(painting) + } + + res.send({ paintings }) +} + +paintingsRouter.get("/:uuid", paintingRouterGet) +paintingsRouter.get("/random/:limit", paintingRouterGetRandoms) + +export default paintingsRouter diff --git a/src/utils/queries.ts b/src/utils/queries.ts new file mode 100644 index 0000000..7b828d0 --- /dev/null +++ b/src/utils/queries.ts @@ -0,0 +1,39 @@ +export function getPaintingQuery(uuid: string) { + return ` +{ + nodeQuery( + filter: {conditions: [{field: "uuid", value: "${uuid}"}]} + ) { + entities { + entityUuid + ... on NodeOeuvre { + title + absolutePath + fieldUrlAlias + fieldOeuvreAuteurs { + entity { + fieldAuteurAuteur { + entity { + name + } + } + } + } + fieldVisuels { + entity { + name + vignette + publicUrl + } + } + fieldMusee { + entity { + name + } + } + } + } + } +} +` +}