UNPKG

@levante-framework/firekit

Version:

A library to facilitate Firebase authentication and Firestore interaction for LEVANTE apps

125 lines (124 loc) 5.92 kB
"use strict"; 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 */ constructor({ db, taskId, taskName, taskDescription, taskImage, taskURL, gameConfig, taskVersion = undefined, registered, external, variantName, variantParams = {}, }) { 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.variantParams = variantParams; 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 */ async toFirestore() { // Check if task document exists to determine if we should set createdAt const taskDocSnap = await (0, firestore_1.getDoc)(this.taskRef); const taskExists = taskDocSnap.exists(); // Push/update the task using the user provided task ID const taskData = { 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)(), updatedAt: (0, firestore_1.serverTimestamp)(), // Only set createdAt if this is a new document ...((!taskExists) && { createdAt: (0, firestore_1.serverTimestamp)() }), }; try { await (0, firestore_1.setDoc)(this.taskRef, (0, util_1.removeUndefined)(taskData), { merge: true }); } catch (error) { console.error('RoarTaskVariant toFirestore: error saving task to firestore', { error, errorMessage: error instanceof Error ? error.message : String(error), errorCode: error?.code, taskId: this.taskId, taskRefPath: this.taskRef?.path, }); throw error; } // 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)('updatedAt', 'desc'), (0, firestore_1.limit)(1)); const querySnapshot = await (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)({ lastUpdated: (0, firestore_1.serverTimestamp)(), updatedAt: (0, firestore_1.serverTimestamp)(), })); }); if (!foundVariantWithCurrentParams) { // Create new variant with both createdAt and updatedAt const variantData = { name: this.variantName, taskURL: this.taskURL, registered: this.registered, external: this.external, params: this.variantParams, lastUpdated: (0, firestore_1.serverTimestamp)(), createdAt: (0, firestore_1.serverTimestamp)(), updatedAt: (0, firestore_1.serverTimestamp)(), }; this.variantRef = (0, firestore_1.doc)(this.variantsCollectionRef); await (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 */ async updateTaskParams(newParams) { 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; await this.toFirestore(); } } exports.RoarTaskVariant = RoarTaskVariant;