@63klabs/cache-data 1.2.3 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -65,9 +65,16 @@ class S3Cache {
65
65
  * Initialize the S3 bucket for storing cached data.
66
66
  * @param {string} bucket The bucket name for storing cached data
67
67
  */
68
- static init(bucket) {
69
- if ( S3Cache.getBucket() === null) {
70
- this.#bucket = bucket;
68
+
69
+ static init(bucket = null) {
70
+ if ( S3Cache.getBucket() === null ) {
71
+ bucket = (bucket === null) ? process.env?.CACHE_DATA_DYNAMO_DB_TABLE || null : bucket;
72
+ if (bucket === null || bucket === "") {
73
+ tools.DebugAndLog.error("Unable to initialize S3 Bucket for Cache. No bucket name provided.");
74
+ throw new Error("Unable to initialize S3 Cache. No bucket name provided. Please set the CACHE_DATA_S3_BUCKET environment variable or pass a bucket name to S3Cache.init().");
75
+ } else {
76
+ this.#bucket = bucket;
77
+ }
71
78
  } else {
72
79
  tools.DebugAndLog.error("S3Cache already initialized. Ignoring call to S3Cache.init()");
73
80
  }
@@ -197,11 +204,17 @@ class DynamoDbCache {
197
204
 
198
205
  /**
199
206
  * Initialize the DynamoDb settings for storing cached data
200
- * @param {string} table The table name to store cached data
207
+ * @param {string|null} table The table name to store cached data
201
208
  */
202
- static init(table) {
209
+ static init(table = null) {
203
210
  if ( this.#table === null ) {
204
- this.#table = table;
211
+ table = (table === null || table === "") ? process.env?.CACHE_DATA_DYNAMO_DB_TABLE || null : table;
212
+ if (table === null || table === "") {
213
+ tools.DebugAndLog.error("Unable to initialize DynamoDbCache. No table name provided.");
214
+ throw new Error("Unable to initialize DynamoDbCache. No table name provided. Please set the CACHE_DATA_DYNAMO_DB_TABLE environment variable or pass a table name to DynamoDbCache.init().");
215
+ } else {
216
+ this.#table = table;
217
+ }
205
218
  } else {
206
219
  tools.DebugAndLog.error("DynamoDbCache already initialized. Ignoring call to DynamoDbCache.init()");
207
220
  }
@@ -328,18 +341,54 @@ class CacheData {
328
341
  // if we don't have the key set, we don't have anything set
329
342
  if ( this.#secureDataKey === null ) {
330
343
 
331
- // TODO: Throw error if data is missing
344
+ // Throw error if no secureData key
345
+ if ( !("secureDataKey" in parameters) || parameters.secureDataKey === null ) {
346
+ tools.DebugAndLog.error("CacheData.init() requires a secureDataKey parameter.");
347
+ throw new Error("CacheData.init() requires a secureDataKey parameter.");
348
+ }
332
349
 
333
- DynamoDbCache.init(parameters.dynamoDbTable);
334
- S3Cache.init(parameters.s3Bucket);
350
+ // let DynamoDbCache and S3Cache know where to store the data, let them handle the Env variables
351
+ DynamoDbCache.init(parameters?.dynamoDbTable || null);
352
+ S3Cache.init(parameters?.s3Bucket || null);
335
353
 
336
- // set other values
337
- this.#secureDataAlgorithm = parameters.secureDataAlgorithm;
354
+ // secureDataKey can be a string, Buffer, or CachedParameterSecret
338
355
  this.#secureDataKey = parameters.secureDataKey;
339
356
 
340
- if ("DynamoDbMaxCacheSize_kb" in parameters ) { this.#dynamoDbMaxCacheSize_kb = parameters.DynamoDbMaxCacheSize_kb; }
341
- if ("purgeExpiredCacheEntriesAfterXHours" in parameters ) { this.#purgeExpiredCacheEntriesAfterXHours = parameters.purgeExpiredCacheEntriesAfterXHours; }
342
- if ("timeZoneForInterval" in parameters ) { this.#timeZoneForInterval = parameters.timeZoneForInterval; }
357
+ // set other values based on parameters or environment variables
358
+ this.#secureDataAlgorithm = parameters.secureDataAlgorithm || process.env.CACHE_DATA_SECURE_DATA_ALGORITHM || "aes-256-cbc";
359
+
360
+ // CACHE_DATA_DYNAMO_DB_MAX_CACHE_SIZE_KB
361
+ if ("DynamoDbMaxCacheSize_kb" in parameters ) {
362
+ if (!Number.isInteger(parameters.DynamoDbMaxCacheSize_kb) || parameters.DynamoDbMaxCacheSize_kb <= 0) throw new Error("DynamoDbMaxCacheSize_kb must be a positive integer");
363
+ this.#dynamoDbMaxCacheSize_kb = parameters.DynamoDbMaxCacheSize_kb;
364
+ } else if (process.env.CACHE_DATA_DYNAMO_DB_MAX_CACHE_SIZE_KB) {
365
+ let val = parseInt(process.env.CACHE_DATA_DYNAMO_DB_MAX_CACHE_SIZE_KB);
366
+ if (isNaN(val) || val <= 0) throw new Error("CACHE_DATA_DYNAMO_DB_MAX_CACHE_SIZE_KB must be a positive integer");
367
+ this.#dynamoDbMaxCacheSize_kb = val;
368
+ } else {
369
+ this.#dynamoDbMaxCacheSize_kb = 10; // default to 10KB
370
+ }
371
+ // CACHE_DATA_PURGE_EXPIRED_CACHE_ENTRIES_AFTER_X_HRS
372
+ if ("purgeExpiredCacheEntriesAfterXHours" in parameters ) {
373
+ if (!Number.isInteger(parameters.purgeExpiredCacheEntriesAfterXHours) || parameters.purgeExpiredCacheEntriesAfterXHours <= 0) throw new Error("purgeExpiredCacheEntriesAfterXHours must be a positive integer");
374
+ this.#purgeExpiredCacheEntriesAfterXHours = parameters.purgeExpiredCacheEntriesAfterXHours;
375
+ } else if (process.env.CACHE_DATA_PURGE_EXPIRED_CACHE_ENTRIES_AFTER_X_HRS) {
376
+ let val = parseInt(process.env.CACHE_DATA_PURGE_EXPIRED_CACHE_ENTRIES_AFTER_X_HRS);
377
+ if (isNaN(val) || val <= 0) throw new Error("CACHE_DATA_PURGE_EXPIRED_CACHE_ENTRIES_AFTER_X_HRS must be a positive integer");
378
+ this.#purgeExpiredCacheEntriesAfterXHours = val;
379
+ } else {
380
+ this.#purgeExpiredCacheEntriesAfterXHours = 24; // default to 24 hours
381
+ }
382
+ // CACHE_DATA_TIME_ZONE_FOR_INTERVAL
383
+ if ("timeZoneForInterval" in parameters ) {
384
+ if (typeof parameters.timeZoneForInterval !== 'string' || parameters.timeZoneForInterval.trim() === '') throw new Error("timeZoneForInterval must be a non-empty string");
385
+ this.#timeZoneForInterval = parameters.timeZoneForInterval;
386
+ } else if (process.env.CACHE_DATA_TIME_ZONE_FOR_INTERVAL) {
387
+ if (process.env.CACHE_DATA_TIME_ZONE_FOR_INTERVAL.trim() === '') throw new Error("CACHE_DATA_TIME_ZONE_FOR_INTERVAL must be a non-empty string");
388
+ this.#timeZoneForInterval = process.env.CACHE_DATA_TIME_ZONE_FOR_INTERVAL;
389
+ } else {
390
+ this.#timeZoneForInterval = "Etc/UTC"; // default to Etc/UTC
391
+ }
343
392
 
344
393
  this._setOffsetInMinutes();
345
394
 
@@ -936,9 +985,6 @@ class CacheData {
936
985
 
937
986
  };
938
987
 
939
-
940
-
941
-
942
988
  /**
943
989
  * The Cache object handles reads and writes from the cache.
944
990
  * It also acts as a proxy between the app and CacheData which is a private class.
@@ -971,7 +1017,7 @@ class Cache {
971
1017
  static STATUS_FORCED = "original:cache-update-forced";
972
1018
 
973
1019
  static #idHashAlgorithm = null;
974
- static #useToolsHash = false;
1020
+ static #useToolsHash = null; // gets set in Cache.init()
975
1021
 
976
1022
  #syncedNowTimestampInSeconds = 0; // consistent time base for calculations
977
1023
  #syncedLaterTimestampInSeconds = 0; // default expiration if not adjusted
@@ -1041,7 +1087,6 @@ class Cache {
1041
1087
  this.#idHash = Cache.generateIdHash(connection);
1042
1088
  this.#syncedNowTimestampInSeconds = CacheData.convertTimestampFromMilliToSeconds(Date.now());
1043
1089
  this.#syncedLaterTimestampInSeconds = this.#syncedNowTimestampInSeconds + this.#defaultExpirationInSeconds; // now + default cache time
1044
-
1045
1090
  };
1046
1091
 
1047
1092
  /**
@@ -1054,29 +1099,38 @@ class Cache {
1054
1099
  * Sample param object:
1055
1100
  * @example
1056
1101
  * cache.Cache.init({
1057
- * dynamoDbTable: process.env.CacheData_DynamoDbTable,
1058
- * s3Bucket: process.env.CacheData_S3Bucket,
1059
- * secureDataAlgorithm: process.env.CacheData_CryptSecureDataAlgorithm,
1102
+ * dynamoDbTable: process.env.CACHE_DATA_DYNAMO_DB_TABLE,
1103
+ * s3Bucket: process.env.CACHE_DATA_S3_BUCKET,
1104
+ * secureDataAlgorithm: process.env.CACHE_DATA_SECURE_DATA_ALGORITHM,
1060
1105
  * secureDataKey: Buffer.from(params.app.crypt_secureDataKey, cache.Cache.CRYPT_ENCODING),
1061
- * idHashAlgorithm: process.env.CacheData_CryptIdHashAlgorithm,
1062
- * DynamoDbMaxCacheSize_kb: parseInt(process.env.CacheData_DynamoDb_maxCacheSize_kb, 10),
1063
- * purgeExpiredCacheEntriesAfterXHours: parseInt(process.env.CacheData_PurgeExpiredCacheEntriesAfterXHours, 10),
1064
- * timeZoneForInterval: process.env.CacheData_TimeZoneForInterval // if caching on interval, we need a timezone to account for calculating hours, days, and weeks. List: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
1106
+ * idHashAlgorithm: process.env.CACHE_DATA_ID_HASH_ALGORITHM, // sha1, sha256, sha512, etc.
1107
+ * DynamoDbMaxCacheSize_kb: parseInt(process.env.CACHE_DATA_DYNAMO_DB_MAX_CACHE_SIZE_KB, 10),
1108
+ * purgeExpiredCacheEntriesAfterXHours: parseInt(process.env.CACHE_DATA_PURGE_EXPIRED_CACHE_ENTRIES_AFTER_X_HRS, 10),
1109
+ * timeZoneForInterval: process.env.CACHE_DATA_TIME_ZONE_FOR_INTERVAL // if caching on interval, we need a timezone to account for calculating hours, days, and weeks. List: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
1065
1110
  * });
1066
1111
  *
1067
1112
  * @param {Object} parameters
1068
- * @param {string} parameters.dynamoDbTable
1069
- * @param {string} parameters.s3Bucket
1070
- * @param {string} parameters.secureDataAlgorithm
1071
- * @param {string} parameters.secureDataKey
1072
- * @param {number} parameters.DynamoDbMaxCacheSize_kb
1073
- * @param {number} parameters.purgeExpiredCacheEntriesAfterXHours
1074
- * @param {string} parameters.timeZoneForInterval
1113
+ * @param {string} parameters.dynamoDbTable Can also be set with environment variable CACHE_DATA_DYNAMO_DB_TABLE
1114
+ * @param {string} parameters.s3Bucket Can also be set with environment variable CACHE_DATA_S3_BUCKET
1115
+ * @param {string} parameters.secureDataAlgorithm Can also be set with environment variable CACHE_DATA_SECURE_DATA_ALGORITHM
1116
+ * @param {string|Buffer|tools.Secret|tools.CachedSSMParameter|tools.CachedSecret} parameters.secureDataKey Must be passed, will not accept an environment variable for security reasons.
1117
+ * @param {number} parameters.DynamoDbMaxCacheSize_kb Can also be set with environment variable CACHE_DATA_DYNAMO_DB_MAX_CACHE_SIZE_KB
1118
+ * @param {number} parameters.purgeExpiredCacheEntriesAfterXHours Can also be set with environment variable CACHE_DATA_PURGE_EXPIRED_CACHE_ENTRIES_AFTER_X_HRS
1119
+ * @param {string} parameters.timeZoneForInterval Can also be set with environment variable CACHE_DATA_TIME_ZONE_FOR_INTERVAL
1075
1120
  */
1076
1121
  static init(parameters) {
1077
- if ( "idHashAlgorithm" in parameters ) { this.#idHashAlgorithm = parameters.idHashAlgorithm; } else { tools.DebugAndLog.error("parameters.idHashAlgorithm not set in Cache.init()")};
1078
- if ("useToolsHash" in parameters ) { this.#useToolsHash = Boolean(parameters.useToolsHash); }
1122
+ // check if parameters is an object
1123
+ if ( typeof parameters !== 'object' || parameters === null ) {
1124
+ tools.DebugAndLog.error("Cache.init() parameters must be an object");
1125
+ throw new Error("Cache.init() parameters must be an object");
1126
+ }
1127
+
1128
+ // if parameters are set, use them, otherwise check for environment variables
1129
+ this.#idHashAlgorithm = parameters.idHashAlgorithm || process.env.CACHE_DATA_ID_HASH_ALGORITHM || "RSA-SHA256";
1130
+ this.#useToolsHash = ( "useToolsHash" in parameters ) ? Cache.bool(parameters.useToolsHash) :
1131
+ ("CACHE_DATA_USE_TOOLS_HASH" in process.env ? Cache.bool(process.env.CACHE_DATA_USE_TOOLS_HASH_METHOD) : false);
1079
1132
 
1133
+ // Let CacheData handle the rest of the initialization
1080
1134
  CacheData.init(parameters);
1081
1135
  };
1082
1136
 
@@ -104,8 +104,8 @@ class DebugAndLog {
104
104
  * @returns {string} The current environment.
105
105
  */
106
106
  static getEnv() {
107
- var possibleVars = ["env", "deployEnvironment", "environment", "stage"]; // this is the application env, not the NODE_ENV
108
- var env = DebugAndLog.PROD; // if env or deployEnvironment not set, fail to safe
107
+ var possibleVars = ["env", "deployEnvironment", "environment", "stage, deploy_environment"]; // this is the application env, not the NODE_ENV
108
+ var env = (process.env?.NODE_ENV === "development" ? DebugAndLog.DEV : DebugAndLog.PROD); // if env or deployEnvironment not set, fail to safe
109
109
 
110
110
  if ( "env" in process ) {
111
111
  for (let i in possibleVars) {
@@ -249,18 +249,18 @@ class _ConfigSuperClass {
249
249
  * let params = await this._initParameters(
250
250
  * [
251
251
  * {
252
- * "group": "appone", // so we can do params.app.authOSTActionsUsername later
253
- * "path": process.env.paramStorePath, // Lambda environment variable
252
+ * "group": "appone", // so we can do params.app.authUsername later
253
+ * "path": process.env.PARAM_STORE_PATH, // Lambda environment variable
254
254
  * "names": [
255
- * "authOSTActionsUsername",
256
- * "authOSTActionsPassword",
257
- * "authExLibrisAPIkey",
255
+ * "authUsername",
256
+ * "authPassword",
257
+ * "authAPIkey",
258
258
  * "crypt_secureDataKey"
259
259
  * ]
260
260
  * }, // OR get all under a single path
261
261
  * {
262
- * "group": "app", // so we can do params.app.authOSTActionsUsername later
263
- * "path": process.env.paramStorePath // Lambda environment variable
262
+ * "group": "app", // so we can do params.app.authUsername later
263
+ * "path": process.env.PARAM_STORE_PATH // Lambda environment variable
264
264
  * }
265
265
  * ]
266
266
  * );