// *** DEBUG START ***
// Remove comments for testing in NODE
export { ScriptSettings };
import { PropertiesService } from "../GasMocks.js";
// *** DEBUG END ***/
/** @classdesc
* Stores settings for the SCRIPT. Long term cache storage for small tables. */
class ScriptSettings { // skipcq: JS-0128
/**
* For storing cache data for very long periods of time.
*/
constructor() {
this.scriptProperties = PropertiesService.getScriptProperties();
}
/**
* Get script property using key. If not found, returns null.
* @param {String} propertyKey
* @returns {any}
*/
get(propertyKey) {
const myData = this.scriptProperties.getProperty(propertyKey);
if (myData === null)
return null;
/** @type {PropertyData} */
const myPropertyData = JSON.parse(myData);
return PropertyData.getData(myPropertyData);
}
/**
* Put data into our PROPERTY cache, which can be held for long periods of time.
* @param {String} propertyKey - key to finding property data.
* @param {any} propertyData - value. Any object can be saved..
* @param {Number} daysToHold - number of days to hold before item is expired.
*/
put(propertyKey, propertyData, daysToHold = 1) {
// Create our object with an expiry time.
const objData = new PropertyData(propertyData, daysToHold);
// Our property needs to be a string
const jsonData = JSON.stringify(objData);
try {
this.scriptProperties.setProperty(propertyKey, jsonData);
}
catch (ex) {
throw new Error("Cache Limit Exceeded. Long cache times have limited storage available. Only cache small tables for long periods.");
}
}
/**
*
* @param {Object} propertyDataObject
* @param {Number} daysToHold
*/
putAll(propertyDataObject, daysToHold = 1) {
const keys = Object.keys(propertyDataObject);
keys.forEach(key => this.put(key, propertyDataObject[key], daysToHold));
}
/**
* Removes script settings that have expired.
* @param {Boolean} deleteAll - true - removes ALL script settings regardless of expiry time.
*/
expire(deleteAll) {
const allKeys = this.scriptProperties.getKeys();
for (const key of allKeys) {
const myData = this.scriptProperties.getProperty(key);
if (myData !== null) {
let propertyValue = null;
try {
propertyValue = JSON.parse(myData);
}
catch (e) {
Logger.log(`Script property data is not JSON. key=${key}`);
continue;
}
const propertyOfThisApplication = propertyValue?.expiry !== undefined;
if (propertyOfThisApplication && (PropertyData.isExpired(propertyValue) || deleteAll)) {
this.scriptProperties.deleteProperty(key);
Logger.log(`Removing expired SCRIPT PROPERTY: key=${key}`);
}
}
}
}
/**
* Delete a specific key in script properties.
* @param {String} key
*/
delete(key) {
if (this.scriptProperties.getProperty(key) !== null) {
this.scriptProperties.deleteProperty(key);
}
}
}
/**
* @classdesc Converts data into JSON for getting/setting in ScriptSettings.
*/
class PropertyData {
/**
*
* @param {any} propertyData
* @param {Number} daysToHold
*/
constructor(propertyData, daysToHold) {
const someDate = new Date();
/** @property {String} */
this.myData = JSON.stringify(propertyData);
/** @property {Date} */
this.expiry = someDate.setMinutes(someDate.getMinutes() + daysToHold * 1440);
}
/**
*
* @param {PropertyData} obj
* @returns {any}
*/
static getData(obj) {
let value = null;
try {
if (!PropertyData.isExpired(obj)) {
value = JSON.parse(obj.myData);
}
}
catch (ex) {
Logger.log(`Invalid property value. Not JSON: ${ex.toString()}`);
}
return value;
}
/**
*
* @param {PropertyData} obj
* @returns {Boolean}
*/
static isExpired(obj) {
const someDate = new Date();
const expiryDate = new Date(obj.expiry);
return (expiryDate.getTime() < someDate.getTime())
}
}