From 37e4f35e33a042f48f0d740c806f67b94d2c9cd8 Mon Sep 17 00:00:00 2001 From: aronmal Date: Tue, 11 Apr 2023 20:06:55 +0200 Subject: [PATCH] Creating API endpoints --- .../lib/backend/components/getPinFromBody.ts | 18 +++++++ .../lib/backend/components/getPlayer.ts | 21 ++++++++ leaky-ships/pages/api/game/create.ts | 53 +++++++++++++++++++ leaky-ships/pages/api/game/join.ts | 47 ++++++++++++++++ leaky-ships/pages/api/user/data.ts | 23 +++----- leaky-ships/prisma/schema.prisma | 2 +- 6 files changed, 147 insertions(+), 17 deletions(-) create mode 100644 leaky-ships/lib/backend/components/getPinFromBody.ts create mode 100644 leaky-ships/lib/backend/components/getPlayer.ts create mode 100644 leaky-ships/pages/api/game/create.ts create mode 100644 leaky-ships/pages/api/game/join.ts diff --git a/leaky-ships/lib/backend/components/getPinFromBody.ts b/leaky-ships/lib/backend/components/getPinFromBody.ts new file mode 100644 index 0000000..a674f45 --- /dev/null +++ b/leaky-ships/lib/backend/components/getPinFromBody.ts @@ -0,0 +1,18 @@ +import { rejectionErrors } from "../errors" +import sendError, { API } from "./sendError" + +async function getPinFromBody(context: API, next: (pin: string) => void) { + const body = JSON.parse(context.req.body) + if ( + typeof body !== "object" || + !body || + !("pin" in body) || + typeof body.pin !== "string" + ) + return sendError(context, rejectionErrors.noUsername) + const { pin } = body + + return next(pin) +} + +export default getPinFromBody diff --git a/leaky-ships/lib/backend/components/getPlayer.ts b/leaky-ships/lib/backend/components/getPlayer.ts new file mode 100644 index 0000000..4e15e5a --- /dev/null +++ b/leaky-ships/lib/backend/components/getPlayer.ts @@ -0,0 +1,21 @@ +import checkTokenIsValid from "./checkTokenIsValid" +import getPlayerByIdDB from "./getPlayerByIdDB" +import getTokenDB from "./getTokenDB" +import getTokenFromBody from "./getTokenFromBody" +import { API } from "./sendError" +import { Player, Token } from "@prisma/client" + +function getPlayer( + context: API, + next: (player: Player, tokenDB: Token) => void +) { + return getTokenFromBody(context, (accessToken) => { + checkTokenIsValid(context, accessToken, (token) => { + getTokenDB(context, token, (tokenDB) => { + getPlayerByIdDB(context, tokenDB, (player) => next(player, tokenDB)) + }) + }) + }) +} + +export default getPlayer diff --git a/leaky-ships/pages/api/game/create.ts b/leaky-ships/pages/api/game/create.ts new file mode 100644 index 0000000..fc9c386 --- /dev/null +++ b/leaky-ships/pages/api/game/create.ts @@ -0,0 +1,53 @@ +import sendError from "@backend/components/sendError" +import sendResponse from "@backend/components/sendResponse" +import getPlayer from "@lib/backend/components/getPlayer" +import prisma from "@lib/prisma" +import type { Game } from "@prisma/client" +import type { NextApiRequest, NextApiResponse } from "next" + +interface Data { + game: Game +} + +export default async function create( + req: NextApiRequest, + res: NextApiResponse +) { + const context = { req, res } + + return getPlayer(context, async (player) => { + // Generate a random 4-digit code + const pin = Math.floor(Math.random() * 10000) + .toString() + .padStart(4, "0") + const game = await prisma.game.create({ + data: { + pin: { + create: { + pin, + }, + }, + players: { + create: { + isOwner: true, + playerId: player.id, + }, + }, + }, + include: { + pin: true, + players: true, + }, + }) + // Generate a random 4-digit code + const code = Math.floor(Math.random() * 10000) + + console.log(code) // Output: a random 4-digit code, e.g. 5678 + + sendResponse(context, { + message: `Player: ${player.id} created game: ${game.id}`, + body: { game }, + type: ["debug", "infoCyan"], + }) + }).catch((err) => sendError(context, err)) +} diff --git a/leaky-ships/pages/api/game/join.ts b/leaky-ships/pages/api/game/join.ts new file mode 100644 index 0000000..c2c63d0 --- /dev/null +++ b/leaky-ships/pages/api/game/join.ts @@ -0,0 +1,47 @@ +import sendError from "@backend/components/sendError" +import sendResponse from "@backend/components/sendResponse" +import getPinFromBody from "@lib/backend/components/getPinFromBody" +import getPlayer from "@lib/backend/components/getPlayer" +import prisma from "@lib/prisma" +import type { Game } from "@prisma/client" +import type { NextApiRequest, NextApiResponse } from "next" + +interface Data { + game: Game +} + +export default async function join( + req: NextApiRequest, + res: NextApiResponse +) { + const context = { req, res } + + return getPinFromBody(context, (pin) => + getPlayer(context, async (player) => { + const { game } = await prisma.gamepin.update({ + where: { + pin, + }, + data: { + game: { + update: { + players: { + create: { + isOwner: false, + playerId: player.id, + }, + }, + }, + }, + }, + include: { game: true }, + }) + + sendResponse(context, { + message: `Player: ${player.id} joined game: ${game.id}`, + body: { game }, + type: ["debug", "infoCyan"], + }) + }) + ).catch((err) => sendError(context, err)) +} diff --git a/leaky-ships/pages/api/user/data.ts b/leaky-ships/pages/api/user/data.ts index b41de97..e810c9e 100644 --- a/leaky-ships/pages/api/user/data.ts +++ b/leaky-ships/pages/api/user/data.ts @@ -1,9 +1,6 @@ -import checkTokenIsValid from "@backend/components/checkTokenIsValid" -import getPlayerByIdDB from "@backend/components/getPlayerByIdDB" -import getTokenDB from "@backend/components/getTokenDB" -import getTokenFromBody from "@backend/components/getTokenFromBody" import sendError from "@backend/components/sendError" import sendResponse from "@backend/components/sendResponse" +import getPlayer from "@lib/backend/components/getPlayer" import type { Game } from "@prisma/client" import type { NextApiRequest, NextApiResponse } from "next" @@ -17,18 +14,12 @@ export default async function data( ) { const context = { req, res } - return getTokenFromBody(context, (accessToken) => { - checkTokenIsValid(context, accessToken, (token) => { - getTokenDB(context, token, (tokenDB) => { - getPlayerByIdDB(context, tokenDB, (player) => { - const games: any = {} - sendResponse(context, { - message: `Requested data of user: ${player.id} with Access-Token: ${tokenDB.id}`, - body: { games }, - type: ["debug", "infoCyan"], - }) - }) - }) + return getPlayer(context, (player, tokenDB) => { + const games: any = {} + sendResponse(context, { + message: `Requested data of user: ${player.id} with Access-Token: ${tokenDB.id}`, + body: { games }, + type: ["debug", "infoCyan"], }) }).catch((err) => sendError(context, err)) } diff --git a/leaky-ships/prisma/schema.prisma b/leaky-ships/prisma/schema.prisma index bf71764..f3e9ce4 100644 --- a/leaky-ships/prisma/schema.prisma +++ b/leaky-ships/prisma/schema.prisma @@ -69,7 +69,7 @@ model Move { model Gamepin { id String @id @default(cuid()) createdAt DateTime @default(now()) - pin Int @unique + pin String @unique gameId String @unique game Game @relation(fields: [gameId], references: [id]) }