feat(tournament): better frontend and database handling

This commit is contained in:
Maieul BOYER 2026-01-12 16:36:51 +01:00 committed by Maix0
parent ca618d64ca
commit 43e3b9af26
41 changed files with 2484 additions and 278 deletions

View file

@ -16,6 +16,10 @@ models/ChangePassword400Response.ts
models/ChangePassword401Response.ts
models/ChangePassword500Response.ts
models/ChangePasswordRequest.ts
models/CreatePauseGame200Response.ts
models/CreatePauseGame200ResponsePayload.ts
models/CreatePauseGame404Response.ts
models/CreatePauseGameRequest.ts
models/DisableOtp200Response.ts
models/DisableOtp400Response.ts
models/DisableOtp500Response.ts
@ -48,18 +52,11 @@ models/LoginOtp500Response.ts
models/LoginOtpRequest.ts
models/LoginRequest.ts
models/Logout200Response.ts
models/PongCreatePauseGame200Response.ts
models/PongCreatePauseGame200ResponsePayload.ts
models/PongCreatePauseGame404Response.ts
models/PongCreatePauseGameRequest.ts
models/PongHistory200Response.ts
models/PongHistory200ResponsePayload.ts
models/PongHistory200ResponsePayloadDataInner.ts
models/PongHistory200ResponsePayloadDataInnerLeft.ts
models/PongHistory404Response.ts
models/PongstartPauseGame200Response.ts
models/PongstartPauseGame404Response.ts
models/PongstartPauseGameRequest.ts
models/ProviderList200Response.ts
models/ProviderList200ResponsePayload.ts
models/ProviderList200ResponsePayloadListInner.ts
@ -74,6 +71,15 @@ models/StatusOtp200ResponseAnyOf1.ts
models/StatusOtp200ResponseAnyOfPayload.ts
models/StatusOtp401Response.ts
models/StatusOtp500Response.ts
models/TournamentData200Response.ts
models/TournamentData200ResponsePayload.ts
models/TournamentData200ResponsePayloadData.ts
models/TournamentData200ResponsePayloadDataUsersInner.ts
models/TournamentData404Response.ts
models/TournamentList200Response.ts
models/TournamentList200ResponsePayload.ts
models/TournamentList200ResponsePayloadDataInner.ts
models/TournamentList404Response.ts
models/TttHistory200Response.ts
models/TttHistory200ResponsePayload.ts
models/TttHistory200ResponsePayloadDataInner.ts

View file

@ -30,6 +30,9 @@ import type {
ChangePassword401Response,
ChangePassword500Response,
ChangePasswordRequest,
CreatePauseGame200Response,
CreatePauseGame404Response,
CreatePauseGameRequest,
DisableOtp200Response,
DisableOtp400Response,
DisableOtp500Response,
@ -55,14 +58,8 @@ import type {
LoginOtpRequest,
LoginRequest,
Logout200Response,
PongCreatePauseGame200Response,
PongCreatePauseGame404Response,
PongCreatePauseGameRequest,
PongHistory200Response,
PongHistory404Response,
PongstartPauseGame200Response,
PongstartPauseGame404Response,
PongstartPauseGameRequest,
ProviderList200Response,
Signin200Response,
Signin400Response,
@ -70,6 +67,10 @@ import type {
StatusOtp200Response,
StatusOtp401Response,
StatusOtp500Response,
TournamentData200Response,
TournamentData404Response,
TournamentList200Response,
TournamentList404Response,
TttHistory200Response,
TttHistory404Response,
} from '../models/index';
@ -104,6 +105,12 @@ import {
ChangePassword500ResponseToJSON,
ChangePasswordRequestFromJSON,
ChangePasswordRequestToJSON,
CreatePauseGame200ResponseFromJSON,
CreatePauseGame200ResponseToJSON,
CreatePauseGame404ResponseFromJSON,
CreatePauseGame404ResponseToJSON,
CreatePauseGameRequestFromJSON,
CreatePauseGameRequestToJSON,
DisableOtp200ResponseFromJSON,
DisableOtp200ResponseToJSON,
DisableOtp400ResponseFromJSON,
@ -154,22 +161,10 @@ import {
LoginRequestToJSON,
Logout200ResponseFromJSON,
Logout200ResponseToJSON,
PongCreatePauseGame200ResponseFromJSON,
PongCreatePauseGame200ResponseToJSON,
PongCreatePauseGame404ResponseFromJSON,
PongCreatePauseGame404ResponseToJSON,
PongCreatePauseGameRequestFromJSON,
PongCreatePauseGameRequestToJSON,
PongHistory200ResponseFromJSON,
PongHistory200ResponseToJSON,
PongHistory404ResponseFromJSON,
PongHistory404ResponseToJSON,
PongstartPauseGame200ResponseFromJSON,
PongstartPauseGame200ResponseToJSON,
PongstartPauseGame404ResponseFromJSON,
PongstartPauseGame404ResponseToJSON,
PongstartPauseGameRequestFromJSON,
PongstartPauseGameRequestToJSON,
ProviderList200ResponseFromJSON,
ProviderList200ResponseToJSON,
Signin200ResponseFromJSON,
@ -184,6 +179,14 @@ import {
StatusOtp401ResponseToJSON,
StatusOtp500ResponseFromJSON,
StatusOtp500ResponseToJSON,
TournamentData200ResponseFromJSON,
TournamentData200ResponseToJSON,
TournamentData404ResponseFromJSON,
TournamentData404ResponseToJSON,
TournamentList200ResponseFromJSON,
TournamentList200ResponseToJSON,
TournamentList404ResponseFromJSON,
TournamentList404ResponseToJSON,
TttHistory200ResponseFromJSON,
TttHistory200ResponseToJSON,
TttHistory404ResponseFromJSON,
@ -206,6 +209,10 @@ export interface ChangePasswordOperationRequest {
changePasswordRequest: ChangePasswordRequest;
}
export interface CreatePauseGameOperationRequest {
createPauseGameRequest: CreatePauseGameRequest;
}
export interface GetUserRequest {
user: GetUserUserParameter;
}
@ -222,22 +229,18 @@ export interface LoginOtpOperationRequest {
loginOtpRequest: LoginOtpRequest;
}
export interface PongCreatePauseGameOperationRequest {
pongCreatePauseGameRequest: PongCreatePauseGameRequest;
}
export interface PongHistoryRequest {
user: string;
}
export interface PongstartPauseGameOperationRequest {
pongstartPauseGameRequest: PongstartPauseGameRequest;
}
export interface SigninRequest {
loginRequest: LoginRequest;
}
export interface TournamentDataRequest {
id: string;
}
export interface TttHistoryRequest {
user: string;
}
@ -516,6 +519,58 @@ export class OpenapiOtherApi extends runtime.BaseAPI {
return await response.value();
}
/**
*/
async createPauseGameRaw(requestParameters: CreatePauseGameOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<CreatePauseGame200Response | CreatePauseGame404Response>> {
if (requestParameters['createPauseGameRequest'] == null) {
throw new runtime.RequiredError(
'createPauseGameRequest',
'Required parameter "createPauseGameRequest" was null or undefined when calling createPauseGame().'
);
}
const queryParameters: any = {};
const headerParameters: runtime.HTTPHeaders = {};
headerParameters['Content-Type'] = 'application/json';
let urlPath = `/api/pong/createPausedGame`;
const response = await this.request({
path: urlPath,
method: 'POST',
headers: headerParameters,
query: queryParameters,
body: CreatePauseGameRequestToJSON(requestParameters['createPauseGameRequest']),
}, initOverrides);
// CHANGED: Handle all status codes defined in the OpenAPI spec, not just 2xx responses
// This allows typed access to error responses (4xx, 5xx) and other status codes.
// The code routes responses based on the actual HTTP status code and returns
// appropriately typed ApiResponse wrappers for each status code.
if (response.status === 200) {
// Object response for status 200
return new runtime.JSONApiResponse(response, (jsonValue) => CreatePauseGame200ResponseFromJSON(jsonValue));
}
if (response.status === 404) {
// Object response for status 404
return new runtime.JSONApiResponse(response, (jsonValue) => CreatePauseGame404ResponseFromJSON(jsonValue));
}
// CHANGED: Throw error if status code is not handled by any of the defined responses
// This ensures all code paths return a value and provides clear error messages for unexpected status codes
// Only throw if responses were defined but none matched the actual status code
throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 404`);
}
/**
*/
async createPauseGame(requestParameters: CreatePauseGameOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<CreatePauseGame200Response | CreatePauseGame404Response> {
const response = await this.createPauseGameRaw(requestParameters, initOverrides);
return await response.value();
}
/**
*/
async denyGuestMessageRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AllowGuestMessage200Response | StatusOtp401Response | AllowGuestMessage403Response>> {
@ -923,58 +978,6 @@ export class OpenapiOtherApi extends runtime.BaseAPI {
return await response.value();
}
/**
*/
async pongCreatePauseGameRaw(requestParameters: PongCreatePauseGameOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<PongCreatePauseGame200Response | PongCreatePauseGame404Response>> {
if (requestParameters['pongCreatePauseGameRequest'] == null) {
throw new runtime.RequiredError(
'pongCreatePauseGameRequest',
'Required parameter "pongCreatePauseGameRequest" was null or undefined when calling pongCreatePauseGame().'
);
}
const queryParameters: any = {};
const headerParameters: runtime.HTTPHeaders = {};
headerParameters['Content-Type'] = 'application/json';
let urlPath = `/createPausedGame`;
const response = await this.request({
path: urlPath,
method: 'POST',
headers: headerParameters,
query: queryParameters,
body: PongCreatePauseGameRequestToJSON(requestParameters['pongCreatePauseGameRequest']),
}, initOverrides);
// CHANGED: Handle all status codes defined in the OpenAPI spec, not just 2xx responses
// This allows typed access to error responses (4xx, 5xx) and other status codes.
// The code routes responses based on the actual HTTP status code and returns
// appropriately typed ApiResponse wrappers for each status code.
if (response.status === 200) {
// Object response for status 200
return new runtime.JSONApiResponse(response, (jsonValue) => PongCreatePauseGame200ResponseFromJSON(jsonValue));
}
if (response.status === 404) {
// Object response for status 404
return new runtime.JSONApiResponse(response, (jsonValue) => PongCreatePauseGame404ResponseFromJSON(jsonValue));
}
// CHANGED: Throw error if status code is not handled by any of the defined responses
// This ensures all code paths return a value and provides clear error messages for unexpected status codes
// Only throw if responses were defined but none matched the actual status code
throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 404`);
}
/**
*/
async pongCreatePauseGame(requestParameters: PongCreatePauseGameOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<PongCreatePauseGame200Response | PongCreatePauseGame404Response> {
const response = await this.pongCreatePauseGameRaw(requestParameters, initOverrides);
return await response.value();
}
/**
*/
async pongHistoryRaw(requestParameters: PongHistoryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<PongHistory200Response | StatusOtp401Response | PongHistory404Response>> {
@ -1029,58 +1032,6 @@ export class OpenapiOtherApi extends runtime.BaseAPI {
return await response.value();
}
/**
*/
async pongstartPauseGameRaw(requestParameters: PongstartPauseGameOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<PongstartPauseGame200Response | PongstartPauseGame404Response>> {
if (requestParameters['pongstartPauseGameRequest'] == null) {
throw new runtime.RequiredError(
'pongstartPauseGameRequest',
'Required parameter "pongstartPauseGameRequest" was null or undefined when calling pongstartPauseGame().'
);
}
const queryParameters: any = {};
const headerParameters: runtime.HTTPHeaders = {};
headerParameters['Content-Type'] = 'application/json';
let urlPath = `/startPausedGame`;
const response = await this.request({
path: urlPath,
method: 'POST',
headers: headerParameters,
query: queryParameters,
body: PongstartPauseGameRequestToJSON(requestParameters['pongstartPauseGameRequest']),
}, initOverrides);
// CHANGED: Handle all status codes defined in the OpenAPI spec, not just 2xx responses
// This allows typed access to error responses (4xx, 5xx) and other status codes.
// The code routes responses based on the actual HTTP status code and returns
// appropriately typed ApiResponse wrappers for each status code.
if (response.status === 200) {
// Object response for status 200
return new runtime.JSONApiResponse(response, (jsonValue) => PongstartPauseGame200ResponseFromJSON(jsonValue));
}
if (response.status === 404) {
// Object response for status 404
return new runtime.JSONApiResponse(response, (jsonValue) => PongstartPauseGame404ResponseFromJSON(jsonValue));
}
// CHANGED: Throw error if status code is not handled by any of the defined responses
// This ensures all code paths return a value and provides clear error messages for unexpected status codes
// Only throw if responses were defined but none matched the actual status code
throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 404`);
}
/**
*/
async pongstartPauseGame(requestParameters: PongstartPauseGameOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<PongstartPauseGame200Response | PongstartPauseGame404Response> {
const response = await this.pongstartPauseGameRaw(requestParameters, initOverrides);
return await response.value();
}
/**
*/
async providerListRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<ProviderList200Response>> {
@ -1221,6 +1172,106 @@ export class OpenapiOtherApi extends runtime.BaseAPI {
return await response.value();
}
/**
*/
async tournamentDataRaw(requestParameters: TournamentDataRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<TournamentData200Response | StatusOtp401Response | TournamentData404Response>> {
if (requestParameters['id'] == null) {
throw new runtime.RequiredError(
'id',
'Required parameter "id" was null or undefined when calling tournamentData().'
);
}
const queryParameters: any = {};
const headerParameters: runtime.HTTPHeaders = {};
let urlPath = `/api/pong/tournament/{id}`;
urlPath = urlPath.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters['id'])));
const response = await this.request({
path: urlPath,
method: 'GET',
headers: headerParameters,
query: queryParameters,
}, initOverrides);
// CHANGED: Handle all status codes defined in the OpenAPI spec, not just 2xx responses
// This allows typed access to error responses (4xx, 5xx) and other status codes.
// The code routes responses based on the actual HTTP status code and returns
// appropriately typed ApiResponse wrappers for each status code.
if (response.status === 200) {
// Object response for status 200
return new runtime.JSONApiResponse(response, (jsonValue) => TournamentData200ResponseFromJSON(jsonValue));
}
if (response.status === 401) {
// Object response for status 401
return new runtime.JSONApiResponse(response, (jsonValue) => StatusOtp401ResponseFromJSON(jsonValue));
}
if (response.status === 404) {
// Object response for status 404
return new runtime.JSONApiResponse(response, (jsonValue) => TournamentData404ResponseFromJSON(jsonValue));
}
// CHANGED: Throw error if status code is not handled by any of the defined responses
// This ensures all code paths return a value and provides clear error messages for unexpected status codes
// Only throw if responses were defined but none matched the actual status code
throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 401, 404`);
}
/**
*/
async tournamentData(requestParameters: TournamentDataRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<TournamentData200Response | StatusOtp401Response | TournamentData404Response> {
const response = await this.tournamentDataRaw(requestParameters, initOverrides);
return await response.value();
}
/**
*/
async tournamentListRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<TournamentList200Response | StatusOtp401Response | TournamentList404Response>> {
const queryParameters: any = {};
const headerParameters: runtime.HTTPHeaders = {};
let urlPath = `/api/pong/tournament/`;
const response = await this.request({
path: urlPath,
method: 'GET',
headers: headerParameters,
query: queryParameters,
}, initOverrides);
// CHANGED: Handle all status codes defined in the OpenAPI spec, not just 2xx responses
// This allows typed access to error responses (4xx, 5xx) and other status codes.
// The code routes responses based on the actual HTTP status code and returns
// appropriately typed ApiResponse wrappers for each status code.
if (response.status === 200) {
// Object response for status 200
return new runtime.JSONApiResponse(response, (jsonValue) => TournamentList200ResponseFromJSON(jsonValue));
}
if (response.status === 401) {
// Object response for status 401
return new runtime.JSONApiResponse(response, (jsonValue) => StatusOtp401ResponseFromJSON(jsonValue));
}
if (response.status === 404) {
// Object response for status 404
return new runtime.JSONApiResponse(response, (jsonValue) => TournamentList404ResponseFromJSON(jsonValue));
}
// CHANGED: Throw error if status code is not handled by any of the defined responses
// This ensures all code paths return a value and provides clear error messages for unexpected status codes
// Only throw if responses were defined but none matched the actual status code
throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 401, 404`);
}
/**
*/
async tournamentList(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<TournamentList200Response | StatusOtp401Response | TournamentList404Response> {
const response = await this.tournamentListRaw(initOverrides);
return await response.value();
}
/**
*/
async tttHistoryRaw(requestParameters: TttHistoryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<TttHistory200Response | StatusOtp401Response | TttHistory404Response>> {

View file

@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
*/
export interface ChangeDisplayNameRequest {
/**
* New Display Name
*
* @type {string}
* @memberof ChangeDisplayNameRequest
*/

View file

@ -0,0 +1,110 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
import type { CreatePauseGame200ResponsePayload } from './CreatePauseGame200ResponsePayload';
import {
CreatePauseGame200ResponsePayloadFromJSON,
CreatePauseGame200ResponsePayloadFromJSONTyped,
CreatePauseGame200ResponsePayloadToJSON,
CreatePauseGame200ResponsePayloadToJSONTyped,
} from './CreatePauseGame200ResponsePayload';
/**
*
* @export
* @interface CreatePauseGame200Response
*/
export interface CreatePauseGame200Response {
/**
*
* @type {string}
* @memberof CreatePauseGame200Response
*/
kind: CreatePauseGame200ResponseKindEnum;
/**
*
* @type {string}
* @memberof CreatePauseGame200Response
*/
msg: CreatePauseGame200ResponseMsgEnum;
/**
*
* @type {CreatePauseGame200ResponsePayload}
* @memberof CreatePauseGame200Response
*/
payload: CreatePauseGame200ResponsePayload;
}
/**
* @export
*/
export const CreatePauseGame200ResponseKindEnum = {
Success: 'success'
} as const;
export type CreatePauseGame200ResponseKindEnum = typeof CreatePauseGame200ResponseKindEnum[keyof typeof CreatePauseGame200ResponseKindEnum];
/**
* @export
*/
export const CreatePauseGame200ResponseMsgEnum = {
CreatePausedGameSuccess: 'createPausedGame.success'
} as const;
export type CreatePauseGame200ResponseMsgEnum = typeof CreatePauseGame200ResponseMsgEnum[keyof typeof CreatePauseGame200ResponseMsgEnum];
/**
* Check if a given object implements the CreatePauseGame200Response interface.
*/
export function instanceOfCreatePauseGame200Response(value: object): value is CreatePauseGame200Response {
if (!('kind' in value) || value['kind'] === undefined) return false;
if (!('msg' in value) || value['msg'] === undefined) return false;
if (!('payload' in value) || value['payload'] === undefined) return false;
return true;
}
export function CreatePauseGame200ResponseFromJSON(json: any): CreatePauseGame200Response {
return CreatePauseGame200ResponseFromJSONTyped(json, false);
}
export function CreatePauseGame200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePauseGame200Response {
if (json == null) {
return json;
}
return {
'kind': json['kind'],
'msg': json['msg'],
'payload': CreatePauseGame200ResponsePayloadFromJSON(json['payload']),
};
}
export function CreatePauseGame200ResponseToJSON(json: any): CreatePauseGame200Response {
return CreatePauseGame200ResponseToJSONTyped(json, false);
}
export function CreatePauseGame200ResponseToJSONTyped(value?: CreatePauseGame200Response | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'kind': value['kind'],
'msg': value['msg'],
'payload': CreatePauseGame200ResponsePayloadToJSON(value['payload']),
};
}

View file

@ -0,0 +1,66 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface CreatePauseGame200ResponsePayload
*/
export interface CreatePauseGame200ResponsePayload {
/**
*
* @type {string}
* @memberof CreatePauseGame200ResponsePayload
*/
gameId: string;
}
/**
* Check if a given object implements the CreatePauseGame200ResponsePayload interface.
*/
export function instanceOfCreatePauseGame200ResponsePayload(value: object): value is CreatePauseGame200ResponsePayload {
if (!('gameId' in value) || value['gameId'] === undefined) return false;
return true;
}
export function CreatePauseGame200ResponsePayloadFromJSON(json: any): CreatePauseGame200ResponsePayload {
return CreatePauseGame200ResponsePayloadFromJSONTyped(json, false);
}
export function CreatePauseGame200ResponsePayloadFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePauseGame200ResponsePayload {
if (json == null) {
return json;
}
return {
'gameId': json['gameId'],
};
}
export function CreatePauseGame200ResponsePayloadToJSON(json: any): CreatePauseGame200ResponsePayload {
return CreatePauseGame200ResponsePayloadToJSONTyped(json, false);
}
export function CreatePauseGame200ResponsePayloadToJSONTyped(value?: CreatePauseGame200ResponsePayload | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'gameId': value['gameId'],
};
}

View file

@ -0,0 +1,93 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface CreatePauseGame404Response
*/
export interface CreatePauseGame404Response {
/**
*
* @type {string}
* @memberof CreatePauseGame404Response
*/
kind: CreatePauseGame404ResponseKindEnum;
/**
*
* @type {string}
* @memberof CreatePauseGame404Response
*/
msg: CreatePauseGame404ResponseMsgEnum;
}
/**
* @export
*/
export const CreatePauseGame404ResponseKindEnum = {
Failure: 'failure'
} as const;
export type CreatePauseGame404ResponseKindEnum = typeof CreatePauseGame404ResponseKindEnum[keyof typeof CreatePauseGame404ResponseKindEnum];
/**
* @export
*/
export const CreatePauseGame404ResponseMsgEnum = {
CreatePausedGameGenericFail: 'createPausedGame.generic.fail'
} as const;
export type CreatePauseGame404ResponseMsgEnum = typeof CreatePauseGame404ResponseMsgEnum[keyof typeof CreatePauseGame404ResponseMsgEnum];
/**
* Check if a given object implements the CreatePauseGame404Response interface.
*/
export function instanceOfCreatePauseGame404Response(value: object): value is CreatePauseGame404Response {
if (!('kind' in value) || value['kind'] === undefined) return false;
if (!('msg' in value) || value['msg'] === undefined) return false;
return true;
}
export function CreatePauseGame404ResponseFromJSON(json: any): CreatePauseGame404Response {
return CreatePauseGame404ResponseFromJSONTyped(json, false);
}
export function CreatePauseGame404ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePauseGame404Response {
if (json == null) {
return json;
}
return {
'kind': json['kind'],
'msg': json['msg'],
};
}
export function CreatePauseGame404ResponseToJSON(json: any): CreatePauseGame404Response {
return CreatePauseGame404ResponseToJSONTyped(json, false);
}
export function CreatePauseGame404ResponseToJSONTyped(value?: CreatePauseGame404Response | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'kind': value['kind'],
'msg': value['msg'],
};
}

View file

@ -0,0 +1,75 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface CreatePauseGameRequest
*/
export interface CreatePauseGameRequest {
/**
*
* @type {string}
* @memberof CreatePauseGameRequest
*/
user1: string;
/**
*
* @type {string}
* @memberof CreatePauseGameRequest
*/
user2: string;
}
/**
* Check if a given object implements the CreatePauseGameRequest interface.
*/
export function instanceOfCreatePauseGameRequest(value: object): value is CreatePauseGameRequest {
if (!('user1' in value) || value['user1'] === undefined) return false;
if (!('user2' in value) || value['user2'] === undefined) return false;
return true;
}
export function CreatePauseGameRequestFromJSON(json: any): CreatePauseGameRequest {
return CreatePauseGameRequestFromJSONTyped(json, false);
}
export function CreatePauseGameRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePauseGameRequest {
if (json == null) {
return json;
}
return {
'user1': json['user1'],
'user2': json['user2'],
};
}
export function CreatePauseGameRequestToJSON(json: any): CreatePauseGameRequest {
return CreatePauseGameRequestToJSONTyped(json, false);
}
export function CreatePauseGameRequestToJSONTyped(value?: CreatePauseGameRequest | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'user1': value['user1'],
'user2': value['user2'],
};
}

View file

@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
*/
export interface EnableOtp200ResponsePayload {
/**
* The otp url to feed into a 2fa app
*
* @type {string}
* @memberof EnableOtp200ResponsePayload
*/

View file

@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
*/
export interface GuestLogin200ResponsePayload {
/**
* JWT that represent a logged in user
*
* @type {string}
* @memberof GuestLogin200ResponsePayload
*/

View file

@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
*/
export interface Login202ResponsePayload {
/**
* JWT to send with the OTP to finish login
*
* @type {string}
* @memberof Login202ResponsePayload
*/

View file

@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
*/
export interface LoginOtp200ResponsePayload {
/**
* the JWT Token
*
* @type {string}
* @memberof LoginOtp200ResponsePayload
*/

View file

@ -20,13 +20,13 @@ import { mapValues } from '../runtime';
*/
export interface LoginOtpRequest {
/**
* The token given at the login phase
*
* @type {string}
* @memberof LoginOtpRequest
*/
token: string;
/**
* The OTP given by the user
*
* @type {string}
* @memberof LoginOtpRequest
*/

View file

@ -28,7 +28,7 @@ import {
*/
export interface PongHistory200ResponsePayloadDataInner {
/**
* gameId
*
* @type {string}
* @memberof PongHistory200ResponsePayloadDataInner
*/

View file

@ -28,13 +28,13 @@ import {
*/
export interface ProviderList200ResponsePayloadListInner {
/**
* Name to display to the user
*
* @type {string}
* @memberof ProviderList200ResponsePayloadListInner
*/
displayName: string;
/**
* internal Name of the provider
*
* @type {string}
* @memberof ProviderList200ResponsePayloadListInner
*/

View file

@ -20,13 +20,13 @@ import { mapValues } from '../runtime';
*/
export interface ProviderList200ResponsePayloadListInnerColors {
/**
* Default color for the provider
*
* @type {string}
* @memberof ProviderList200ResponsePayloadListInnerColors
*/
normal: string;
/**
* Hover color for the provider
*
* @type {string}
* @memberof ProviderList200ResponsePayloadListInnerColors
*/

View file

@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
*/
export interface Signin200ResponsePayload {
/**
* the JWT token
*
* @type {string}
* @memberof Signin200ResponsePayload
*/

View file

@ -20,7 +20,7 @@ import { mapValues } from '../runtime';
*/
export interface StatusOtp200ResponseAnyOfPayload {
/**
* The otp secret
*
* @type {string}
* @memberof StatusOtp200ResponseAnyOfPayload
*/

View file

@ -0,0 +1,110 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
import type { TournamentData200ResponsePayload } from './TournamentData200ResponsePayload';
import {
TournamentData200ResponsePayloadFromJSON,
TournamentData200ResponsePayloadFromJSONTyped,
TournamentData200ResponsePayloadToJSON,
TournamentData200ResponsePayloadToJSONTyped,
} from './TournamentData200ResponsePayload';
/**
*
* @export
* @interface TournamentData200Response
*/
export interface TournamentData200Response {
/**
*
* @type {string}
* @memberof TournamentData200Response
*/
kind: TournamentData200ResponseKindEnum;
/**
*
* @type {string}
* @memberof TournamentData200Response
*/
msg: TournamentData200ResponseMsgEnum;
/**
*
* @type {TournamentData200ResponsePayload}
* @memberof TournamentData200Response
*/
payload: TournamentData200ResponsePayload;
}
/**
* @export
*/
export const TournamentData200ResponseKindEnum = {
Success: 'success'
} as const;
export type TournamentData200ResponseKindEnum = typeof TournamentData200ResponseKindEnum[keyof typeof TournamentData200ResponseKindEnum];
/**
* @export
*/
export const TournamentData200ResponseMsgEnum = {
TournamentDataSuccess: 'tournamentData.success'
} as const;
export type TournamentData200ResponseMsgEnum = typeof TournamentData200ResponseMsgEnum[keyof typeof TournamentData200ResponseMsgEnum];
/**
* Check if a given object implements the TournamentData200Response interface.
*/
export function instanceOfTournamentData200Response(value: object): value is TournamentData200Response {
if (!('kind' in value) || value['kind'] === undefined) return false;
if (!('msg' in value) || value['msg'] === undefined) return false;
if (!('payload' in value) || value['payload'] === undefined) return false;
return true;
}
export function TournamentData200ResponseFromJSON(json: any): TournamentData200Response {
return TournamentData200ResponseFromJSONTyped(json, false);
}
export function TournamentData200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentData200Response {
if (json == null) {
return json;
}
return {
'kind': json['kind'],
'msg': json['msg'],
'payload': TournamentData200ResponsePayloadFromJSON(json['payload']),
};
}
export function TournamentData200ResponseToJSON(json: any): TournamentData200Response {
return TournamentData200ResponseToJSONTyped(json, false);
}
export function TournamentData200ResponseToJSONTyped(value?: TournamentData200Response | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'kind': value['kind'],
'msg': value['msg'],
'payload': TournamentData200ResponsePayloadToJSON(value['payload']),
};
}

View file

@ -0,0 +1,74 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
import type { TournamentData200ResponsePayloadData } from './TournamentData200ResponsePayloadData';
import {
TournamentData200ResponsePayloadDataFromJSON,
TournamentData200ResponsePayloadDataFromJSONTyped,
TournamentData200ResponsePayloadDataToJSON,
TournamentData200ResponsePayloadDataToJSONTyped,
} from './TournamentData200ResponsePayloadData';
/**
*
* @export
* @interface TournamentData200ResponsePayload
*/
export interface TournamentData200ResponsePayload {
/**
*
* @type {TournamentData200ResponsePayloadData}
* @memberof TournamentData200ResponsePayload
*/
data: TournamentData200ResponsePayloadData;
}
/**
* Check if a given object implements the TournamentData200ResponsePayload interface.
*/
export function instanceOfTournamentData200ResponsePayload(value: object): value is TournamentData200ResponsePayload {
if (!('data' in value) || value['data'] === undefined) return false;
return true;
}
export function TournamentData200ResponsePayloadFromJSON(json: any): TournamentData200ResponsePayload {
return TournamentData200ResponsePayloadFromJSONTyped(json, false);
}
export function TournamentData200ResponsePayloadFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentData200ResponsePayload {
if (json == null) {
return json;
}
return {
'data': TournamentData200ResponsePayloadDataFromJSON(json['data']),
};
}
export function TournamentData200ResponsePayloadToJSON(json: any): TournamentData200ResponsePayload {
return TournamentData200ResponsePayloadToJSONTyped(json, false);
}
export function TournamentData200ResponsePayloadToJSONTyped(value?: TournamentData200ResponsePayload | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'data': TournamentData200ResponsePayloadDataToJSON(value['data']),
};
}

View file

@ -0,0 +1,108 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
import type { TournamentData200ResponsePayloadDataUsersInner } from './TournamentData200ResponsePayloadDataUsersInner';
import {
TournamentData200ResponsePayloadDataUsersInnerFromJSON,
TournamentData200ResponsePayloadDataUsersInnerFromJSONTyped,
TournamentData200ResponsePayloadDataUsersInnerToJSON,
TournamentData200ResponsePayloadDataUsersInnerToJSONTyped,
} from './TournamentData200ResponsePayloadDataUsersInner';
import type { PongHistory200ResponsePayloadDataInner } from './PongHistory200ResponsePayloadDataInner';
import {
PongHistory200ResponsePayloadDataInnerFromJSON,
PongHistory200ResponsePayloadDataInnerFromJSONTyped,
PongHistory200ResponsePayloadDataInnerToJSON,
PongHistory200ResponsePayloadDataInnerToJSONTyped,
} from './PongHistory200ResponsePayloadDataInner';
/**
*
* @export
* @interface TournamentData200ResponsePayloadData
*/
export interface TournamentData200ResponsePayloadData {
/**
*
* @type {string}
* @memberof TournamentData200ResponsePayloadData
*/
owner: string;
/**
*
* @type {Array<TournamentData200ResponsePayloadDataUsersInner>}
* @memberof TournamentData200ResponsePayloadData
*/
users: Array<TournamentData200ResponsePayloadDataUsersInner>;
/**
*
* @type {Array<PongHistory200ResponsePayloadDataInner>}
* @memberof TournamentData200ResponsePayloadData
*/
games: Array<PongHistory200ResponsePayloadDataInner>;
/**
*
* @type {string}
* @memberof TournamentData200ResponsePayloadData
*/
time: string;
}
/**
* Check if a given object implements the TournamentData200ResponsePayloadData interface.
*/
export function instanceOfTournamentData200ResponsePayloadData(value: object): value is TournamentData200ResponsePayloadData {
if (!('owner' in value) || value['owner'] === undefined) return false;
if (!('users' in value) || value['users'] === undefined) return false;
if (!('games' in value) || value['games'] === undefined) return false;
if (!('time' in value) || value['time'] === undefined) return false;
return true;
}
export function TournamentData200ResponsePayloadDataFromJSON(json: any): TournamentData200ResponsePayloadData {
return TournamentData200ResponsePayloadDataFromJSONTyped(json, false);
}
export function TournamentData200ResponsePayloadDataFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentData200ResponsePayloadData {
if (json == null) {
return json;
}
return {
'owner': json['owner'],
'users': ((json['users'] as Array<any>).map(TournamentData200ResponsePayloadDataUsersInnerFromJSON)),
'games': ((json['games'] as Array<any>).map(PongHistory200ResponsePayloadDataInnerFromJSON)),
'time': json['time'],
};
}
export function TournamentData200ResponsePayloadDataToJSON(json: any): TournamentData200ResponsePayloadData {
return TournamentData200ResponsePayloadDataToJSONTyped(json, false);
}
export function TournamentData200ResponsePayloadDataToJSONTyped(value?: TournamentData200ResponsePayloadData | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'owner': value['owner'],
'users': ((value['users'] as Array<any>).map(TournamentData200ResponsePayloadDataUsersInnerToJSON)),
'games': ((value['games'] as Array<any>).map(PongHistory200ResponsePayloadDataInnerToJSON)),
'time': value['time'],
};
}

View file

@ -0,0 +1,84 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface TournamentData200ResponsePayloadDataUsersInner
*/
export interface TournamentData200ResponsePayloadDataUsersInner {
/**
*
* @type {number}
* @memberof TournamentData200ResponsePayloadDataUsersInner
*/
score: number;
/**
*
* @type {string}
* @memberof TournamentData200ResponsePayloadDataUsersInner
*/
id: string;
/**
*
* @type {string}
* @memberof TournamentData200ResponsePayloadDataUsersInner
*/
nickname: string;
}
/**
* Check if a given object implements the TournamentData200ResponsePayloadDataUsersInner interface.
*/
export function instanceOfTournamentData200ResponsePayloadDataUsersInner(value: object): value is TournamentData200ResponsePayloadDataUsersInner {
if (!('score' in value) || value['score'] === undefined) return false;
if (!('id' in value) || value['id'] === undefined) return false;
if (!('nickname' in value) || value['nickname'] === undefined) return false;
return true;
}
export function TournamentData200ResponsePayloadDataUsersInnerFromJSON(json: any): TournamentData200ResponsePayloadDataUsersInner {
return TournamentData200ResponsePayloadDataUsersInnerFromJSONTyped(json, false);
}
export function TournamentData200ResponsePayloadDataUsersInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentData200ResponsePayloadDataUsersInner {
if (json == null) {
return json;
}
return {
'score': json['score'],
'id': json['id'],
'nickname': json['nickname'],
};
}
export function TournamentData200ResponsePayloadDataUsersInnerToJSON(json: any): TournamentData200ResponsePayloadDataUsersInner {
return TournamentData200ResponsePayloadDataUsersInnerToJSONTyped(json, false);
}
export function TournamentData200ResponsePayloadDataUsersInnerToJSONTyped(value?: TournamentData200ResponsePayloadDataUsersInner | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'score': value['score'],
'id': value['id'],
'nickname': value['nickname'],
};
}

View file

@ -0,0 +1,93 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface TournamentData404Response
*/
export interface TournamentData404Response {
/**
*
* @type {string}
* @memberof TournamentData404Response
*/
kind: TournamentData404ResponseKindEnum;
/**
*
* @type {string}
* @memberof TournamentData404Response
*/
msg: TournamentData404ResponseMsgEnum;
}
/**
* @export
*/
export const TournamentData404ResponseKindEnum = {
Failure: 'failure'
} as const;
export type TournamentData404ResponseKindEnum = typeof TournamentData404ResponseKindEnum[keyof typeof TournamentData404ResponseKindEnum];
/**
* @export
*/
export const TournamentData404ResponseMsgEnum = {
TournamentDataFailureNotFound: 'tournamentData.failure.notFound'
} as const;
export type TournamentData404ResponseMsgEnum = typeof TournamentData404ResponseMsgEnum[keyof typeof TournamentData404ResponseMsgEnum];
/**
* Check if a given object implements the TournamentData404Response interface.
*/
export function instanceOfTournamentData404Response(value: object): value is TournamentData404Response {
if (!('kind' in value) || value['kind'] === undefined) return false;
if (!('msg' in value) || value['msg'] === undefined) return false;
return true;
}
export function TournamentData404ResponseFromJSON(json: any): TournamentData404Response {
return TournamentData404ResponseFromJSONTyped(json, false);
}
export function TournamentData404ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentData404Response {
if (json == null) {
return json;
}
return {
'kind': json['kind'],
'msg': json['msg'],
};
}
export function TournamentData404ResponseToJSON(json: any): TournamentData404Response {
return TournamentData404ResponseToJSONTyped(json, false);
}
export function TournamentData404ResponseToJSONTyped(value?: TournamentData404Response | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'kind': value['kind'],
'msg': value['msg'],
};
}

View file

@ -0,0 +1,110 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
import type { TournamentList200ResponsePayload } from './TournamentList200ResponsePayload';
import {
TournamentList200ResponsePayloadFromJSON,
TournamentList200ResponsePayloadFromJSONTyped,
TournamentList200ResponsePayloadToJSON,
TournamentList200ResponsePayloadToJSONTyped,
} from './TournamentList200ResponsePayload';
/**
*
* @export
* @interface TournamentList200Response
*/
export interface TournamentList200Response {
/**
*
* @type {string}
* @memberof TournamentList200Response
*/
kind: TournamentList200ResponseKindEnum;
/**
*
* @type {string}
* @memberof TournamentList200Response
*/
msg: TournamentList200ResponseMsgEnum;
/**
*
* @type {TournamentList200ResponsePayload}
* @memberof TournamentList200Response
*/
payload: TournamentList200ResponsePayload;
}
/**
* @export
*/
export const TournamentList200ResponseKindEnum = {
Success: 'success'
} as const;
export type TournamentList200ResponseKindEnum = typeof TournamentList200ResponseKindEnum[keyof typeof TournamentList200ResponseKindEnum];
/**
* @export
*/
export const TournamentList200ResponseMsgEnum = {
TournamentListSuccess: 'tournamentList.success'
} as const;
export type TournamentList200ResponseMsgEnum = typeof TournamentList200ResponseMsgEnum[keyof typeof TournamentList200ResponseMsgEnum];
/**
* Check if a given object implements the TournamentList200Response interface.
*/
export function instanceOfTournamentList200Response(value: object): value is TournamentList200Response {
if (!('kind' in value) || value['kind'] === undefined) return false;
if (!('msg' in value) || value['msg'] === undefined) return false;
if (!('payload' in value) || value['payload'] === undefined) return false;
return true;
}
export function TournamentList200ResponseFromJSON(json: any): TournamentList200Response {
return TournamentList200ResponseFromJSONTyped(json, false);
}
export function TournamentList200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentList200Response {
if (json == null) {
return json;
}
return {
'kind': json['kind'],
'msg': json['msg'],
'payload': TournamentList200ResponsePayloadFromJSON(json['payload']),
};
}
export function TournamentList200ResponseToJSON(json: any): TournamentList200Response {
return TournamentList200ResponseToJSONTyped(json, false);
}
export function TournamentList200ResponseToJSONTyped(value?: TournamentList200Response | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'kind': value['kind'],
'msg': value['msg'],
'payload': TournamentList200ResponsePayloadToJSON(value['payload']),
};
}

View file

@ -0,0 +1,74 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
import type { TournamentList200ResponsePayloadDataInner } from './TournamentList200ResponsePayloadDataInner';
import {
TournamentList200ResponsePayloadDataInnerFromJSON,
TournamentList200ResponsePayloadDataInnerFromJSONTyped,
TournamentList200ResponsePayloadDataInnerToJSON,
TournamentList200ResponsePayloadDataInnerToJSONTyped,
} from './TournamentList200ResponsePayloadDataInner';
/**
*
* @export
* @interface TournamentList200ResponsePayload
*/
export interface TournamentList200ResponsePayload {
/**
*
* @type {Array<TournamentList200ResponsePayloadDataInner>}
* @memberof TournamentList200ResponsePayload
*/
data: Array<TournamentList200ResponsePayloadDataInner>;
}
/**
* Check if a given object implements the TournamentList200ResponsePayload interface.
*/
export function instanceOfTournamentList200ResponsePayload(value: object): value is TournamentList200ResponsePayload {
if (!('data' in value) || value['data'] === undefined) return false;
return true;
}
export function TournamentList200ResponsePayloadFromJSON(json: any): TournamentList200ResponsePayload {
return TournamentList200ResponsePayloadFromJSONTyped(json, false);
}
export function TournamentList200ResponsePayloadFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentList200ResponsePayload {
if (json == null) {
return json;
}
return {
'data': ((json['data'] as Array<any>).map(TournamentList200ResponsePayloadDataInnerFromJSON)),
};
}
export function TournamentList200ResponsePayloadToJSON(json: any): TournamentList200ResponsePayload {
return TournamentList200ResponsePayloadToJSONTyped(json, false);
}
export function TournamentList200ResponsePayloadToJSONTyped(value?: TournamentList200ResponsePayload | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'data': ((value['data'] as Array<any>).map(TournamentList200ResponsePayloadDataInnerToJSON)),
};
}

View file

@ -0,0 +1,84 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface TournamentList200ResponsePayloadDataInner
*/
export interface TournamentList200ResponsePayloadDataInner {
/**
*
* @type {string}
* @memberof TournamentList200ResponsePayloadDataInner
*/
id: string;
/**
*
* @type {string}
* @memberof TournamentList200ResponsePayloadDataInner
*/
owner: string;
/**
*
* @type {string}
* @memberof TournamentList200ResponsePayloadDataInner
*/
time: string;
}
/**
* Check if a given object implements the TournamentList200ResponsePayloadDataInner interface.
*/
export function instanceOfTournamentList200ResponsePayloadDataInner(value: object): value is TournamentList200ResponsePayloadDataInner {
if (!('id' in value) || value['id'] === undefined) return false;
if (!('owner' in value) || value['owner'] === undefined) return false;
if (!('time' in value) || value['time'] === undefined) return false;
return true;
}
export function TournamentList200ResponsePayloadDataInnerFromJSON(json: any): TournamentList200ResponsePayloadDataInner {
return TournamentList200ResponsePayloadDataInnerFromJSONTyped(json, false);
}
export function TournamentList200ResponsePayloadDataInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentList200ResponsePayloadDataInner {
if (json == null) {
return json;
}
return {
'id': json['id'],
'owner': json['owner'],
'time': json['time'],
};
}
export function TournamentList200ResponsePayloadDataInnerToJSON(json: any): TournamentList200ResponsePayloadDataInner {
return TournamentList200ResponsePayloadDataInnerToJSONTyped(json, false);
}
export function TournamentList200ResponsePayloadDataInnerToJSONTyped(value?: TournamentList200ResponsePayloadDataInner | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'id': value['id'],
'owner': value['owner'],
'time': value['time'],
};
}

View file

@ -0,0 +1,93 @@
/* tslint:disable */
/* eslint-disable */
/**
* @fastify/swagger
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 9.6.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
/**
*
* @export
* @interface TournamentList404Response
*/
export interface TournamentList404Response {
/**
*
* @type {string}
* @memberof TournamentList404Response
*/
kind: TournamentList404ResponseKindEnum;
/**
*
* @type {string}
* @memberof TournamentList404Response
*/
msg: TournamentList404ResponseMsgEnum;
}
/**
* @export
*/
export const TournamentList404ResponseKindEnum = {
Failure: 'failure'
} as const;
export type TournamentList404ResponseKindEnum = typeof TournamentList404ResponseKindEnum[keyof typeof TournamentList404ResponseKindEnum];
/**
* @export
*/
export const TournamentList404ResponseMsgEnum = {
TournamentListFailureGeneric: 'tournamentList.failure.generic'
} as const;
export type TournamentList404ResponseMsgEnum = typeof TournamentList404ResponseMsgEnum[keyof typeof TournamentList404ResponseMsgEnum];
/**
* Check if a given object implements the TournamentList404Response interface.
*/
export function instanceOfTournamentList404Response(value: object): value is TournamentList404Response {
if (!('kind' in value) || value['kind'] === undefined) return false;
if (!('msg' in value) || value['msg'] === undefined) return false;
return true;
}
export function TournamentList404ResponseFromJSON(json: any): TournamentList404Response {
return TournamentList404ResponseFromJSONTyped(json, false);
}
export function TournamentList404ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): TournamentList404Response {
if (json == null) {
return json;
}
return {
'kind': json['kind'],
'msg': json['msg'],
};
}
export function TournamentList404ResponseToJSON(json: any): TournamentList404Response {
return TournamentList404ResponseToJSONTyped(json, false);
}
export function TournamentList404ResponseToJSONTyped(value?: TournamentList404Response | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
return {
'kind': value['kind'],
'msg': value['msg'],
};
}

View file

@ -28,7 +28,7 @@ import {
*/
export interface TttHistory200ResponsePayloadDataInner {
/**
* gameId
*
* @type {string}
* @memberof TttHistory200ResponsePayloadDataInner
*/

View file

@ -15,6 +15,10 @@ export * from './ChangePassword400Response';
export * from './ChangePassword401Response';
export * from './ChangePassword500Response';
export * from './ChangePasswordRequest';
export * from './CreatePauseGame200Response';
export * from './CreatePauseGame200ResponsePayload';
export * from './CreatePauseGame404Response';
export * from './CreatePauseGameRequest';
export * from './DisableOtp200Response';
export * from './DisableOtp400Response';
export * from './DisableOtp500Response';
@ -47,18 +51,11 @@ export * from './LoginOtp500Response';
export * from './LoginOtpRequest';
export * from './LoginRequest';
export * from './Logout200Response';
export * from './PongCreatePauseGame200Response';
export * from './PongCreatePauseGame200ResponsePayload';
export * from './PongCreatePauseGame404Response';
export * from './PongCreatePauseGameRequest';
export * from './PongHistory200Response';
export * from './PongHistory200ResponsePayload';
export * from './PongHistory200ResponsePayloadDataInner';
export * from './PongHistory200ResponsePayloadDataInnerLeft';
export * from './PongHistory404Response';
export * from './PongstartPauseGame200Response';
export * from './PongstartPauseGame404Response';
export * from './PongstartPauseGameRequest';
export * from './ProviderList200Response';
export * from './ProviderList200ResponsePayload';
export * from './ProviderList200ResponsePayloadListInner';
@ -73,6 +70,15 @@ export * from './StatusOtp200ResponseAnyOf1';
export * from './StatusOtp200ResponseAnyOfPayload';
export * from './StatusOtp401Response';
export * from './StatusOtp500Response';
export * from './TournamentData200Response';
export * from './TournamentData200ResponsePayload';
export * from './TournamentData200ResponsePayloadData';
export * from './TournamentData200ResponsePayloadDataUsersInner';
export * from './TournamentData404Response';
export * from './TournamentList200Response';
export * from './TournamentList200ResponsePayload';
export * from './TournamentList200ResponsePayloadDataInner';
export * from './TournamentList404Response';
export * from './TttHistory200Response';
export * from './TttHistory200ResponsePayload';
export * from './TttHistory200ResponsePayloadDataInner';

View file

@ -54,24 +54,7 @@
<kbd class="disp-key">L</kbd>
</span>
</div>
<div id="tourscore-box" class="white-color rounded-elem focus-elem text-2xl hidden">
up:
<kbd class="pong-protips-key">W</kbd>
down:
<kbd class="pong-protips-key">S</kbd>
<br />
You are <span class="text-red-500">red</span>.
<br />
Your goal is to bounce the ball back to the adversary.
<br />
<span class="text-gray-400">local games keys for the left paddle:
<br />
up:
<kbd class="disp-key">O</kbd>
down:
<kbd class="disp-key">L</kbd>
</span>
</div>
<div id="tourscore-box" class="white-color rounded-elem focus-elem text-2xl hidden">We havent seen any tournament yet !</div>
<button id="readyup-btn" class="justify-center white-color focus-elem rounded-elem">ready!</button>
<div class="pong-field">
<div id="batleft" class="pong-bat pong-batleft top-0"></div>

View file

@ -6,6 +6,7 @@ import {
type RouteHandlerReturn,
} from "@app/routing";
import authHtml from "./pong.html?raw";
import tourScoresHtml from "./tourTable.html?raw";
import io from "socket.io-client";
import { JoinRes, type CSocket, type GameMove, type GameUpdate, type TourInfo } from "./socket";
import { showError, showInfo, showSuccess } from "@app/toast";
@ -301,39 +302,28 @@ function pongClient(
const renderTournamentScores = (info: TourInfo) => {
let players = info.players.sort((l, r) => r.score - l.score);
tour_scores.innerHTML = `
<div class="overflow-x-auto">
<table class="min-w-full border border-gray-200 rounded-lg shadow-sm">
<thead class="bg-gray-100">
<tr>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 border-b">
Name
</th>
<th class="px-4 py-2 text-right text-sm font-semibold text-gray-700 border-b">
Score
</th>
</tr>
</thead>
<tbody>
${players
.map(
(player) => `
<tr class="hover:bg-gray-50" key="${player.id}">
<td class="px-4 py-2 text-sm text-gray-800 border-b">
${player.name}
</td>
<td class="px-4 py-2 text-sm text-gray-800 text-right border-b">
${player.score}
</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
</div>`;
const medals = ["🥇", "🥈", "🥉"];
tour_scores.innerHTML = tourScoresHtml;
let table = tour_scores.querySelector("#tour-score-body");
if (table)
table.innerHTML = players.map((player, idx) =>
`<tr class="${player.id === user.id ? "bg-amber-400 hover:bg-amber-500" : "hover:bg-gray-50"}" key="${player.id}">
<td class="px-4 py-2 text-sm text-gray-800 text-center border-b font-semibold min-w-100px">${idx < medals.length ? `<span class="font-lg">${medals[idx]}</span>` : ''}${player.name}</td>
<td class="px-4 py-2 text-sm text-gray-800 text-center border-b font-bold min-w-100px">${player.score}</td>
</tr>`)
.join("");
};
// TODO: REMOVE THIS
// const makePlayer = (n: number) => ({ name: `user${n}`, id: `${n}`, score: n })
//
// renderTournamentScores({
// state: "playing",
// ownerId: "ownerID",
// remainingMatches: null,
// players: [...Array.from(Array(10).keys()).map(makePlayer), { id: user.id, name: user.name, score: 99 }],
// });
const render = (state: GameUpdate) => {
batLeft.style.top = `${state.left.paddle.y}px`;
batLeft.style.left = `${state.left.paddle.x}px`;

View file

@ -0,0 +1,22 @@
<div class="px-4">
<span class="block mb-2 font-semibold">Tournament Scores</span>
<div class="max-h-[320px] overflow-y-auto overflow-x-auto border rounded-lg">
<table class="min-w-full border-collapse table-fixed">
<thead class="sticky top-0 z-10 bg-gray-100">
<tr>
<th class="px-4 py-2 text-right text-sm font-semibold text-gray-700 border-b">
Name
</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 border-b">
Score
</th>
</tr>
</thead>
<tbody id="tour-score-body">
<!-- rows -->
</tbody>
</table>
</div>
</div>

View file

@ -6,13 +6,15 @@ import { IUserDb, UserImpl } from './mixin/user';
import { IBlockedDb, BlockedImpl } from './mixin/blocked';
import { ITicTacToeDb, TicTacToeImpl } from './mixin/tictactoe';
import { IPongDb, PongImpl } from './mixin/pong';
import { ITournamentDb, TournamentImpl } from './mixin/tournament';
Object.assign(DbImpl.prototype, UserImpl);
Object.assign(DbImpl.prototype, BlockedImpl);
Object.assign(DbImpl.prototype, TicTacToeImpl);
Object.assign(DbImpl.prototype, PongImpl);
Object.assign(DbImpl.prototype, TournamentImpl);
export interface Database extends DbImpl, IUserDb, IBlockedDb, ITicTacToeDb, IPongDb { }
export interface Database extends DbImpl, IUserDb, IBlockedDb, ITicTacToeDb, IPongDb, ITournamentDb { }
// When using .decorate you have to specify added properties for Typescript
declare module 'fastify' {

View file

@ -1,3 +1,7 @@
----------------
-- AUTH --
----------------
CREATE TABLE IF NOT EXISTS user (
id TEXT PRIMARY KEY NOT NULL,
login TEXT UNIQUE,
@ -10,6 +14,10 @@ CREATE TABLE IF NOT EXISTS user (
allow_guest_message INTEGER NOT NULL DEFAULT 1
);
----------------
-- CHAT --
----------------
CREATE TABLE IF NOT EXISTS blocked (
id INTEGER PRIMARY KEY NOT NULL,
user TEXT NOT NULL,
@ -19,19 +27,27 @@ CREATE TABLE IF NOT EXISTS blocked (
CREATE UNIQUE INDEX IF NOT EXISTS idx_blocked_user_pair ON blocked (user, blocked);
----------------
-- TICTACTOE --
----------------
CREATE TABLE IF NOT EXISTS tictactoe (
id TEXT PRIMARY KEY NOT NULL,
time TEXT NOT NULL default (datetime('now')),
playerX TEXT NOT NULL,
playerO TEXT NOT NULL,
outcome TEXT NOT NULL,
FOREIGN KEY(playerX) REFERENCES user(id),
FOREIGN KEY(playerO) REFERENCES user(id)
id TEXT PRIMARY KEY NOT NULL,
time TEXT NOT NULL default (datetime ('now')),
playerX TEXT NOT NULL,
playerO TEXT NOT NULL,
outcome TEXT NOT NULL,
FOREIGN KEY (playerX) REFERENCES user (id),
FOREIGN KEY (playerO) REFERENCES user (id)
);
----------------
-- PONG --
----------------
CREATE TABLE IF NOT EXISTS pong (
id TEXT PRIMARY KEY NOT NULL,
time TEXT NOT NULL default (datetime('now')),
time TEXT NOT NULL default (datetime ('now')),
playerL TEXT NOT NULL,
playerR TEXT NOT NULL,
scoreL INTEGER NOT NULL,
@ -41,3 +57,32 @@ CREATE TABLE IF NOT EXISTS pong (
FOREIGN KEY (playerL) REFERENCES user (id),
FOREIGN KEY (playerR) REFERENCES user (id)
);
----------------
-- TOURNAMENT --
----------------
CREATE TABLE IF NOT EXISTS tournament (
id TEXT PRIMARY KEY NOT NULL,
time TEXT NOT NULL default (datetime ('now')),
owner TEXT NOT NULL,
FOREIGN KEY (owner) REFERENCES user (id)
);
CREATE TABLE IF NOT EXISTS tour_user (
id INTEGER PRIMARY KEY NOT NULL,
user TEXT NOT NULL,
tournament TEXT NOT NULL,
nickname TEXT NOT NULL,
score INTEGER NOT NULL,
FOREIGN KEY (user) REFERENCES user (id),
FOREIGN KEY (tournament) REFERENCES tournament (id)
);
CREATE TABLE IF NOT EXISTS tour_game (
id INTEGER PRIMARY KEY NOT NULL,
tournament TEXT NOT NULL,
game TEXT NOT NULL,
FOREIGN KEY (game) REFERENCES pong (id),
FOREIGN KEY (tournament) REFERENCES tournament (id)
);

View file

@ -108,7 +108,7 @@ type PongGameTable = {
local: number,
};
function pongGameFromRow(r: Partial<PongGameTable> | undefined): PongGame | undefined {
export function pongGameFromRow(r: Partial<PongGameTable> | undefined): PongGame | undefined {
if (isNullish(r)) return undefined;
if (isNullish(r.id)) return undefined;
if (isNullish(r.playerL)) return undefined;

View file

@ -0,0 +1,133 @@
import UUID, { newUUID } from '@shared/utils/uuid';
import type { Database } from './_base';
import { UserId } from './user';
import { PongGame, pongGameFromRow, PongGameId } from './pong';
import { isNullish } from '@shared/utils';
// never use this directly
// describe every function in the object
export interface ITournamentDb extends Database {
getTournamentById(
this: ITournamentDb,
id: TournamentId,
): TournamentData | null,
createNewTournamentById(
this: ITournamentDb,
owner: UserId,
users: { id: UserId, name: string, score: number }[],
games: PongGameId[],
): void,
getAllTournamentsData(this: ITournamentDb): TournamentTable[],
getLastTournament(this: ITournamentDb): TournamentTable | undefined;
};
export const TournamentImpl: Omit<ITournamentDb, keyof Database> = {
/**
* whole function description
*
* @param id the argument description
*
* @returns what does the function return ?
*/
getTournamentById(
this: ITournamentDb,
id: TournamentId,
): TournamentData | null {
// Fetch tournament
const tournament = this
.prepare('SELECT id, time, owner FROM tournament WHERE id = @id')
.get({ id }) as TournamentTable;
if (!tournament) {
return null;
}
// Fetch games
const games = this.prepare(`
SELECT
pong.*,
userL.name AS nameL,
userR.name AS nameR
FROM
tour_game
INNER JOIN pong
ON pong.id == tour_game.game
INNER JOIN user AS userL
ON pong.playerL = userL.id
INNER JOIN user AS userR
ON pong.playerR = userR.id
WHERE
tour_game.tournament = @id
ORDER BY pong.id`).all({ id })
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.map((s: any) => {
const g: (PongGame & { nameL?: string, nameR?: string }) | undefined = pongGameFromRow(s);
if (isNullish(g)) return undefined;
g.nameL = s.nameL;
g.nameR = s.nameR;
if (isNullish(g.nameL) || isNullish(g.nameR)) return undefined;
return g as PongGame & { nameL: string, nameR: string };
}).filter(v => !isNullish(v));
;
// Fetch users
const users = this.prepare('SELECT id, user, tournament, nickname, score FROM tour_user WHERE tournament = @id').all({ id }) as TournamentUser[];
return {
...tournament,
games,
users,
};
},
createNewTournamentById(
this: ITournamentDb,
owner: UserId,
users: { id: UserId, name: string, score: number }[],
games: PongGameId[],
): void {
const tournamentId = newUUID() as TournamentId;
this.prepare('INSERT INTO tournament (id, owner) VALUES (@id, @owner)').run({ id: tournamentId, owner });
for (const u of users) {
this.prepare('INSERT INTO tour_user (user, nickname, score, tournament) VALUES (@id, @name, @score, @tournament)').run({ id: u.id, name: u.name, score: u.score, tournament: tournamentId });
}
for (const g of games) {
this.prepare('INSERT INTO tour_game (tournament, game) VALUES (@tournament, @game)').run({ tournament: tournamentId, game: g });
}
},
getAllTournamentsData(this: ITournamentDb): TournamentTable[] {
return this.prepare('SELECT * FROM tournament ORDER BY rowid').all() as TournamentTable[];
},
getLastTournament(this: ITournamentDb): TournamentTable | undefined {
return this.prepare('SELECT * FROM tournament ORDER BY rowid LIMIT 1').get() as TournamentTable | undefined;
},
};
export type TournamentId = UUID & { readonly __uuid: unique symbol };
export interface TournamentTable {
id: TournamentId;
time: string;
owner: UserId;
}
export interface TournamentUser {
user: UserId;
tournament: TournamentId;
nickname: string;
score: number;
}
export type TournamentGame = PongGame & { nameL: string, nameR: string };
export interface TournamentData extends TournamentTable {
games: TournamentGame[];
users: TournamentUser[];
}

View file

@ -2144,9 +2144,9 @@
]
}
},
"/createPausedGame": {
"/api/pong/createPausedGame": {
"post": {
"operationId": "pongCreatePauseGame",
"operationId": "createPauseGame",
"requestBody": {
"content": {
"application/json": {
@ -2451,28 +2451,20 @@
]
}
},
"/startPausedGame": {
"post": {
"operationId": "pongstartPauseGame",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"gameId"
],
"properties": {
"gameId": {
"type": "string",
"description": "'id' | <gameid>"
}
}
}
}
},
"required": true
},
"/api/pong/tournament/{id}": {
"get": {
"operationId": "TournamentData",
"parameters": [
{
"schema": {
"type": "string"
},
"in": "path",
"name": "id",
"required": true,
"description": "the tournament id"
}
],
"responses": {
"200": {
"description": "Default Response",
@ -2493,18 +2485,188 @@
},
"msg": {
"enum": [
"startPausedGame.success"
"tournamentData.success"
]
},
"payload": {
"type": "object",
"properties": {}
"required": [
"data"
],
"properties": {
"data": {
"type": "object",
"required": [
"owner",
"users",
"games",
"time"
],
"properties": {
"owner": {
"type": "string",
"description": "ownerId"
},
"users": {
"type": "array",
"items": {
"type": "object",
"required": [
"score",
"id",
"nickname"
],
"properties": {
"score": {
"type": "integer"
},
"id": {
"type": "string"
},
"nickname": {
"type": "string"
}
}
}
},
"games": {
"type": "array",
"items": {
"type": "object",
"required": [
"gameId",
"left",
"right",
"local",
"date",
"outcome"
],
"properties": {
"gameId": {
"type": "string",
"description": "gameId"
},
"left": {
"type": "object",
"required": [
"score",
"id",
"name"
],
"properties": {
"score": {
"type": "integer"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"right": {
"type": "object",
"required": [
"score",
"id",
"name"
],
"properties": {
"score": {
"type": "integer"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"local": {
"type": "boolean"
},
"date": {
"type": "string"
},
"outcome": {
"enum": [
"winL",
"winR",
"other"
]
}
}
}
},
"time": {
"type": "string"
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"anyOf": [
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
},
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
}
]
}
}
}
},
"404": {
"description": "Default Response",
"content": {
@ -2523,7 +2685,157 @@
},
"msg": {
"enum": [
"startPausedGame.no_such_game"
"tournamentData.failure.notFound"
]
}
}
}
}
}
}
},
"tags": [
"openapi_other"
]
}
},
"/api/pong/tournament/": {
"get": {
"operationId": "TournamentList",
"responses": {
"200": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"kind",
"msg",
"payload"
],
"properties": {
"kind": {
"enum": [
"success"
]
},
"msg": {
"enum": [
"tournamentList.success"
]
},
"payload": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"owner",
"time"
],
"properties": {
"id": {
"type": "string",
"description": "tournamentId"
},
"owner": {
"type": "string",
"description": "ownerId"
},
"time": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"anyOf": [
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
},
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
}
]
}
}
}
},
"404": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"failure"
]
},
"msg": {
"enum": [
"tournamentList.failure.generic"
]
}
}

View file

@ -8,9 +8,9 @@
"schemas": {}
},
"paths": {
"/createPausedGame": {
"/api/pong/createPausedGame": {
"post": {
"operationId": "pongCreatePauseGame",
"operationId": "createPauseGame",
"requestBody": {
"content": {
"application/json": {
@ -309,28 +309,20 @@
}
}
},
"/startPausedGame": {
"post": {
"operationId": "pongstartPauseGame",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"gameId"
],
"properties": {
"gameId": {
"type": "string",
"description": "'id' | <gameid>"
}
}
}
}
},
"required": true
},
"/api/pong/tournament/{id}": {
"get": {
"operationId": "TournamentData",
"parameters": [
{
"schema": {
"type": "string"
},
"in": "path",
"name": "id",
"required": true,
"description": "the tournament id"
}
],
"responses": {
"200": {
"description": "Default Response",
@ -351,18 +343,188 @@
},
"msg": {
"enum": [
"startPausedGame.success"
"tournamentData.success"
]
},
"payload": {
"type": "object",
"properties": {}
"required": [
"data"
],
"properties": {
"data": {
"type": "object",
"required": [
"owner",
"users",
"games",
"time"
],
"properties": {
"owner": {
"type": "string",
"description": "ownerId"
},
"users": {
"type": "array",
"items": {
"type": "object",
"required": [
"score",
"id",
"nickname"
],
"properties": {
"score": {
"type": "integer"
},
"id": {
"type": "string"
},
"nickname": {
"type": "string"
}
}
}
},
"games": {
"type": "array",
"items": {
"type": "object",
"required": [
"gameId",
"left",
"right",
"local",
"date",
"outcome"
],
"properties": {
"gameId": {
"type": "string",
"description": "gameId"
},
"left": {
"type": "object",
"required": [
"score",
"id",
"name"
],
"properties": {
"score": {
"type": "integer"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"right": {
"type": "object",
"required": [
"score",
"id",
"name"
],
"properties": {
"score": {
"type": "integer"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"local": {
"type": "boolean"
},
"date": {
"type": "string"
},
"outcome": {
"enum": [
"winL",
"winR",
"other"
]
}
}
}
},
"time": {
"type": "string"
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"anyOf": [
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
},
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
}
]
}
}
}
},
"404": {
"description": "Default Response",
"content": {
@ -381,7 +543,154 @@
},
"msg": {
"enum": [
"startPausedGame.no_such_game"
"tournamentData.failure.notFound"
]
}
}
}
}
}
}
}
}
},
"/api/pong/tournament/": {
"get": {
"operationId": "TournamentList",
"responses": {
"200": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"kind",
"msg",
"payload"
],
"properties": {
"kind": {
"enum": [
"success"
]
},
"msg": {
"enum": [
"tournamentList.success"
]
},
"payload": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"owner",
"time"
],
"properties": {
"id": {
"type": "string",
"description": "tournamentId"
},
"owner": {
"type": "string",
"description": "ownerId"
},
"time": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"anyOf": [
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
},
{
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"notLoggedIn"
]
},
"msg": {
"enum": [
"auth.noCookie",
"auth.invalidKind",
"auth.noUser",
"auth.invalid"
]
}
}
}
]
}
}
}
},
"404": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"failure"
]
},
"msg": {
"enum": [
"tournamentList.failure.generic"
]
}
}

View file

@ -0,0 +1,101 @@
import { TournamentId } from '@shared/database/mixin/tournament';
import { isNullish, MakeStaticResponse, typeResponse } from '@shared/utils';
import { FastifyPluginAsync } from 'fastify';
import { Static, Type } from 'typebox';
const TournamentDataParams = Type.Object({
id: Type.String({ description: 'the tournament id' }),
});
type TournamentDataParams = Static<typeof TournamentDataParams>;
const TournamentDataResponse = {
'200': typeResponse('success', 'tournamentData.success', {
data: Type.Object({
owner: Type.String({ description: 'ownerId' }),
users: Type.Array(
Type.Object({
score: Type.Integer(),
id: Type.String(),
nickname: Type.String(),
}),
),
games: Type.Array(
Type.Object({
gameId: Type.String({ description: 'gameId' }),
left: Type.Object({
score: Type.Integer(),
id: Type.String(),
name: Type.String(),
}),
right: Type.Object({
score: Type.Integer(),
id: Type.String(),
name: Type.String(),
}),
local: Type.Boolean(),
date: Type.String(),
outcome: Type.Enum(['winL', 'winR', 'other']),
}),
),
time: Type.String(),
}),
}),
'404': typeResponse('failure', 'tournamentData.failure.notFound'),
};
type TournamentDataResponse = MakeStaticResponse<typeof TournamentDataResponse>;
const route: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.get<{ Params: TournamentDataParams }>(
'/api/pong/tournament/:id',
{
schema: {
params: TournamentDataParams,
response: TournamentDataResponse,
operationId: 'TournamentData',
},
config: { requireAuth: true },
},
async function(req, res) {
const tourId = req.params.id;
const data = this.db.getTournamentById(tourId as TournamentId);
if (isNullish(data)) {
return res.makeResponse(
404,
'failure',
'tournamentData.failure.notFound',
);
}
const typed_res: TournamentDataResponse['200']['payload']['data'] =
{
owner: data.owner,
time: data.time,
users: data.users.map((v) => ({
nickname: v.nickname,
score: v.score,
id: v.user,
})),
games: data.games.map((v) => ({
gameId: v.id,
left: {
score: v.left.score,
id: v.left.id,
name: `${v.nameL}-left`,
},
right: {
score: v.right.score,
id: v.right.id,
name: `${v.nameR}-right`,
},
local: v.local,
date: v.time.toString(),
outcome: v.outcome,
})),
};
console.log(JSON.stringify(typed_res));
return res.makeResponse(200, 'success', 'tournamentData.success', {
data: typed_res,
});
},
);
};
export default route;

View file

@ -0,0 +1,71 @@
import { MakeStaticResponse, typeResponse } from '@shared/utils';
import { FastifyPluginAsync } from 'fastify';
import { Type } from 'typebox';
const TournamentListResponse = {
'200': typeResponse('success', 'tournamentList.success', {
data: Type.Array(
Type.Object({
id: Type.String({ description: 'tournamentId' }),
owner: Type.String({ description: 'ownerId' }),
time: Type.String(),
}),
),
}),
'404': typeResponse('failure', 'tournamentList.failure.generic'),
};
/*
const TournamentListResponse = {
'200': typeResponse('success', 'tournamentHistory.success', {
data: Type.Array(
Type.Object({
owner: Type.String({ description: 'ownerId' }),
users: Type.Array(Type.Object({
score: Type.Integer(),
id: Type.String(),
name: Type.String(),
})),
game: Type.Object({
gameId: Type.String({ description: 'gameId' }),
left: Type.Object({
score: Type.Integer(),
id: Type.String(),
name: Type.String(),
}),
right: Type.Object({
score: Type.Integer(),
id: Type.String(),
name: Type.String(),
}),
local: Type.Boolean(),
date: Type.String(),
outcome: Type.Enum(['winL', 'winR', 'other']),
}),
date: Type.String(),
}),
),
}),
'404': typeResponse('failure', 'tournamentHistory.failure.generic'),
};
*/
type TournamentListResponse = MakeStaticResponse<typeof TournamentListResponse>;
const route: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.get(
'/api/pong/tournament/',
{
schema: {
response: TournamentListResponse,
operationId: 'TournamentList',
},
config: { requireAuth: true },
},
async function(req, res) {
void req;
const typed_data: TournamentListResponse['200']['payload']['data'] = this.db.getAllTournamentsData();
return res.makeResponse(200, 'success', 'tournamentHistory.success', { data: typed_data });
},
);
};
export default route;

View file

@ -208,6 +208,7 @@ class StateI {
private cleanupTournament() {
if (this.tournament === null) return;
if (this.tournament.state === 'ended') { this.fastify.db.createNewTournamentById(this.tournament.owner, this.tournament.users.values().toArray(), this.tournament.games); }
this.tournament = null;
this.fastify.log.info('Tournament has been ended');
}
@ -305,6 +306,8 @@ class StateI {
const user = this.users.get(sock.authUser.id);
if (!user) return;
if (this.tournament && this.tournament.users.has(sock.authUser.id)) return;
const gameId = newUUID() as unknown as GameId;
const g = Pong.makeLocal(user.id);
const iState: GameUpdate = StateI.getGameUpdateData(gameId, g);
@ -538,6 +541,8 @@ class StateI {
if (this.users.get(socket.authUser.id)?.currentGame !== null) return;
if (this.tournament && this.tournament.users.has(socket.authUser.id)) return;
this.queue.add(socket.authUser.id);
socket.emit('queueEvent', 'registered');
}

View file

@ -17,6 +17,7 @@ export class Tournament {
public matchup: [UserId, UserId][] = [];
public state: TournamentState = 'prestart';
public startTimeout: NodeJS.Timeout | undefined;
public games: PongGameId[] = [];
constructor(public owner: UserId) { }
@ -69,6 +70,7 @@ export class Tournament {
game.onEnd = () => this.gameEnd();
}
this.currentGame = gameId;
this.games.push(gameId);
}
else {
this.state = 'ended';
@ -78,15 +80,9 @@ export class Tournament {
}
public gameEnd() {
console.log(this);
State.fastify.log.info('tournament game ended');
if (!isNullish(this.currentGame)) {
State.fastify.log.info('HERE2');
State.fastify.log.info(State.games);
State.fastify.log.info(this.currentGame);
const game = State.games.get(this.currentGame);
if (game) {
State.fastify.log.info('HERE3');
const winner = game.checkWinner();
const winnerId = winner === 'left' ? game.userLeft : game.userRight;