import { HttpStatus } from '@nestjs/common/enums'; import { HttpException } from '@nestjs/common/exceptions'; import mongoose, { Document } from 'mongoose'; import { Game, Player, Team } from './schemas/game.schema'; import { ReadUserDto } from './dto/read-games.dto'; export function shuffle(a) { let j, x, i; for (i = a.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = a[i]; a[i] = a[j]; a[j] = x; } return a; } export function getCurrentTeam(game: Document & Game) { return game.teams.find((t) => t._id.equals(game.currentTurn.currentTeam)); } export function getPlayer(session: Record, game: Game) { const user = session.user as ReadUserDto; if (!user) { throw new HttpException('Please log in', HttpStatus.UNAUTHORIZED); } return findUser(user._id, game); } export function findUser(playerId: string, game: Game) { for (const team of game.teams) { for (const player of team.players) { if (player.user._id.equals(playerId)) { return player as Document & Player; } } } throw new HttpException('User not found in game', HttpStatus.FORBIDDEN); } export function findPlayer(playerId: string, game: Game) { for (const team of game.teams) { for (const player of team.players) { if (player._id.equals(playerId)) { return player as Document & Player; } } } throw new HttpException('Player not found in game', HttpStatus.FORBIDDEN); } export function isInTeam(team: Team, player: Player) { if (team.players.some((p) => p._id.equals(player._id))) { return true; } return false; } export function getPlayerTeam(game: Game, player: Player) { return game.teams.find((t) => t.players.some((p) => p._id.equals(player._id)), ); } export function WithTransaction( target: any, propertyKey: string, descriptor: PropertyDescriptor, ) { const originalFunc = descriptor.value; descriptor.value = function (...args: any[]) { return new Promise(async (resolve, reject) => { try { if (args.at(-1) instanceof mongoose.mongo.ClientSession) { const data = await originalFunc.apply(this, args).catch((e) => { if (e instanceof HttpException) { throw e; } reject( new HttpException( 'Another request is processing', HttpStatus.TOO_MANY_REQUESTS, ), ); return; }); resolve(data); return data; } else { await this.connection .transaction(async (session) => { const data = await originalFunc.apply(this, [...args, session]); resolve(data); return data; }) .catch((e) => { if (e instanceof HttpException) { reject(e); } reject( new HttpException( 'Another request is processing', HttpStatus.TOO_MANY_REQUESTS, ), ); }); } } catch (e) { reject(e); } }); }; return descriptor; }