@creator.co/wapi 1.5.3 → 1.5.5

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/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@creator.co/wapi",
3
- "version": "1.5.3",
3
+ "version": "1.5.5",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { RedisClientType } from 'redis';
1
+ import { RedisClientType, RedisClusterType } from 'redis';
2
2
  import { CacheConfig } from './types';
3
3
  /**
4
4
  * Represents a Redis cache connection class.
@@ -10,7 +10,13 @@ export default class Redis {
10
10
  * This property is used to create client.
11
11
  */
12
12
  private static ClientFactory;
13
- static connection(config: CacheConfig<'redis'>): Promise<RedisClientType>;
13
+ /**
14
+ * A private static property that references the createCluster function.
15
+ * This property can be used to create clusters within the class.
16
+ */
17
+ private static ClusterFactory;
18
+ static connection(config: CacheConfig<'redis'>): Promise<RedisClientType | RedisClusterType>;
19
+ private static connectionFactory;
14
20
  /**
15
21
  * Establishes a connection to a Redis client based on the provided configuration
16
22
  * and holds it for reusability. If connection is detected closed, new connection is
@@ -18,5 +24,6 @@ export default class Redis {
18
24
  * @param {CacheConfig<'redis'>} config - The configuration object for connecting to the Redis client.
19
25
  * @returns {Promise<RedisClientType>} A promise that resolves to the Redis client connection.
20
26
  */
21
- private static redisConnection;
27
+ private static redisClientConnection;
28
+ private static redisClusterConnection;
22
29
  }
@@ -58,6 +58,17 @@ var Redis = /** @class */ (function () {
58
58
  Redis.connection = function (config) {
59
59
  return _a.singleton.instance(config);
60
60
  };
61
+ Redis.connectionFactory = function (config) {
62
+ return __awaiter(this, void 0, void 0, function () {
63
+ return __generator(this, function (_b) {
64
+ if (config.clusterMode)
65
+ return [2 /*return*/, _a.redisClusterConnection(config)];
66
+ else
67
+ return [2 /*return*/, _a.redisClientConnection(config)];
68
+ return [2 /*return*/];
69
+ });
70
+ });
71
+ };
61
72
  /**
62
73
  * Establishes a connection to a Redis client based on the provided configuration
63
74
  * and holds it for reusability. If connection is detected closed, new connection is
@@ -65,14 +76,45 @@ var Redis = /** @class */ (function () {
65
76
  * @param {CacheConfig<'redis'>} config - The configuration object for connecting to the Redis client.
66
77
  * @returns {Promise<RedisClientType>} A promise that resolves to the Redis client connection.
67
78
  */
68
- Redis.redisConnection = function (config) {
79
+ Redis.redisClientConnection = function (config) {
80
+ return __awaiter(this, void 0, void 0, function () {
81
+ var connection;
82
+ return __generator(this, function (_b) {
83
+ switch (_b.label) {
84
+ case 0:
85
+ console.debug('Starting remote client cache connection');
86
+ connection = _a.ClientFactory(__assign(__assign({ username: config.username }, (config.password ? { password: config.password } : {})), { disableOfflineQueue: true, socket: {
87
+ host: config.hostname,
88
+ tls: config.enableTLS,
89
+ connectTimeout: 10000,
90
+ } }));
91
+ return [4 /*yield*/, connection.connect()];
92
+ case 1:
93
+ _b.sent();
94
+ return [2 /*return*/, connection];
95
+ }
96
+ });
97
+ });
98
+ };
99
+ Redis.redisClusterConnection = function (config) {
69
100
  return __awaiter(this, void 0, void 0, function () {
70
101
  var connection;
71
102
  return __generator(this, function (_b) {
72
103
  switch (_b.label) {
73
104
  case 0:
74
- console.debug('Starting remote cache connection');
75
- connection = _a.ClientFactory(__assign(__assign({ username: config.username }, (config.password ? { password: config.password } : {})), { disableOfflineQueue: true, socket: __assign(__assign({ host: config.hostname }, (config.enableTLS ? { tls: true } : {})), { connectTimeout: 10000 }) }));
105
+ console.debug('Starting remote cluster cache connection');
106
+ connection = _a.ClusterFactory({
107
+ defaults: __assign(__assign({ username: config.username }, (config.password ? { password: config.password } : {})), { socket: {
108
+ tls: config.enableTLS,
109
+ connectTimeout: 10000,
110
+ } }),
111
+ rootNodes: [
112
+ {
113
+ url: "redis://".concat(config.username, ":").concat(config.username, "@").concat(config.hostname, ":6379"),
114
+ disableOfflineQueue: true,
115
+ },
116
+ ],
117
+ });
76
118
  return [4 /*yield*/, connection.connect()];
77
119
  case 1:
78
120
  _b.sent();
@@ -83,7 +125,7 @@ var Redis = /** @class */ (function () {
83
125
  };
84
126
  var _a;
85
127
  _a = Redis;
86
- Redis.singleton = new AsyncSingleton_1.default(_a.redisConnection, function (c) { return __awaiter(void 0, void 0, void 0, function () { return __generator(_a, function (_b) {
128
+ Redis.singleton = new AsyncSingleton_1.default(_a.connectionFactory, function (c) { return __awaiter(void 0, void 0, void 0, function () { return __generator(_a, function (_b) {
87
129
  return [2 /*return*/, c.isOpen];
88
130
  }); }); });
89
131
  /**
@@ -91,6 +133,11 @@ var Redis = /** @class */ (function () {
91
133
  * This property is used to create client.
92
134
  */
93
135
  Redis.ClientFactory = redis_1.createClient;
136
+ /**
137
+ * A private static property that references the createCluster function.
138
+ * This property can be used to create clusters within the class.
139
+ */
140
+ Redis.ClusterFactory = redis_1.createCluster;
94
141
  return Redis;
95
142
  }());
96
143
  exports.default = Redis;
@@ -1 +1 @@
1
- {"version":3,"file":"Redis.js","sourceRoot":"","sources":["../../../src/Cache/Redis.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAqD;AAGrD,yDAAmD;AACnD;;GAEG;AACH;IAAA;IAuCA,CAAC;IA3Be,gBAAU,GAAxB,UAAyB,MAA4B;QACnD,OAAO,EAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACzC,CAAC;IAED;;;;;;OAMG;IACkB,qBAAe,GAApC,UAAqC,MAA4B;;;;;;wBAC/D,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAA;wBAC3C,UAAU,GAAG,EAAK,CAAC,aAAa,qBACpC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IACtB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KACzD,mBAAmB,EAAE,IAAI,EACzB,MAAM,sBACJ,IAAI,EAAE,MAAM,CAAC,QAAQ,IAClB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC1C,cAAc,EAAE,KAAK,OAEvB,CAAA;wBACF,qBAAM,UAAU,CAAC,OAAO,EAAE,EAAA;;wBAA1B,SAA0B,CAAA;wBAE1B,sBAAO,UAAiB,EAAA;;;;KACzB;;;IArCc,eAAS,GAAG,IAAI,wBAAc,CAC3C,EAAK,CAAC,eAAe,EACrB,UAAM,CAAC;QAAI,sBAAA,CAAC,CAAC,MAAM,EAAA;aAAA,CACpB,AAHuB,CAGvB;IAED;;;OAGG;IACY,mBAAa,GAAG,oBAAY,AAAf,CAAe;IA6B7C,YAAC;CAAA,AAvCD,IAuCC;kBAvCoB,KAAK"}
1
+ {"version":3,"file":"Redis.js","sourceRoot":"","sources":["../../../src/Cache/Redis.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAsF;AAGtF,yDAAmD;AACnD;;GAEG;AACH;IAAA;IAgFA,CAAC;IA9De,gBAAU,GAAxB,UACE,MAA4B;QAE5B,OAAO,EAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACzC,CAAC;IAEoB,uBAAiB,GAAtC,UACE,MAA4B;;;gBAE5B,IAAI,MAAM,CAAC,WAAW;oBAAE,sBAAO,EAAK,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAA;;oBAC9D,sBAAO,EAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAA;;;;KAChD;IACD;;;;;;OAMG;IACkB,2BAAqB,GAA1C,UACE,MAA4B;;;;;;wBAE5B,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAA;wBAClD,UAAU,GAAG,EAAK,CAAC,aAAa,qBACpC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IACtB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KACzD,mBAAmB,EAAE,IAAI,EACzB,MAAM,EAAE;gCACN,IAAI,EAAE,MAAM,CAAC,QAAQ;gCACrB,GAAG,EAAE,MAAM,CAAC,SAAS;gCACrB,cAAc,EAAE,KAAK;6BACtB,IACD,CAAA;wBACF,qBAAM,UAAU,CAAC,OAAO,EAAE,EAAA;;wBAA1B,SAA0B,CAAA;wBAE1B,sBAAO,UAAiB,EAAA;;;;KACzB;IAEoB,4BAAsB,GAA3C,UACE,MAA4B;;;;;;wBAE5B,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;wBACnD,UAAU,GAAG,EAAK,CAAC,cAAc,CAAC;4BACtC,QAAQ,sBACN,QAAQ,EAAE,MAAM,CAAC,QAAQ,IACtB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KACzD,MAAM,EAAE;oCACN,GAAG,EAAE,MAAM,CAAC,SAAS;oCACrB,cAAc,EAAE,KAAK;iCACtB,GACF;4BACD,SAAS,EAAE;gCACT;oCACE,GAAG,EAAE,kBAAW,MAAM,CAAC,QAAQ,cAAI,MAAM,CAAC,QAAQ,cAAI,MAAM,CAAC,QAAQ,UAAO;oCAC5E,mBAAmB,EAAE,IAAI;iCAC1B;6BACF;yBACF,CAAC,CAAA;wBACF,qBAAM,UAAU,CAAC,OAAO,EAAE,EAAA;;wBAA1B,SAA0B,CAAA;wBAE1B,sBAAO,UAAiB,EAAA;;;;KACzB;;;IA9Ec,eAAS,GAAG,IAAI,wBAAc,CAG3C,EAAK,CAAC,iBAAiB,EAAE,UAAM,CAAC;QAAI,sBAAA,CAAC,CAAC,MAAM,EAAA;aAAA,CAAC,AAHvB,CAGuB;IAE/C;;;OAGG;IACY,mBAAa,GAAG,oBAAY,AAAf,CAAe;IAE3C;;;OAGG;IACY,oBAAc,GAAG,qBAAa,AAAhB,CAAgB;IAgE/C,YAAC;CAAA,AAhFD,IAgFC;kBAhFoB,KAAK"}
@@ -18,6 +18,7 @@ export type CacheBaseConfig = {
18
18
  username: string;
19
19
  password?: string;
20
20
  enableTLS: boolean;
21
+ clusterMode?: boolean;
21
22
  };
22
23
  /**
23
24
  * Defines a CacheConfig type that extends CacheBaseConfig and includes a specific cache type.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@creator.co/wapi",
3
- "version": "1.5.3",
3
+ "version": "1.5.5",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { RedisClientType, createClient } from 'redis'
1
+ import { RedisClientType, RedisClusterType, createCluster, createClient } from 'redis'
2
2
 
3
3
  import { CacheConfig } from './types'
4
4
  import AsyncSingleton from '../Util/AsyncSingleton'
@@ -6,10 +6,10 @@ import AsyncSingleton from '../Util/AsyncSingleton'
6
6
  * Represents a Redis cache connection class.
7
7
  */
8
8
  export default class Redis {
9
- private static singleton = new AsyncSingleton<RedisClientType, CacheConfig<'redis'>>(
10
- Redis.redisConnection,
11
- async c => c.isOpen
12
- )
9
+ private static singleton = new AsyncSingleton<
10
+ RedisClientType | RedisClusterType,
11
+ CacheConfig<'redis'>
12
+ >(Redis.connectionFactory, async c => c.isOpen)
13
13
 
14
14
  /**
15
15
  * A private static property that holds a reference to the redis.createClient function.
@@ -17,10 +17,24 @@ export default class Redis {
17
17
  */
18
18
  private static ClientFactory = createClient
19
19
 
20
- public static connection(config: CacheConfig<'redis'>): Promise<RedisClientType> {
20
+ /**
21
+ * A private static property that references the createCluster function.
22
+ * This property can be used to create clusters within the class.
23
+ */
24
+ private static ClusterFactory = createCluster
25
+
26
+ public static connection(
27
+ config: CacheConfig<'redis'>
28
+ ): Promise<RedisClientType | RedisClusterType> {
21
29
  return Redis.singleton.instance(config)
22
30
  }
23
31
 
32
+ private static async connectionFactory(
33
+ config: CacheConfig<'redis'>
34
+ ): Promise<RedisClientType | RedisClusterType> {
35
+ if (config.clusterMode) return Redis.redisClusterConnection(config)
36
+ else return Redis.redisClientConnection(config)
37
+ }
24
38
  /**
25
39
  * Establishes a connection to a Redis client based on the provided configuration
26
40
  * and holds it for reusability. If connection is detected closed, new connection is
@@ -28,15 +42,17 @@ export default class Redis {
28
42
  * @param {CacheConfig<'redis'>} config - The configuration object for connecting to the Redis client.
29
43
  * @returns {Promise<RedisClientType>} A promise that resolves to the Redis client connection.
30
44
  */
31
- private static async redisConnection(config: CacheConfig<'redis'>): Promise<RedisClientType> {
32
- console.debug('Starting remote cache connection')
45
+ private static async redisClientConnection(
46
+ config: CacheConfig<'redis'>
47
+ ): Promise<RedisClientType> {
48
+ console.debug('Starting remote client cache connection')
33
49
  const connection = Redis.ClientFactory({
34
50
  username: config.username,
35
51
  ...(config.password ? { password: config.password } : {}),
36
52
  disableOfflineQueue: true,
37
53
  socket: {
38
54
  host: config.hostname,
39
- ...(config.enableTLS ? { tls: true } : {}),
55
+ tls: config.enableTLS,
40
56
  connectTimeout: 10000,
41
57
  },
42
58
  })
@@ -44,4 +60,29 @@ export default class Redis {
44
60
 
45
61
  return connection as any
46
62
  }
63
+
64
+ private static async redisClusterConnection(
65
+ config: CacheConfig<'redis'>
66
+ ): Promise<RedisClusterType> {
67
+ console.debug('Starting remote cluster cache connection')
68
+ const connection = Redis.ClusterFactory({
69
+ defaults: {
70
+ username: config.username,
71
+ ...(config.password ? { password: config.password } : {}),
72
+ socket: {
73
+ tls: config.enableTLS,
74
+ connectTimeout: 10000,
75
+ },
76
+ },
77
+ rootNodes: [
78
+ {
79
+ url: `redis://${config.username}:${config.username}@${config.hostname}:6379`,
80
+ disableOfflineQueue: true,
81
+ },
82
+ ],
83
+ })
84
+ await connection.connect()
85
+
86
+ return connection as any
87
+ }
47
88
  }
@@ -21,6 +21,7 @@ export type CacheBaseConfig = {
21
21
  username: string
22
22
  password?: string
23
23
  enableTLS: boolean
24
+ clusterMode?: boolean
24
25
  }
25
26
 
26
27
  /**
@@ -33,7 +33,7 @@ async function simpleRedisTest(config: any, concurrent?: boolean) {
33
33
  disableOfflineQueue: true,
34
34
  socket: {
35
35
  host: config.hostname,
36
- ...(config.enableTLS ? { tls: true } : {}),
36
+ tls: config.enableTLS,
37
37
  connectTimeout: 10000,
38
38
  },
39
39
  })
@@ -43,7 +43,7 @@ async function simpleRedisTest(config: any, concurrent?: boolean) {
43
43
  expect(provider2.connect).toHaveBeenCalledTimes(1)
44
44
  }
45
45
 
46
- describe('Redis', () => {
46
+ describe('Redis (client)', () => {
47
47
  beforeEach(async () => {
48
48
  // hack to close singleton connection
49
49
  if (Redis['singleton'].getValue()) Redis['singleton'].clear()
@@ -0,0 +1,98 @@
1
+ import Redis from '../../src/Cache/Redis'
2
+
3
+ let _connectionId = 1
4
+
5
+ async function simpleRedisTest(config: any, concurrent?: boolean) {
6
+ const RedisMock = jest.fn(() => {
7
+ let opened = false
8
+ const connectionId = _connectionId++
9
+ return {
10
+ connectionId,
11
+ isOpen: () => opened,
12
+ close: () => (opened = false),
13
+ connect: jest.fn(() => {
14
+ opened = true
15
+ return {
16
+ mget: jest.fn(() => {
17
+ return true
18
+ }),
19
+ }
20
+ }),
21
+ } as any
22
+ })
23
+ Redis['ClusterFactory'] = RedisMock
24
+ // Double call is intentional
25
+ const [provider, provider2] = concurrent
26
+ ? await Promise.all([Redis.connection(config), Redis.connection(config)])
27
+ : [await Redis.connection(config), await Redis.connection(config)]
28
+
29
+ // client checks
30
+ expect(RedisMock).toHaveBeenNthCalledWith(1, {
31
+ defaults: {
32
+ username: config.username,
33
+ ...(config.password ? { password: config.password } : {}),
34
+ socket: {
35
+ tls: config.enableTLS,
36
+ connectTimeout: 10000,
37
+ },
38
+ },
39
+ rootNodes: [
40
+ {
41
+ url: `redis://${config.username}:${config.username}@${config.hostname}:6379`,
42
+ disableOfflineQueue: true,
43
+ },
44
+ ],
45
+ })
46
+ // Does not have double connection
47
+ expect(provider['connectionId']).toEqual(provider2['connectionId'])
48
+ expect(provider.connect).toHaveBeenCalledTimes(1)
49
+ expect(provider2.connect).toHaveBeenCalledTimes(1)
50
+ }
51
+
52
+ describe('Redis (cluster)', () => {
53
+ beforeEach(async () => {
54
+ // hack to close singleton connection
55
+ if (Redis['singleton'].getValue()) Redis['singleton'].clear()
56
+ })
57
+ test('Simple redis - do not connect twice', async () => {
58
+ await simpleRedisTest({
59
+ hostname: 'redis://localhost',
60
+ username: 'gabe',
61
+ password: 'mypassword',
62
+ enableTLS: true,
63
+ clusterMode: true,
64
+ type: 'redis',
65
+ })
66
+ })
67
+ test('Simple redis (no SSL) - do not connect twice', async () => {
68
+ await simpleRedisTest({
69
+ hostname: 'redis://localhost',
70
+ username: 'gabe',
71
+ password: 'mypassword',
72
+ enableTLS: false,
73
+ clusterMode: true,
74
+ type: 'redis',
75
+ })
76
+ })
77
+ test('Simple redis (passwordless) - do not connect twice', async () => {
78
+ await simpleRedisTest({
79
+ hostname: 'redis://localhost',
80
+ username: 'gabe',
81
+ enableTLS: false,
82
+ clusterMode: true,
83
+ type: 'redis',
84
+ })
85
+ })
86
+ test('Concurrent redis - do not connect twice', async () => {
87
+ await simpleRedisTest(
88
+ {
89
+ hostname: 'redis://localhost',
90
+ username: 'gabe',
91
+ enableTLS: false,
92
+ clusterMode: true,
93
+ type: 'redis',
94
+ },
95
+ true
96
+ )
97
+ })
98
+ })