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.
|
|
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);
|
package/src/utils/appConst.ts
CHANGED
|
@@ -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
|
+
}
|