Feat : create games

This commit is contained in:
2024-06-06 19:50:29 -04:00
parent 30e9a3efcb
commit e870a254ed
18 changed files with 379 additions and 82 deletions
-1
View File
@@ -1 +0,0 @@
export class CreateGameDto {}
+11
View File
@@ -0,0 +1,11 @@
import { ApiProperty } from '@nestjs/swagger';
import { Types } from 'mongoose';
export class DatabaseObjectDto {
constructor(data: { _id: Types.ObjectId }) {
this._id = data._id.toString();
}
@ApiProperty()
_id: string;
}
+86
View File
@@ -0,0 +1,86 @@
import { ApiProperty } from '@nestjs/swagger';
import { DatabaseObjectDto } from './database-object.dto';
import { Container, Team } from '../schemas/game.schema';
import { User } from 'src/users/schemas/user.entity';
export class ReadTeamDto extends DatabaseObjectDto {
constructor(data: ConstructorParameters<typeof DatabaseObjectDto>[0]) {
super(data);
}
}
export class ReadContainerDto extends DatabaseObjectDto {
constructor(data: ConstructorParameters<typeof DatabaseObjectDto>[0]) {
super(data);
}
}
export class ReadUserDto extends DatabaseObjectDto {
constructor(
data: { username: string; avatar: string } & ConstructorParameters<
typeof DatabaseObjectDto
>[0],
) {
super(data);
this.username = data.username;
this.avatar = data.avatar;
}
@ApiProperty()
username: string;
@ApiProperty()
avatar: string;
}
export class ReadGameDto extends DatabaseObjectDto {
constructor(
data: {
teams: Team[];
market: Container;
marketStack: Container;
fireGems: Container;
currentTurn?: Team;
started: boolean;
ended: boolean;
owner: User;
} & ConstructorParameters<typeof DatabaseObjectDto>[0],
) {
super(data);
this.teams = data.teams.map((e) => new ReadTeamDto(e));
this.market = new ReadContainerDto(data.market);
this.marketStack = new ReadContainerDto(data.marketStack);
this.fireGems = new ReadContainerDto(data.fireGems);
this.started = data.started;
this.ended = data.ended;
this.owner = new ReadUserDto(data.owner);
if (data.currentTurn) {
this.currentTurn = new ReadTeamDto(data.currentTurn);
}
}
@ApiProperty()
teams: ReadTeamDto[];
@ApiProperty()
market: ReadContainerDto;
@ApiProperty()
marketStack: ReadContainerDto;
@ApiProperty()
fireGems: ReadContainerDto;
@ApiProperty()
currentTurn?: ReadTeamDto;
@ApiProperty()
started: boolean;
@ApiProperty()
ended: boolean;
@ApiProperty()
owner: ReadUserDto;
}
+1 -4
View File
@@ -1,4 +1 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateGameDto } from './create-game.dto';
export class UpdateGameDto extends PartialType(CreateGameDto) {}
export class UpdateGameDto {}
+32 -8
View File
@@ -2,32 +2,56 @@ import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
UseGuards,
Session,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { GamesService } from './games.service';
import { CreateGameDto } from './dto/create-game.dto';
import { UpdateGameDto } from './dto/update-game.dto';
import { AuthGuard } from './guards/auth.guard';
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
import { DatabaseObjectDto } from './dto/database-object.dto';
@Controller('games')
export class GamesController {
constructor(private readonly gamesService: GamesService) {}
@Post()
create() {
return this.gamesService.create();
@ApiOperation({ summary: 'Create game' })
@ApiResponse({
status: 201,
description: 'Game successfully created.',
type: DatabaseObjectDto,
})
@ApiResponse({
status: 400,
description: 'You can only create one game at a time',
})
@ApiResponse({ status: 403, description: 'Forbidden.' })
@UseGuards(AuthGuard)
async create(@Session() session: Record<string, any>) {
const games = await this.gamesService.findByOwner(session.user._id);
if (games.length > 0) {
throw new HttpException(
'You can only create one game at a time',
HttpStatus.BAD_REQUEST,
);
}
return this.gamesService.create(session.user);
}
@Get()
@ApiOperation({ summary: 'List all games' })
findAll() {
return this.gamesService.findAll();
const games = this.gamesService.findAll();
return games;
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.gamesService.findOne(id);
return this.gamesService.findById(id);
}
// @Patch(':id')
+17 -8
View File
@@ -1,24 +1,33 @@
import { Injectable } from '@nestjs/common';
import { CreateGameDto } from './dto/create-game.dto';
import { UpdateGameDto } from './dto/update-game.dto';
import { DatabaseObjectDto } from './dto/database-object.dto';
import { InjectModel } from '@nestjs/mongoose';
import { Game } from './schemas/game.schema';
import { Model } from 'mongoose';
import { ReadGameDto } from './dto/read-games.dto';
import { User } from 'src/users/schemas/user.entity';
@Injectable()
export class GamesService {
constructor(@InjectModel(Game.name) private gameModel: Model<Game>) {}
async create(): Promise<Game> {
async create(owner: User): Promise<DatabaseObjectDto> {
const createdGame = new this.gameModel();
return createdGame.save();
createdGame.owner = owner;
const gamedata = await createdGame.save();
return new DatabaseObjectDto(gamedata);
}
findAll() {
return this.gameModel.find();
async findAll(): Promise<ReadGameDto[]> {
const games = await this.gameModel.find().exec();
return games.map((e) => new ReadGameDto(e));
}
findOne(id: string) {
return this.gameModel.find({ _id: id }).exec();
findById(id: string) {
return this.gameModel.findById(id).exec();
}
findByOwner(_id: string) {
return this.gameModel.find({ owner: _id }).exec();
}
// update(id: number, updateGameDto: UpdateGameDto) {
+23
View File
@@ -0,0 +1,23 @@
import {
Injectable,
CanActivate,
ExecutionContext,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { Request } from 'express';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const http = context.switchToHttp();
const request = http.getRequest<Request>();
if (!(request.session as Record<string, any>).user) {
throw new HttpException('Please log in', HttpStatus.UNAUTHORIZED);
}
return true;
}
}
+5 -8
View File
@@ -1,20 +1,17 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import mongoose, { HydratedDocument } from 'mongoose';
import mongoose, { HydratedDocument, Types } from 'mongoose';
import { Card } from 'src/cards/schemas/cards.schema';
import { User } from 'src/users/schemas/user.entity';
export type GameDocument = HydratedDocument<Game>;
@Schema()
class GameObject {}
@Schema()
export class Team extends GameObject {}
export class Team extends Types.ObjectId {}
export const TeamSchema = SchemaFactory.createForClass(Team);
@Schema()
export class Container extends GameObject {
export class Container extends Types.ObjectId {
@Prop([{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }])
cards: Card[];
}
@@ -22,7 +19,7 @@ export class Container extends GameObject {
export const ContainerSchema = SchemaFactory.createForClass(Container);
@Schema()
export class Game extends GameObject {
export class Game extends Types.ObjectId {
@Prop([Team])
teams: Team[];
@@ -42,7 +39,7 @@ export class Game extends GameObject {
started: boolean;
@Prop({ default: false })
private ended: boolean;
ended: boolean;
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
owner: User;