skyeye-svc-common-utils 0.0.209 → 0.0.211

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skyeye-svc-common-utils",
3
- "version": "0.0.209",
3
+ "version": "0.0.211",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,6 +33,9 @@
33
33
  "@types/jsonwebtoken": "^8.3.7",
34
34
  "@types/swagger-jsdoc": "^3.0.2",
35
35
  "@types/swagger-ui-express": "^4.1.1",
36
+ "@types/ioredis": "^4.26.4",
37
+ "ioredis": "^4.27.6",
38
+ "cron-parser": "^4.6.0",
36
39
  "async-mutex": "^0.3.2",
37
40
  "azure-storage": "^2.10.3",
38
41
  "dateformat": "^3.0.3",
package/src/index.ts CHANGED
@@ -18,4 +18,5 @@ export * from './lib/azure/azureBlobStorage';
18
18
  export * from './utils/documentation/swagger';
19
19
  export * from './lib/httpClient';
20
20
  export * from './utils/monitoring/apm';
21
- export * from './models/baseControllerParameter';
21
+ export * from './models/baseControllerParameter';
22
+ export * from './lib/redisClient';
@@ -0,0 +1,115 @@
1
+ import Redis, { RedisOptions } from 'ioredis';
2
+ import { logger } from '../utils/logger/logger';
3
+ import { commonAppConst } from '../utils/appConst'
4
+
5
+ /**
6
+ * A wrapper class for Redis client that adds error handling and logging
7
+ */
8
+ class RedisClient extends Redis {
9
+ /**
10
+ * @constructor
11
+ * @param {RedisOptions} options - config options for redis connection
12
+ */
13
+ constructor(options: RedisOptions) {
14
+ super(options);
15
+ // emits immediately right after the connect event.
16
+ this.on("ready", () => {
17
+ logger.info(`RedisClient connected, host: ${options.host}, port: ${options.port}`);
18
+ });
19
+ // emits when an error occurs while connecting.
20
+ this.on("error", (err) => {
21
+ logger.error(`RedisClient connection error: ${err}`);
22
+ });
23
+ }
24
+
25
+ /**
26
+ * @override It returns the value of the key from the Redis database.
27
+ * @param {string} key - The key to get the value of.
28
+ * @returns {Promise<string | null>} Value of the key.
29
+ */
30
+ async get(key: string): Promise<string | null> {
31
+ logger.info("start RedisClient.get");
32
+ try {
33
+ return super.get(key);
34
+ } catch (err) {
35
+ logger.warn(`RedisClient/get error: ${err}`);
36
+ return null;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * It sets a key-value pair in the Redis cache.
42
+ * @param {string} key - The key to store the value in.
43
+ * @param {any} value - The value for the key
44
+ * @param {number} time - Time to live, in seconds
45
+ * @returns {Promise<boolean>} A boolean to tell whether it is able to set a key in redis.
46
+ */
47
+ async put(
48
+ key: string,
49
+ value: any,
50
+ time: number = commonAppConst.redis.TTLfor5min
51
+ ): Promise<boolean> {
52
+ logger.info("start RedisClient.put");
53
+ try {
54
+ return Promise.resolve(!!await super.set(key, value, commonAppConst.redis.expiryMode.inSeconds, time));
55
+ } catch (err) {
56
+ logger.warn(`RedisClient/put error: ${err}`);
57
+ return Promise.resolve(false);
58
+ }
59
+ }
60
+
61
+ /**
62
+ * It locks a key in redis with a default TTL of 5 minutes, if possible.
63
+ * @param {string} key - The key to lock.
64
+ * @param {number} time - Time to live, in seconds
65
+ * @returns {Promise<boolean>} A boolean to tell whether it is able to lock the key.
66
+ */
67
+ async lock(
68
+ key: string,
69
+ time: number = commonAppConst.redis.TTLfor5min
70
+ ): Promise<boolean> {
71
+ logger.info("start RedisClient.lock");
72
+ try {
73
+ return Promise.resolve(!!await super.set(key, null, commonAppConst.redis.expiryMode.inSeconds, time, commonAppConst.redis.setMode.setIfNotExist));
74
+ } catch (err) {
75
+ logger.error(`RedisClient/lock error: ${err}`);
76
+ return Promise.resolve(false);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * If the key is locked (i.e. key exists in redis), return true, otherwise return false.
82
+ * @param {string} key - the key to check
83
+ * @returns {Promise<boolean>} A boolean to tell whether a key is locked in redis.
84
+ */
85
+ async isLocked(key: string): Promise<boolean> {
86
+ logger.info("start RedisClient.isLocked");
87
+ try {
88
+ return !!await super.exists(key);
89
+ } catch (err) {
90
+ logger.warn(`RedisClient/isLocked error: ${err}`);
91
+ return Promise.resolve(true);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * It unlocks a key in redis.
97
+ * @param {string} key - The key to unlock.
98
+ */
99
+ async unlock(key: string): Promise<void> {
100
+ logger.info("start RedisClient.unlock");
101
+ try {
102
+ await super.del(key);
103
+ } catch (err) {
104
+ logger.error(`RedisClient/unlock error: ${err}`);
105
+ }
106
+ }
107
+ }
108
+
109
+ const options: RedisOptions = {
110
+ host: process.env.REDIS_URL,
111
+ port: Number(process.env.REDIS_PORT),
112
+ password: process.env.REDIS_PRIMARY_SECRET,
113
+ tls: {} // do not remove the ssl connection default config
114
+ }
115
+ export const redisClient = new RedisClient(options);
@@ -31,6 +31,15 @@ export const commonAppConst = {
31
31
  id: "id",
32
32
  createdDate: "createdDate",
33
33
  lastModifiedDate: "lastModifiedDate"
34
+ },
35
+ redis: {
36
+ expiryMode: {
37
+ inSeconds: "ex"
38
+ },
39
+ TTLfor5min: 300, //5 minutes by default
40
+ setMode: {
41
+ setIfNotExist: 'nx'
42
+ }
34
43
  }
35
44
  }
36
45
 
@@ -0,0 +1,25 @@
1
+ import parser, { ParserOptions, CronExpression } from 'cron-parser';
2
+ import { logger } from '../logger/logger';
3
+
4
+ /**
5
+ * @description Get previous or next date given start date, cron expression and flag
6
+ * @param {string} cron - Cron expression
7
+ * @param {Date} [startDate] - a starting date
8
+ * @param {boolean} [getNext] - boolean value to indicate getting previous or next date
9
+ * @returns {Date} - the resultant date
10
+ * @throws Unexpected error
11
+ */
12
+ export function getDateFromCron(cron: string, startDate: Date = new Date(), getNext: boolean = false): Date | never {
13
+
14
+ let options: ParserOptions = {
15
+ currentDate: startDate
16
+ };
17
+ try {
18
+ const interval: CronExpression = parser.parseExpression(cron, options);
19
+ const val = getNext ? interval.next() : interval.prev();
20
+ return val.toDate();
21
+ } catch (err) {
22
+ logger.error(`getDateFromCron with error, ${err}`);
23
+ throw err;
24
+ }
25
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './appUtils';
2
2
  export * from './responseUtils';
3
3
  export * from './validation';
4
- export * from './jwtUtils';
4
+ export * from './jwtUtils';
5
+ export * from './cronUtils';