Creating API endpoints
This commit is contained in:
parent
85fb7cfa7a
commit
37e4f35e33
6 changed files with 147 additions and 17 deletions
18
leaky-ships/lib/backend/components/getPinFromBody.ts
Normal file
18
leaky-ships/lib/backend/components/getPinFromBody.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { rejectionErrors } from "../errors"
|
||||||
|
import sendError, { API } from "./sendError"
|
||||||
|
|
||||||
|
async function getPinFromBody<T>(context: API<T>, 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
|
21
leaky-ships/lib/backend/components/getPlayer.ts
Normal file
21
leaky-ships/lib/backend/components/getPlayer.ts
Normal file
|
@ -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<T>(
|
||||||
|
context: API<T>,
|
||||||
|
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
|
53
leaky-ships/pages/api/game/create.ts
Normal file
53
leaky-ships/pages/api/game/create.ts
Normal file
|
@ -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<Data>
|
||||||
|
) {
|
||||||
|
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))
|
||||||
|
}
|
47
leaky-ships/pages/api/game/join.ts
Normal file
47
leaky-ships/pages/api/game/join.ts
Normal file
|
@ -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<Data>
|
||||||
|
) {
|
||||||
|
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))
|
||||||
|
}
|
|
@ -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 sendError from "@backend/components/sendError"
|
||||||
import sendResponse from "@backend/components/sendResponse"
|
import sendResponse from "@backend/components/sendResponse"
|
||||||
|
import getPlayer from "@lib/backend/components/getPlayer"
|
||||||
import type { Game } from "@prisma/client"
|
import type { Game } from "@prisma/client"
|
||||||
import type { NextApiRequest, NextApiResponse } from "next"
|
import type { NextApiRequest, NextApiResponse } from "next"
|
||||||
|
|
||||||
|
@ -17,18 +14,12 @@ export default async function data(
|
||||||
) {
|
) {
|
||||||
const context = { req, res }
|
const context = { req, res }
|
||||||
|
|
||||||
return getTokenFromBody(context, (accessToken) => {
|
return getPlayer(context, (player, tokenDB) => {
|
||||||
checkTokenIsValid(context, accessToken, (token) => {
|
const games: any = {}
|
||||||
getTokenDB(context, token, (tokenDB) => {
|
sendResponse(context, {
|
||||||
getPlayerByIdDB(context, tokenDB, (player) => {
|
message: `Requested data of user: ${player.id} with Access-Token: ${tokenDB.id}`,
|
||||||
const games: any = {}
|
body: { games },
|
||||||
sendResponse(context, {
|
type: ["debug", "infoCyan"],
|
||||||
message: `Requested data of user: ${player.id} with Access-Token: ${tokenDB.id}`,
|
|
||||||
body: { games },
|
|
||||||
type: ["debug", "infoCyan"],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}).catch((err) => sendError(context, err))
|
}).catch((err) => sendError(context, err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ model Move {
|
||||||
model Gamepin {
|
model Gamepin {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
pin Int @unique
|
pin String @unique
|
||||||
gameId String @unique
|
gameId String @unique
|
||||||
game Game @relation(fields: [gameId], references: [id])
|
game Game @relation(fields: [gameId], references: [id])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue