UNPKG

brackets-manager

Version:

A simple library to manage tournament brackets (round-robin, single elimination, double elimination)

151 lines 6.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BracketsManager = void 0; const create_1 = require("./create"); const get_1 = require("./get"); const update_1 = require("./update"); const delete_1 = require("./delete"); const find_1 = require("./find"); const reset_1 = require("./reset"); const uuid_1 = require("uuid"); const helpers = require("./helpers"); /** * A class to handle tournament management at those levels: `stage`, `group`, `round`, `match` and `match_game`. */ class BracketsManager { /** * Creates an instance of BracketsManager, which will handle all the stuff from the library. * * @param storageInterface An implementation of CrudInterface. * @param verbose Whether to log CRUD operations. */ constructor(storageInterface, verbose) { this.verbose = false; this.verbose = verbose !== null && verbose !== void 0 ? verbose : false; this.storage = storageInterface; this.instrumentStorage(); // eslint-disable-next-line @typescript-eslint/explicit-function-return-type this.storage.selectFirst = async (table, filter, assertUnique = true) => { var _a; const results = await this.storage.select(table, filter); if (!results || results.length === 0) return null; if (assertUnique && results.length > 1) throw Error(`Selecting ${JSON.stringify(filter)} on table "${table}" must return a unique value.`); return (_a = results[0]) !== null && _a !== void 0 ? _a : null; }; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type this.storage.selectLast = async (table, filter, assertUnique = true) => { var _a; const results = await this.storage.select(table, filter); if (!results || results.length === 0) return null; if (assertUnique && results.length > 1) throw Error(`Selecting ${JSON.stringify(filter)} on table "${table}" must return a unique value.`); return (_a = results[results.length - 1]) !== null && _a !== void 0 ? _a : null; }; const create = new create_1.Create(this.storage); const createStageFunction = create.stage.bind(this); this.create = Object.assign(createStageFunction, { stage: createStageFunction }); this.get = new get_1.Get(this.storage); this.update = new update_1.Update(this.storage); this.delete = new delete_1.Delete(this.storage); this.find = new find_1.Find(this.storage); this.reset = new reset_1.Reset(this.storage); } /** * Imports data in the database. * * @param data Data to import. * @param normalizeIds Enable ID normalization: all IDs (and references to them) are remapped to consecutive IDs starting from 0. */ async import(data, normalizeIds = false) { if (normalizeIds) data = helpers.normalizeIds(data); if (!await this.storage.delete('participant')) throw Error('Could not empty the participant table.'); if (!await this.storage.insert('participant', data.participant)) throw Error('Could not import participants.'); if (!await this.storage.delete('stage')) throw Error('Could not empty the stage table.'); if (!await this.storage.insert('stage', data.stage)) throw Error('Could not import stages.'); if (!await this.storage.delete('group')) throw Error('Could not empty the group table.'); if (!await this.storage.insert('group', data.group)) throw Error('Could not import groups.'); if (!await this.storage.delete('round')) throw Error('Could not empty the round table.'); if (!await this.storage.insert('round', data.round)) throw Error('Could not import rounds.'); if (!await this.storage.delete('match')) throw Error('Could not empty the match table.'); if (!await this.storage.insert('match', data.match)) throw Error('Could not import matches.'); if (!await this.storage.delete('match_game')) throw Error('Could not empty the match_game table.'); if (!await this.storage.insert('match_game', data.match_game)) throw Error('Could not import match games.'); } /** * Exports data from the database. */ async export() { const participants = await this.storage.select('participant'); if (!participants) throw Error('Error getting participants.'); const stages = await this.storage.select('stage'); if (!stages) throw Error('Error getting stages.'); const groups = await this.storage.select('group'); if (!groups) throw Error('Error getting groups.'); const rounds = await this.storage.select('round'); if (!rounds) throw Error('Error getting rounds.'); const matches = await this.storage.select('match'); if (!matches) throw Error('Error getting matches.'); const matchGames = await this.get.matchGames(matches); return { participant: participants, stage: stages, group: groups, round: rounds, match: matches, match_game: matchGames, }; } /** * Add `console.log()` to storage methods in verbose mode. */ instrumentStorage() { const storage = this.storage; const instrumentedMethods = ['insert', 'select', 'update', 'delete']; for (const method of Object.getOwnPropertyNames(Object.getPrototypeOf(storage))) { if (!instrumentedMethods.includes(method)) continue; const originalMethod = storage[method].bind(storage); storage[method] = async (table, ...args) => { const verbose = this.verbose; let id; let start; if (verbose) { id = (0, uuid_1.v4)(); start = Date.now(); console.log(`${id} ${method.toUpperCase()} "${table}" args: ${JSON.stringify(args)}`); } const result = await originalMethod(table, ...args); if (verbose) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const duration = Date.now() - start; // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion console.log(`${id} ${duration}ms - Returned ${JSON.stringify(result)}`); } return result; }; } } } exports.BracketsManager = BracketsManager; //# sourceMappingURL=manager.js.map