UNPKG

@bdelab/roar-firekit

Version:

A library to facilitate Firebase authentication and Cloud Firestore interaction for ROAR apps

106 lines (105 loc) 6.3 kB
"use strict"; 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RoarTaskVariant = void 0; const firestore_1 = require("firebase/firestore"); const util_1 = require("../util"); /** * Class representing a ROAR task. */ class RoarTaskVariant { /** Create a ROAR task * @param {TaskVariantInput} input * @param {Firestore} input.db - The assessment Firestore instance to which this task'data will be written * @param {string} input.taskId - The ID of the parent task. Should be a short initialism, e.g. "swr" or "sre" * @param {string} input.taskName - The name of the parent task * @param {string} input.taskDescription - The description of the task * @param {string} input.variantName - The name of the task variant * @param {string} input.variantDescription - The description of the variant * @param {object} input.variantParams - The parameters of the task variant * @param {TaskVariantDataFlags} input.testData = Boolean flags indicating test data * @param {TaskVariantDataFlags} input.demoData = Boolean flags indicating demo data */ constructor({ db, taskId, taskName, taskDescription, taskImage, taskURL, gameConfig, taskVersion = undefined, registered, external, variantName, variantDescription, variantParams = {}, testData = { task: false, variant: false }, demoData = { task: false, variant: false }, }) { this.db = db; this.taskId = taskId.toLowerCase(); this.taskName = taskName; this.taskDescription = taskDescription; this.taskImage = taskImage; this.taskURL = taskURL; this.taskVersion = taskVersion; this.gameConfig = gameConfig; this.registered = registered; this.external = external; this.variantName = variantName; this.variantDescription = variantDescription; this.variantParams = variantParams; this.testData = testData; this.demoData = demoData; this.taskRef = (0, firestore_1.doc)(this.db, 'tasks', this.taskId); this.variantsCollectionRef = (0, firestore_1.collection)(this.taskRef, 'variants'); this.variantId = undefined; this.variantRef = undefined; } /** * Push the trial and trial variant to Firestore * @method * @async */ toFirestore() { return __awaiter(this, void 0, void 0, function* () { // Push/update the task using the user provided task ID const taskData = Object.assign(Object.assign({ name: this.taskName, description: this.taskDescription, image: this.taskImage, taskURL: this.taskURL, gameConfig: this.gameConfig, registered: this.registered, external: this.external, lastUpdated: (0, firestore_1.serverTimestamp)() }, (this.testData.task && { testData: true })), (this.demoData.task && { demoData: true })); yield (0, firestore_1.setDoc)(this.taskRef, (0, util_1.removeUndefined)(taskData), { merge: true }); // Check to see if variant exists already by querying for a match on the params. const q = (0, firestore_1.query)(this.variantsCollectionRef, (0, firestore_1.where)('params', '==', this.variantParams), (0, firestore_1.orderBy)('lastUpdated', 'desc'), (0, firestore_1.limit)(1)); const querySnapshot = yield (0, firestore_1.getDocs)(q); let foundVariantWithCurrentParams = false; // If this query snapshot yielded results, then we can use it and // update the timestamp querySnapshot.forEach((docRef) => { this.variantId = docRef.id; this.variantRef = (0, firestore_1.doc)(this.variantsCollectionRef, this.variantId); foundVariantWithCurrentParams = true; (0, firestore_1.updateDoc)(this.variantRef, (0, util_1.removeUndefined)({ description: this.variantDescription, lastUpdated: (0, firestore_1.serverTimestamp)(), })); }); const variantData = Object.assign(Object.assign({ name: this.variantName, description: this.variantDescription, taskURL: this.taskURL, registered: this.registered, external: this.external, params: this.variantParams, lastUpdated: (0, firestore_1.serverTimestamp)() }, (this.testData.variant && { testData: true })), (this.demoData.variant && { demoData: true })); if (!foundVariantWithCurrentParams) { this.variantRef = (0, firestore_1.doc)(this.variantsCollectionRef); yield (0, firestore_1.setDoc)(this.variantRef, (0, util_1.removeUndefined)(variantData)); this.variantId = this.variantRef.id; } }); } /** * Update variant params in Firestore * @method * @param {object} newParams - The parameters of the task variant * @async */ updateTaskParams(newParams) { return __awaiter(this, void 0, void 0, function* () { if (this.variantRef === undefined) { throw new Error('Cannot update task params before writing task to Firestore. Please call `.toFirestore()` first.'); } const oldParams = (0, util_1.replaceValues)(this.variantParams); const cleanParams = (0, util_1.replaceValues)(newParams); // Only allow updating the task params if we are updating previously null values. const { merged } = (0, util_1.mergeGameParams)(oldParams, cleanParams); this.variantParams = merged; yield this.toFirestore(); }); } } exports.RoarTaskVariant = RoarTaskVariant;