dimensions-ai
Version:
A generalized AI Competition framework that allows you to create any competition you want in any language you want with no hassle.
250 lines • 9.66 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import admin from 'firebase-admin';
import { Plugin } from '../../Plugin';
import { Database } from '../../Plugin/Database';
import { DatabaseType } from '../../Dimension';
import { pickMatch } from '../../Station/routes/api/dimensions/match';
import bcrypt from 'bcryptjs';
import { generateToken, verify } from '../../Plugin/Database/utils';
import { Player } from '../../Tournament';
import { deepMerge } from '../../utils/DeepMerge';
import { deepCopy } from '../../utils/DeepCopy';
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();
const salt = bcrypt.genSaltSync();
export class FireStore extends Database {
constructor(fireStoreConfigs, configs = {}) {
super(configs);
this.name = 'FireStore';
this.type = Plugin.Type.DATABASE;
admin.initializeApp({
credential: admin.credential.cert(fireStoreConfigs.keyFile),
});
}
/**
* Connects to the firestore database and returns the db object
*/
connect() {
return __awaiter(this, void 0, void 0, function* () {
this.db = admin.firestore();
this.db.settings({ ignoreUndefinedProperties: true });
return this.db;
});
}
initialize() {
return __awaiter(this, void 0, void 0, function* () {
yield this.connect();
this.userCollection = this.db.collection(FireStore.Collections.USERS);
this.matchesCollection = this.db.collection(FireStore.Collections.MATCHES);
this.tournamentConfigsCollection = this.db.collection(FireStore.Collections.TOURNAMENT_CONFIGS);
// create admin user
const existingUser = yield this.getUser('admin');
if (!existingUser) {
yield this.registerUser('admin', process.env.ADMIN_PASSWORD);
}
return;
});
}
storeMatch(match, governID) {
return __awaiter(this, void 0, void 0, function* () {
const data = Object.assign(Object.assign({}, pickMatch(match)), { governID: governID });
// remove extra data
delete data.configs;
// store all relevant data
const plainAgentIDtoTournamentID = {};
data.mapAgentIDtoTournamentID.forEach((val, key) => {
plainAgentIDtoTournamentID[key] = val;
});
data.mapAgentIDtoTournamentID = plainAgentIDtoTournamentID;
return this.matchesCollection.doc().set(data);
});
}
getMatch(id) {
return __awaiter(this, void 0, void 0, function* () {
const snapshot = yield this.matchesCollection
.where('matchID', '==', id)
.get();
return snapshot.docs[0].data();
});
}
getPlayerMatches(playerID, governID, offset = 0, limit = 10, order = -1) {
return __awaiter(this, void 0, void 0, function* () {
let sortOrder = 'desc';
if (order > 0) {
sortOrder = 'asc';
}
let query = this.matchesCollection
.where('governID', '==', governID)
.orderBy('creationDate', sortOrder)
.offset(offset);
if (limit == 0) {
return [];
}
if (limit > 0) {
query = query.limit(limit);
}
const snapshot = yield query.get();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return snapshot.docs.map((d) => d.data());
});
}
registerUser(username, password,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
userData) {
return __awaiter(this, void 0, void 0, function* () {
const hash = bcrypt.hashSync(password, salt);
return this.userCollection.doc(username).set({
username: username,
passwordHash: hash,
statistics: {},
playerID: Player.generatePlayerID(),
meta: Object.assign({}, userData),
});
});
}
/**
* Gets user information. If public is false, will retrieve all information other than password
* @param usernameOrID
*/
getUser(usernameOrID, publicView = true) {
return __awaiter(this, void 0, void 0, function* () {
const doc = yield this.getUserDoc(usernameOrID);
if (doc === null) {
return null;
}
const user = doc.data();
if (user && publicView) {
user.passwordHash = '';
}
return user;
});
}
getUserDoc(usernameOrID) {
return __awaiter(this, void 0, void 0, function* () {
let snapshot = yield this.userCollection
.where('playerID', '==', usernameOrID)
.get();
if (snapshot.empty) {
snapshot = yield this.userCollection
.where('username', '==', usernameOrID)
.get();
}
if (snapshot.empty) {
return null;
}
return snapshot.docs[0];
});
}
loginUser(username, password) {
return __awaiter(this, void 0, void 0, function* () {
const snapshot = yield this.userCollection
.where('username', '==', username)
.get();
if (snapshot.empty) {
throw new Error('Not a valid user');
}
const user = snapshot.docs[0].data();
if (bcrypt.compareSync(password, user.passwordHash)) {
return generateToken(user);
}
else {
throw new Error('Invalid password');
}
});
}
updateUser(usernameOrID, update) {
return __awaiter(this, void 0, void 0, function* () {
const doc = yield this.getUserDoc(usernameOrID);
if (doc === null) {
throw new Error('Not a valid user');
}
yield doc.ref.update(update);
return deepMerge(deepCopy(doc.data()), deepCopy(update));
});
}
deleteUser(usernameOrID) {
return __awaiter(this, void 0, void 0, function* () {
const doc = yield this.getUserDoc(usernameOrID);
yield doc.ref.delete();
});
}
verifyToken(jwt) {
return __awaiter(this, void 0, void 0, function* () {
return verify(jwt);
});
}
isAdmin(user) {
if (user.username === 'admin')
return true;
return false;
}
getUsersInTournament(tournamentKey, offset = 0, limit = -1) {
return __awaiter(this, void 0, void 0, function* () {
const key = `statistics.${tournamentKey}`;
if (limit == 0) {
return [];
}
let query = this.userCollection
.where(`${key}.matchesPlayed`, '>=', 0)
.offset(offset);
if (limit > 0) {
query = query.limit(limit);
}
const snapshot = yield query.get();
return snapshot.docs.map((d) => d.data());
});
}
manipulate(dimension) {
return __awaiter(this, void 0, void 0, function* () {
dimension.configs.backingDatabase = DatabaseType.FIRESTORE;
return;
});
}
storeTournamentConfigs(tournamentID, tournamentConfigs, status) {
return __awaiter(this, void 0, void 0, function* () {
yield this.tournamentConfigsCollection.doc(tournamentID).set({
status: status,
configs: tournamentConfigs,
modificationDate: new Date(),
});
return;
});
}
getTournamentConfigsModificationDate(tournamentID) {
return __awaiter(this, void 0, void 0, function* () {
const snapshot = yield this.tournamentConfigsCollection
.doc(tournamentID)
.get();
if (snapshot.exists) {
return new Date(snapshot.data().modificationDate);
}
return null;
});
}
getTournamentConfigs(tournamentID) {
return __awaiter(this, void 0, void 0, function* () {
const snapshot = yield this.tournamentConfigsCollection
.doc(tournamentID)
.get();
return snapshot.data();
});
}
}
(function (FireStore) {
let Collections;
(function (Collections) {
Collections["MATCHES"] = "d_matches";
Collections["USERS"] = "d_users";
Collections["TOURNAMENT_CONFIGS"] = "d_tourney_configs";
})(Collections = FireStore.Collections || (FireStore.Collections = {}));
})(FireStore || (FireStore = {}));
//# sourceMappingURL=index.js.map