UNPKG

@reshuffle/monday-redis-service

Version:
824 lines 42 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; 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()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; exports.__esModule = true; exports.createAndInitializeMondayRedisService = exports.MondayRedisService = void 0; var reshuffle_base_connector_1 = require("reshuffle-base-connector"); var Cipher_1 = require("./Cipher"); var MONDAY_SYNC_TIMER_MS = parseInt(process.env.MONDAY_SYNC_TIMER_MS || '5000', 10); var UNDEFINED_NULL_PLACEHOLDER = 'UNDEFINED_OR_NULL'; var MondayRedisService = /** @class */ (function (_super) { __extends(MondayRedisService, _super); function MondayRedisService(app, options, id) { var _this = _super.call(this, app, options, id) || this; _this.encryptedColumns = {}; _this.destageIntervalID = null; _this.mondaySyncIntervalID = null; _this.boardName = MondayRedisService.validateBoardName(options.boardName); _this.keyBase = "MondayBoard/" + encodeURIComponent(_this.boardName); _this.namesKey = _this.keyBase + "/names"; _this.changesKey = _this.keyBase + "/changes"; if (typeof options.monday !== 'object' || options.monday.constructor.name !== 'MondayConnector') { throw new Error("Not a monday connector: " + options.monday); } _this.monday = options.monday; if (typeof options.redis !== 'object' || options.redis.constructor.name !== 'RedisConnector') { throw new Error("Not a redis connector: " + options.redis); } _this.redis = options.redis; if (options.encryptionKey !== undefined && options.encryptedColumnList !== undefined) { if (!Array.isArray(options.encryptedColumnList)) { throw new Error("Invalid column list: " + options.encryptedColumnList); } for (var _i = 0, _a = options.encryptedColumnList; _i < _a.length; _i++) { var title = _a[_i]; if (typeof title !== 'string' || title.trim().length === 0) { throw new Error("Invalid column list: " + options.encryptedColumnList); } _this.encryptedColumns[title] = true; } _this.cipher = new Cipher_1.Cipher(options.encryptionKey); } _this.resetDestageInterval(); _this.resetMondaySync(); return _this; } MondayRedisService.prototype.resetDestageInterval = function () { var _this = this; if (this.destageIntervalID) { clearInterval(this.destageIntervalID); } this.destageIntervalID = setInterval(function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.destageChanges()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }, MONDAY_SYNC_TIMER_MS); }; MondayRedisService.prototype.resetMondaySync = function () { var _this = this; if (this.mondaySyncIntervalID) { clearInterval(this.mondaySyncIntervalID); } this.mondaySyncIntervalID = setInterval(function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.syncBoardItemAdditionDeletion()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }, MONDAY_SYNC_TIMER_MS * 5); }; MondayRedisService.prototype.getChangeKey = function (itemId, title) { return itemId + ":" + encodeURIComponent(title); }; MondayRedisService.prototype.syncBoardItemAdditionDeletion = function () { return __awaiter(this, void 0, void 0, function () { var mondayItemIds_1, redisItemIds_1, createdItems, deletedItems, _i, deletedItems_1, deletedItemId, existInMonday, _a, createdItems_1, createdItemId, exist, res, mondayItem; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!this.boardId) return [3 /*break*/, 12]; return [4 /*yield*/, this.monday.getBoardItemIds(this.boardId)]; case 1: mondayItemIds_1 = _b.sent(); return [4 /*yield*/, this.getBoardItemIds()]; case 2: redisItemIds_1 = _b.sent(); createdItems = mondayItemIds_1.filter(function (id) { return !redisItemIds_1.includes(id); }); deletedItems = redisItemIds_1.filter(function (id) { return !mondayItemIds_1.includes(id); }); _i = 0, deletedItems_1 = deletedItems; _b.label = 3; case 3: if (!(_i < deletedItems_1.length)) return [3 /*break*/, 6]; deletedItemId = deletedItems_1[_i]; existInMonday = mondayItemIds_1.includes(deletedItemId); if (!!existInMonday) return [3 /*break*/, 5]; this.app .getLogger() .info("Item " + deletedItemId + " removed from board " + this.boardName + ", syncing Redis cache"); return [4 /*yield*/, this.deleteItemInRedis(deletedItemId)]; case 4: _b.sent(); _b.label = 5; case 5: _i++; return [3 /*break*/, 3]; case 6: _a = 0, createdItems_1 = createdItems; _b.label = 7; case 7: if (!(_a < createdItems_1.length)) return [3 /*break*/, 12]; createdItemId = createdItems_1[_a]; return [4 /*yield*/, this.redis.hexists(this.keyForItem(createdItemId), 'id')]; case 8: exist = _b.sent(); if (!!exist) return [3 /*break*/, 11]; this.app .getLogger() .info("New item " + createdItemId + " detected in board " + this.boardName + ", syncing Redis cache"); return [4 /*yield*/, this.monday.getItem(parseInt(createdItemId, 10))]; case 9: res = _b.sent(); mondayItem = res && res.items && res.items.length && res.items[0]; if (!mondayItem) return [3 /*break*/, 11]; return [4 /*yield*/, this.createItemInRedis(__assign({ id: createdItemId }, mondayItem))]; case 10: _b.sent(); _b.label = 11; case 11: _a++; return [3 /*break*/, 7]; case 12: return [2 /*return*/]; } }); }); }; MondayRedisService.prototype.destageChanges = function (skipChangeKey) { return __awaiter(this, void 0, void 0, function () { var changes; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.redis.getset(this.changesKey, '')]; case 1: changes = _a.sent(); if (!changes) return [3 /*break*/, 3]; return [4 /*yield*/, Promise.all(changes .split(' ') .slice(1) .sort() .filter(function (e, i, a) { return i === a.indexOf(e); }) // unique .filter(function (e) { return e !== skipChangeKey; }) // Skip skipChangeKey .map(function (change) { var _a = change.split(':'), itemId = _a[0], title = _a[1]; return _this.destageOneChange(itemId, decodeURIComponent(title)); }))]; case 2: _a.sent(); _a.label = 3; case 3: return [2 /*return*/]; } }); }); }; MondayRedisService.prototype.destageOneChange = function (itemId, title) { return __awaiter(this, void 0, void 0, function () { var serial, value, _a, _b, _c, _d; var _e; return __generator(this, function (_f) { switch (_f.label) { case 0: return [4 /*yield*/, this.redis.hget(this.keyForItem(itemId), title)]; case 1: serial = _f.sent(); value = this.deserialize(serial, title); if (!(title === 'name')) return [3 /*break*/, 4]; _b = (_a = this.monday).updateItemName; return [4 /*yield*/, this.getBoardId()]; case 2: return [4 /*yield*/, _b.apply(_a, [_f.sent(), itemId, value])]; case 3: _f.sent(); return [3 /*break*/, 7]; case 4: _d = (_c = this.monday).updateColumnValues; return [4 /*yield*/, this.getBoardId()]; case 5: return [4 /*yield*/, _d.apply(_c, [_f.sent(), itemId, (_e = {}, _e[title] = function () { return value; }, _e)])]; case 6: _f.sent(); _f.label = 7; case 7: return [2 /*return*/]; } }); }); }; // Helpers //////////////////////////////////////////////////////// MondayRedisService.prototype.keyForItem = function (itemId) { // If the schema changes, you'll new to review the getBoardItemIds implementation return this.keyBase + "/item/" + (itemId || '*'); }; MondayRedisService.prototype.getBoardItemIds = function () { return __awaiter(this, void 0, void 0, function () { var keys; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.redis.keys(this.keyForItem())]; case 1: keys = _a.sent(); return [2 /*return*/, keys.map(function (key) { return key.substr(key.lastIndexOf('/') + 1); })]; } }); }); }; MondayRedisService.prototype.serialize = function (value, title) { if (value === null || value === undefined) { return UNDEFINED_NULL_PLACEHOLDER; } var json = JSON.stringify(value); return this.cipher && this.encryptedColumns[title] ? this.cipher.encrypt(json) : json; }; MondayRedisService.prototype.deserialize = function (str, title) { if (!str || str === UNDEFINED_NULL_PLACEHOLDER) { return undefined; } var json = this.cipher && this.encryptedColumns[title] ? this.cipher.decrypt(str) : str; return JSON.parse(json); }; MondayRedisService.prototype.getMondayBoardItems = function () { return __awaiter(this, void 0, void 0, function () { var board, _a, _b, _c, _d; return __generator(this, function (_e) { switch (_e.label) { case 0: _b = (_a = this.monday).getBoardItems; return [4 /*yield*/, this.getBoardId()]; case 1: return [4 /*yield*/, _b.apply(_a, [_e.sent()])]; case 2: board = _e.sent(); if (!(!board || board.name !== this.boardName)) return [3 /*break*/, 5]; this.boardId = undefined; _d = (_c = this.monday).getBoardItems; return [4 /*yield*/, this.getBoardId()]; case 3: return [4 /*yield*/, _d.apply(_c, [_e.sent()])]; case 4: board = _e.sent(); _e.label = 5; case 5: if (!board || board.name !== this.boardName) { throw new Error("Unable to read Monday board: " + this.boardName); } return [2 /*return*/, board.items]; } }); }); }; MondayRedisService.prototype.createItemInRedis = function (item) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all(__spreadArrays(Object.keys(item).map(function (title) { return _this.redis.hset(_this.keyForItem(item.id), title, _this.serialize(item[title], title)); }), [ this.redis.hset(this.namesKey, item.name, item.id), ]))]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; MondayRedisService.prototype.deleteItemInRedis = function (itemId) { return __awaiter(this, void 0, void 0, function () { var item; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getBoardItemById(itemId)]; case 1: item = _a.sent(); if (!item) return [3 /*break*/, 3]; return [4 /*yield*/, Promise.all([ this.redis.del(this.keyForItem(item.id)), this.redis.hdel(this.namesKey, item.name), ])]; case 2: _a.sent(); _a.label = 3; case 3: return [2 /*return*/]; } }); }); }; MondayRedisService.prototype.updateColumnValue = function (itemId, title, update) { return __awaiter(this, void 0, void 0, function () { var change; return __generator(this, function (_a) { change = this.getChangeKey(itemId, title); return [2 /*return*/, Promise.all([ update, this.redis.append(this.changesKey, ' ' + change), ])]; }); }); }; // Initialize the Redis mirror for this board. MondayRedisService.prototype.initialize = function () { return __awaiter(this, void 0, void 0, function () { var initialized, items, _a; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: this.app.getLogger().info("Initializing " + this.boardName + " board"); return [4 /*yield*/, this.redis.setnx(this.changesKey, '')]; case 1: initialized = _b.sent(); if (!(initialized === 1)) return [3 /*break*/, 4]; this.app.getLogger().info("Populating Redis mirror for " + this.boardName); return [4 /*yield*/, this.getMondayBoardItems()]; case 2: items = _b.sent(); return [4 /*yield*/, Promise.all(Object.values(items).map(function (item) { return _this.createItemInRedis(item); }))]; case 3: _b.sent(); _b.label = 4; case 4: _a = this; return [4 /*yield*/, this.getBoardId()]; case 5: _a.boardId = _b.sent(); this.monday.on({ type: 'ChangeColumnValue', boardId: this.boardId }, function (event) { return __awaiter(_this, void 0, void 0, function () { var boardId, itemId, columnTitle, columnType, value, userId, newValue, _a, res, mondayItem; return __generator(this, function (_b) { switch (_b.label) { case 0: boardId = event.boardId, itemId = event.itemId, columnTitle = event.columnTitle, columnType = event.columnType, value = event.value, userId = event.userId; if (this.configOptions.apiUserIdsToIgnoreOnNewEvent && this.configOptions.apiUserIdsToIgnoreOnNewEvent.includes(userId)) { this.app .getLogger() .info("Monday event received - skip changes from user: " + userId + " (listed in configOptions.apiUserIdsToIgnoreOnNewEvent)"); return [2 /*return*/]; } _a = columnType; switch (_a) { case 'location': return [3 /*break*/, 1]; case 'color': return [3 /*break*/, 3]; case 'board-relation': return [3 /*break*/, 4]; case 'text': return [3 /*break*/, 5]; case 'numeric': return [3 /*break*/, 5]; case 'dropdown': return [3 /*break*/, 6]; } return [3 /*break*/, 7]; case 1: return [4 /*yield*/, this.monday.getItem(parseInt(itemId, 10))]; case 2: res = _b.sent(); mondayItem = res && res.items && res.items.length && res.items[0]; newValue = mondayItem === null || mondayItem === void 0 ? void 0 : mondayItem.Location; return [3 /*break*/, 8]; case 3: newValue = value.label; return [3 /*break*/, 8]; case 4: newValue = { linkedPulseIds: value.linkedPulseIds }; return [3 /*break*/, 8]; case 5: newValue = value ? value.value : value; return [3 /*break*/, 8]; case 6: newValue = value ? value.chosenValues : value; return [3 /*break*/, 8]; case 7: newValue = value; _b.label = 8; case 8: if (!(this.boardId === parseInt(boardId, 10))) return [3 /*break*/, 11]; this.app .getLogger() .info("Monday event received - Update Redis cache with " + JSON.stringify(newValue) + " for itemId " + itemId + " (columnTitle: " + columnTitle + ")"); return [4 /*yield*/, this.redis.hset(this.keyForItem(itemId), columnTitle, this.serialize(newValue, columnTitle))]; case 9: _b.sent(); this.resetMondaySync(); return [4 /*yield*/, this.destageChanges(this.getChangeKey(itemId, columnTitle))]; case 10: _b.sent(); _b.label = 11; case 11: return [2 /*return*/]; } }); }); }); this.monday.on({ type: 'UpdateName', boardId: this.boardId }, function (event) { return __awaiter(_this, void 0, void 0, function () { var boardId, itemId, previousValue, value, userId; return __generator(this, function (_a) { switch (_a.label) { case 0: boardId = event.boardId, itemId = event.itemId, previousValue = event.previousValue, value = event.value, userId = event.userId; if (this.configOptions.apiUserIdsToIgnoreOnNewEvent && this.configOptions.apiUserIdsToIgnoreOnNewEvent.includes(userId)) { this.app .getLogger() .info("Monday event received - skip changes from user: " + userId + " (listed in configOptions.apiUserIdsToIgnoreOnNewEvent)"); return [2 /*return*/]; } if (!(this.boardId === parseInt(boardId, 10) && typeof value.name === 'string')) return [3 /*break*/, 2]; this.app .getLogger() .info("Monday event received - Update item name in Redis cache (itemId: " + itemId + ", previousName: " + previousValue.name + ", itemName: " + value.name + ")"); return [4 /*yield*/, this.setItemName(itemId, value.name)]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }); this.monday.on({ type: 'CreateItem', boardId: this.boardId }, function (event) { return __awaiter(_this, void 0, void 0, function () { var boardId, itemId, itemName, userId, response; return __generator(this, function (_a) { switch (_a.label) { case 0: boardId = event.boardId, itemId = event.itemId, itemName = event.itemName, userId = event.userId; if (this.configOptions.apiUserIdsToIgnoreOnNewEvent && this.configOptions.apiUserIdsToIgnoreOnNewEvent.includes(userId)) { this.app .getLogger() .info("Monday event received - skip changes from user: " + userId + " (listed in configOptions.apiUserIdsToIgnoreOnNewEvent)"); return [2 /*return*/]; } if (!(this.boardId === parseInt(boardId, 10))) return [3 /*break*/, 3]; this.app .getLogger() .info("Monday event received - Create new item in Redis cache (itemId: " + itemId + ", itemName: " + itemName + ")"); return [4 /*yield*/, this.monday.getItem(parseInt(itemId, 10))]; case 1: response = _a.sent(); if (!(response && response.items && response.items[0])) return [3 /*break*/, 3]; this.resetMondaySync(); return [4 /*yield*/, this.createItemInRedis(__assign({ id: itemId }, response.items[0]))]; case 2: _a.sent(); _a.label = 3; case 3: return [2 /*return*/]; } }); }); }); return [2 /*return*/, this]; } }); }); }; // Create a new item in Monday and the Redis mirror. // // @param name item name // @param columnValues values by column titles // // @return item object // MondayRedisService.prototype.createItem = function (name, columnValues) { return __awaiter(this, void 0, void 0, function () { var boardId, columnUpdaters, _loop_1, _i, _a, _b, title, value, itemId, item; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.getBoardId()]; case 1: boardId = _c.sent(); columnUpdaters = {}; _loop_1 = function (title, value) { columnUpdaters[title] = function () { return value; }; }; for (_i = 0, _a = Object.entries(columnValues); _i < _a.length; _i++) { _b = _a[_i], title = _b[0], value = _b[1]; _loop_1(title, value); } return [4 /*yield*/, this.monday.createItem(boardId, name, columnUpdaters)]; case 2: itemId = _c.sent(); item = __assign({ id: itemId, name: name }, columnValues); return [4 /*yield*/, this.createItemInRedis(item)]; case 3: _c.sent(); return [2 /*return*/, item]; } }); }); }; // Get the id of this board. // // @return board id // MondayRedisService.prototype.getBoardId = function () { return __awaiter(this, void 0, void 0, function () { var BoardIdInRedis, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!!this.boardId) return [3 /*break*/, 6]; return [4 /*yield*/, this.redis.get("boards/" + this.boardName)]; case 1: BoardIdInRedis = _b.sent(); if (!BoardIdInRedis) return [3 /*break*/, 2]; this.boardId = parseInt(BoardIdInRedis, 10); return [3 /*break*/, 5]; case 2: _a = this; return [4 /*yield*/, this.monday.getBoardIdByName(this.boardName)]; case 3: _a.boardId = _b.sent(); if (!this.boardId) return [3 /*break*/, 5]; return [4 /*yield*/, this.redis.set("boards/" + this.boardName, this.boardId)]; case 4: _b.sent(); _b.label = 5; case 5: if (!this.boardId) { throw new Error("Monday board not found: " + this.boardName); } _b.label = 6; case 6: return [2 /*return*/, this.boardId]; } }); }); }; // Get all items. // // // @return an array of objects with the item's id, name and column // value (undefined if not found) // MondayRedisService.prototype.getBoardItems = function () { return __awaiter(this, void 0, void 0, function () { var ids, items, _i, ids_1, id, item; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getBoardItemIds()]; case 1: ids = _a.sent(); items = []; if (!ids) return [3 /*break*/, 5]; _i = 0, ids_1 = ids; _a.label = 2; case 2: if (!(_i < ids_1.length)) return [3 /*break*/, 5]; id = ids_1[_i]; return [4 /*yield*/, this.getBoardItemById(id)]; case 3: item = _a.sent(); item && items.push(item); _a.label = 4; case 4: _i++; return [3 /*break*/, 2]; case 5: return [2 /*return*/, items]; } }); }); }; // Get an item with the specified id from this board. // // @param itemId item id // // @return an object with the item's id, name and column // value (undefined if not found) // MondayRedisService.prototype.getBoardItemById = function (itemId) { return __awaiter(this, void 0, void 0, function () { var raw, item, _i, _a, title; return __generator(this, function (_b) { switch (_b.label) { case 0: MondayRedisService.validateId(itemId); return [4 /*yield*/, this.redis.hgetall(this.keyForItem(itemId))]; case 1: raw = _b.sent(); if (raw) { item = {}; for (_i = 0, _a = Object.keys(raw); _i < _a.length; _i++) { title = _a[_i]; item[title] = this.deserialize(raw[title], title); } return [2 /*return*/, item]; } return [2 /*return*/]; } }); }); }; // Get an item with the specified name from this board. // // @param name item name // // @return an object with the item's id, name and column // value (undefined if not found) // MondayRedisService.prototype.getBoardItemByName = function (name) { return __awaiter(this, void 0, void 0, function () { var id; return __generator(this, function (_a) { switch (_a.label) { case 0: MondayRedisService.validateBoardName(name); return [4 /*yield*/, this.redis.hget(this.namesKey, name)]; case 1: id = _a.sent(); return [2 /*return*/, id && this.getBoardItemById(id)]; } }); }); }; // Set a new value for one column of a specific item. // // The new value is atomically written to the Redis mirror, and will // eventually be synchronized back to Monday. This assures updates // are atomic and reduces load on Monday, as multiple updates to the // same column are consolidated before Monday is updated. // // The new value is encrypted if necessary before caching. // // @param itemId id of the Monday item to be updated // @param title title of the Monday column to be updated // @param value new value // MondayRedisService.prototype.setColumnValue = function (itemId, title, // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types value) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.updateColumnValue(itemId, title, this.redis.hset(this.keyForItem(itemId), title, this.serialize(value, title)))]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; MondayRedisService.prototype.setItemName = function (itemId, name) { return __awaiter(this, void 0, void 0, function () { var item; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getBoardItemById(itemId)]; case 1: item = _a.sent(); return [4 /*yield*/, this.setColumnValue(itemId, 'name', name)]; case 2: _a.sent(); if (!item) return [3 /*break*/, 4]; return [4 /*yield*/, this.redis.hdel(this.namesKey, item.name)]; case 3: _a.sent(); _a.label = 4; case 4: return [4 /*yield*/, this.redis.hset(this.namesKey, name, itemId)]; case 5: _a.sent(); return [2 /*return*/]; } }); }); }; // Increase (or decrease) the value for one column of a specific // item. The column must have a numeric value and must not be // encrypted. // // The new value is atomically written to the Redis mirror, and will // eventually be synchronized back to Monday. This assures updates // are atomic and reduces load on Monday, as multiple updates to the // same column are consolidated before Monday is updated. // // @param itemId id of the Monday item to be updated // @param title title of the Monday column to be updated // @param incr numeric increment (negative to decrement) // MondayRedisService.prototype.incrColumnValue = function (itemId, title, incr) { if (incr === void 0) { incr = 1; } return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.updateColumnValue(itemId, title, this.redis.hincrby(this.keyForItem(itemId), title, incr))]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; // Static ///////////////////////////////////////////////////////// // Validate an item id and throw an error otherwise. // // @param itemId item id // // @return same item id // MondayRedisService.validateId = function (itemId) { if (typeof itemId !== 'string' || !/^\d{9,10}$/.test(itemId)) { throw new Error("Invalid item id: " + itemId); } return itemId; }; // Validate an item name and throw an error otherwise. // // @param name item name // // @return same item name // MondayRedisService.validateBoardName = function (name) { if (typeof name !== 'string' || name.trim().length === 0) { throw new Error("Invalid name: " + name); } return name; }; return MondayRedisService; }(reshuffle_base_connector_1.BaseConnector)); exports.MondayRedisService = MondayRedisService; // Create a new service. // // @param boardName name of board // @param monday pre-configured Reshuffle Monday connector // @param redis pre-configured Reshuffle Redis connector // @param encryptionKey optional key for encrypting data in Redis (if // not specified data is mirrored in the clear) // @param encryptedColumnList optional list of columns to be encrypted // // @return new board accessor // function createAndInitializeMondayRedisService(app, boardName, monday, redis, encryptionKey, encryptedColumnList, apiUserIdsToIgnoreOnNewEvent) { return __awaiter(this, void 0, void 0, function () { var mrs; return __generator(this, function (_a) { mrs = new MondayRedisService(app, { boardName: boardName, monday: monday, redis: redis, encryptionKey: encryptionKey, encryptedColumnList: encryptedColumnList, apiUserIdsToIgnoreOnNewEvent: apiUserIdsToIgnoreOnNewEvent }); return [2 /*return*/, mrs.initialize()]; }); }); } exports.createAndInitializeMondayRedisService = createAndInitializeMondayRedisService; //# sourceMappingURL=index.js.map