kythia-core 0.12.6-beta → 0.12.7-beta

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.
Files changed (72) hide show
  1. package/dist/Kythia.d.ts.map +1 -1
  2. package/dist/Kythia.js +1 -521
  3. package/dist/Kythia.js.map +1 -1
  4. package/dist/KythiaClient.js +1 -78
  5. package/dist/cli/Command.js +1 -16
  6. package/dist/cli/commands/AboutCommand.js +1 -114
  7. package/dist/cli/commands/CacheClearCommand.js +1 -97
  8. package/dist/cli/commands/DIGenerateCommand.js +1 -168
  9. package/dist/cli/commands/LangCheckCommand.js +1 -478
  10. package/dist/cli/commands/LangSyncCommand.js +1 -253
  11. package/dist/cli/commands/LangTranslateCommand.js +1 -224
  12. package/dist/cli/commands/MakeMigrationCommand.js +1 -55
  13. package/dist/cli/commands/MakeModelCommand.js +1 -56
  14. package/dist/cli/commands/MigrateCommand.js +1 -190
  15. package/dist/cli/commands/NamespaceCommand.js +1 -92
  16. package/dist/cli/commands/StructureCommand.js +1 -51
  17. package/dist/cli/commands/UpversionCommand.js +1 -68
  18. package/dist/cli/index.js +1 -43
  19. package/dist/cli/utils/db.js +1 -93
  20. package/dist/database/KythiaMigrator.js +1 -94
  21. package/dist/database/KythiaModel.js +1 -1128
  22. package/dist/database/KythiaSequelize.js +1 -99
  23. package/dist/database/KythiaStorage.js +1 -80
  24. package/dist/database/ModelLoader.js +1 -54
  25. package/dist/index.js +1 -36
  26. package/dist/lang/lang/en.json +85 -0
  27. package/dist/managers/AddonManager.js +1 -1097
  28. package/dist/managers/EventManager.js +1 -106
  29. package/dist/managers/InteractionManager.d.ts.map +1 -1
  30. package/dist/managers/InteractionManager.js +1 -482
  31. package/dist/managers/InteractionManager.js.map +1 -1
  32. package/dist/managers/MiddlewareManager.js +1 -106
  33. package/dist/managers/ShutdownManager.js +1 -179
  34. package/dist/managers/TelemetryManager.d.ts +7 -0
  35. package/dist/managers/TelemetryManager.d.ts.map +1 -1
  36. package/dist/managers/TelemetryManager.js +1 -201
  37. package/dist/managers/TelemetryManager.js.map +1 -1
  38. package/dist/managers/TranslatorManager.js +1 -145
  39. package/dist/middlewares/botPermissions.js +1 -28
  40. package/dist/middlewares/cooldown.js +1 -42
  41. package/dist/middlewares/isInMainGuild.js +1 -52
  42. package/dist/middlewares/ownerOnly.js +1 -24
  43. package/dist/middlewares/userPermissions.js +1 -28
  44. package/dist/structures/BaseCommand.js +1 -42
  45. package/dist/types/AddonManager.js +1 -3
  46. package/dist/types/DiscordHelpers.js +1 -3
  47. package/dist/types/EventManager.js +1 -3
  48. package/dist/types/InteractionManager.js +1 -3
  49. package/dist/types/KythiaClient.js +1 -3
  50. package/dist/types/KythiaConfig.js +1 -3
  51. package/dist/types/KythiaContainer.d.ts +1 -0
  52. package/dist/types/KythiaContainer.d.ts.map +1 -1
  53. package/dist/types/KythiaContainer.js +1 -3
  54. package/dist/types/KythiaLogger.js +1 -3
  55. package/dist/types/KythiaMigrator.js +1 -3
  56. package/dist/types/KythiaModel.js +1 -3
  57. package/dist/types/KythiaOptions.js +1 -3
  58. package/dist/types/KythiaSequelize.js +1 -3
  59. package/dist/types/KythiaStorage.js +1 -3
  60. package/dist/types/MiddlewareManager.js +1 -3
  61. package/dist/types/ModelLoader.js +1 -3
  62. package/dist/types/ShutdownManager.js +1 -3
  63. package/dist/types/TranslatorManager.js +1 -3
  64. package/dist/types/error.js +1 -3
  65. package/dist/types/index.js +1 -29
  66. package/dist/utils/InteractionFactory.js +1 -334
  67. package/dist/utils/color.js +1 -156
  68. package/dist/utils/discord.js +1 -19
  69. package/dist/utils/formatter.js +1 -89
  70. package/dist/utils/index.js +1 -56
  71. package/dist/utils/logger.js +1 -204
  72. package/package.json +5 -2
@@ -1,1128 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.KythiaModel = void 0;
7
- const jsonStringify = require("json-stable-stringify");
8
- const sequelize_1 = require("sequelize");
9
- const lru_cache_1 = require("lru-cache");
10
- const logger_1 = __importDefault(require("../utils/logger"));
11
- const NEGATIVE_CACHE_PLACEHOLDER = '__KYTHIA_NEGATIVE_CACHE__';
12
- const RECONNECT_DELAY_MINUTES = 3;
13
- const REDIS_ERROR_TOLERANCE_COUNT = 3;
14
- const REDIS_ERROR_TOLERANCE_INTERVAL_MS = 10 * 1000;
15
- function safeStringify(obj, logger) {
16
- try {
17
- return JSON.stringify(obj, (_key, value) => typeof value === 'bigint' ? value.toString() : value);
18
- }
19
- catch (err) {
20
- (logger || console).error(`❌ [SAFE STRINGIFY] Failed: ${err.message}`);
21
- return '{}';
22
- }
23
- }
24
- function safeParse(str, logger) {
25
- try {
26
- return JSON.parse(str);
27
- }
28
- catch {
29
- (logger || console).warn('⚠️ [SAFE PARSE] Invalid JSON data, returning null');
30
- return null;
31
- }
32
- }
33
- class KythiaModel extends sequelize_1.Model {
34
- static client;
35
- static redis;
36
- static isRedisConnected = false;
37
- static logger;
38
- static config = {};
39
- static CACHE_VERSION = '1.0.0';
40
- static localCache = new lru_cache_1.LRUCache({
41
- max: 1000,
42
- });
43
- static localNegativeCache = new Set();
44
- static MAX_LOCAL_CACHE_SIZE = 1000;
45
- static DEFAULT_TTL = 60 * 60 * 1000;
46
- static lastRedisOpts = null;
47
- static reconnectTimeout = null;
48
- static lastAutoReconnectTs = 0;
49
- static pendingQueries = new Map();
50
- static cacheStats = {
51
- redisHits: 0,
52
- mapHits: 0,
53
- misses: 0,
54
- sets: 0,
55
- clears: 0,
56
- errors: 0,
57
- };
58
- static redisErrorTimestamps = [];
59
- static isShardMode = false;
60
- static _redisFallbackURLs = [];
61
- static _redisCurrentIndex = 0;
62
- static _redisFailedIndexes = new Set();
63
- static _justFailedOver = false;
64
- static fillable;
65
- static guarded;
66
- static structure;
67
- static table;
68
- static cacheKeys;
69
- static CACHE_KEYS;
70
- static CACHE_TTL;
71
- static customInvalidationTags;
72
- static useRedis;
73
- static init(attributes, options) {
74
- const model = super.init(attributes, options);
75
- model.addHook('beforeValidate', (instance) => {
76
- const ModelClass = instance.constructor;
77
- if (ModelClass.fillable && Array.isArray(ModelClass.fillable)) {
78
- const allowedFields = ModelClass.fillable;
79
- Object.keys(instance.dataValues).forEach((key) => {
80
- if (!allowedFields.includes(key)) {
81
- delete instance.dataValues[key];
82
- if (instance.changed())
83
- instance.changed(key, false);
84
- }
85
- });
86
- }
87
- else if (ModelClass.guarded && Array.isArray(ModelClass.guarded)) {
88
- const forbiddenFields = ModelClass.guarded;
89
- if (forbiddenFields.includes('*')) {
90
- instance.dataValues = {};
91
- return;
92
- }
93
- Object.keys(instance.dataValues).forEach((key) => {
94
- if (forbiddenFields.includes(key)) {
95
- delete instance.dataValues[key];
96
- if (instance.changed())
97
- instance.changed(key, false);
98
- }
99
- });
100
- }
101
- });
102
- return model;
103
- }
104
- static async autoBoot(sequelize) {
105
- let tableName = this.table;
106
- if (!tableName) {
107
- const modelName = this.name;
108
- const snakeCase = sequelize_1.Utils.underscoredIf(modelName, true);
109
- tableName = sequelize_1.Utils.pluralize(snakeCase);
110
- }
111
- let manualAttributes = {};
112
- let manualOptions = {};
113
- if (this.structure) {
114
- manualAttributes = this.structure.attributes || {};
115
- manualOptions = this.structure.options || {};
116
- }
117
- const queryInterface = sequelize.getQueryInterface();
118
- let tableSchema;
119
- try {
120
- tableSchema = await queryInterface.describeTable(tableName);
121
- }
122
- catch (error) {
123
- console.warn(`⚠️ [KythiaModel] Table '${tableName}' not found for model '${this.name}'. Skipping auto-boot. err ${error}`);
124
- return;
125
- }
126
- const dbAttributes = {};
127
- for (const [colName, colInfo] of Object.entries(tableSchema)) {
128
- dbAttributes[colName] = {
129
- type: this._mapDbTypeToSequelize(colInfo.type),
130
- allowNull: colInfo.allowNull,
131
- defaultValue: colInfo.defaultValue,
132
- primaryKey: colInfo.primaryKey,
133
- autoIncrement: colInfo.autoIncrement,
134
- };
135
- }
136
- const finalAttributes = { ...dbAttributes, ...manualAttributes };
137
- super.init(finalAttributes, {
138
- sequelize,
139
- modelName: this.name,
140
- tableName: tableName,
141
- timestamps: manualOptions.timestamps !== undefined
142
- ? manualOptions.timestamps
143
- : !!finalAttributes.createdAt,
144
- paranoid: manualOptions.paranoid !== undefined
145
- ? manualOptions.paranoid
146
- : !!finalAttributes.deletedAt,
147
- ...manualOptions,
148
- });
149
- this._setupLaravelHooks();
150
- return this;
151
- }
152
- static _mapDbTypeToSequelize(dbType) {
153
- const type = dbType.toUpperCase();
154
- if (type.startsWith('BOOLEAN') || type.startsWith('TINYINT(1)'))
155
- return sequelize_1.DataTypes.BOOLEAN;
156
- if (type.startsWith('INT') ||
157
- type.startsWith('TINYINT') ||
158
- type.startsWith('BIGINT'))
159
- return sequelize_1.DataTypes.INTEGER;
160
- if (type.startsWith('VARCHAR') ||
161
- type.startsWith('TEXT') ||
162
- type.startsWith('CHAR'))
163
- return sequelize_1.DataTypes.STRING;
164
- if (type.startsWith('DATETIME') || type.startsWith('TIMESTAMP'))
165
- return sequelize_1.DataTypes.DATE;
166
- if (type.startsWith('JSON'))
167
- return sequelize_1.DataTypes.JSON;
168
- if (type.startsWith('FLOAT') ||
169
- type.startsWith('DOUBLE') ||
170
- type.startsWith('DECIMAL'))
171
- return sequelize_1.DataTypes.FLOAT;
172
- if (type.startsWith('ENUM'))
173
- return sequelize_1.DataTypes.STRING;
174
- return sequelize_1.DataTypes.STRING;
175
- }
176
- static _setupLaravelHooks() {
177
- this.addHook('beforeValidate', (instance) => {
178
- const ModelClass = instance.constructor;
179
- const pkAttribute = ModelClass.primaryKeyAttribute || 'id';
180
- if (ModelClass.fillable && Array.isArray(ModelClass.fillable)) {
181
- const allowedFields = ModelClass.fillable;
182
- Object.keys(instance.dataValues).forEach((key) => {
183
- if (key === pkAttribute)
184
- return;
185
- if (!allowedFields.includes(key)) {
186
- delete instance.dataValues[key];
187
- if (instance.changed())
188
- instance.changed(key, false);
189
- }
190
- });
191
- }
192
- else if (ModelClass.guarded && Array.isArray(ModelClass.guarded)) {
193
- const forbiddenFields = ModelClass.guarded;
194
- if (forbiddenFields.includes('*')) {
195
- instance.dataValues = {};
196
- return;
197
- }
198
- Object.keys(instance.dataValues).forEach((key) => {
199
- if (key === pkAttribute)
200
- return;
201
- if (forbiddenFields.includes(key)) {
202
- delete instance.dataValues[key];
203
- if (instance.changed())
204
- instance.changed(key, false);
205
- }
206
- });
207
- }
208
- });
209
- }
210
- static setDependencies({ logger, config, redis, redisOptions, }) {
211
- if (!config) {
212
- throw new Error('KythiaModel.setDependencies requires config!');
213
- }
214
- this.logger = logger || logger_1.default;
215
- this.config = config;
216
- this.CACHE_VERSION = config.db?.redisCacheVersion || '1.0.0';
217
- const redisConfig = config?.db?.redis;
218
- const useRedis = config?.db?.useRedis !== false;
219
- this.useRedis = useRedis;
220
- this.isShardMode =
221
- (typeof redisConfig === 'object' &&
222
- redisConfig !== null &&
223
- redisConfig.shard) ||
224
- false;
225
- if (!useRedis) {
226
- this.logger.warn('🟠 [REDIS] Disabled via config (useRedis: false). Operating in In-Memory Cache mode only.');
227
- this.isRedisConnected = false;
228
- return;
229
- }
230
- if (this.isShardMode) {
231
- this.logger.info('🟣 [REDIS][SHARD] Detected redis sharding mode (shard: true). Local fallback cache DISABLED!');
232
- }
233
- this._redisFallbackURLs = [];
234
- if (Array.isArray(redisOptions)) {
235
- this._redisFallbackURLs = redisOptions.filter((opt) => opt && (typeof opt !== 'string' || opt.trim().length > 0));
236
- }
237
- else if (typeof redisOptions === 'string') {
238
- if (redisOptions.trim().length > 0) {
239
- this._redisFallbackURLs = redisOptions
240
- .split(',')
241
- .map((url) => url.trim())
242
- .filter((url) => url.length > 0);
243
- }
244
- }
245
- else if (redisOptions &&
246
- typeof redisOptions === 'object' &&
247
- Array.isArray(redisOptions.urls)) {
248
- this._redisFallbackURLs = redisOptions.urls.slice();
249
- }
250
- else if (redisOptions &&
251
- typeof redisOptions === 'object' &&
252
- Object.keys(redisOptions).length > 0) {
253
- this._redisFallbackURLs = [redisOptions];
254
- }
255
- this._redisCurrentIndex = 0;
256
- if (redis) {
257
- this.redis = redis;
258
- this.isRedisConnected = redis.status === 'ready';
259
- }
260
- else if (this._redisFallbackURLs.length > 0) {
261
- this.initializeRedis();
262
- }
263
- else {
264
- if (this.isShardMode) {
265
- this.logger.error('❌ [REDIS][SHARD] No Redis client/options, but shard:true. Application will work WITHOUT caching!');
266
- this.isRedisConnected = false;
267
- }
268
- else {
269
- this.logger.warn('🟠 [REDIS] No Redis provided. Switching to In-Memory Cache mode.');
270
- this.isRedisConnected = false;
271
- }
272
- }
273
- }
274
- static _trackRedisError(err) {
275
- const now = Date.now();
276
- this.redisErrorTimestamps = (this.redisErrorTimestamps || []).filter((ts) => now - ts < REDIS_ERROR_TOLERANCE_INTERVAL_MS);
277
- this.redisErrorTimestamps.push(now);
278
- if (this.redisErrorTimestamps.length >= REDIS_ERROR_TOLERANCE_COUNT) {
279
- if (this.isRedisConnected) {
280
- const triedFallback = this._tryRedisFailover();
281
- if (triedFallback) {
282
- this.logger.warn(`[REDIS] Error tolerance reached, switching to NEXT Redis failover...`);
283
- }
284
- else if (this.isShardMode) {
285
- this.logger.error(`❌ [REDIS][SHARD] ${this.redisErrorTimestamps.length} consecutive errors in ${REDIS_ERROR_TOLERANCE_INTERVAL_MS / 1000}s. SHARD MODE: Disabling cache (NO fallback), all queries go to DB. (Last error: ${err?.message})`);
286
- this.isRedisConnected = false;
287
- this._scheduleReconnect();
288
- }
289
- else {
290
- this.logger.error(`❌ [REDIS] ${this.redisErrorTimestamps.length} consecutive errors in ${REDIS_ERROR_TOLERANCE_INTERVAL_MS / 1000}s. All Redis exhausted, fallback to In-Memory Cache! (Last error: ${err?.message})`);
291
- this.isRedisConnected = false;
292
- this._scheduleReconnect();
293
- }
294
- }
295
- this.redisErrorTimestamps = [];
296
- }
297
- else {
298
- this.logger.warn(`🟠 [REDIS] Error #${this.redisErrorTimestamps.length}/${REDIS_ERROR_TOLERANCE_COUNT} tolerated. (${err?.message})`);
299
- }
300
- }
301
- static _tryRedisFailover() {
302
- if (!Array.isArray(this._redisFallbackURLs) ||
303
- this._redisFallbackURLs.length < 2) {
304
- return false;
305
- }
306
- const prevIndex = this._redisCurrentIndex;
307
- if (this._redisCurrentIndex + 1 < this._redisFallbackURLs.length) {
308
- this._redisCurrentIndex++;
309
- this.logger.warn(`[REDIS][FAILOVER] Trying to switch Redis connection from url index ${prevIndex} to ${this._redisCurrentIndex}`);
310
- this._justFailedOver = true;
311
- this._closeCurrentRedis();
312
- this.initializeRedis();
313
- return true;
314
- }
315
- return false;
316
- }
317
- static _closeCurrentRedis() {
318
- if (this.redis && typeof this.redis.quit === 'function') {
319
- try {
320
- this.redis.quit();
321
- }
322
- catch (e) {
323
- console.log(e);
324
- }
325
- }
326
- this.redis = undefined;
327
- this.isRedisConnected = false;
328
- }
329
- static initializeRedis(redisOptions) {
330
- if (redisOptions) {
331
- if (Array.isArray(redisOptions)) {
332
- this._redisFallbackURLs = redisOptions.slice();
333
- this._redisCurrentIndex = 0;
334
- }
335
- else if (redisOptions &&
336
- typeof redisOptions === 'object' &&
337
- Array.isArray(redisOptions.urls)) {
338
- this._redisFallbackURLs = redisOptions.urls.slice();
339
- this._redisCurrentIndex = 0;
340
- }
341
- else {
342
- this._redisFallbackURLs = [redisOptions];
343
- this._redisCurrentIndex = 0;
344
- }
345
- }
346
- if (!Array.isArray(this._redisFallbackURLs) ||
347
- this._redisFallbackURLs.length === 0) {
348
- if (this.isShardMode) {
349
- this.logger.error('❌ [REDIS][SHARD] No Redis URL/options provided but shard:true. Will run without caching!');
350
- this.isRedisConnected = false;
351
- }
352
- else {
353
- this.logger.warn('🟠 [REDIS] No Redis client or options provided. Operating in In-Memory Cache mode only.');
354
- this.isRedisConnected = false;
355
- }
356
- return null;
357
- }
358
- const Redis = require('ioredis');
359
- this.lastRedisOpts = Array.isArray(this._redisFallbackURLs)
360
- ? this._redisFallbackURLs.slice()
361
- : [this._redisFallbackURLs];
362
- if (this.redis)
363
- return this.redis;
364
- const opt = this._redisFallbackURLs[this._redisCurrentIndex];
365
- if (opt && typeof opt === 'object' && opt.shard) {
366
- this.isShardMode = true;
367
- }
368
- let redisOpt;
369
- if (typeof opt === 'string') {
370
- redisOpt = { url: opt, retryStrategy: this._makeRetryStrategy() };
371
- }
372
- else if (opt && typeof opt === 'object') {
373
- redisOpt = {
374
- maxRetriesPerRequest: 2,
375
- enableReadyCheck: true,
376
- retryStrategy: this._makeRetryStrategy(),
377
- ...opt,
378
- };
379
- }
380
- else {
381
- this.logger.error('❌ [REDIS] Invalid redis config detected in list');
382
- this.isRedisConnected = false;
383
- return null;
384
- }
385
- this.redis = new Redis(redisOpt.url || redisOpt);
386
- this._setupRedisEventHandlers();
387
- return this.redis;
388
- }
389
- static _makeRetryStrategy() {
390
- return (times) => {
391
- if (times > 5) {
392
- this.logger.error(`❌ [REDIS] Could not connect after ${times - 1} retries for Redis #${this._redisCurrentIndex + 1}.`);
393
- return null;
394
- }
395
- const delay = Math.min(times * 500, 2000);
396
- this.logger.warn(`🟠 [REDIS] Connection failed for Redis #${this._redisCurrentIndex + 1}. Retrying in ${delay}ms (Attempt ${times})...`);
397
- return delay;
398
- };
399
- }
400
- static _setupRedisEventHandlers() {
401
- if (!this.redis)
402
- return;
403
- this.redis.on('connect', async () => {
404
- if (!this.isRedisConnected) {
405
- this.logger.info('✅ [REDIS] Connection established. Switching to Redis Cache mode.');
406
- }
407
- this.isRedisConnected = true;
408
- this.redisErrorTimestamps = [];
409
- if (this.reconnectTimeout) {
410
- clearTimeout(this.reconnectTimeout);
411
- this.reconnectTimeout = null;
412
- }
413
- this._redisFailedIndexes.delete(this._redisCurrentIndex);
414
- if (this._justFailedOver) {
415
- this.logger.warn(`[REDIS][FAILOVER] Connected to new server, flushing potentially stale cache...`);
416
- try {
417
- await this.redis?.flushdb();
418
- this.logger.info(`[REDIS][FAILOVER] Stale cache flushed successfully.`);
419
- }
420
- catch (err) {
421
- this.logger.error(`[REDIS][FAILOVER] FAILED TO FLUSH CACHE:`, err);
422
- }
423
- this._justFailedOver = false;
424
- }
425
- });
426
- this.redis.on('error', (err) => {
427
- if (err && (err.code === 'ECONNREFUSED' || err.message)) {
428
- this.logger.warn(`🟠 [REDIS] Connection error: ${err.message}`);
429
- }
430
- });
431
- this.redis.on('close', () => {
432
- if (this.isRedisConnected) {
433
- if (this.isShardMode) {
434
- this.logger.error('❌ [REDIS][SHARD] Connection closed. Cache DISABLED (no fallback).');
435
- }
436
- else {
437
- this.logger.error('❌ [REDIS] Connection closed. Fallback/failover will be attempted.');
438
- }
439
- }
440
- this.isRedisConnected = false;
441
- this._redisFailedIndexes.add(this._redisCurrentIndex);
442
- this.logger.warn(`[REDIS] Connection #${this._redisCurrentIndex + 1} closed. Attempting immediate failover...`);
443
- const triedFailover = this._tryRedisFailover();
444
- if (!triedFailover) {
445
- this.logger.warn(`[REDIS] Failover exhausted. Scheduling full reconnect...`);
446
- this._scheduleReconnect();
447
- }
448
- });
449
- }
450
- static _scheduleReconnect() {
451
- if (this.reconnectTimeout)
452
- return;
453
- const sinceLast = Date.now() - this.lastAutoReconnectTs;
454
- if (sinceLast < RECONNECT_DELAY_MINUTES * 60 * 1000)
455
- return;
456
- this.lastAutoReconnectTs = Date.now();
457
- if (this.isShardMode) {
458
- this.logger.warn(`[REDIS][SHARD] Attempting auto-reconnect after ${RECONNECT_DELAY_MINUTES}min downtime...`);
459
- }
460
- else {
461
- this.logger.warn(`🟢 [REDIS] Attempting auto-reconnect after ${RECONNECT_DELAY_MINUTES}min downtime...`);
462
- }
463
- this.reconnectTimeout = setTimeout(() => {
464
- this.reconnectTimeout = null;
465
- this._redisCurrentIndex = 0;
466
- this._redisFailedIndexes.clear();
467
- this._closeCurrentRedis();
468
- this.initializeRedis();
469
- }, RECONNECT_DELAY_MINUTES * 60 * 1000);
470
- }
471
- static getCacheKey(queryIdentifier) {
472
- let dataToHash = queryIdentifier;
473
- if (dataToHash &&
474
- typeof dataToHash === 'object' &&
475
- !dataToHash.where &&
476
- !dataToHash.include) {
477
- dataToHash = { where: dataToHash };
478
- }
479
- const opts = {
480
- replacer: (_key, value) => typeof value === 'bigint' ? value.toString() : value,
481
- };
482
- const keyBody = typeof queryIdentifier === 'string'
483
- ? queryIdentifier
484
- : jsonStringify(this.normalizeQueryOptions(dataToHash), opts);
485
- return `${this.CACHE_VERSION}:${this.name}:${keyBody}`;
486
- }
487
- static normalizeQueryOptions(data) {
488
- if (!data || typeof data !== 'object')
489
- return data;
490
- if (Array.isArray(data))
491
- return data.map((item) => this.normalizeQueryOptions(item));
492
- const normalized = {};
493
- Object.keys(data)
494
- .sort()
495
- .forEach((key) => {
496
- normalized[key] = this.normalizeQueryOptions(data[key]);
497
- });
498
- Object.getOwnPropertySymbols(data).forEach((symbol) => {
499
- const key = `$${symbol.toString().slice(7, -1)}`;
500
- normalized[key] = this.normalizeQueryOptions(data[symbol]);
501
- });
502
- return normalized;
503
- }
504
- static _generateSmartTags(instance) {
505
- if (!instance)
506
- return [`${this.name}`];
507
- const tags = [`${this.name}`];
508
- const pk = this.primaryKeyAttribute;
509
- if (instance[pk]) {
510
- tags.push(`${this.name}:${pk}:${instance[pk]}`);
511
- }
512
- const smartKeys = this.cacheKeys || this.CACHE_KEYS || [];
513
- if (Array.isArray(smartKeys)) {
514
- for (const keyGroup of smartKeys) {
515
- const keys = Array.isArray(keyGroup) ? keyGroup : [keyGroup];
516
- const hasAllValues = keys.every((k) => instance[k] !== undefined && instance[k] !== null);
517
- if (hasAllValues) {
518
- const tagParts = keys
519
- .map((k) => `${k}:${instance[k]}`)
520
- .join(':');
521
- tags.push(`${this.name}:${tagParts}`);
522
- }
523
- }
524
- }
525
- return tags;
526
- }
527
- static async setCacheEntry(cacheKeyOrQuery, data, ttl, tags = []) {
528
- const cacheKey = typeof cacheKeyOrQuery === 'string'
529
- ? cacheKeyOrQuery
530
- : this.getCacheKey(cacheKeyOrQuery);
531
- const finalTtl = ttl || this.CACHE_TTL || this.DEFAULT_TTL;
532
- if (this.isRedisConnected) {
533
- await this._redisSetCacheEntry(cacheKey, data, finalTtl, tags);
534
- }
535
- else if (!this.isShardMode) {
536
- this._mapSetCacheEntry(cacheKey, data, finalTtl);
537
- }
538
- }
539
- static async getCachedEntry(cacheKeyOrQuery, includeOptions) {
540
- const cacheKey = typeof cacheKeyOrQuery === 'string'
541
- ? cacheKeyOrQuery
542
- : this.getCacheKey(cacheKeyOrQuery);
543
- if (this.isRedisConnected) {
544
- return this._redisGetCachedEntry(cacheKey, includeOptions);
545
- }
546
- else if (!this.isShardMode) {
547
- return this._mapGetCachedEntry(cacheKey, includeOptions);
548
- }
549
- return { hit: false, data: undefined };
550
- }
551
- static async clearCache(keys) {
552
- const cacheKey = typeof keys === 'string' ? keys : this.getCacheKey(keys);
553
- if (this.isRedisConnected) {
554
- await this._redisClearCache(cacheKey);
555
- }
556
- else if (!this.isShardMode) {
557
- this._mapClearCache(cacheKey);
558
- }
559
- }
560
- static async _redisSetCacheEntry(cacheKey, data, ttl, tags = []) {
561
- if (!this.redis)
562
- return;
563
- try {
564
- let plainData = data;
565
- if (data && typeof data.toJSON === 'function') {
566
- plainData = data.toJSON();
567
- }
568
- else if (Array.isArray(data)) {
569
- plainData = data.map((item) => item && typeof item.toJSON === 'function' ? item.toJSON() : item);
570
- }
571
- const valueToStore = plainData === null
572
- ? NEGATIVE_CACHE_PLACEHOLDER
573
- : safeStringify(plainData, this.logger);
574
- const multi = this.redis.multi();
575
- multi.set(cacheKey, valueToStore, 'PX', ttl);
576
- for (const tag of tags) {
577
- multi.sadd(tag, cacheKey);
578
- }
579
- await multi.exec();
580
- this.cacheStats.sets++;
581
- }
582
- catch (err) {
583
- this._trackRedisError(err);
584
- }
585
- }
586
- static async _redisGetCachedEntry(cacheKey, includeOptions) {
587
- if (!this.redis)
588
- return { hit: false, data: undefined };
589
- try {
590
- const result = await this.redis.get(cacheKey);
591
- if (result === null || result === undefined)
592
- return { hit: false, data: undefined };
593
- this.cacheStats.redisHits++;
594
- if (result === NEGATIVE_CACHE_PLACEHOLDER) {
595
- return { hit: true, data: null };
596
- }
597
- const parsedData = safeParse(result, this.logger);
598
- if (parsedData === null) {
599
- return { hit: false, data: undefined };
600
- }
601
- const includeAsArray = includeOptions
602
- ? Array.isArray(includeOptions)
603
- ? includeOptions
604
- : [includeOptions]
605
- : undefined;
606
- const buildInstance = (data) => {
607
- const instance = this.build(data, {
608
- isNewRecord: false,
609
- include: includeAsArray,
610
- });
611
- return instance;
612
- };
613
- if (Array.isArray(parsedData)) {
614
- const instances = parsedData.map((d) => buildInstance(d));
615
- return { hit: true, data: instances };
616
- }
617
- else {
618
- const instance = buildInstance(parsedData);
619
- return { hit: true, data: instance };
620
- }
621
- }
622
- catch (err) {
623
- this._trackRedisError(err);
624
- return { hit: false, data: undefined };
625
- }
626
- }
627
- static async _redisClearCache(cacheKey) {
628
- if (!this.redis)
629
- return;
630
- try {
631
- await this.redis.del(cacheKey);
632
- this.cacheStats.clears++;
633
- }
634
- catch (err) {
635
- this._trackRedisError(err);
636
- }
637
- }
638
- static async invalidateByTags(tags) {
639
- if (!this.isRedisConnected ||
640
- !Array.isArray(tags) ||
641
- tags.length === 0 ||
642
- !this.redis)
643
- return;
644
- try {
645
- const keysToDelete = await this.redis.sunion(tags);
646
- if (keysToDelete && keysToDelete.length > 0) {
647
- this.logger.info(`🎯 [SNIPER] Invalidating ${keysToDelete.length} keys for tags: ${tags.join(', ')}`);
648
- await this.redis.multi().del(keysToDelete).del(tags).exec();
649
- }
650
- else {
651
- await this.redis.del(tags);
652
- }
653
- }
654
- catch (err) {
655
- this._trackRedisError(err);
656
- }
657
- }
658
- static _mapSetCacheEntry(cacheKey, data, ttl) {
659
- if (this.isShardMode)
660
- return;
661
- if (data === null) {
662
- this.localNegativeCache.add(cacheKey);
663
- this.localCache.delete(cacheKey);
664
- }
665
- else {
666
- let plainData = data;
667
- if (data && typeof data.toJSON === 'function') {
668
- plainData = data.toJSON();
669
- }
670
- else if (Array.isArray(data)) {
671
- plainData = data.map((item) => item && typeof item.toJSON === 'function' ? item.toJSON() : item);
672
- }
673
- const dataCopy = plainData === null
674
- ? NEGATIVE_CACHE_PLACEHOLDER
675
- : safeStringify(plainData, this.logger);
676
- this.localCache.set(cacheKey, {
677
- data: dataCopy,
678
- expires: Date.now() + ttl,
679
- });
680
- this.localNegativeCache.delete(cacheKey);
681
- }
682
- this.cacheStats.sets++;
683
- }
684
- static _mapGetCachedEntry(cacheKey, includeOptions) {
685
- if (this.isShardMode)
686
- return { hit: false, data: undefined };
687
- if (this.localNegativeCache.has(cacheKey)) {
688
- this.cacheStats.mapHits++;
689
- return { hit: true, data: null };
690
- }
691
- const entry = this.localCache.get(cacheKey);
692
- if (entry && entry.expires > Date.now()) {
693
- this.cacheStats.mapHits++;
694
- const dataRaw = entry.data;
695
- let parsedData;
696
- if (typeof dataRaw === 'string') {
697
- parsedData = safeParse(dataRaw, this.logger);
698
- }
699
- else {
700
- parsedData = dataRaw;
701
- }
702
- if (typeof parsedData !== 'object' || parsedData === null) {
703
- return { hit: true, data: parsedData };
704
- }
705
- const includeAsArray = includeOptions
706
- ? Array.isArray(includeOptions)
707
- ? includeOptions
708
- : [includeOptions]
709
- : undefined;
710
- if (Array.isArray(parsedData)) {
711
- const instances = this.bulkBuild(parsedData, {
712
- isNewRecord: false,
713
- include: includeAsArray,
714
- });
715
- return { hit: true, data: instances };
716
- }
717
- else {
718
- const instance = this.build(parsedData, {
719
- isNewRecord: false,
720
- include: includeAsArray,
721
- });
722
- return { hit: true, data: instance };
723
- }
724
- }
725
- if (entry)
726
- this.localCache.delete(cacheKey);
727
- return { hit: false, data: undefined };
728
- }
729
- static _mapClearCache(cacheKey) {
730
- if (this.isShardMode)
731
- return;
732
- this.localCache.delete(cacheKey);
733
- this.localNegativeCache.delete(cacheKey);
734
- this.cacheStats.clears++;
735
- }
736
- static _mapClearAllModelCache() {
737
- if (this.isShardMode)
738
- return;
739
- const prefix = `${this.CACHE_VERSION}:${this.name}:`;
740
- let cleared = 0;
741
- for (const key of this.localCache.keys()) {
742
- if (key.startsWith(prefix)) {
743
- this.localCache.delete(key);
744
- cleared++;
745
- }
746
- }
747
- for (const key of this.localNegativeCache.keys()) {
748
- if (key.startsWith(prefix)) {
749
- this.localNegativeCache.delete(key);
750
- cleared++;
751
- }
752
- }
753
- if (cleared > 0) {
754
- this.logger.info(`♻️ [MAP CACHE] Cleared ${cleared} in-memory entries for ${this.name} (Redis fallback).`);
755
- }
756
- }
757
- static _normalizeFindOptions(options) {
758
- if (!options ||
759
- typeof options !== 'object' ||
760
- Object.keys(options).length === 0)
761
- return { where: {} };
762
- if (options.where) {
763
- const sequelizeOptions = { ...options };
764
- delete sequelizeOptions.cacheTags;
765
- delete sequelizeOptions.noCache;
766
- return sequelizeOptions;
767
- }
768
- const knownOptions = [
769
- 'order',
770
- 'limit',
771
- 'attributes',
772
- 'include',
773
- 'group',
774
- 'having',
775
- ];
776
- const cacheSpecificOptions = ['cacheTags', 'noCache'];
777
- const whereClause = {};
778
- const otherOptions = {};
779
- for (const key in options) {
780
- if (cacheSpecificOptions.includes(key)) {
781
- continue;
782
- }
783
- if (knownOptions.includes(key))
784
- otherOptions[key] = options[key];
785
- else
786
- whereClause[key] = options[key];
787
- }
788
- return { where: whereClause, ...otherOptions };
789
- }
790
- static async getCache(keys, options = {}) {
791
- const { noCache, customCacheKey, ttl, ...explicitQueryOptions } = options;
792
- if (Array.isArray(keys)) {
793
- const pk = this.primaryKeyAttribute;
794
- return this.findAll({ where: { [pk]: keys.map((m) => m[pk]) } });
795
- }
796
- const normalizedKeys = this._normalizeFindOptions(keys);
797
- const finalQuery = {
798
- ...normalizedKeys,
799
- ...explicitQueryOptions,
800
- where: {
801
- ...(normalizedKeys.where || {}),
802
- ...(explicitQueryOptions.where || {}),
803
- },
804
- };
805
- if (noCache) {
806
- return this.findOne(finalQuery);
807
- }
808
- if (!finalQuery.where || Object.keys(finalQuery.where).length === 0) {
809
- return null;
810
- }
811
- const cacheKey = customCacheKey || this.getCacheKey(finalQuery);
812
- const cacheResult = await this.getCachedEntry(cacheKey, finalQuery.include);
813
- if (cacheResult.hit)
814
- return cacheResult.data;
815
- this.cacheStats.misses++;
816
- if (this.pendingQueries.has(cacheKey))
817
- return this.pendingQueries.get(cacheKey);
818
- const queryPromise = this.findOne(finalQuery)
819
- .then(async (record) => {
820
- if (this.isRedisConnected || !this.isShardMode) {
821
- const tags = [`${this.name}`];
822
- if (record)
823
- tags.push(`${this.name}:${this.primaryKeyAttribute}:${record[this.primaryKeyAttribute]}`);
824
- await this.setCacheEntry(cacheKey, record, ttl, tags);
825
- }
826
- return record;
827
- })
828
- .finally(() => this.pendingQueries.delete(cacheKey));
829
- this.pendingQueries.set(cacheKey, queryPromise);
830
- return queryPromise;
831
- }
832
- static async getAllCache(options = {}) {
833
- const { cacheTags, noCache, customCacheKey, ttl, ...explicitQueryOptions } = options || {};
834
- const normalizedOptions = this._normalizeFindOptions(explicitQueryOptions);
835
- if (noCache) {
836
- return this.findAll(normalizedOptions);
837
- }
838
- const cacheKey = customCacheKey || this.getCacheKey(normalizedOptions);
839
- const cacheResult = await this.getCachedEntry(cacheKey, normalizedOptions.include);
840
- if (cacheResult.hit)
841
- return cacheResult.data;
842
- this.cacheStats.misses++;
843
- if (this.pendingQueries.has(cacheKey))
844
- return this.pendingQueries.get(cacheKey);
845
- const queryPromise = this.findAll(normalizedOptions)
846
- .then(async (records) => {
847
- if (this.isRedisConnected || !this.isShardMode) {
848
- const tags = [`${this.name}`];
849
- if (Array.isArray(cacheTags))
850
- tags.push(...cacheTags);
851
- await this.setCacheEntry(cacheKey, records, ttl, tags);
852
- }
853
- return records;
854
- })
855
- .finally(() => this.pendingQueries.delete(cacheKey));
856
- this.pendingQueries.set(cacheKey, queryPromise);
857
- return queryPromise;
858
- }
859
- static async scheduleAdd(keySuffix, score, value) {
860
- if (!this.isRedisConnected || !this.redis)
861
- return;
862
- const key = `${this.name}:${keySuffix}`;
863
- try {
864
- await this.redis.zadd(key, score, value);
865
- }
866
- catch (e) {
867
- this._trackRedisError(e);
868
- }
869
- }
870
- static async scheduleRemove(keySuffix, value) {
871
- if (!this.isRedisConnected || !this.redis)
872
- return;
873
- const key = `${this.name}:${keySuffix}`;
874
- try {
875
- await this.redis.zrem(key, value);
876
- }
877
- catch (e) {
878
- this._trackRedisError(e);
879
- }
880
- }
881
- static async scheduleGetExpired(keySuffix, scoreLimit = Date.now()) {
882
- if (!this.isRedisConnected || !this.redis)
883
- return [];
884
- const key = `${this.name}:${keySuffix}`;
885
- try {
886
- return await this.redis.zrangebyscore(key, 0, scoreLimit);
887
- }
888
- catch (e) {
889
- this._trackRedisError(e);
890
- return [];
891
- }
892
- }
893
- static async scheduleClear(keySuffix) {
894
- if (!this.isRedisConnected || !this.redis)
895
- return;
896
- const key = `${this.name}:${keySuffix}`;
897
- try {
898
- await this.redis.del(key);
899
- }
900
- catch (e) {
901
- this._trackRedisError(e);
902
- }
903
- }
904
- static async findOrCreateWithCache(options) {
905
- if (!options || !options.where) {
906
- throw new Error("findOrCreateWithCache requires a 'where' option.");
907
- }
908
- const { where, defaults, noCache, ...otherOptions } = options;
909
- if (noCache) {
910
- return this.findOrCreate(options);
911
- }
912
- const normalizedWhere = this._normalizeFindOptions(where).where;
913
- const cacheKey = this.getCacheKey(normalizedWhere);
914
- const cacheResult = await this.getCachedEntry(cacheKey, otherOptions.include);
915
- if (cacheResult.hit && cacheResult.data) {
916
- const instance = cacheResult.data;
917
- let needsUpdate = false;
918
- if (defaults && typeof defaults === 'object') {
919
- for (const key in defaults) {
920
- if (instance[key] === undefined ||
921
- String(instance[key]) !== String(defaults[key])) {
922
- instance[key] = defaults[key];
923
- needsUpdate = true;
924
- }
925
- }
926
- }
927
- if (needsUpdate) {
928
- await instance.saveAndUpdateCache();
929
- }
930
- return [instance, false];
931
- }
932
- this.cacheStats.misses++;
933
- if (this.pendingQueries.has(cacheKey)) {
934
- return this.pendingQueries.get(cacheKey);
935
- }
936
- const findPromise = this.findOne({ where, ...otherOptions })
937
- .then(async (instance) => {
938
- if (instance) {
939
- let needsUpdate = false;
940
- if (defaults && typeof defaults === 'object') {
941
- for (const key in defaults) {
942
- if (instance[key] === undefined ||
943
- String(instance[key]) !== String(defaults[key])) {
944
- instance[key] = defaults[key];
945
- needsUpdate = true;
946
- }
947
- }
948
- }
949
- if (needsUpdate) {
950
- await instance.saveAndUpdateCache();
951
- }
952
- else {
953
- const tags = [
954
- `${this.name}`,
955
- `${this.name}:${this.primaryKeyAttribute}:${instance[this.primaryKeyAttribute]}`,
956
- ];
957
- await this.setCacheEntry(cacheKey, instance, undefined, tags);
958
- }
959
- return [instance, false];
960
- }
961
- else {
962
- const createData = { ...where, ...defaults };
963
- const newInstance = await this.create(createData);
964
- const tags = [
965
- `${this.name}`,
966
- `${this.name}:${this.primaryKeyAttribute}:${newInstance[this.primaryKeyAttribute]}`,
967
- ];
968
- await this.setCacheEntry(cacheKey, newInstance, undefined, tags);
969
- return [newInstance, true];
970
- }
971
- })
972
- .finally(() => {
973
- this.pendingQueries.delete(cacheKey);
974
- });
975
- this.pendingQueries.set(cacheKey, findPromise);
976
- return findPromise;
977
- }
978
- static async countWithCache(options = {}, ttl = 5 * 60 * 1000) {
979
- const { ...countOptions } = options || {};
980
- const cacheKeyOptions = { queryType: 'count', ...countOptions };
981
- const cacheKey = this.getCacheKey(cacheKeyOptions);
982
- const cacheResult = await this.getCachedEntry(cacheKey);
983
- if (cacheResult.hit) {
984
- return cacheResult.data;
985
- }
986
- this.cacheStats.misses++;
987
- const count = await this.count(countOptions);
988
- if (this.isRedisConnected || !this.isShardMode) {
989
- const tags = [`${this.name}`];
990
- this.setCacheEntry(cacheKey, count, ttl, tags);
991
- }
992
- return count;
993
- }
994
- async saveAndUpdateCache() {
995
- const savedInstance = await this.save();
996
- const pk = this.constructor.primaryKeyAttribute;
997
- const pkValue = this[pk];
998
- if (pkValue &&
999
- (this.constructor.isRedisConnected ||
1000
- !this.constructor.isShardMode)) {
1001
- const cacheKey = this.constructor.getCacheKey({
1002
- where: { [pk]: pkValue },
1003
- });
1004
- const tags = [
1005
- `${this.constructor.name}`,
1006
- `${this.constructor.name}:${pk}:${pkValue}`,
1007
- ];
1008
- await this.constructor.setCacheEntry(cacheKey, savedInstance, undefined, tags);
1009
- this.constructor.logger.info(`🔄 [CACHE] Updated cache for ${this.constructor.name}:${pk}:${pkValue}`);
1010
- }
1011
- return savedInstance;
1012
- }
1013
- static async clearNegativeCache(keys) {
1014
- return this.clearCache(keys);
1015
- }
1016
- static async aggregateWithCache(options = {}, cacheOptions = {}) {
1017
- const { cacheTags, ...queryOptions } = options || {};
1018
- const { ttl = 5 * 60 * 1000 } = cacheOptions || {};
1019
- const cacheKeyOptions = { queryType: 'aggregate', ...queryOptions };
1020
- const cacheKey = this.getCacheKey(cacheKeyOptions);
1021
- const cacheResult = await this.getCachedEntry(cacheKey);
1022
- if (cacheResult.hit) {
1023
- return cacheResult.data;
1024
- }
1025
- this.cacheStats.misses++;
1026
- const result = await this.findAll(queryOptions);
1027
- if (this.isRedisConnected || !this.isShardMode) {
1028
- const tags = [`${this.name}`];
1029
- if (Array.isArray(cacheTags))
1030
- tags.push(...cacheTags);
1031
- this.setCacheEntry(cacheKey, result, ttl, tags);
1032
- }
1033
- return result;
1034
- }
1035
- static initializeCacheHooks() {
1036
- if (!this.redis) {
1037
- this.logger.warn(`❌ Redis not initialized for model ${this.name}. Cache hooks will not be attached.`);
1038
- return;
1039
- }
1040
- const afterSaveLogic = async (instance) => {
1041
- const modelClass = instance.constructor;
1042
- if (modelClass.isRedisConnected) {
1043
- const tagsToInvalidate = modelClass._generateSmartTags(instance);
1044
- if (Array.isArray(modelClass.customInvalidationTags)) {
1045
- tagsToInvalidate.push(...modelClass.customInvalidationTags);
1046
- }
1047
- await modelClass.invalidateByTags(tagsToInvalidate);
1048
- }
1049
- else if (!modelClass.isShardMode) {
1050
- modelClass._mapClearAllModelCache();
1051
- }
1052
- };
1053
- const afterDestroyLogic = async (instance) => {
1054
- const modelClass = instance.constructor;
1055
- if (modelClass.isRedisConnected) {
1056
- const tagsToInvalidate = modelClass._generateSmartTags(instance);
1057
- if (Array.isArray(modelClass.customInvalidationTags)) {
1058
- tagsToInvalidate.push(...modelClass.customInvalidationTags);
1059
- }
1060
- await modelClass.invalidateByTags(tagsToInvalidate);
1061
- }
1062
- else if (!modelClass.isShardMode) {
1063
- modelClass._mapClearAllModelCache();
1064
- }
1065
- };
1066
- const afterBulkLogic = async () => {
1067
- if (this.isRedisConnected) {
1068
- await this.invalidateByTags([`${this.name}`]);
1069
- }
1070
- else if (!this.isShardMode) {
1071
- this._mapClearAllModelCache();
1072
- }
1073
- };
1074
- this.addHook('afterSave', afterSaveLogic);
1075
- this.addHook('afterDestroy', afterDestroyLogic);
1076
- this.addHook('afterBulkCreate', afterBulkLogic);
1077
- this.addHook('afterBulkUpdate', afterBulkLogic);
1078
- this.addHook('afterBulkDestroy', afterBulkLogic);
1079
- }
1080
- static attachHooksToAllModels(sequelizeInstance, client) {
1081
- if (!this.redis) {
1082
- this.logger.warn('🟠 Cannot attach hooks because Redis is not initialized or useRedis is false.');
1083
- return;
1084
- }
1085
- for (const modelName in sequelizeInstance.models) {
1086
- const model = sequelizeInstance.models[modelName];
1087
- if (model.prototype instanceof KythiaModel) {
1088
- model.client = client;
1089
- this.logger.info(`⚙️ Attaching hooks to ${model.name}`);
1090
- model.initializeCacheHooks();
1091
- }
1092
- }
1093
- }
1094
- static async touchParent(childInstance, foreignKeyField, ParentModel, timestampField = 'updatedAt') {
1095
- if (!childInstance || !childInstance[foreignKeyField]) {
1096
- return;
1097
- }
1098
- try {
1099
- const parentPk = ParentModel.primaryKeyAttribute;
1100
- const parent = await ParentModel.findByPk(childInstance[foreignKeyField]);
1101
- if (parent) {
1102
- parent.changed(timestampField, true);
1103
- await parent.save({ fields: [timestampField] });
1104
- this.logger.info(`🔄 Touched parent ${ParentModel.name} #${parent[parentPk]} due to change in ${this.name}.`);
1105
- }
1106
- }
1107
- catch (e) {
1108
- this.logger.error(`🔄 Failed to touch parent ${ParentModel.name}`, e);
1109
- }
1110
- }
1111
- static setupParentTouch(foreignKeyField, ParentModel, timestampField = 'updatedAt') {
1112
- const touchHandler = (instance) => {
1113
- return this.touchParent(instance, foreignKeyField, ParentModel, timestampField);
1114
- };
1115
- const bulkTouchHandler = (instances) => {
1116
- if (instances && instances.length > 0) {
1117
- return this.touchParent(instances[0], foreignKeyField, ParentModel, timestampField);
1118
- }
1119
- return Promise.resolve();
1120
- };
1121
- this.addHook('afterSave', touchHandler);
1122
- this.addHook('afterDestroy', touchHandler);
1123
- this.addHook('afterBulkCreate', bulkTouchHandler);
1124
- }
1125
- }
1126
- exports.KythiaModel = KythiaModel;
1127
- exports.default = KythiaModel;
1128
- //# sourceMappingURL=KythiaModel.js.map
1
+ 'use strict';const a18_0x5cf52a=a18_0x30ce;(function(_0x4e52eb,_0xa6c5ef){const a18_0x3f1b37={_0x295cb2:0x1d9,_0x2efce2:0x18b,_0x5b46a1:0x164,_0xd46f75:0x17f},_0x437330=a18_0x30ce,_0x406645=_0x4e52eb();while(!![]){try{const _0x26c420=parseInt(_0x437330(0x180))/(0x1599+-0x1*0xdd8+0x1f0*-0x4)*(parseInt(_0x437330(0x14c))/(0x183*-0x9+-0x16e5+0x2482))+parseInt(_0x437330(a18_0x3f1b37._0x295cb2))/(-0x1*-0x55d+0x1*0x236b+-0x28c5)+-parseInt(_0x437330(a18_0x3f1b37._0x2efce2))/(-0xc89+0x294+0x9f9)*(parseInt(_0x437330(a18_0x3f1b37._0x5b46a1))/(0x1577+-0x1e2d+0x8bb))+parseInt(_0x437330(0x19a))/(-0x1d32*-0x1+-0x7d*0xd+-0x16d3)+-parseInt(_0x437330(a18_0x3f1b37._0xd46f75))/(-0x5*-0x47+-0x1fbe+0x1e62)+-parseInt(_0x437330(0x178))/(0x9ad+-0x1a48+-0x1*-0x10a3)+-parseInt(_0x437330(0x1ac))/(0x231a+0xd9d+-0x30ae);if(_0x26c420===_0xa6c5ef)break;else _0x406645['push'](_0x406645['shift']());}catch(_0x33141f){_0x406645['push'](_0x406645['shift']());}}}(a18_0x59cb,0x3f77c*-0x2+0x21d1e+0xb9ab4*0x1));function a18_0x59cb(){const _0x4bc324=['zNvUy3rPB24','ywrKsg9VAW','B3b0Aw9UCW','DhjPBq','Aw5PDa','runptK5sruzvu0ve','ignVBNnLy3v0AxzLigvYCM9YCYbPBIa','y0jYre0','z2v0uxvLCNLjBNrLCMzHy2u','C3rYAw5NAwz5','CgTOBuW','zxzLCNK','ChvZAa','BgfZDfjLzgLZt3b0CW','8j+oRYbBu05juevsxsbjBNzHBgLKyxrPBMCG','revgqvvmvf9uveW','Aw5JBhvKzq','CMvJB25Uzwn0vgLTzw91Da','Bw9KzwXZ','zNLYEgK','ru5vtq','s3L0AgLHtw9KzwW','8j+FOIbBuKvesvnDief0DgvTChrPBMCGyxv0BY1YzwnVBM5Ly3qGywz0zxiG','x19PBxbVCNrezwzHDwX0','C2v0q2fJAgvfBNrYEq','jY4Gu2TPChbPBMCGyxv0BY1IB290lIbLCNiG','x3jLzgLZrMfSBgjHy2TvuKXZ','ywrK','q0HbuG','x25VCM1HBgL6zuzPBMrpChrPB25Z','lI4VDxrPBhmVBg9Nz2vY','zvrVwxC','q0fdsevFvfrm','zMLUzej5ugS','DxjSCW','CgfYyw5VAwq','Dg9ku09o','DgLTzxn0yw1WCW','mK1QrefMDG','CxvPDa','zgf0yvzHBhvLCW','8j+FOcbBuKvesvnDienVBM5Ly3rPB24GzMfPBgvKigzVCIbszwrPCYaJ','qNPkve4','qK9ptevbtG','ChjPBwfYEuTLEuf0DhjPyNv0zq','zgvMAw5LuhjVCgvYDhK','C2nOzwr1Bgvszw1VDMu','Dg9vChbLCKnHC2u','C2XPy2u','x3rYEvjLzgLZrMfPBg92zxi','lIbdywnOzsbOB29RCYb3AwXSig5VDcbIzsbHDhrHy2HLzc4','C2HHCMq','y291BNq','C3bSAxq','x21HCenSzwfYq2fJAgu','y29UzMLN','4PM777IpifTnqvaGq0fdsevDienSzwfYzwqG','y2fJAgvuywDZ','w1jfreLtxvTgquLmt1zfuL0Gvhj5Aw5NihrVihn3AxrJAcbszwrPCYbJB25Uzwn0Aw9UigzYB20GDxjSigLUzgv4ia','zMLUze9Yq3jLyxrL','sLnptG','x2nSB3nLq3vYCMvUDfjLzgLZ','mti1vK5us2rM','ywDNCMvNyxrL','zgvSzxrL','rKXpqvq','AxnszwrPC0nVBM5Ly3rLza','CY4GqwXSifjLzgLZigv4Agf1C3rLzcWGzMfSBgjHy2SGDg8Gsw4TtwvTB3j5ienHy2HLisaOtgfZDcbLCNjVCJOG','BwvZC2fNzq','x3jLzgLZr2v0q2fJAgvKrw50CNK','C2f2zufUzfvWzgf0zunHy2HL','AgfZ','ywz0zxjcDwXRq3jLyxrL','DxbKyxrLzef0','CgvUzgLUz1f1zxjPzxm','4P2mifTsrurju10G','BMfTzq','icHszwrPCYbMywXSyMfJAYKU','C2DtDwS','x21HCeDLDenHy2HLzevUDhj5','q0fdsevFvKvsu0LptG','zxD6sxa','mtC5mJiZmK9AwxHcAq','yxv0B0LUy3jLBwvUDa','CMvKAxnfCNjVCLrPBwvZDgfTChm','vxrPBhm','Bg9Nz2vY','Bg9JywXozwDHDgL2zunHy2HL','Aw52ywXPzgf0zuj5vgfNCW','mZGWodGXmLL1A1fHrq','ndGXnJKXBev2vxvz','BxmGkef0DgvTChqG','uKf6Bgu','BwLUigrVD250Aw1LlI4U','CMvZB2X2zq','w1jfreLtxvTgquLmt1zfuL0GrKfjteveifrpiezmvvniienbq0HfoG','B2jQzwn0','zM9YrwfJAa','y2HHBMDLza','DvHKAw4','C3rHCNrZv2L0Aa','nZK0mZzLwKTrzfG','y2fJAgvtDgf0CW','DgfIBgu','EMfKza','zxHWAxjLCW','v0rcz3K','8j+FOcbBuKvesvnDievYCM9Yicm','AxnbCNjHEq','yNvSA0j1AwXK','qxLIz1y','BwLZC2vZ','x3jLzgLZrMfPBgvKsw5KzxHLCW','AgL0','zMLSDgvY','yxr0CMLIDxrLCW','mZa2mJa3nNHZwgzYqq','y2XLyxi','Dg9tDhjPBMC','zMLUze9Yq3jLyxrLv2L0AenHy2HLihjLCxvPCMvZigeGj3DOzxjLjYbVChrPB24U','zgf0yq','Bhj1lwnHy2HL','veLnrvnuqu1q','Dg91y2HqyxjLBNq','refurq','ms4WlJa','z2v0q2fJAgvlzxK','AM9PBG','su5u','zMLUywXSEq','x3nLDhvWtgfYyxzLBeHVB2TZ','w1jfreLtxsbfCNjVCIb0B2XLCMfUy2uGCMvHy2HLzcWGC3DPDgnOAw5NihrVie5fwfqGuMvKAxmGzMfPBg92zxiUlI4','x3nLDhvWuMvKAxnfDMvUDeHHBMrSzxjZ','y2XVC2u','odG4odG1A2XSCKTM','refurvrjtuu','y2XLyxjdywnOzq','BM9YBwfSAxPLuxvLCNLpChrPB25Z','zNbSsKy','A2v5CW','tfjvq2fJAgu','Bg9JywXdywnOzq','x3jLzgLZu2v0q2fJAgvfBNrYEq','zxjYB3i','D2HLCMu','ENjLBq','u1rssu5h','BwfW','8j+uHcbgywLSzwqGDg8GDg91y2GGCgfYzw50ia','yNvPBgq','z2v0qwXSq2fJAgu','ywz0zxjtyxzL','BxvSDgK','4P2mifTsrurju10Gsw52ywXPzcbYzwrPCYbJB25MAwCGzgv0zwn0zwqGAw4GBgLZDa','zMLUzefSBa','x21HA2vszxrYEvn0CMf0zwD5','8j+FOcbdyw5UB3qGyxr0ywnOigHVB2TZigjLy2f1C2uGuMvKAxmGAxmGBM90igLUAxrPywXPEMvKig9YihvZzvjLzgLZigLZigzHBhnLlG','z3vHCMrLza','BwfWsgL0CW','AxntAgfYze1Vzgu','qK1nueS','Aw5JBhvKzxm','8j+uHcbBq0fdsevDifvWzgf0zwqGy2fJAguGzM9Yia','ywDNCMvNyxrLv2L0AenHy2HL','x21HCfnLDenHy2HLrw50CNK','x3jLzgLZq3vYCMvUDeLUzgv4','zMLSBgfIBgu','igLUlw1LBw9YEsbLBNrYAwvZigzVCIa','CgfYC2u','wNDRDha','x3nJAgvKDwXLuMvJB25Uzwn0','BM93','8j+FOcbBuKvesvnDie5VifjLzgLZignSAwvUDcbVCIbVChrPB25ZihbYB3zPzgvKlIbpCgvYyxrPBMCGAw4Gsw4TtwvTB3j5ienHy2HLig1VzguGB25SEs4','C3rYDwn0DxjL','y3vZDg9Tsw52ywXPzgf0Aw9UvgfNCW','x21HCenSzwfYqwXStw9KzwXdywnOzq','rgf0yvr5CgvZ','CY4Gu0HbuKqGtu9ertOGrgLZywjSAw5NignHy2HLicHotYbMywXSyMfJAYKSigfSBcbXDwvYAwvZigDVihrVierclIaOtgfZDcbLCNjVCJOG','vLzAy2K','mJi1mtmZoe9zrgL2Ca','y2fJAgvlzxLZ','z2v0','x19LC01VzhvSzq','Aw5MBW','wunbuuC','q0fdsevFs0vzuW','C2f2zq','C2v0','CMvKAxm','z2v0q2fJAgvKrw50CNK','CMvKAxniAxrZ','BgvUz3rO','Euvlwwi','ywz0zxjezxn0CM95','C3rYAw5N','y2XPzw50','x2P1C3rgywLSzwrpDMvY','y29UC3rYDwn0B3i','y2XLyxjZ','yxv0B0jVB3q','zw50CMLLCW','zxHLyW','C2vXDwvSAxPL','Aw9YzwrPCW','yMLNAw50','Aw5PDgLHBgL6zvjLzgLZ','s3L0AgLHtw9KzwWUC2v0rgvWzw5Kzw5JAwvZihjLCxvPCMvZignVBMzPzYe','x3rYywnRuMvKAxnfCNjVCG','D2fYBG','zgvS','jYbUB3qGzM91BMqGzM9Yig1VzgvSicC'];a18_0x59cb=function(){return _0x4bc324;};return a18_0x59cb();}var __importDefault=this&&this[a18_0x5cf52a(0x13d)]||function(_0x30ba5f){const _0x2c00ba=a18_0x5cf52a;return _0x30ba5f&&_0x30ba5f[_0x2c00ba(0x1dc)]?_0x30ba5f:{'default':_0x30ba5f};};function a18_0x30ce(_0x69820,_0x5c3f42){_0x69820=_0x69820-(0x1*0x13ad+-0xa5e+-0x3*0x2b1);const _0x45ea67=a18_0x59cb();let _0x4d69cf=_0x45ea67[_0x69820];if(a18_0x30ce['lmnDCv']===undefined){var _0x52694e=function(_0x59aecd){const _0xfcd73f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4a8653='',_0x23065f='';for(let _0x5eafb9=-0xe15+0x132c+-0x517*0x1,_0x3e29cd,_0x14fcfc,_0xf0fa23=0xce5*0x1+-0x4*0x77c+0x110b;_0x14fcfc=_0x59aecd['charAt'](_0xf0fa23++);~_0x14fcfc&&(_0x3e29cd=_0x5eafb9%(-0xa*-0xb7+-0x1*0x102+-0x1*0x620)?_0x3e29cd*(0x1*-0x128c+-0x9b9*0x3+0x3*0xffd)+_0x14fcfc:_0x14fcfc,_0x5eafb9++%(-0xf3b+0x7e0+0x75f))?_0x4a8653+=String['fromCharCode'](0xcef+-0x60a*-0x5+-0x2a22&_0x3e29cd>>(-(0x4d*0x16+0xe98*0x1+-0x1534)*_0x5eafb9&-0x3b*0x1e+-0x7*0x19f+0x1249)):-0xd1c+-0x1a51*0x1+0x1*0x276d){_0x14fcfc=_0xfcd73f['indexOf'](_0x14fcfc);}for(let _0x9940ea=0x5cc+0x1*-0x1dcd+-0x4cd*-0x5,_0xfdbc3f=_0x4a8653['length'];_0x9940ea<_0xfdbc3f;_0x9940ea++){_0x23065f+='%'+('00'+_0x4a8653['charCodeAt'](_0x9940ea)['toString'](0x13ed+-0x396+0x1047*-0x1))['slice'](-(0x583+-0xcb*0x13+0x3*0x330));}return decodeURIComponent(_0x23065f);};a18_0x30ce['JlsZZl']=_0x52694e,a18_0x30ce['ibSLsE']={},a18_0x30ce['lmnDCv']=!![];}const _0x37b0d0=_0x45ea67[0x1ce5*0x1+0x26cb+-0x43b0],_0x153222=_0x69820+_0x37b0d0,_0x1a619e=a18_0x30ce['ibSLsE'][_0x153222];return!_0x1a619e?(_0x4d69cf=a18_0x30ce['JlsZZl'](_0x4d69cf),a18_0x30ce['ibSLsE'][_0x153222]=_0x4d69cf):_0x4d69cf=_0x1a619e,_0x4d69cf;}Object[a18_0x5cf52a(0x153)](exports,'__esModule',{'value':!![]}),exports['KythiaModel']=void(-0x1a6b+0x1297+0x7d4);const jsonStringify=require('json-stable-stringify'),sequelize_1=require(a18_0x5cf52a(0x1f0)),lru_cache_1=require(a18_0x5cf52a(0x19f)),logger_1=__importDefault(require(a18_0x5cf52a(0x144))),NEGATIVE_CACHE_PLACEHOLDER='__KYTHIA_NEGATIVE_CACHE__',RECONNECT_DELAY_MINUTES=-0x1*0x108d+0x479*-0x4+0x2274,REDIS_ERROR_TOLERANCE_COUNT=0x11f1+-0xa75*0x3+0x6f*0x1f,REDIS_ERROR_TOLERANCE_INTERVAL_MS=(-0x2e2*0x5+0x29*0xdc+-0x14c8)*(-0x10fe+-0x179a+-0xb20*-0x4);function safeStringify(_0x4d976c,_0x55ac2f){const a18_0x1e2b88={_0x4b2d4b:0x202},_0x5c5537=a18_0x5cf52a;try{return JSON[_0x5c5537(a18_0x1e2b88._0x4b2d4b)](_0x4d976c,(_0x2f4b3f,_0x32f7b9)=>typeof _0x32f7b9===_0x5c5537(0x1f2)?_0x32f7b9[_0x5c5537(0x19c)]():_0x32f7b9);}catch(_0x298b8e){return(_0x55ac2f||console)[_0x5c5537(0x1b5)]('❌\x20[SAFE\x20STRINGIFY]\x20Failed:\x20'+_0x298b8e['message']),'{}';}}function safeParse(_0x43685a,_0x27e290){const a18_0x3ea301={_0x29ede1:0x1ce,_0x272358:0x1f6},_0x361f7e=a18_0x5cf52a;try{return JSON[_0x361f7e(a18_0x3ea301._0x29ede1)](_0x43685a);}catch{return(_0x27e290||console)[_0x361f7e(a18_0x3ea301._0x272358)]('⚠️\x20[SAFE\x20PARSE]\x20Invalid\x20JSON\x20data,\x20returning\x20null'),null;}}class KythiaModel extends sequelize_1['Model']{static [a18_0x5cf52a(0x1e9)];static ['redis'];static [a18_0x5cf52a(0x168)]=![];static ['logger'];static [a18_0x5cf52a(0x15d)]={};static ['CACHE_VERSION']=a18_0x5cf52a(0x1a3);static ['localCache']=new lru_cache_1[(a18_0x5cf52a(0x1b2))]({'max':0x3e8});static [a18_0x5cf52a(0x17d)]=new Set();static ['MAX_LOCAL_CACHE_SIZE']=0x42c*0x7+-0x2702+-0x10e*-0xd;static [a18_0x5cf52a(0x208)]=(0x25*0x51+0x792+0x659*-0x3)*(-0x1*-0x1f49+0x9f3+-0x2900)*(-0x10cc+0x304+0x11b0);static [a18_0x5cf52a(0x206)]=null;static [a18_0x5cf52a(0x20a)]=null;static ['lastAutoReconnectTs']=-0xb7d+0x1d19+-0x119c;static [a18_0x5cf52a(0x170)]=new Map();static ['cacheStats']={'redisHits':0x0,'mapHits':0x0,'misses':0x0,'sets':0x0,'clears':0x0,'errors':0x0};static [a18_0x5cf52a(0x17a)]=[];static ['isShardMode']=![];static ['_redisFallbackURLs']=[];static ['_redisCurrentIndex']=0xf8b*-0x2+0x62*0x27+0x1028;static ['_redisFailedIndexes']=new Set();static [a18_0x5cf52a(0x1ea)]=![];static ['fillable'];static ['guarded'];static ['structure'];static [a18_0x5cf52a(0x18d)];static [a18_0x5cf52a(0x1da)];static ['CACHE_KEYS'];static [a18_0x5cf52a(0x146)];static [a18_0x5cf52a(0x1d4)];static ['useRedis'];static['init'](_0x251f41,_0x19486a){const a18_0x328ac0={_0xc674f:0x192,_0x47a1c6:0x1c3,_0xe33ed:0x1c7,_0x27d75b:0x14e},a18_0x5d184a={_0x225096:0x1c7},_0x4b322b=a18_0x5cf52a,_0x26a82f=super['init'](_0x251f41,_0x19486a);return _0x26a82f[_0x4b322b(0x1fa)]('beforeValidate',_0x4c6cc0=>{const _0x24830a=_0x4b322b,_0x167ebb=_0x4c6cc0['constructor'];if(_0x167ebb['fillable']&&Array['isArray'](_0x167ebb['fillable'])){const _0x4377e2=_0x167ebb[_0x24830a(0x1cc)];Object['keys'](_0x4c6cc0[_0x24830a(0x14e)])[_0x24830a(0x187)](_0x180c8b=>{const _0x2e685a=_0x24830a;if(!_0x4377e2[_0x2e685a(a18_0x5d184a._0x225096)](_0x180c8b)){delete _0x4c6cc0['dataValues'][_0x180c8b];if(_0x4c6cc0[_0x2e685a(0x188)]())_0x4c6cc0['changed'](_0x180c8b,![]);}});}else{if(_0x167ebb[_0x24830a(0x1c3)]&&Array[_0x24830a(a18_0x328ac0._0xc674f)](_0x167ebb[_0x24830a(a18_0x328ac0._0x47a1c6)])){const _0x2c87c7=_0x167ebb[_0x24830a(a18_0x328ac0._0x47a1c6)];if(_0x2c87c7[_0x24830a(a18_0x328ac0._0xe33ed)]('*')){_0x4c6cc0[_0x24830a(a18_0x328ac0._0x27d75b)]={};return;}Object['keys'](_0x4c6cc0[_0x24830a(0x14e)])[_0x24830a(0x187)](_0x492fe3=>{const _0x37bc26=_0x24830a;if(_0x2c87c7['includes'](_0x492fe3)){delete _0x4c6cc0['dataValues'][_0x492fe3];if(_0x4c6cc0[_0x37bc26(0x188)]())_0x4c6cc0[_0x37bc26(0x188)](_0x492fe3,![]);}});}}}),_0x26a82f;}static async[a18_0x5cf52a(0x1ed)](_0x2acaee){const a18_0x2a6b27={_0xa530b6:0x172,_0x2e891b:0x172,_0x2b4365:0x13f,_0x17d629:0x179,_0x4f36c9:0x1fd,_0x586639:0x203,_0x520fcc:0x14b,_0x35a7c4:0x149,_0x4c4c83:0x149,_0x703644:0x1a8},_0x12a0e3=a18_0x5cf52a,_0x3d1a5e={'pkhmL':function(_0x356d48,_0x2613b2){return _0x356d48!==_0x2613b2;}};let _0x5ec3ea=this['table'];if(!_0x5ec3ea){const _0x363d8a=this[_0x12a0e3(a18_0x2a6b27._0xa530b6)],_0x311633=sequelize_1[_0x12a0e3(0x17b)]['underscoredIf'](_0x363d8a,!![]);_0x5ec3ea=sequelize_1[_0x12a0e3(0x17b)]['pluralize'](_0x311633);}let _0x436810={},_0x2cd018={};this[_0x12a0e3(0x1d3)]&&(_0x436810=this['structure'][_0x12a0e3(0x199)]||{},_0x2cd018=this[_0x12a0e3(0x1d3)][_0x12a0e3(0x1fb)]||{});const _0x828ec0=_0x2acaee[_0x12a0e3(0x201)]();let _0x320490;try{_0x320490=await _0x828ec0['describeTable'](_0x5ec3ea);}catch(_0x6720d0){console['warn']('⚠️\x20[KythiaModel]\x20Table\x20\x27'+_0x5ec3ea+_0x12a0e3(0x1f8)+this[_0x12a0e3(a18_0x2a6b27._0x2e891b)]+_0x12a0e3(a18_0x2a6b27._0x2b4365)+_0x6720d0);return;}const _0xc64fe5={};for(const [_0x417add,_0x8252f3]of Object[_0x12a0e3(0x1ee)](_0x320490)){_0xc64fe5[_0x417add]={'type':this['_mapDbTypeToSequelize'](_0x8252f3['type']),'allowNull':_0x8252f3['allowNull'],'defaultValue':_0x8252f3['defaultValue'],'primaryKey':_0x8252f3['primaryKey'],'autoIncrement':_0x8252f3[_0x12a0e3(a18_0x2a6b27._0x17d629)]};}const _0x2b6048={..._0xc64fe5,..._0x436810};return super[_0x12a0e3(a18_0x2a6b27._0x4f36c9)](_0x2b6048,{'sequelize':_0x2acaee,'modelName':this[_0x12a0e3(0x172)],'tableName':_0x5ec3ea,'timestamps':_0x3d1a5e[_0x12a0e3(a18_0x2a6b27._0x586639)](_0x2cd018[_0x12a0e3(a18_0x2a6b27._0x520fcc)],undefined)?_0x2cd018[_0x12a0e3(a18_0x2a6b27._0x520fcc)]:!!_0x2b6048['createdAt'],'paranoid':_0x2cd018[_0x12a0e3(a18_0x2a6b27._0x35a7c4)]!==undefined?_0x2cd018[_0x12a0e3(a18_0x2a6b27._0x4c4c83)]:!!_0x2b6048['deletedAt'],..._0x2cd018}),this[_0x12a0e3(a18_0x2a6b27._0x703644)](),this;}static['_mapDbTypeToSequelize'](_0x1fda0f){const a18_0x186b7a={_0x2e1316:0x155,_0x4dddb5:0x151,_0x321268:0x190,_0x218c8c:0x1d6,_0x488cd4:0x18a,_0xd65b26:0x142,_0xc1f03a:0x189,_0x3ea667:0x1a0,_0x43a1b3:0x1a2,_0x3ffbe8:0x162,_0x230998:0x1d6,_0x1076ce:0x167,_0x78402e:0x1b8},_0x2eef6c=a18_0x5cf52a,_0x152184={'WDBgy':_0x2eef6c(0x1a6),'uXdin':_0x2eef6c(0x1ad),'VVZci':'DECIMAL'},_0x13a146=_0x1fda0f[_0x2eef6c(a18_0x186b7a._0x2e1316)]();if(_0x13a146['startsWith'](_0x2eef6c(a18_0x186b7a._0x4dddb5))||_0x13a146['startsWith']('TINYINT(1)'))return sequelize_1['DataTypes']['BOOLEAN'];if(_0x13a146['startsWith'](_0x152184[_0x2eef6c(a18_0x186b7a._0x321268)])||_0x13a146['startsWith']('TINYINT')||_0x13a146['startsWith']('BIGINT'))return sequelize_1[_0x2eef6c(a18_0x186b7a._0x218c8c)]['INTEGER'];if(_0x13a146[_0x2eef6c(0x18a)]('VARCHAR')||_0x13a146[_0x2eef6c(0x18a)]('TEXT')||_0x13a146[_0x2eef6c(a18_0x186b7a._0x488cd4)](_0x2eef6c(a18_0x186b7a._0xd65b26)))return sequelize_1['DataTypes']['STRING'];if(_0x13a146[_0x2eef6c(a18_0x186b7a._0x488cd4)](_0x152184[_0x2eef6c(a18_0x186b7a._0xc1f03a)])||_0x13a146['startsWith'](_0x2eef6c(a18_0x186b7a._0x3ea667)))return sequelize_1['DataTypes'][_0x2eef6c(a18_0x186b7a._0x43a1b3)];if(_0x13a146[_0x2eef6c(0x18a)](_0x2eef6c(a18_0x186b7a._0x3ffbe8)))return sequelize_1['DataTypes'][_0x2eef6c(a18_0x186b7a._0x3ffbe8)];if(_0x13a146[_0x2eef6c(a18_0x186b7a._0x488cd4)]('FLOAT')||_0x13a146[_0x2eef6c(0x18a)]('DOUBLE')||_0x13a146['startsWith'](_0x152184[_0x2eef6c(0x1d8)]))return sequelize_1[_0x2eef6c(a18_0x186b7a._0x230998)][_0x2eef6c(a18_0x186b7a._0x1076ce)];if(_0x13a146['startsWith'](_0x2eef6c(0x20d)))return sequelize_1['DataTypes'][_0x2eef6c(0x1b8)];return sequelize_1[_0x2eef6c(0x1d6)][_0x2eef6c(a18_0x186b7a._0x78402e)];}static[a18_0x5cf52a(0x1a8)](){const a18_0x2c9f96={_0x2c407a:0x1cc,_0x12d677:0x1c7},a18_0x9fad0={_0xfecdfc:0x14e,_0x40722a:0x188},_0x4f2507=a18_0x5cf52a;this[_0x4f2507(0x1fa)]('beforeValidate',_0x3ae4ba=>{const _0xfb7c9e=_0x4f2507,_0x35e72e=_0x3ae4ba['constructor'],_0x3ec167=_0x35e72e['primaryKeyAttribute']||'id';if(_0x35e72e['fillable']&&Array[_0xfb7c9e(0x192)](_0x35e72e['fillable'])){const _0x58a9a8=_0x35e72e[_0xfb7c9e(a18_0x2c9f96._0x2c407a)];Object['keys'](_0x3ae4ba['dataValues'])[_0xfb7c9e(0x187)](_0x385058=>{const _0x5dcdec=_0xfb7c9e;if(_0x385058===_0x3ec167)return;if(!_0x58a9a8[_0x5dcdec(0x1c7)](_0x385058)){delete _0x3ae4ba[_0x5dcdec(a18_0x9fad0._0xfecdfc)][_0x385058];if(_0x3ae4ba['changed']())_0x3ae4ba[_0x5dcdec(a18_0x9fad0._0x40722a)](_0x385058,![]);}});}else{if(_0x35e72e['guarded']&&Array[_0xfb7c9e(0x192)](_0x35e72e['guarded'])){const _0x573d0d=_0x35e72e['guarded'];if(_0x573d0d[_0xfb7c9e(a18_0x2c9f96._0x12d677)]('*')){_0x3ae4ba['dataValues']={};return;}Object['keys'](_0x3ae4ba['dataValues'])['forEach'](_0x1da97c=>{const _0x1d5e55=_0xfb7c9e;if(_0x1da97c===_0x3ec167)return;if(_0x573d0d['includes'](_0x1da97c)){delete _0x3ae4ba[_0x1d5e55(0x14e)][_0x1da97c];if(_0x3ae4ba['changed']())_0x3ae4ba['changed'](_0x1da97c,![]);}});}}});}static['setDependencies']({logger:_0x2e8598,config:_0x4c2d8a,redis:_0x2640a0,redisOptions:_0x1be7e5}){const a18_0x1efadd={_0x2e38d0:0x1f4,_0x494bb5:0x1b0,_0x56a3c2:0x176,_0x52cddd:0x1c5,_0x5c7886:0x159,_0x4483bf:0x168,_0x2eca74:0x192,_0x1f698e:0x140,_0x3cb244:0x1e2,_0x2539af:0x1f6},_0x313f08=a18_0x5cf52a,_0x336041={'fplJF':_0x313f08(a18_0x1efadd._0x2e38d0),'BzJTN':function(_0x41baa6,_0x4bf76b){return _0x41baa6===_0x4bf76b;},'pyERw':'🟠\x20[REDIS]\x20No\x20Redis\x20provided.\x20Switching\x20to\x20In-Memory\x20Cache\x20mode.'};if(!_0x4c2d8a)throw new Error(_0x336041[_0x313f08(a18_0x1efadd._0x494bb5)]);this['logger']=_0x2e8598||logger_1['default'],this[_0x313f08(0x15d)]=_0x4c2d8a,this[_0x313f08(a18_0x1efadd._0x56a3c2)]=_0x4c2d8a['db']?.['redisCacheVersion']||_0x313f08(0x1a3);const _0x178bee=_0x4c2d8a?.['db']?.[_0x313f08(0x1e2)],_0x1ab98f=_0x4c2d8a?.['db']?.['useRedis']!==![];this['useRedis']=_0x1ab98f,this[_0x313f08(a18_0x1efadd._0x52cddd)]=_0x336041[_0x313f08(0x150)](typeof _0x178bee,'object')&&_0x178bee!==null&&_0x178bee[_0x313f08(a18_0x1efadd._0x5c7886)]||![];if(!_0x1ab98f){this['logger'][_0x313f08(0x1f6)]('🟠\x20[REDIS]\x20Disabled\x20via\x20config\x20(useRedis:\x20false).\x20Operating\x20in\x20In-Memory\x20Cache\x20mode\x20only.'),this[_0x313f08(a18_0x1efadd._0x4483bf)]=![];return;}this['isShardMode']&&this[_0x313f08(0x17c)][_0x313f08(0x1dd)]('🟣\x20[REDIS][SHARD]\x20Detected\x20redis\x20sharding\x20mode\x20(shard:\x20true).\x20Local\x20fallback\x20cache\x20DISABLED!');this['_redisFallbackURLs']=[];if(Array['isArray'](_0x1be7e5))this['_redisFallbackURLs']=_0x1be7e5['filter'](_0x41d2c1=>_0x41d2c1&&(typeof _0x41d2c1!==_0x313f08(0x1e8)||_0x41d2c1['trim']()['length']>-0xa0f+-0x161a+0x2029));else{if(typeof _0x1be7e5===_0x313f08(0x1e8))_0x1be7e5[_0x313f08(0x1fc)]()['length']>0x41*0x13+-0x127*-0x19+-0x21a2&&(this[_0x313f08(0x140)]=_0x1be7e5[_0x313f08(0x15b)](',')['map'](_0x2c878d=>_0x2c878d[_0x313f08(0x1fc)]())['filter'](_0x27f2e1=>_0x27f2e1[_0x313f08(0x1e5)]>-0x907+-0x89b+0x11a2));else{if(_0x1be7e5&&typeof _0x1be7e5==='object'&&Array[_0x313f08(a18_0x1efadd._0x2eca74)](_0x1be7e5[_0x313f08(0x148)]))this[_0x313f08(a18_0x1efadd._0x1f698e)]=_0x1be7e5['urls']['slice']();else _0x1be7e5&&typeof _0x1be7e5==='object'&&Object['keys'](_0x1be7e5)['length']>0x2293*-0x1+0x10cd+0x11c6&&(this['_redisFallbackURLs']=[_0x1be7e5]);}}this[_0x313f08(0x1cb)]=0xefa+-0x4cd*-0x2+-0xf2*0x1a;if(_0x2640a0)this[_0x313f08(a18_0x1efadd._0x3cb244)]=_0x2640a0,this['isRedisConnected']=_0x2640a0['status']==='ready';else this[_0x313f08(0x140)]['length']>-0x1*0x12db+0x427*0x2+-0x49*-0x25?this[_0x313f08(0x1f3)]():this['isShardMode']?(this[_0x313f08(0x17c)]['error']('❌\x20[REDIS][SHARD]\x20No\x20Redis\x20client/options,\x20but\x20shard:true.\x20Application\x20will\x20work\x20WITHOUT\x20caching!'),this[_0x313f08(a18_0x1efadd._0x4483bf)]=![]):(this['logger'][_0x313f08(a18_0x1efadd._0x2539af)](_0x336041['pyERw']),this[_0x313f08(0x168)]=![]);}static[a18_0x5cf52a(0x1f5)](_0x44e123){const a18_0x30d76a={_0x1b2069:0x17a,_0x1b526e:0x198,_0x4444eb:0x205,_0x15319f:0x17a,_0xa424a1:0x1e5,_0x16b2eb:0x157,_0x4becbd:0x17c,_0x194d71:0x1a9,_0x52ade0:0x1d7,_0x34a2e6:0x171,_0x1ad36f:0x1ff,_0x599e33:0x16a,_0xbec96f:0x168,_0x7f13da:0x191,_0x4b2430:0x17a},_0x531c15=a18_0x5cf52a,_0x2dc508=Date['now']();this[_0x531c15(0x17a)]=(this[_0x531c15(a18_0x30d76a._0x1b2069)]||[])[_0x531c15(a18_0x30d76a._0x1b526e)](_0x12b07f=>_0x2dc508-_0x12b07f<REDIS_ERROR_TOLERANCE_INTERVAL_MS),this['redisErrorTimestamps'][_0x531c15(a18_0x30d76a._0x4444eb)](_0x2dc508);if(this[_0x531c15(a18_0x30d76a._0x15319f)][_0x531c15(a18_0x30d76a._0xa424a1)]>=REDIS_ERROR_TOLERANCE_COUNT){if(this['isRedisConnected']){const _0x469ccb=this[_0x531c15(a18_0x30d76a._0x16b2eb)]();if(_0x469ccb)this[_0x531c15(a18_0x30d76a._0x4becbd)]['warn'](_0x531c15(a18_0x30d76a._0x194d71));else this[_0x531c15(0x1c5)]?(this['logger'][_0x531c15(0x1b5)]('❌\x20[REDIS][SHARD]\x20'+this[_0x531c15(0x17a)][_0x531c15(a18_0x30d76a._0xa424a1)]+'\x20consecutive\x20errors\x20in\x20'+REDIS_ERROR_TOLERANCE_INTERVAL_MS/(0x778+-0x1*-0x1a35+-0x1*0x1dc5)+_0x531c15(a18_0x30d76a._0x52ade0)+_0x44e123?.['message']+')'),this['isRedisConnected']=![],this['_scheduleReconnect']()):(this['logger']['error'](_0x531c15(a18_0x30d76a._0x34a2e6)+this['redisErrorTimestamps'][_0x531c15(a18_0x30d76a._0xa424a1)]+_0x531c15(a18_0x30d76a._0x1ad36f)+REDIS_ERROR_TOLERANCE_INTERVAL_MS/(0x293*0x3+0x181f+-0x254*0xc)+_0x531c15(0x169)+_0x44e123?.[_0x531c15(a18_0x30d76a._0x599e33)]+')'),this[_0x531c15(a18_0x30d76a._0xbec96f)]=![],this['_scheduleReconnect']());}this['redisErrorTimestamps']=[];}else this[_0x531c15(0x17c)]['warn'](_0x531c15(a18_0x30d76a._0x7f13da)+this[_0x531c15(a18_0x30d76a._0x4b2430)][_0x531c15(0x1e5)]+'/'+REDIS_ERROR_TOLERANCE_COUNT+'\x20tolerated.\x20('+_0x44e123?.[_0x531c15(a18_0x30d76a._0x599e33)]+')');}static['_tryRedisFailover'](){const a18_0x436b90={_0x5e9c38:0x140,_0x38b5c2:0x1e5,_0x4a7987:0x1ea},_0x35bcb4=a18_0x5cf52a;if(!Array[_0x35bcb4(0x192)](this[_0x35bcb4(a18_0x436b90._0x5e9c38)])||this['_redisFallbackURLs'][_0x35bcb4(a18_0x436b90._0x38b5c2)]<0x5*-0x1ed+-0x2099+-0xe14*-0x3)return![];const _0x50a4de=this['_redisCurrentIndex'];if(this[_0x35bcb4(0x1cb)]+(0x389*-0x1+0x12c1+-0xf37)<this['_redisFallbackURLs']['length'])return this[_0x35bcb4(0x1cb)]++,this['logger']['warn'](_0x35bcb4(0x160)+_0x50a4de+'\x20to\x20'+this['_redisCurrentIndex']),this[_0x35bcb4(a18_0x436b90._0x4a7987)]=!![],this[_0x35bcb4(0x163)](),this[_0x35bcb4(0x1f3)](),!![];return![];}static['_closeCurrentRedis'](){const a18_0x514fbd={_0x5ea1c8:0x1e2},_0xb0652d=a18_0x5cf52a,_0x1c1bae={'DwpqB':_0xb0652d(0x1f9)};if(this[_0xb0652d(a18_0x514fbd._0x5ea1c8)]&&typeof this['redis'][_0xb0652d(0x14d)]===_0x1c1bae['DwpqB'])try{this['redis'][_0xb0652d(0x14d)]();}catch(_0x7297b5){console['log'](_0x7297b5);}this['redis']=undefined,this[_0xb0652d(0x168)]=![];}static['initializeRedis'](_0x74b521){const a18_0x402c34={_0x5a184e:0x186,_0x9f419c:0x1cb,_0x156b8b:0x182,_0x4c2bc5:0x148,_0x5ca04d:0x148,_0x4c349f:0x140,_0x1f3846:0x140,_0x3cdddc:0x17c,_0x1b4a86:0x1b5,_0x302600:0x1d2,_0x42aea1:0x1f1,_0x308bb2:0x206,_0xb9416e:0x192,_0x4d7aaf:0x1c1},_0x9ccb31=a18_0x5cf52a,_0x13af8c={'RAzle':_0x9ccb31(a18_0x402c34._0x5a184e),'eToYw':function(_0xcf1560,_0x3b4f58){return _0xcf1560(_0x3b4f58);},'ewzIp':function(_0x239fcc,_0x42a660){return _0x239fcc===_0x42a660;}};if(_0x74b521){if(Array['isArray'](_0x74b521))this[_0x9ccb31(0x140)]=_0x74b521['slice'](),this[_0x9ccb31(a18_0x402c34._0x9f419c)]=-0x645*-0x1+-0x26ce+0x2089;else _0x74b521&&typeof _0x74b521===_0x13af8c[_0x9ccb31(a18_0x402c34._0x156b8b)]&&Array[_0x9ccb31(0x192)](_0x74b521[_0x9ccb31(a18_0x402c34._0x4c2bc5)])?(this[_0x9ccb31(0x140)]=_0x74b521[_0x9ccb31(a18_0x402c34._0x5ca04d)][_0x9ccb31(0x156)](),this['_redisCurrentIndex']=0x1*-0x1313+-0xacb*-0x1+0x848):(this[_0x9ccb31(a18_0x402c34._0x4c349f)]=[_0x74b521],this['_redisCurrentIndex']=-0x116*0x16+0x1094+0xd*0x90);}if(!Array['isArray'](this[_0x9ccb31(a18_0x402c34._0x1f3846)])||this[_0x9ccb31(a18_0x402c34._0x1f3846)][_0x9ccb31(0x1e5)]===-0x2659+-0xb49+0x31a2)return this['isShardMode']?(this[_0x9ccb31(a18_0x402c34._0x3cdddc)][_0x9ccb31(a18_0x402c34._0x1b4a86)]('❌\x20[REDIS][SHARD]\x20No\x20Redis\x20URL/options\x20provided\x20but\x20shard:true.\x20Will\x20run\x20without\x20caching!'),this[_0x9ccb31(0x168)]=![]):(this['logger']['warn'](_0x9ccb31(a18_0x402c34._0x302600)),this['isRedisConnected']=![]),null;const _0x277e4f=_0x13af8c[_0x9ccb31(0x145)](require,_0x9ccb31(a18_0x402c34._0x42aea1));this[_0x9ccb31(a18_0x402c34._0x308bb2)]=Array[_0x9ccb31(a18_0x402c34._0xb9416e)](this['_redisFallbackURLs'])?this[_0x9ccb31(a18_0x402c34._0x1f3846)]['slice']():[this[_0x9ccb31(0x140)]];if(this['redis'])return this[_0x9ccb31(0x1e2)];const _0x2ac1cd=this['_redisFallbackURLs'][this['_redisCurrentIndex']];_0x2ac1cd&&typeof _0x2ac1cd==='object'&&_0x2ac1cd['shard']&&(this['isShardMode']=!![]);let _0x5e0dc1;if(_0x13af8c[_0x9ccb31(0x177)](typeof _0x2ac1cd,'string'))_0x5e0dc1={'url':_0x2ac1cd,'retryStrategy':this['_makeRetryStrategy']()};else{if(_0x2ac1cd&&typeof _0x2ac1cd===_0x9ccb31(0x186))_0x5e0dc1={'maxRetriesPerRequest':0x2,'enableReadyCheck':!![],'retryStrategy':this[_0x9ccb31(a18_0x402c34._0x4d7aaf)](),..._0x2ac1cd};else return this[_0x9ccb31(0x17c)]['error'](_0x9ccb31(0x1bf)),this[_0x9ccb31(0x168)]=![],null;}return this[_0x9ccb31(0x1e2)]=new _0x277e4f(_0x5e0dc1['url']||_0x5e0dc1),this['_setupRedisEventHandlers'](),this['redis'];}static['_makeRetryStrategy'](){const a18_0x3276c6={_0x2af7f3:0x17c,_0x40f9da:0x14f,_0x4dfb9f:0x1cb,_0x51fdc6:0x181},_0xe0f04a={'cXuxw':function(_0xcb55c2,_0x2aafb1){return _0xcb55c2>_0x2aafb1;},'NjWiE':function(_0x4fe4ff,_0x469d1f){return _0x4fe4ff*_0x469d1f;}};return _0x37f0a6=>{const _0x4e15d1=a18_0x30ce;if(_0xe0f04a['cXuxw'](_0x37f0a6,0x4f3+-0x1*0x298+-0x256))return this[_0x4e15d1(a18_0x3276c6._0x2af7f3)]['error']('❌\x20[REDIS]\x20Could\x20not\x20connect\x20after\x20'+(_0x37f0a6-(0x3*0x44b+-0x3fd+-0x145*0x7))+'\x20retries\x20for\x20Redis\x20#'+(this[_0x4e15d1(0x1cb)]+(0x5d4*-0x4+0x1224+0x1*0x52d))+'.'),null;const _0x3faad8=Math['min'](_0xe0f04a['NjWiE'](_0x37f0a6,-0x1431+-0xb1*-0x7+-0x376*-0x5),0xdcb+-0x260+0x39b*-0x1);return this[_0x4e15d1(0x17c)]['warn'](_0x4e15d1(a18_0x3276c6._0x40f9da)+(this[_0x4e15d1(a18_0x3276c6._0x4dfb9f)]+(0x5ed*-0x4+-0x1a57+0x320c))+'.\x20Retrying\x20in\x20'+_0x3faad8+_0x4e15d1(a18_0x3276c6._0x51fdc6)+_0x37f0a6+')...'),_0x3faad8;};}static[a18_0x5cf52a(0x1aa)](){const a18_0x25bbc7={_0x26a150:0x168,_0x4118c2:0x1c5,_0x5ec5fe:0x200,_0x1f9ea4:0x17c,_0x48e73e:0x1f6},a18_0x3a87f6={_0x4743f5:0x1fe,_0x3d166a:0x16a,_0x5c0b6f:0x17c},a18_0x586a91={_0x52ae33:0x20a,_0x501ac0:0x1cb,_0x1a5fc3:0x1f6,_0x2770da:0x1ea},_0x496aa4=a18_0x5cf52a,_0x920db5={'cBrDM':'❌\x20[REDIS][SHARD]\x20Connection\x20closed.\x20Cache\x20DISABLED\x20(no\x20fallback).','Zwktp':'❌\x20[REDIS]\x20Connection\x20closed.\x20Fallback/failover\x20will\x20be\x20attempted.','sgSuk':'connect'};if(!this['redis'])return;this[_0x496aa4(0x1e2)]['on'](_0x920db5[_0x496aa4(0x174)],async()=>{const _0x476516=_0x496aa4;!this['isRedisConnected']&&this['logger']['info']('✅\x20[REDIS]\x20Connection\x20established.\x20Switching\x20to\x20Redis\x20Cache\x20mode.');this[_0x476516(0x168)]=!![],this[_0x476516(0x17a)]=[];this[_0x476516(0x20a)]&&(clearTimeout(this[_0x476516(a18_0x586a91._0x52ae33)]),this['reconnectTimeout']=null);this[_0x476516(0x196)]['delete'](this[_0x476516(a18_0x586a91._0x501ac0)]);if(this[_0x476516(0x1ea)]){this[_0x476516(0x17c)][_0x476516(a18_0x586a91._0x1a5fc3)]('[REDIS][FAILOVER]\x20Connected\x20to\x20new\x20server,\x20flushing\x20potentially\x20stale\x20cache...');try{await this[_0x476516(0x1e2)]?.['flushdb'](),this[_0x476516(0x17c)]['info']('[REDIS][FAILOVER]\x20Stale\x20cache\x20flushed\x20successfully.');}catch(_0x5e2102){this['logger']['error'](_0x476516(0x185),_0x5e2102);}this[_0x476516(a18_0x586a91._0x2770da)]=![];}}),this['redis']['on']('error',_0x13898a=>{const _0x57d33e=_0x496aa4;_0x13898a&&(_0x13898a['code']===_0x57d33e(a18_0x3a87f6._0x4743f5)||_0x13898a[_0x57d33e(a18_0x3a87f6._0x3d166a)])&&this[_0x57d33e(a18_0x3a87f6._0x5c0b6f)]['warn']('🟠\x20[REDIS]\x20Connection\x20error:\x20'+_0x13898a[_0x57d33e(a18_0x3a87f6._0x3d166a)]);}),this['redis']['on'](_0x496aa4(0x1ab),()=>{const _0x5a06bf=_0x496aa4;this[_0x5a06bf(a18_0x25bbc7._0x26a150)]&&(this[_0x5a06bf(a18_0x25bbc7._0x4118c2)]?this[_0x5a06bf(0x17c)]['error'](_0x920db5[_0x5a06bf(a18_0x25bbc7._0x5ec5fe)]):this[_0x5a06bf(a18_0x25bbc7._0x1f9ea4)][_0x5a06bf(0x1b5)](_0x920db5[_0x5a06bf(0x1cf)]));this[_0x5a06bf(0x168)]=![],this['_redisFailedIndexes'][_0x5a06bf(0x141)](this[_0x5a06bf(0x1cb)]),this[_0x5a06bf(0x17c)][_0x5a06bf(0x1f6)]('[REDIS]\x20Connection\x20#'+(this[_0x5a06bf(0x1cb)]+(0x14a2+0x26ba+-0x3b5b))+'\x20closed.\x20Attempting\x20immediate\x20failover...');const _0x361e39=this['_tryRedisFailover']();!_0x361e39&&(this[_0x5a06bf(0x17c)][_0x5a06bf(a18_0x25bbc7._0x48e73e)]('[REDIS]\x20Failover\x20exhausted.\x20Scheduling\x20full\x20reconnect...'),this['_scheduleReconnect']());});}static[a18_0x5cf52a(0x1d0)](){const a18_0x433cca={_0x57d20d:0x1d1,_0x414738:0x1f6,_0x425991:0x1f6,_0x17ab05:0x13c,_0x40e3a0:0x183},a18_0x2cb8f3={_0x5dd6be:0x163},_0x1fac6a=a18_0x5cf52a;if(this['reconnectTimeout'])return;const _0x192823=Date[_0x1fac6a(a18_0x433cca._0x57d20d)]()-this['lastAutoReconnectTs'];if(_0x192823<RECONNECT_DELAY_MINUTES*(-0x900+0x7a*0x1+0x8c2)*(0x4*0x2fc+-0x295*-0x5+-0x14f1*0x1))return;this['lastAutoReconnectTs']=Date[_0x1fac6a(0x1d1)](),this['isShardMode']?this['logger'][_0x1fac6a(a18_0x433cca._0x414738)]('[REDIS][SHARD]\x20Attempting\x20auto-reconnect\x20after\x20'+RECONNECT_DELAY_MINUTES+'min\x20downtime...'):this[_0x1fac6a(0x17c)][_0x1fac6a(a18_0x433cca._0x425991)](_0x1fac6a(a18_0x433cca._0x17ab05)+RECONNECT_DELAY_MINUTES+_0x1fac6a(a18_0x433cca._0x40e3a0)),this['reconnectTimeout']=setTimeout(()=>{const _0x211746=_0x1fac6a,_0x282d84='4|0|1|2|3'['split']('|');let _0x34f2cf=0x11b9*-0x2+-0x1b02*0x1+0x3e74;while(!![]){switch(_0x282d84[_0x34f2cf++]){case'0':this['_redisCurrentIndex']=-0x1*-0x1cc9+0x525+-0x21ee;continue;case'1':this['_redisFailedIndexes'][_0x211746(0x19b)]();continue;case'2':this[_0x211746(a18_0x2cb8f3._0x5dd6be)]();continue;case'3':this['initializeRedis']();continue;case'4':this['reconnectTimeout']=null;continue;}break;}},RECONNECT_DELAY_MINUTES*(-0x20a4+-0x1*0x2665+0x4745)*(-0x5e3*-0x1+-0x1860+0x1665));}static['getCacheKey'](_0x4f8c08){const a18_0x556a68={_0x38de7c:0x186,_0x57e295:0x172},_0x5e1bed=a18_0x5cf52a,_0x46087b={'WgUMy':function(_0x44025f,_0x26b7e2){return _0x44025f===_0x26b7e2;},'LdAZo':_0x5e1bed(0x1e8)};let _0x196b4f=_0x4f8c08;_0x196b4f&&typeof _0x196b4f===_0x5e1bed(a18_0x556a68._0x38de7c)&&!_0x196b4f[_0x5e1bed(0x1b6)]&&!_0x196b4f[_0x5e1bed(0x209)]&&(_0x196b4f={'where':_0x196b4f});const _0x69ae35={'replacer':(_0xd71b03,_0x2fc555)=>typeof _0x2fc555==='bigint'?_0x2fc555[_0x5e1bed(0x19c)]():_0x2fc555},_0x28efea=_0x46087b['WgUMy'](typeof _0x4f8c08,_0x46087b['LdAZo'])?_0x4f8c08:jsonStringify(this['normalizeQueryOptions'](_0x196b4f),_0x69ae35);return this['CACHE_VERSION']+':'+this[_0x5e1bed(a18_0x556a68._0x57e295)]+':'+_0x28efea;}static[a18_0x5cf52a(0x1af)](_0x4618a1){const a18_0xade086={_0x423431:0x1b1,_0x2b4c6:0x187},a18_0x775d1d={_0x5e3833:0x1af},_0x53347d=a18_0x5cf52a,_0x245e12={'ishJe':function(_0x1b9987,_0x36e450){return _0x1b9987!==_0x36e450;}};if(!_0x4618a1||_0x245e12['ishJe'](typeof _0x4618a1,'object'))return _0x4618a1;if(Array['isArray'](_0x4618a1))return _0x4618a1[_0x53347d(0x1b9)](_0x17ce51=>this[_0x53347d(0x1af)](_0x17ce51));const _0x1d03ac={};return Object[_0x53347d(a18_0xade086._0x423431)](_0x4618a1)['sort']()['forEach'](_0x47dbd6=>{_0x1d03ac[_0x47dbd6]=this['normalizeQueryOptions'](_0x4618a1[_0x47dbd6]);}),Object['getOwnPropertySymbols'](_0x4618a1)[_0x53347d(a18_0xade086._0x2b4c6)](_0x2265ba=>{const _0x19f740=_0x53347d,_0x42a2a9='$'+_0x2265ba[_0x19f740(0x19c)]()['slice'](-0x18df+0x9*0x8+0x189e,-(-0x7b*0x3+0x7*-0x76+0x4*0x12b));_0x1d03ac[_0x42a2a9]=this[_0x19f740(a18_0x775d1d._0x5e3833)](_0x4618a1[_0x2265ba]);}),_0x1d03ac;}static['_generateSmartTags'](_0x360d91){const a18_0x4e54bb={_0x34a05c:0x192,_0x564eab:0x204,_0x5dc3ed:0x1b9,_0x1b83bb:0x205,_0x3f8101:0x172},_0x32f879=a18_0x5cf52a;if(!_0x360d91)return[''+this[_0x32f879(0x172)]];const _0x2f9729=[''+this[_0x32f879(0x172)]],_0x3476ee=this[_0x32f879(0x152)];_0x360d91[_0x3476ee]&&_0x2f9729['push'](this['name']+':'+_0x3476ee+':'+_0x360d91[_0x3476ee]);const _0x55791b=this[_0x32f879(0x1da)]||this[_0x32f879(0x1df)]||[];if(Array[_0x32f879(a18_0x4e54bb._0x34a05c)](_0x55791b))for(const _0x4f1f16 of _0x55791b){const _0x2cb7cc=Array['isArray'](_0x4f1f16)?_0x4f1f16:[_0x4f1f16],_0x93d8bd=_0x2cb7cc[_0x32f879(a18_0x4e54bb._0x564eab)](_0x546335=>_0x360d91[_0x546335]!==undefined&&_0x360d91[_0x546335]!==null);if(_0x93d8bd){const _0x1f6704=_0x2cb7cc[_0x32f879(a18_0x4e54bb._0x5dc3ed)](_0x332b12=>_0x332b12+':'+_0x360d91[_0x332b12])[_0x32f879(0x1a5)](':');_0x2f9729[_0x32f879(a18_0x4e54bb._0x1b83bb)](this[_0x32f879(a18_0x4e54bb._0x3f8101)]+':'+_0x1f6704);}}return _0x2f9729;}static async[a18_0x5cf52a(0x13e)](_0x5bd68b,_0x540233,_0x37c23a,_0x373768=[]){const a18_0x4cad53={_0x199961:0x146,_0x246614:0x1b4},_0x15a9ea=a18_0x5cf52a,_0x368412=typeof _0x5bd68b===_0x15a9ea(0x1e8)?_0x5bd68b:this[_0x15a9ea(0x1a4)](_0x5bd68b),_0x4bdb7b=_0x37c23a||this[_0x15a9ea(a18_0x4cad53._0x199961)]||this[_0x15a9ea(0x208)];if(this['isRedisConnected'])await this[_0x15a9ea(a18_0x4cad53._0x246614)](_0x368412,_0x540233,_0x4bdb7b,_0x373768);else!this['isShardMode']&&this[_0x15a9ea(0x1ca)](_0x368412,_0x540233,_0x4bdb7b);}static async[a18_0x5cf52a(0x1e3)](_0x3e56cb,_0x1a6545){const a18_0x4fb090={_0x51dd0d:0x1a4,_0x3af648:0x16b},_0x522a65=a18_0x5cf52a,_0x18a191=typeof _0x3e56cb==='string'?_0x3e56cb:this[_0x522a65(a18_0x4fb090._0x51dd0d)](_0x3e56cb);if(this[_0x522a65(0x168)])return this[_0x522a65(a18_0x4fb090._0x3af648)](_0x18a191,_0x1a6545);else{if(!this['isShardMode'])return this['_mapGetCachedEntry'](_0x18a191,_0x1a6545);}return{'hit':![],'data':undefined};}static async[a18_0x5cf52a(0x1ae)](_0x2fd5da){const a18_0x3b98c3={_0x5d63fd:0x1a4},_0x12a7e3=a18_0x5cf52a,_0x58a416=typeof _0x2fd5da===_0x12a7e3(0x1e8)?_0x2fd5da:this[_0x12a7e3(a18_0x3b98c3._0x5d63fd)](_0x2fd5da);if(this['isRedisConnected'])await this['_redisClearCache'](_0x58a416);else!this['isShardMode']&&this['_mapClearCache'](_0x58a416);}static async[a18_0x5cf52a(0x1b4)](_0x2470ef,_0xc14f14,_0x29a685,_0x1b5aa5=[]){const a18_0x567347={_0x45b18e:0x14a,_0x8d20e:0x1be},_0x24fa4b=a18_0x5cf52a;if(!this['redis'])return;try{let _0x216316=_0xc14f14;if(_0xc14f14&&typeof _0xc14f14['toJSON']===_0x24fa4b(0x1f9))_0x216316=_0xc14f14[_0x24fa4b(a18_0x567347._0x45b18e)]();else Array['isArray'](_0xc14f14)&&(_0x216316=_0xc14f14['map'](_0x3e4d43=>_0x3e4d43&&typeof _0x3e4d43['toJSON']==='function'?_0x3e4d43[_0x24fa4b(0x14a)]():_0x3e4d43));const _0x5cb953=_0x216316===null?NEGATIVE_CACHE_PLACEHOLDER:safeStringify(_0x216316,this['logger']),_0x1727af=this[_0x24fa4b(0x1e2)][_0x24fa4b(a18_0x567347._0x8d20e)]();_0x1727af['set'](_0x2470ef,_0x5cb953,'PX',_0x29a685);for(const _0x14a383 of _0x1b5aa5){_0x1727af['sadd'](_0x14a383,_0x2470ef);}await _0x1727af[_0x24fa4b(0x1ef)](),this[_0x24fa4b(0x18c)]['sets']++;}catch(_0x18d92c){this['_trackRedisError'](_0x18d92c);}}static async[a18_0x5cf52a(0x16b)](_0x5637b9,_0x377ace){const a18_0x229aae={_0x231c8e:0x1db,_0x305e96:0x1e4},_0x592a3e=a18_0x5cf52a,_0x352b72={'yLIsa':function(_0x1ecb69,_0x414fa3){return _0x1ecb69===_0x414fa3;}};if(!this['redis'])return{'hit':![],'data':undefined};try{const _0x2ff687=await this['redis'][_0x592a3e(a18_0x229aae._0x231c8e)](_0x5637b9);if(_0x2ff687===null||_0x352b72['yLIsa'](_0x2ff687,undefined))return{'hit':![],'data':undefined};this[_0x592a3e(0x18c)][_0x592a3e(a18_0x229aae._0x305e96)]++;if(_0x352b72['yLIsa'](_0x2ff687,NEGATIVE_CACHE_PLACEHOLDER))return{'hit':!![],'data':null};const _0x39b895=safeParse(_0x2ff687,this[_0x592a3e(0x17c)]);if(_0x39b895===null)return{'hit':![],'data':undefined};const _0x42148e=_0x377ace?Array['isArray'](_0x377ace)?_0x377ace:[_0x377ace]:undefined,_0x459297=_0x191db3=>{const _0x1355dc=_0x592a3e,_0x42b9d7=this[_0x1355dc(0x1bb)](_0x191db3,{'isNewRecord':![],'include':_0x42148e});return _0x42b9d7;};if(Array['isArray'](_0x39b895)){const _0x922c6a=_0x39b895['map'](_0x45b993=>_0x459297(_0x45b993));return{'hit':!![],'data':_0x922c6a};}else{const _0x518755=_0x459297(_0x39b895);return{'hit':!![],'data':_0x518755};}}catch(_0x3cb669){return this['_trackRedisError'](_0x3cb669),{'hit':![],'data':undefined};}}static async['_redisClearCache'](_0x3906e3){const a18_0xf0dafe={_0x3fcaa3:0x1f7,_0x33a18f:0x1ec},_0x57592a=a18_0x5cf52a;if(!this[_0x57592a(0x1e2)])return;try{await this['redis'][_0x57592a(a18_0xf0dafe._0x3fcaa3)](_0x3906e3),this['cacheStats'][_0x57592a(a18_0xf0dafe._0x33a18f)]++;}catch(_0x37b28c){this[_0x57592a(0x1f5)](_0x37b28c);}}static async[a18_0x5cf52a(0x17e)](_0x5d6fd3){const a18_0x59aaaa={_0x3c1c8b:0x1e5,_0x1dfdfd:0x1ef,_0x376fe2:0x1f5},_0x46f4a1=a18_0x5cf52a;if(!this[_0x46f4a1(0x168)]||!Array[_0x46f4a1(0x192)](_0x5d6fd3)||_0x5d6fd3[_0x46f4a1(a18_0x59aaaa._0x3c1c8b)]===-0x1c24+0x1239+0x9eb*0x1||!this['redis'])return;try{const _0x3ef446=await this['redis']['sunion'](_0x5d6fd3);_0x3ef446&&_0x3ef446['length']>0x12d3*-0x2+0x1*-0x5d3+0x1f*0x167?(this['logger']['info'](_0x46f4a1(0x207)+_0x3ef446['length']+'\x20keys\x20for\x20tags:\x20'+_0x5d6fd3[_0x46f4a1(0x1a5)](',\x20')),await this['redis'][_0x46f4a1(0x1be)]()['del'](_0x3ef446)[_0x46f4a1(0x1f7)](_0x5d6fd3)[_0x46f4a1(a18_0x59aaaa._0x1dfdfd)]()):await this[_0x46f4a1(0x1e2)][_0x46f4a1(0x1f7)](_0x5d6fd3);}catch(_0x2da2ef){this[_0x46f4a1(a18_0x59aaaa._0x376fe2)](_0x2da2ef);}}static[a18_0x5cf52a(0x1ca)](_0x82a95,_0x1fded2,_0x28cd20){const a18_0x51d8f4={_0x1695e7:0x192,_0x3ec861:0x1e6,_0x28186c:0x1d1},_0x1bd64d=a18_0x5cf52a,_0x35c825={'yEKYb':function(_0x58e1fa,_0x46a5e8){return _0x58e1fa+_0x46a5e8;}};if(this['isShardMode'])return;if(_0x1fded2===null)this['localNegativeCache'][_0x1bd64d(0x141)](_0x82a95),this['localCache']['delete'](_0x82a95);else{let _0x184716=_0x1fded2;if(_0x1fded2&&typeof _0x1fded2['toJSON']==='function')_0x184716=_0x1fded2['toJSON']();else Array[_0x1bd64d(a18_0x51d8f4._0x1695e7)](_0x1fded2)&&(_0x184716=_0x1fded2['map'](_0x194efc=>_0x194efc&&typeof _0x194efc[_0x1bd64d(0x14a)]==='function'?_0x194efc['toJSON']():_0x194efc));const _0x2ab189=_0x184716===null?NEGATIVE_CACHE_PLACEHOLDER:safeStringify(_0x184716,this[_0x1bd64d(0x17c)]);this[_0x1bd64d(0x1b3)][_0x1bd64d(0x1e1)](_0x82a95,{'data':_0x2ab189,'expires':_0x35c825[_0x1bd64d(a18_0x51d8f4._0x3ec861)](Date[_0x1bd64d(a18_0x51d8f4._0x28186c)](),_0x28cd20)}),this['localNegativeCache'][_0x1bd64d(0x166)](_0x82a95);}this[_0x1bd64d(0x18c)]['sets']++;}static[a18_0x5cf52a(0x175)](_0x21ec36,_0x56ab6e){const a18_0x570825={_0x54f77b:0x1b3,_0x46037d:0x1c4,_0x4f1200:0x17c,_0x2167f0:0x192},_0x275f3e=a18_0x5cf52a,_0x5ec580={'rTjIe':function(_0x2e7f38,_0x4a650d){return _0x2e7f38!==_0x4a650d;}};if(this[_0x275f3e(0x1c5)])return{'hit':![],'data':undefined};if(this['localNegativeCache']['has'](_0x21ec36))return this[_0x275f3e(0x18c)]['mapHits']++,{'hit':!![],'data':null};const _0x548a2b=this[_0x275f3e(a18_0x570825._0x54f77b)]['get'](_0x21ec36);if(_0x548a2b&&_0x548a2b[_0x275f3e(0x18f)]>Date[_0x275f3e(0x1d1)]()){this['cacheStats'][_0x275f3e(a18_0x570825._0x46037d)]++;const _0x3f33ec=_0x548a2b[_0x275f3e(0x19e)];let _0x46a748;typeof _0x3f33ec===_0x275f3e(0x1e8)?_0x46a748=safeParse(_0x3f33ec,this[_0x275f3e(a18_0x570825._0x4f1200)]):_0x46a748=_0x3f33ec;if(_0x5ec580['rTjIe'](typeof _0x46a748,_0x275f3e(0x186))||_0x46a748===null)return{'hit':!![],'data':_0x46a748};const _0x103f82=_0x56ab6e?Array[_0x275f3e(a18_0x570825._0x2167f0)](_0x56ab6e)?_0x56ab6e:[_0x56ab6e]:undefined;if(Array['isArray'](_0x46a748)){const _0x93dfc1=this[_0x275f3e(0x193)](_0x46a748,{'isNewRecord':![],'include':_0x103f82});return{'hit':!![],'data':_0x93dfc1};}else{const _0x522fda=this['build'](_0x46a748,{'isNewRecord':![],'include':_0x103f82});return{'hit':!![],'data':_0x522fda};}}if(_0x548a2b)this[_0x275f3e(0x1b3)]['delete'](_0x21ec36);return{'hit':![],'data':undefined};}static[a18_0x5cf52a(0x15c)](_0x21a6eb){const a18_0xffa817={_0x3a6e4c:0x166,_0x50b2dc:0x17d},_0xc13227=a18_0x5cf52a;if(this[_0xc13227(0x1c5)])return;this['localCache'][_0xc13227(a18_0xffa817._0x3a6e4c)](_0x21a6eb),this[_0xc13227(a18_0xffa817._0x50b2dc)]['delete'](_0x21a6eb),this['cacheStats']['clears']++;}static[a18_0x5cf52a(0x1d5)](){const a18_0x3794b6={_0xc71bf8:0x1b3,_0x144348:0x166,_0x4a6c5b:0x1b1,_0x3b7f3a:0x18a,_0x10500c:0x17c,_0x3e28c9:0x1dd,_0x5064da:0x15e,_0x50ad52:0x1cd,_0x270a03:0x173},_0x3f50b0=a18_0x5cf52a;if(this['isShardMode'])return;const _0x46aa88=this['CACHE_VERSION']+':'+this['name']+':';let _0x181e98=0x8c*0x2f+-0x2d1+-0x16e3;for(const _0x419ab9 of this[_0x3f50b0(0x1b3)][_0x3f50b0(0x1b1)]()){_0x419ab9['startsWith'](_0x46aa88)&&(this[_0x3f50b0(a18_0x3794b6._0xc71bf8)][_0x3f50b0(a18_0x3794b6._0x144348)](_0x419ab9),_0x181e98++);}for(const _0x585d4a of this['localNegativeCache'][_0x3f50b0(a18_0x3794b6._0x4a6c5b)]()){_0x585d4a[_0x3f50b0(a18_0x3794b6._0x3b7f3a)](_0x46aa88)&&(this['localNegativeCache']['delete'](_0x585d4a),_0x181e98++);}_0x181e98>0x7e9+-0x29e*0x5+0x52d&&this[_0x3f50b0(a18_0x3794b6._0x10500c)][_0x3f50b0(a18_0x3794b6._0x3e28c9)](_0x3f50b0(a18_0x3794b6._0x5064da)+_0x181e98+_0x3f50b0(a18_0x3794b6._0x50ad52)+this['name']+_0x3f50b0(a18_0x3794b6._0x270a03));}static[a18_0x5cf52a(0x143)](_0x310d70){const a18_0x3fefe9={_0x242cf7:0x1b1},_0x66bbd0=a18_0x5cf52a,_0x84694={'YCAQG':'limit','ThSTl':'group','fyrxi':_0x66bbd0(0x15f)};if(!_0x310d70||typeof _0x310d70!=='object'||Object[_0x66bbd0(a18_0x3fefe9._0x242cf7)](_0x310d70)[_0x66bbd0(0x1e5)]===0x143f+-0xe06+-0x639*0x1)return{'where':{}};if(_0x310d70['where']){const _0x43fa82={..._0x310d70};return delete _0x43fa82['cacheTags'],delete _0x43fa82['noCache'],_0x43fa82;}const _0x15a9b2=['order',_0x84694[_0x66bbd0(0x1de)],'attributes','include',_0x84694['ThSTl'],'having'],_0x756412=[_0x84694[_0x66bbd0(0x20c)],'noCache'],_0x5e8118={},_0x4e07ff={};for(const _0x461595 in _0x310d70){if(_0x756412['includes'](_0x461595))continue;if(_0x15a9b2['includes'](_0x461595))_0x4e07ff[_0x461595]=_0x310d70[_0x461595];else _0x5e8118[_0x461595]=_0x310d70[_0x461595];}return{'where':_0x5e8118,..._0x4e07ff};}static async['getCache'](_0x33ee09,_0x6e09f5={}){const a18_0x231562={_0x319fd7:0x143,_0x1be080:0x1b6,_0x302e28:0x1a4,_0x2c0c18:0x19e,_0x3483a8:0x170,_0x42c9d6:0x1e1},a18_0x539e31={_0x3022e8:0x168},_0x4477b0=a18_0x5cf52a,{noCache:_0x128b0f,customCacheKey:_0x3b2e7d,ttl:_0x2116a8,..._0xea85bb}=_0x6e09f5;if(Array['isArray'](_0x33ee09)){const _0x14b38b=this['primaryKeyAttribute'];return this['findAll']({'where':{[_0x14b38b]:_0x33ee09[_0x4477b0(0x1b9)](_0x3396f1=>_0x3396f1[_0x14b38b])}});}const _0x38e93b=this[_0x4477b0(a18_0x231562._0x319fd7)](_0x33ee09),_0x159459={..._0x38e93b,..._0xea85bb,'where':{..._0x38e93b['where']||{},..._0xea85bb[_0x4477b0(0x1b6)]||{}}};if(_0x128b0f)return this['findOne'](_0x159459);if(!_0x159459[_0x4477b0(a18_0x231562._0x1be080)]||Object[_0x4477b0(0x1b1)](_0x159459['where'])[_0x4477b0(0x1e5)]===-0xc6d+-0x210*0x2+0x108d)return null;const _0x3d368c=_0x3b2e7d||this[_0x4477b0(a18_0x231562._0x302e28)](_0x159459),_0xec6ba4=await this['getCachedEntry'](_0x3d368c,_0x159459['include']);if(_0xec6ba4[_0x4477b0(0x197)])return _0xec6ba4[_0x4477b0(a18_0x231562._0x2c0c18)];this[_0x4477b0(0x18c)]['misses']++;if(this['pendingQueries']['has'](_0x3d368c))return this[_0x4477b0(a18_0x231562._0x3483a8)]['get'](_0x3d368c);const _0x2ec312=this['findOne'](_0x159459)['then'](async _0x37b806=>{const _0x4dcb29=_0x4477b0;if(this[_0x4dcb29(a18_0x539e31._0x3022e8)]||!this[_0x4dcb29(0x1c5)]){const _0xc66586=[''+this[_0x4dcb29(0x172)]];if(_0x37b806)_0xc66586[_0x4dcb29(0x205)](this['name']+':'+this[_0x4dcb29(0x152)]+':'+_0x37b806[this[_0x4dcb29(0x152)]]);await this['setCacheEntry'](_0x3d368c,_0x37b806,_0x2116a8,_0xc66586);}return _0x37b806;})[_0x4477b0(0x1a7)](()=>this[_0x4477b0(0x170)][_0x4477b0(0x166)](_0x3d368c));return this['pendingQueries'][_0x4477b0(a18_0x231562._0x42c9d6)](_0x3d368c,_0x2ec312),_0x2ec312;}static async[a18_0x5cf52a(0x1bc)](_0x289b71={}){const a18_0x23e936={_0x582d49:0x143,_0x1be139:0x1e1},a18_0x1e0448={_0x1b08f8:0x168,_0x49ef2e:0x1c5,_0x2ad946:0x192,_0x4243fd:0x205,_0x2dc85a:0x13e},_0x2291b2=a18_0x5cf52a,{cacheTags:_0x2ae595,noCache:_0x43af89,customCacheKey:_0x2db9aa,ttl:_0x3a248b,..._0x4a1610}=_0x289b71||{},_0x5c5903=this[_0x2291b2(a18_0x23e936._0x582d49)](_0x4a1610);if(_0x43af89)return this['findAll'](_0x5c5903);const _0x3c335c=_0x2db9aa||this['getCacheKey'](_0x5c5903),_0x163d18=await this['getCachedEntry'](_0x3c335c,_0x5c5903['include']);if(_0x163d18['hit'])return _0x163d18['data'];this['cacheStats']['misses']++;if(this['pendingQueries']['has'](_0x3c335c))return this['pendingQueries'][_0x2291b2(0x1db)](_0x3c335c);const _0xff969e=this[_0x2291b2(0x1c0)](_0x5c5903)['then'](async _0x30ff35=>{const _0x34a794=_0x2291b2;if(this[_0x34a794(a18_0x1e0448._0x1b08f8)]||!this[_0x34a794(a18_0x1e0448._0x49ef2e)]){const _0x5c3ec8=[''+this['name']];if(Array[_0x34a794(a18_0x1e0448._0x2ad946)](_0x2ae595))_0x5c3ec8[_0x34a794(a18_0x1e0448._0x4243fd)](..._0x2ae595);await this[_0x34a794(a18_0x1e0448._0x2dc85a)](_0x3c335c,_0x30ff35,_0x3a248b,_0x5c3ec8);}return _0x30ff35;})['finally'](()=>this[_0x2291b2(0x170)]['delete'](_0x3c335c));return this['pendingQueries'][_0x2291b2(a18_0x23e936._0x1be139)](_0x3c335c,_0xff969e),_0xff969e;}static async['scheduleAdd'](_0x5df7b0,_0x5007b3,_0x784dce){const a18_0x5370f2={_0x5cfb27:0x168},_0x129078=a18_0x5cf52a;if(!this[_0x129078(a18_0x5370f2._0x5cfb27)]||!this[_0x129078(0x1e2)])return;const _0x569c6b=this['name']+':'+_0x5df7b0;try{await this[_0x129078(0x1e2)][_0x129078(0x18e)](_0x569c6b,_0x5007b3,_0x784dce);}catch(_0x4ccae1){this['_trackRedisError'](_0x4ccae1);}}static async[a18_0x5cf52a(0x154)](_0x20a25e,_0x563611){const a18_0xd0938d={_0xcee2ce:0x1b7},_0x28d991=a18_0x5cf52a;if(!this['isRedisConnected']||!this['redis'])return;const _0x425afe=this['name']+':'+_0x20a25e;try{await this[_0x28d991(0x1e2)][_0x28d991(a18_0xd0938d._0xcee2ce)](_0x425afe,_0x563611);}catch(_0x14170f){this[_0x28d991(0x1f5)](_0x14170f);}}static async['scheduleGetExpired'](_0x3fdb67,_0x25f312=Date[a18_0x5cf52a(0x1d1)]()){const _0x123fde=a18_0x5cf52a;if(!this[_0x123fde(0x168)]||!this['redis'])return[];const _0x2a584d=this['name']+':'+_0x3fdb67;try{return await this['redis']['zrangebyscore'](_0x2a584d,-0x2251+-0x1*-0x13f0+0xe61,_0x25f312);}catch(_0x2d79ef){return this['_trackRedisError'](_0x2d79ef),[];}}static async['scheduleClear'](_0x4ae2c6){const a18_0x379873={_0xa00022:0x1f7},_0x169b7f=a18_0x5cf52a;if(!this['isRedisConnected']||!this['redis'])return;const _0x2bebe5=this['name']+':'+_0x4ae2c6;try{await this[_0x169b7f(0x1e2)][_0x169b7f(a18_0x379873._0xa00022)](_0x2bebe5);}catch(_0x37b007){this[_0x169b7f(0x1f5)](_0x37b007);}}static async['findOrCreateWithCache'](_0x3bcf77){const a18_0x5437e7={_0x45130f:0x1b6,_0x195f66:0x1a4,_0x455866:0x186,_0x2899ad:0x1db,_0x37a585:0x1a7},a18_0x235e18={_0x54f44e:0x172},_0x5b77b8=a18_0x5cf52a,_0xc5a7b9={'fPLVz':function(_0x4c48f2,_0x2956d8){return _0x4c48f2===_0x2956d8;},'BMMPK':function(_0x3e3e2f,_0x3b3744){return _0x3e3e2f(_0x3b3744);}};if(!_0x3bcf77||!_0x3bcf77[_0x5b77b8(a18_0x5437e7._0x45130f)])throw new Error(_0x5b77b8(0x19d));const {where:_0x16aa7d,defaults:_0x122a21,noCache:_0x305886,..._0x2c301e}=_0x3bcf77;if(_0x305886)return this[_0x5b77b8(0x161)](_0x3bcf77);const _0x410f72=this['_normalizeFindOptions'](_0x16aa7d)[_0x5b77b8(a18_0x5437e7._0x45130f)],_0x2094c2=this[_0x5b77b8(a18_0x5437e7._0x195f66)](_0x410f72),_0x3fac2c=await this[_0x5b77b8(0x1e3)](_0x2094c2,_0x2c301e['include']);if(_0x3fac2c[_0x5b77b8(0x197)]&&_0x3fac2c['data']){const _0x35c756=_0x3fac2c['data'];let _0x12cc46=![];if(_0x122a21&&typeof _0x122a21===_0x5b77b8(a18_0x5437e7._0x455866))for(const _0x32548b in _0x122a21){(_0x35c756[_0x32548b]===undefined||_0xc5a7b9[_0x5b77b8(0x1c6)](String,_0x35c756[_0x32548b])!==String(_0x122a21[_0x32548b]))&&(_0x35c756[_0x32548b]=_0x122a21[_0x32548b],_0x12cc46=!![]);}return _0x12cc46&&await _0x35c756['saveAndUpdateCache'](),[_0x35c756,![]];}this['cacheStats']['misses']++;if(this['pendingQueries'][_0x5b77b8(0x16d)](_0x2094c2))return this[_0x5b77b8(0x170)][_0x5b77b8(a18_0x5437e7._0x2899ad)](_0x2094c2);const _0x3c35ac=this['findOne']({'where':_0x16aa7d,..._0x2c301e})['then'](async _0x42d0ce=>{const _0x4318a8=_0x5b77b8;if(_0x42d0ce){let _0x5044fd=![];if(_0x122a21&&typeof _0x122a21==='object')for(const _0xccf6dc in _0x122a21){(_0xc5a7b9['fPLVz'](_0x42d0ce[_0xccf6dc],undefined)||String(_0x42d0ce[_0xccf6dc])!==String(_0x122a21[_0xccf6dc]))&&(_0x42d0ce[_0xccf6dc]=_0x122a21[_0xccf6dc],_0x5044fd=!![]);}if(_0x5044fd)await _0x42d0ce['saveAndUpdateCache']();else{const _0x39562b=[''+this[_0x4318a8(a18_0x235e18._0x54f44e)],this[_0x4318a8(0x172)]+':'+this['primaryKeyAttribute']+':'+_0x42d0ce[this['primaryKeyAttribute']]];await this[_0x4318a8(0x13e)](_0x2094c2,_0x42d0ce,undefined,_0x39562b);}return[_0x42d0ce,![]];}else{const _0x4fee0f={..._0x16aa7d,..._0x122a21},_0x29f7d6=await this['create'](_0x4fee0f),_0xa16f38=[''+this['name'],this[_0x4318a8(0x172)]+':'+this['primaryKeyAttribute']+':'+_0x29f7d6[this[_0x4318a8(0x152)]]];return await this[_0x4318a8(0x13e)](_0x2094c2,_0x29f7d6,undefined,_0xa16f38),[_0x29f7d6,!![]];}})[_0x5b77b8(a18_0x5437e7._0x37a585)](()=>{const _0x107b29=_0x5b77b8;this['pendingQueries'][_0x107b29(0x166)](_0x2094c2);});return this[_0x5b77b8(0x170)]['set'](_0x2094c2,_0x3c35ac),_0x3c35ac;}static async['countWithCache'](_0x87731c={},_0x57afb2=(0x1274*0x1+-0x481+-0xdee*0x1)*(-0x1d*-0x64+0x2224+-0x243*0x14)*(-0x8a2+-0xcb6+0x1940)){const a18_0x348572={_0x3c0652:0x15a,_0x1553e9:0x1e3,_0x51a474:0x15a,_0x168d42:0x1c5,_0x2fcd06:0x13e},_0x57122a=a18_0x5cf52a,{..._0x426c60}=_0x87731c||{},_0x6a81a3={'queryType':_0x57122a(a18_0x348572._0x3c0652),..._0x426c60},_0x6da95e=this['getCacheKey'](_0x6a81a3),_0x283dca=await this[_0x57122a(a18_0x348572._0x1553e9)](_0x6da95e);if(_0x283dca[_0x57122a(0x197)])return _0x283dca['data'];this['cacheStats']['misses']++;const _0x3d6d7a=await this[_0x57122a(a18_0x348572._0x51a474)](_0x426c60);if(this['isRedisConnected']||!this[_0x57122a(a18_0x348572._0x168d42)]){const _0x5e7535=[''+this['name']];this[_0x57122a(a18_0x348572._0x2fcd06)](_0x6da95e,_0x3d6d7a,_0x57afb2,_0x5e7535);}return _0x3d6d7a;}async[a18_0x5cf52a(0x16c)](){const a18_0xc8a94d={_0x563b75:0x1e0,_0x41a08b:0x1c5,_0x9feb5f:0x1a4,_0x567a4c:0x13e},_0x36a7f9=a18_0x5cf52a,_0x1c9c9e=await this[_0x36a7f9(a18_0xc8a94d._0x563b75)](),_0x3143c5=this['constructor']['primaryKeyAttribute'],_0x404ddf=this[_0x3143c5];if(_0x404ddf&&(this[_0x36a7f9(0x1eb)]['isRedisConnected']||!this['constructor'][_0x36a7f9(a18_0xc8a94d._0x41a08b)])){const _0x7dcc16=this[_0x36a7f9(0x1eb)][_0x36a7f9(a18_0xc8a94d._0x9feb5f)]({'where':{[_0x3143c5]:_0x404ddf}}),_0x102a21=[''+this['constructor'][_0x36a7f9(0x172)],this['constructor'][_0x36a7f9(0x172)]+':'+_0x3143c5+':'+_0x404ddf];await this['constructor'][_0x36a7f9(a18_0xc8a94d._0x567a4c)](_0x7dcc16,_0x1c9c9e,undefined,_0x102a21),this[_0x36a7f9(0x1eb)]['logger'][_0x36a7f9(0x1dd)](_0x36a7f9(0x1c8)+this[_0x36a7f9(0x1eb)][_0x36a7f9(0x172)]+':'+_0x3143c5+':'+_0x404ddf);}return _0x1c9c9e;}static async['clearNegativeCache'](_0x446bcc){const _0x471e54=a18_0x5cf52a;return this[_0x471e54(0x1ae)](_0x446bcc);}static async[a18_0x5cf52a(0x1c9)](_0x4a604={},_0x28f2b6={}){const a18_0x55c89d={_0x4f4e09:0x1e3,_0x9d3930:0x197,_0x4418d8:0x19e,_0x50adf4:0x195},_0x217cac=a18_0x5cf52a,{cacheTags:_0x140a32,..._0x4e71b1}=_0x4a604||{},{ttl:ttl=(0x5bc+-0x117*0x16+0x1243)*(-0x19ec+-0x10*-0x1ab+-0x88)*(0xea5*0x1+-0x45a*-0x2+0x3f*-0x4f)}=_0x28f2b6||{},_0x3556da={'queryType':_0x217cac(0x165),..._0x4e71b1},_0x59b760=this['getCacheKey'](_0x3556da),_0x499bea=await this[_0x217cac(a18_0x55c89d._0x4f4e09)](_0x59b760);if(_0x499bea[_0x217cac(a18_0x55c89d._0x9d3930)])return _0x499bea[_0x217cac(a18_0x55c89d._0x4418d8)];this['cacheStats'][_0x217cac(a18_0x55c89d._0x50adf4)]++;const _0x577e72=await this['findAll'](_0x4e71b1);if(this['isRedisConnected']||!this['isShardMode']){const _0x270382=[''+this['name']];if(Array['isArray'](_0x140a32))_0x270382['push'](..._0x140a32);this[_0x217cac(0x13e)](_0x59b760,_0x577e72,ttl,_0x270382);}return _0x577e72;}static['initializeCacheHooks'](){const a18_0x3d9a0b={_0x475194:0x1fa,_0x49ce06:0x1fa},a18_0x1cd1b4={_0x53b821:0x1d5},a18_0x2ecc40={_0x4672b6:0x168,_0x772878:0x1d4},a18_0x530a62={_0x3c5617:0x1eb,_0x3f0001:0x1d4,_0x448b56:0x1c5},_0x281ea4=a18_0x5cf52a,_0x5ef104={'cXShu':'afterSave','psfSZ':_0x281ea4(0x1e7),'AybgV':'afterBulkCreate','zUFqz':'afterBulkDestroy'};if(!this['redis']){this['logger'][_0x281ea4(0x1f6)]('❌\x20Redis\x20not\x20initialized\x20for\x20model\x20'+this[_0x281ea4(0x172)]+_0x281ea4(0x158));return;}const _0x8fbb85=async _0x5885c3=>{const _0x2ba154=_0x281ea4,_0x17a019=_0x5885c3[_0x2ba154(a18_0x530a62._0x3c5617)];if(_0x17a019[_0x2ba154(0x168)]){const _0x29ba62=_0x17a019['_generateSmartTags'](_0x5885c3);Array[_0x2ba154(0x192)](_0x17a019['customInvalidationTags'])&&_0x29ba62['push'](..._0x17a019[_0x2ba154(a18_0x530a62._0x3f0001)]),await _0x17a019[_0x2ba154(0x17e)](_0x29ba62);}else!_0x17a019[_0x2ba154(a18_0x530a62._0x448b56)]&&_0x17a019['_mapClearAllModelCache']();},_0x2a2ea5=async _0x3e455f=>{const _0x321be7=_0x281ea4,_0x520241=_0x3e455f['constructor'];if(_0x520241[_0x321be7(a18_0x2ecc40._0x4672b6)]){const _0x34555d=_0x520241['_generateSmartTags'](_0x3e455f);Array['isArray'](_0x520241['customInvalidationTags'])&&_0x34555d['push'](..._0x520241[_0x321be7(a18_0x2ecc40._0x772878)]),await _0x520241['invalidateByTags'](_0x34555d);}else!_0x520241['isShardMode']&&_0x520241[_0x321be7(0x1d5)]();},_0x5ee77b=async()=>{const _0x4688bf=_0x281ea4;if(this[_0x4688bf(0x168)])await this[_0x4688bf(0x17e)]([''+this[_0x4688bf(0x172)]]);else!this['isShardMode']&&this[_0x4688bf(a18_0x1cd1b4._0x53b821)]();};this['addHook'](_0x5ef104['cXShu'],_0x8fbb85),this['addHook'](_0x5ef104['psfSZ'],_0x2a2ea5),this[_0x281ea4(a18_0x3d9a0b._0x475194)](_0x5ef104[_0x281ea4(0x194)],_0x5ee77b),this[_0x281ea4(a18_0x3d9a0b._0x49ce06)]('afterBulkUpdate',_0x5ee77b),this[_0x281ea4(0x1fa)](_0x5ef104['zUFqz'],_0x5ee77b);}static['attachHooksToAllModels'](_0xe42222,_0x4d6dd7){const a18_0x19fe16={_0x2799d1:0x17c,_0x44f750:0x1f6,_0x1884dc:0x1c2,_0x167c95:0x20b},_0x47ea77=a18_0x5cf52a;if(!this['redis']){this[_0x47ea77(a18_0x19fe16._0x2799d1)][_0x47ea77(a18_0x19fe16._0x44f750)](_0x47ea77(a18_0x19fe16._0x1884dc));return;}for(const _0x2a6e55 in _0xe42222['models']){const _0x3269a9=_0xe42222[_0x47ea77(a18_0x19fe16._0x167c95)][_0x2a6e55];_0x3269a9['prototype']instanceof KythiaModel&&(_0x3269a9['client']=_0x4d6dd7,this[_0x47ea77(a18_0x19fe16._0x2799d1)]['info']('⚙️\x20\x20Attaching\x20hooks\x20to\x20'+_0x3269a9['name']),_0x3269a9['initializeCacheHooks']());}}static async[a18_0x5cf52a(0x1a1)](_0x4a3ead,_0xa9c7da,_0x3f11bd,_0x45ea0b='updatedAt'){const a18_0x413791={_0x103a05:0x152,_0x2cda6d:0x188,_0x110851:0x17c,_0x3493b7:0x172},_0x14f0dd=a18_0x5cf52a;if(!_0x4a3ead||!_0x4a3ead[_0xa9c7da])return;try{const _0x303c4a=_0x3f11bd[_0x14f0dd(a18_0x413791._0x103a05)],_0x383efa=await _0x3f11bd[_0x14f0dd(0x147)](_0x4a3ead[_0xa9c7da]);_0x383efa&&(_0x383efa[_0x14f0dd(a18_0x413791._0x2cda6d)](_0x45ea0b,!![]),await _0x383efa['save']({'fields':[_0x45ea0b]}),this[_0x14f0dd(a18_0x413791._0x110851)]['info']('🔄\x20Touched\x20parent\x20'+_0x3f11bd[_0x14f0dd(a18_0x413791._0x3493b7)]+'\x20#'+_0x383efa[_0x303c4a]+'\x20due\x20to\x20change\x20in\x20'+this[_0x14f0dd(0x172)]+'.'));}catch(_0x4153a1){this['logger']['error'](_0x14f0dd(0x1ba)+_0x3f11bd['name'],_0x4153a1);}}static['setupParentTouch'](_0x147b71,_0x91c4b1,_0x884953=a18_0x5cf52a(0x16f)){const a18_0x2a9646={_0x5f072c:0x16e,_0x1ecb00:0x1fa},a18_0x2c8d99={_0x3ce776:0x1e5,_0x375d5b:0x184},_0x1254c7=a18_0x5cf52a,_0x45e3c3={'kpVfN':_0x1254c7(a18_0x2a9646._0x5f072c)},_0x38c885=_0x3a99c7=>{return this['touchParent'](_0x3a99c7,_0x147b71,_0x91c4b1,_0x884953);},_0x117e37=_0x5f8553=>{const _0x584cbf=_0x1254c7;if(_0x5f8553&&_0x5f8553[_0x584cbf(a18_0x2c8d99._0x3ce776)]>0x1*-0x1eab+-0x19e1+0x4d*0xbc)return this['touchParent'](_0x5f8553[-0x95*0x1e+0x11*0x9b+0x72b],_0x147b71,_0x91c4b1,_0x884953);return Promise[_0x584cbf(a18_0x2c8d99._0x375d5b)]();};this[_0x1254c7(a18_0x2a9646._0x1ecb00)](_0x1254c7(0x1bd),_0x38c885),this['addHook']('afterDestroy',_0x38c885),this['addHook'](_0x45e3c3['kpVfN'],_0x117e37);}}exports[a18_0x5cf52a(0x20e)]=KythiaModel,exports['default']=KythiaModel;