cloudcms-server 3.3.1-beta.1 → 3.3.1-beta.10
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/.last_command +7 -0
- package/broadcast/providers/redis.js +32 -57
- package/clients/nrp.js +117 -0
- package/clients/redis.js +48 -0
- package/duster/helpers/sample/nyt.js +5 -7
- package/framework/controllers.js +0 -1
- package/index.js +23 -13
- package/insight/insight.js +6 -9
- package/locks/providers/redis.js +29 -58
- package/middleware/admin/admin.js +4 -4
- package/middleware/awareness/awareness.js +4 -1
- package/middleware/awareness/plugins/editorial.js +41 -66
- package/middleware/awareness/plugins/resources.js +74 -0
- package/middleware/awareness/providers/redis.js +263 -237
- package/middleware/cache/providers/redis.js +134 -92
- package/middleware/config/config.js +41 -2
- package/middleware/deployment/deployment.js +19 -22
- package/middleware/form/form.js +18 -33
- package/middleware/modules/modules.js +64 -11
- package/middleware/proxy/proxy.js +1 -2
- package/middleware/stores/engines/s3.js +0 -2
- package/middleware/stores/stores.js +50 -6
- package/middleware/themes/themes.js +49 -0
- package/middleware/virtual-config/virtual-config.js +35 -39
- package/notifications/notifications.js +75 -2
- package/package.json +18 -19
- package/server/index.js +105 -24
- package/server/standalone.js +2 -0
- package/util/auth.js +2 -7
- package/util/cloudcms.js +19 -34
- package/util/proxy-factory.js +17 -7
- package/util/redis.js +113 -0
- package/util/renditions.js +6 -12
- package/util/request.js +117 -0
- package/util/util.js +23 -36
- package/web/socket.io/socket.io.js +4240 -2
- package/web/cms/ice.js +0 -109
- package/web/cms/preview.js +0 -106
|
@@ -1,193 +1,194 @@
|
|
|
1
1
|
var AbstractAsyncProvider = require("./abstract-async");
|
|
2
2
|
|
|
3
|
-
var redis = require("redis");
|
|
3
|
+
//var redis = require("redis");
|
|
4
4
|
var async = require("async");
|
|
5
5
|
|
|
6
6
|
var logFactory = require("../../../util/logger");
|
|
7
|
+
//var redisHelper = require("../../../util/redis");
|
|
8
|
+
|
|
9
|
+
var redisClientFactory = require("../../../clients/redis");
|
|
10
|
+
const redisHelper = require("../../../util/redis");
|
|
7
11
|
|
|
8
12
|
class RedisProvider extends AbstractAsyncProvider
|
|
9
13
|
{
|
|
10
14
|
constructor(config)
|
|
11
15
|
{
|
|
12
16
|
super(config);
|
|
13
|
-
|
|
14
|
-
this.logger =
|
|
15
|
-
|
|
16
|
-
// allow for global redis default
|
|
17
|
-
// allow for redis broadcast specific
|
|
18
|
-
// otherwise default to error
|
|
19
|
-
if (typeof(process.env.CLOUDCMS_REDIS_DEBUG_LEVEL) !== "undefined") {
|
|
20
|
-
this.logger.setLevel(("" + process.env.CLOUDCMS_REDIS_DEBUG_LEVEL).toLowerCase(), true);
|
|
21
|
-
}
|
|
22
|
-
else if (typeof(process.env.CLOUDCMS_AWARENESS_REDIS_DEBUG_LEVEL) !== "undefined") {
|
|
23
|
-
this.logger.setLevel(("" + process.env.CLOUDCMS_AWARENESS_REDIS_DEBUG_LEVEL).toLowerCase(), true);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
this.logger.setLevel("error");
|
|
27
|
-
}
|
|
17
|
+
|
|
18
|
+
this.logger = redisHelper.redisLogger("REDIS_AWARENESS", "CLOUDCMS_AWARENESS_", "error")
|
|
28
19
|
}
|
|
29
|
-
|
|
20
|
+
|
|
30
21
|
init(callback)
|
|
31
22
|
{
|
|
32
23
|
var self = this;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
var redisOptions = {};
|
|
55
|
-
|
|
56
|
-
this.client = redis.createClient(redisPort, redisHost, redisOptions);
|
|
57
|
-
|
|
58
|
-
callback();
|
|
24
|
+
|
|
25
|
+
redisClientFactory.create(config, function(err, _client) {
|
|
26
|
+
|
|
27
|
+
if (err) {
|
|
28
|
+
return callback(err);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
self.client = _client;
|
|
32
|
+
|
|
33
|
+
return callback();
|
|
34
|
+
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
(async function() {
|
|
38
|
+
var redisOptions = redisHelper.redisOptions(this.config, "CLOUDCMS_AWARENESS");
|
|
39
|
+
await redisHelper.createAndConnect(redisOptions, function(err, _client) {
|
|
40
|
+
|
|
41
|
+
});
|
|
42
|
+
})();
|
|
59
43
|
}
|
|
60
|
-
|
|
44
|
+
|
|
61
45
|
readOrCreateChannel(channelId, callback)
|
|
62
46
|
{
|
|
63
47
|
var self = this;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (channelJsonText)
|
|
72
|
-
{
|
|
73
|
-
var channel = JSON.parse("" + channelJsonText);
|
|
74
|
-
return callback(null, channel);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
var channel = {};
|
|
78
|
-
self.client.set("channel-" + channelId, JSON.stringify(channel), function(err) {
|
|
79
|
-
|
|
48
|
+
|
|
49
|
+
(async function() {
|
|
50
|
+
|
|
51
|
+
await self.client.get("channel-" + channelId, function(err, channelJsonText) {
|
|
52
|
+
|
|
80
53
|
if (err) {
|
|
81
54
|
return callback(err);
|
|
82
55
|
}
|
|
83
|
-
|
|
84
|
-
|
|
56
|
+
|
|
57
|
+
if (channelJsonText)
|
|
58
|
+
{
|
|
59
|
+
var channel = JSON.parse("" + channelJsonText);
|
|
60
|
+
return callback(null, channel);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
(async function() {
|
|
64
|
+
var channel = {};
|
|
65
|
+
await self.client.set("channel-" + channelId, JSON.stringify(channel), function (err) {
|
|
66
|
+
|
|
67
|
+
if (err) {
|
|
68
|
+
return callback(err);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
callback(null, channel);
|
|
72
|
+
});
|
|
73
|
+
})();
|
|
85
74
|
});
|
|
86
|
-
|
|
75
|
+
|
|
76
|
+
})();
|
|
87
77
|
};
|
|
88
|
-
|
|
78
|
+
|
|
89
79
|
readChannel(channelId, callback)
|
|
90
80
|
{
|
|
91
81
|
var self = this;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
82
|
+
|
|
83
|
+
(async function() {
|
|
84
|
+
|
|
85
|
+
await self.client.get("channel-" + channelId, function(err, channelJsonText) {
|
|
86
|
+
|
|
87
|
+
if (err) {
|
|
88
|
+
return callback(err);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (channelJsonText)
|
|
92
|
+
{
|
|
93
|
+
var channel = JSON.parse("" + channelJsonText);
|
|
94
|
+
return callback(null, channel);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
callback();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
})();
|
|
107
101
|
};
|
|
108
|
-
|
|
102
|
+
|
|
109
103
|
writeChannel(channelId, channel, callback)
|
|
110
104
|
{
|
|
111
105
|
var self = this;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
106
|
+
|
|
107
|
+
(async function() {
|
|
108
|
+
|
|
109
|
+
await self.client.set("channel-" + channelId, JSON.stringify(channel), function(err) {
|
|
110
|
+
|
|
111
|
+
if (err) {
|
|
112
|
+
return callback(err);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
callback();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
})();
|
|
121
119
|
};
|
|
122
|
-
|
|
120
|
+
|
|
123
121
|
listChannelIds(callback)
|
|
124
122
|
{
|
|
125
123
|
var self = this;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
var
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
124
|
+
|
|
125
|
+
(async function() {
|
|
126
|
+
|
|
127
|
+
// fetch all keys for channels
|
|
128
|
+
await self.client.keys("channel-*", function(err, channelKeys) {
|
|
129
|
+
|
|
130
|
+
if (err)
|
|
131
|
+
{
|
|
132
|
+
return callback(err);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!channelKeys || channelKeys.length === 0)
|
|
136
|
+
{
|
|
137
|
+
return callback(null, []);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var channelIds = [];
|
|
141
|
+
for (var i = 0; i < channelKeys.length; i++)
|
|
142
|
+
{
|
|
143
|
+
var channelId = channelKeys[i].substring(channelKeys[i].indexOf("-") + 1);
|
|
144
|
+
channelIds.push(channelId);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
callback(null, channelIds);
|
|
148
|
+
});
|
|
149
|
+
})();
|
|
149
150
|
};
|
|
150
|
-
|
|
151
|
+
|
|
151
152
|
/**
|
|
152
153
|
* @override
|
|
153
154
|
*/
|
|
154
155
|
expire(beforeMs, callback)
|
|
155
156
|
{
|
|
156
157
|
var self = this;
|
|
157
|
-
|
|
158
|
+
|
|
158
159
|
self.listChannelIds(function(err, channelIds) {
|
|
159
|
-
|
|
160
|
+
|
|
160
161
|
if (err) {
|
|
161
162
|
return callback(err);
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
+
|
|
164
165
|
if (!channelIds || channelIds.length === 0) {
|
|
165
166
|
return callback(null, [], {});
|
|
166
167
|
}
|
|
167
|
-
|
|
168
|
+
|
|
168
169
|
// a list of channel IDs whose memberships were updated
|
|
169
170
|
var updatedMembershipChannelIds = [];
|
|
170
171
|
var expiredUserIdsByChannelId = {};
|
|
171
|
-
|
|
172
|
+
|
|
172
173
|
var fns = [];
|
|
173
|
-
|
|
174
|
+
|
|
174
175
|
for (var i = 0; i < channelIds.length; i++)
|
|
175
176
|
{
|
|
176
177
|
var channelId = channelIds[i];
|
|
177
|
-
|
|
178
|
+
|
|
178
179
|
var fn = function (channelId, updatedMembershipChannelIds, expiredUserIdsByChannelId, beforeMs) {
|
|
179
180
|
return function (done) {
|
|
180
|
-
|
|
181
|
+
|
|
181
182
|
self.readChannel(channelId, function(err, channel) {
|
|
182
|
-
|
|
183
|
+
|
|
183
184
|
if (err) {
|
|
184
185
|
return done(err);
|
|
185
186
|
}
|
|
186
|
-
|
|
187
|
+
|
|
187
188
|
if (!channel) {
|
|
188
189
|
return done();
|
|
189
190
|
}
|
|
190
|
-
|
|
191
|
+
|
|
191
192
|
if (channel.users)
|
|
192
193
|
{
|
|
193
194
|
// populate all of the user IDs that need to be removed
|
|
@@ -199,182 +200,207 @@ class RedisProvider extends AbstractAsyncProvider
|
|
|
199
200
|
{
|
|
200
201
|
updatedMembershipChannelIds.push(channelId);
|
|
201
202
|
userIdsToRemove.push(userId);
|
|
202
|
-
|
|
203
|
+
|
|
203
204
|
var expiredUserIds = expiredUserIdsByChannelId[channelId]
|
|
204
205
|
if (!expiredUserIds) {
|
|
205
206
|
expiredUserIds = expiredUserIdsByChannelId[channelId] = [];
|
|
206
207
|
}
|
|
207
|
-
|
|
208
|
+
|
|
208
209
|
expiredUserIds.push(userId);
|
|
209
210
|
}
|
|
210
211
|
}
|
|
211
|
-
|
|
212
|
+
|
|
212
213
|
// remove the user IDs
|
|
213
214
|
for (var i = 0; i < userIdsToRemove.length; i++)
|
|
214
215
|
{
|
|
215
216
|
delete channel.users[userIdsToRemove[i]];
|
|
216
217
|
}
|
|
217
|
-
|
|
218
|
+
|
|
218
219
|
self.writeChannel(channelId, channel, function() {
|
|
219
220
|
done();
|
|
220
221
|
});
|
|
221
222
|
}
|
|
222
|
-
|
|
223
|
+
|
|
223
224
|
});
|
|
224
225
|
};
|
|
225
226
|
}(channelId, updatedMembershipChannelIds, expiredUserIdsByChannelId, beforeMs);
|
|
226
227
|
fns.push(fn);
|
|
227
228
|
}
|
|
228
|
-
|
|
229
|
+
|
|
229
230
|
async.parallel(fns, function(err) {
|
|
230
|
-
|
|
231
|
+
|
|
231
232
|
if (err) {
|
|
232
233
|
return callback(err);
|
|
233
234
|
}
|
|
234
|
-
|
|
235
|
+
|
|
235
236
|
callback(null, updatedMembershipChannelIds, expiredUserIdsByChannelId);
|
|
236
237
|
});
|
|
237
238
|
});
|
|
238
239
|
};
|
|
239
|
-
|
|
240
|
+
|
|
240
241
|
readLock(lockId, callback)
|
|
241
242
|
{
|
|
242
243
|
var self = this;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
244
|
+
|
|
245
|
+
(async function() {
|
|
246
|
+
|
|
247
|
+
await self.client.get("lock-" + lockId, function(err, lockJsonText) {
|
|
248
|
+
|
|
249
|
+
if (err) {
|
|
250
|
+
return callback(err);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (lockJsonText)
|
|
254
|
+
{
|
|
255
|
+
var lock = JSON.parse("" + lockJsonText);
|
|
256
|
+
return callback(null, lock);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
callback();
|
|
260
|
+
});
|
|
261
|
+
})();
|
|
258
262
|
};
|
|
259
|
-
|
|
263
|
+
|
|
260
264
|
writeLock(lockId, lock, callback)
|
|
261
265
|
{
|
|
262
266
|
var self = this;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
267
|
+
|
|
268
|
+
(async function() {
|
|
269
|
+
|
|
270
|
+
await self.client.set("lock-" + lockId, JSON.stringify(lock), function(err) {
|
|
271
|
+
|
|
272
|
+
if (err) {
|
|
273
|
+
return callback(err);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
callback();
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
})();
|
|
272
280
|
};
|
|
273
|
-
|
|
281
|
+
|
|
274
282
|
deleteLock(lockId, callback)
|
|
275
283
|
{
|
|
276
284
|
var self = this;
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
285
|
+
|
|
286
|
+
(async function() {
|
|
287
|
+
|
|
288
|
+
await self.client.del("lock-" + lockId, function(err) {
|
|
289
|
+
|
|
290
|
+
if (err) {
|
|
291
|
+
return callback(err);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
callback();
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
})();
|
|
286
298
|
};
|
|
287
|
-
|
|
299
|
+
|
|
288
300
|
listLockIds(callback)
|
|
289
301
|
{
|
|
290
302
|
var self = this;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
var
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
303
|
+
|
|
304
|
+
(async function() {
|
|
305
|
+
|
|
306
|
+
// fetch all keys for locks
|
|
307
|
+
await self.client.keys("lock-*", function(err, lockKeys) {
|
|
308
|
+
|
|
309
|
+
if (err)
|
|
310
|
+
{
|
|
311
|
+
return callback(err);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (!lockKeys || lockKeys.length === 0)
|
|
315
|
+
{
|
|
316
|
+
return callback(null, []);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
var lockIds = [];
|
|
320
|
+
for (var i = 0; i < lockKeys.length; i++)
|
|
321
|
+
{
|
|
322
|
+
var lockId = lockKeys[i].substring(0, lockKeys[i].indexOf("-"));
|
|
323
|
+
lockIds.push(lockId);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
callback(null, lockIds);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
})();
|
|
314
330
|
};
|
|
315
|
-
|
|
331
|
+
|
|
316
332
|
acquireSession(sessionId, callback)
|
|
317
333
|
{
|
|
318
334
|
var self = this;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (sessionJsonText)
|
|
327
|
-
{
|
|
328
|
-
var session = JSON.parse("" + sessionJsonText);
|
|
329
|
-
return callback(null, session);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// create a new session
|
|
333
|
-
var session = {};
|
|
334
|
-
self.client.set("session-" + sessionId, JSON.stringify(session), function(err) {
|
|
335
|
-
|
|
335
|
+
|
|
336
|
+
(async function() {
|
|
337
|
+
|
|
338
|
+
await self.client.get("session-" + sessionId, function(err, sessionJsonText) {
|
|
339
|
+
|
|
336
340
|
if (err) {
|
|
337
341
|
return callback(err);
|
|
338
342
|
}
|
|
339
|
-
|
|
340
|
-
|
|
343
|
+
|
|
344
|
+
if (sessionJsonText)
|
|
345
|
+
{
|
|
346
|
+
var session = JSON.parse("" + sessionJsonText);
|
|
347
|
+
return callback(null, session);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// create a new session
|
|
351
|
+
(async function() {
|
|
352
|
+
var session = {};
|
|
353
|
+
await self.client.set("session-" + sessionId, JSON.stringify(session), function(err) {
|
|
354
|
+
|
|
355
|
+
if (err) {
|
|
356
|
+
return callback(err);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
callback(null, session);
|
|
360
|
+
});
|
|
361
|
+
})();
|
|
341
362
|
});
|
|
342
|
-
});
|
|
363
|
+
})();
|
|
343
364
|
}
|
|
344
|
-
|
|
365
|
+
|
|
345
366
|
updateSession(sessionId, session, callback)
|
|
346
367
|
{
|
|
347
368
|
var self = this;
|
|
348
|
-
|
|
369
|
+
|
|
349
370
|
if (!session) {
|
|
350
371
|
session = {};
|
|
351
372
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
373
|
+
|
|
374
|
+
(async function() {
|
|
375
|
+
|
|
376
|
+
// create a new session
|
|
377
|
+
await self.client.set("session-" + sessionId, JSON.stringify(session), function (err) {
|
|
378
|
+
|
|
379
|
+
if (err) {
|
|
380
|
+
return callback(err);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
callback(null, session);
|
|
384
|
+
});
|
|
385
|
+
})();
|
|
362
386
|
}
|
|
363
|
-
|
|
387
|
+
|
|
364
388
|
deleteSession(sessionId, callback)
|
|
365
389
|
{
|
|
366
390
|
var self = this;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
391
|
+
|
|
392
|
+
(async function() {
|
|
393
|
+
await self.client.del("session-" + sessionId, function (err) {
|
|
394
|
+
|
|
395
|
+
if (err) {
|
|
396
|
+
return callback(err);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
callback();
|
|
400
|
+
});
|
|
401
|
+
})();
|
|
376
402
|
}
|
|
377
|
-
|
|
403
|
+
|
|
378
404
|
}
|
|
379
405
|
|
|
380
406
|
module.exports = RedisProvider;
|