@nest-omni/core 4.1.3-2 → 4.1.3-4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/audit/audit.module.d.ts +10 -0
- package/audit/audit.module.js +15 -0
- package/audit/controllers/audit.controller.d.ts +24 -0
- package/audit/controllers/audit.controller.js +24 -0
- package/audit/decorators/audit-controller.decorator.d.ts +8 -0
- package/audit/decorators/audit-controller.decorator.js +9 -0
- package/audit/decorators/audit-operation.decorator.d.ts +45 -0
- package/audit/decorators/audit-operation.decorator.js +49 -0
- package/audit/decorators/entity-audit.decorator.d.ts +8 -0
- package/audit/decorators/entity-audit.decorator.js +9 -0
- package/audit/dto/audit-log-query.dto.d.ts +3 -0
- package/audit/dto/audit-log-query.dto.js +3 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +3 -0
- package/audit/dto/compare-entities.dto.d.ts +3 -0
- package/audit/dto/compare-entities.dto.js +3 -0
- package/audit/dto/pre-check-restore.dto.d.ts +3 -0
- package/audit/dto/pre-check-restore.dto.js +3 -0
- package/audit/dto/restore-entity.dto.d.ts +3 -0
- package/audit/dto/restore-entity.dto.js +3 -0
- package/audit/entities/entity-audit-log.entity.d.ts +3 -0
- package/audit/entities/entity-audit-log.entity.js +3 -0
- package/audit/entities/entity-transaction.entity.d.ts +3 -0
- package/audit/entities/entity-transaction.entity.js +3 -0
- package/audit/entities/manual-operation-log.entity.d.ts +4 -0
- package/audit/entities/manual-operation-log.entity.js +4 -0
- package/audit/entities/operation-template.entity.d.ts +4 -0
- package/audit/entities/operation-template.entity.js +4 -0
- package/audit/enums/audit.enums.d.ts +17 -2
- package/audit/enums/audit.enums.js +15 -0
- package/audit/index.js +10 -0
- package/audit/interceptors/audit.interceptor.d.ts +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interfaces/audit.interfaces.d.ts +42 -0
- package/audit/services/audit-context.service.d.ts +15 -0
- package/audit/services/audit-context.service.js +15 -0
- package/audit/services/audit-strategy.service.d.ts +6 -0
- package/audit/services/audit-strategy.service.js +13 -0
- package/audit/services/entity-audit.service.d.ts +57 -0
- package/audit/services/entity-audit.service.js +91 -0
- package/audit/services/manual-audit-log.service.d.ts +124 -0
- package/audit/services/manual-audit-log.service.js +138 -0
- package/audit/services/multi-database.service.d.ts +12 -0
- package/audit/services/multi-database.service.js +12 -0
- package/audit/services/operation-description.service.d.ts +59 -0
- package/audit/services/operation-description.service.js +76 -2
- package/audit/services/transaction-audit.service.d.ts +30 -0
- package/audit/services/transaction-audit.service.js +47 -0
- package/audit/subscribers/entity-audit.subscriber.d.ts +15 -0
- package/audit/subscribers/entity-audit.subscriber.js +29 -1
- package/cache/cache-metrics.service.d.ts +67 -0
- package/cache/cache-metrics.service.js +68 -4
- package/cache/cache-serialization.service.d.ts +31 -0
- package/cache/cache-serialization.service.js +25 -0
- package/cache/cache.constants.d.ts +9 -0
- package/cache/cache.constants.js +9 -0
- package/cache/cache.health.d.ts +26 -0
- package/cache/cache.health.js +30 -0
- package/cache/cache.module.d.ts +86 -0
- package/cache/cache.module.js +71 -0
- package/cache/cache.service.d.ts +140 -0
- package/cache/cache.service.js +157 -0
- package/cache/cache.warmup.service.d.ts +39 -0
- package/cache/cache.warmup.service.js +32 -0
- package/cache/decorators/cache-evict.decorator.d.ts +47 -0
- package/cache/decorators/cache-evict.decorator.js +56 -0
- package/cache/decorators/cache-put.decorator.d.ts +34 -0
- package/cache/decorators/cache-put.decorator.js +39 -0
- package/cache/decorators/cacheable.decorator.d.ts +40 -0
- package/cache/decorators/cacheable.decorator.js +55 -0
- package/cache/dependencies/callback.dependency.d.ts +33 -0
- package/cache/dependencies/callback.dependency.js +39 -1
- package/cache/dependencies/chain.dependency.d.ts +28 -0
- package/cache/dependencies/chain.dependency.js +34 -0
- package/cache/dependencies/db.dependency.d.ts +45 -0
- package/cache/dependencies/db.dependency.js +48 -1
- package/cache/dependencies/file.dependency.d.ts +32 -0
- package/cache/dependencies/file.dependency.js +34 -0
- package/cache/dependencies/tag.dependency.d.ts +36 -0
- package/cache/dependencies/tag.dependency.js +36 -0
- package/cache/dependencies/time.dependency.d.ts +43 -0
- package/cache/dependencies/time.dependency.js +43 -0
- package/cache/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.js +9 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +81 -0
- package/cache/interfaces/cache-options.interface.js +6 -0
- package/cache/interfaces/cache-provider.interface.d.ts +78 -0
- package/cache/providers/base-cache.provider.d.ts +14 -0
- package/cache/providers/base-cache.provider.js +16 -0
- package/cache/providers/cls-cache.provider.d.ts +20 -0
- package/cache/providers/cls-cache.provider.js +28 -0
- package/cache/providers/memory-cache.provider.d.ts +23 -0
- package/cache/providers/memory-cache.provider.js +26 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/utils/dependency-manager.util.d.ts +52 -0
- package/cache/utils/dependency-manager.util.js +59 -0
- package/cache/utils/key-generator.util.d.ts +42 -0
- package/cache/utils/key-generator.util.js +53 -1
- package/common/abstract.entity.d.ts +14 -0
- package/common/abstract.entity.js +14 -0
- package/common/boilerplate.polyfill.d.ts +142 -0
- package/common/boilerplate.polyfill.js +17 -0
- package/common/dto/dto-container.d.ts +16 -0
- package/common/dto/dto-container.js +20 -0
- package/common/dto/dto-decorators.d.ts +18 -0
- package/common/dto/dto-decorators.js +14 -0
- package/common/dto/dto-extensions.d.ts +11 -0
- package/common/dto/dto-extensions.js +9 -0
- package/common/dto/dto-service-accessor.d.ts +17 -0
- package/common/dto/dto-service-accessor.js +18 -0
- package/common/dto/dto-transformer.d.ts +12 -0
- package/common/dto/dto-transformer.js +9 -0
- package/common/dto/index.js +2 -0
- package/common/examples/paginate-and-map.example.d.ts +6 -0
- package/common/examples/paginate-and-map.example.js +26 -0
- package/common/utils.d.ts +15 -0
- package/common/utils.js +15 -0
- package/constants/language-code.js +1 -0
- package/decorators/field.decorators.js +8 -1
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -0
- package/decorators/transform.decorators.js +29 -0
- package/decorators/translate.decorator.js +1 -0
- package/decorators/user.decorator.js +1 -0
- package/decorators/validator.decorators.d.ts +8 -18
- package/decorators/validator.decorators.js +22 -190
- package/filters/constraint-errors.js +1 -0
- package/helpers/common.helper.d.ts +13 -0
- package/helpers/common.helper.js +13 -0
- package/http-client/config/http-client.config.d.ts +15 -0
- package/http-client/config/http-client.config.js +25 -9
- package/http-client/decorators/http-client.decorators.d.ts +63 -0
- package/http-client/decorators/http-client.decorators.js +71 -3
- package/http-client/entities/http-log.entity.d.ts +229 -0
- package/http-client/entities/http-log.entity.js +6 -1
- package/http-client/errors/http-client.errors.d.ts +57 -0
- package/http-client/errors/http-client.errors.js +58 -0
- package/http-client/examples/advanced-usage.example.d.ts +41 -0
- package/http-client/examples/advanced-usage.example.js +68 -24
- package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
- package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
- package/http-client/examples/basic-usage.example.d.ts +60 -0
- package/http-client/examples/basic-usage.example.js +60 -0
- package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
- package/http-client/examples/multi-api-configuration.example.js +76 -5
- package/http-client/http-client.module.d.ts +13 -0
- package/http-client/http-client.module.js +19 -0
- package/http-client/index.js +8 -0
- package/http-client/interfaces/api-client-config.interface.d.ts +125 -0
- package/http-client/interfaces/api-client-config.interface.js +3 -0
- package/http-client/interfaces/http-client-config.interface.d.ts +60 -0
- package/http-client/services/api-client-registry.service.d.ts +57 -0
- package/http-client/services/api-client-registry.service.js +84 -1
- package/http-client/services/cache.service.d.ts +52 -0
- package/http-client/services/cache.service.js +72 -3
- package/http-client/services/circuit-breaker.service.d.ts +46 -0
- package/http-client/services/circuit-breaker.service.js +52 -0
- package/http-client/services/http-client.service.d.ts +67 -0
- package/http-client/services/http-client.service.js +105 -4
- package/http-client/services/http-log-query.service.d.ts +83 -0
- package/http-client/services/http-log-query.service.js +122 -1
- package/http-client/services/http-replay.service.d.ts +101 -0
- package/http-client/services/http-replay.service.js +86 -0
- package/http-client/services/log-cleanup.service.d.ts +63 -0
- package/http-client/services/log-cleanup.service.js +54 -2
- package/http-client/services/logging.service.d.ts +40 -0
- package/http-client/services/logging.service.js +53 -0
- package/http-client/utils/call-stack-extractor.util.d.ts +37 -0
- package/http-client/utils/call-stack-extractor.util.js +48 -0
- package/http-client/utils/context-extractor.util.d.ts +49 -0
- package/http-client/utils/context-extractor.util.js +52 -0
- package/http-client/utils/curl-generator.util.d.ts +21 -0
- package/http-client/utils/curl-generator.util.js +44 -3
- package/http-client/utils/request-id.util.d.ts +18 -0
- package/http-client/utils/request-id.util.js +20 -0
- package/http-client/utils/retry-recorder.util.d.ts +42 -0
- package/http-client/utils/retry-recorder.util.js +44 -0
- package/index.js +8 -0
- package/interceptors/translation-interceptor.service.js +5 -0
- package/package.json +1 -1
- package/providers/context.provider.js +2 -0
- package/providers/generator.provider.d.ts +4 -0
- package/providers/generator.provider.js +4 -0
- package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
- package/redis-lock/examples/lock-strategy.examples.js +130 -15
- package/redis-lock/index.js +3 -0
- package/redis-lock/redis-lock.decorator.d.ts +101 -0
- package/redis-lock/redis-lock.decorator.js +120 -0
- package/redis-lock/redis-lock.module.d.ts +60 -0
- package/redis-lock/redis-lock.module.js +46 -0
- package/redis-lock/redis-lock.service.d.ts +251 -0
- package/redis-lock/redis-lock.service.js +219 -3
- package/setup/bootstrap.setup.js +20 -0
- package/setup/mode.setup.d.ts +44 -0
- package/setup/mode.setup.js +44 -0
- package/setup/schedule.decorator.d.ts +226 -0
- package/setup/schedule.decorator.js +214 -1
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +88 -0
- package/shared/serviceRegistryModule.js +5 -1
- package/shared/services/api-config.service.d.ts +3 -0
- package/shared/services/api-config.service.js +20 -9
- package/validator-json/decorators.d.ts +17 -0
- package/validator-json/decorators.js +17 -2
- package/validator-json/default.d.ts +6 -0
- package/validator-json/default.js +30 -2
- package/validator-json/defaultConverters.js +1 -0
- package/validator-json/options.d.ts +23 -0
- package/validators/common-validators.d.ts +143 -0
- package/validators/common-validators.js +249 -0
- package/validators/custom-validate.examples.d.ts +23 -0
- package/validators/custom-validate.examples.js +78 -6
- package/validators/custom-validate.validator.d.ts +107 -0
- package/validators/custom-validate.validator.js +84 -0
- package/validators/index.d.ts +1 -0
- package/validators/index.js +1 -0
- package/validators/is-exists.validator.d.ts +11 -0
- package/validators/is-exists.validator.js +22 -0
- package/validators/is-unique.validator.d.ts +11 -0
- package/validators/is-unique.validator.js +31 -3
- package/validators/skip-empty.validator.d.ts +5 -0
- package/validators/skip-empty.validator.js +5 -0
- package/vault/interfaces/vault-options.interface.d.ts +9 -0
- package/vault/vault-config.loader.d.ts +30 -0
- package/vault/vault-config.loader.js +48 -1
- package/vault/vault-config.service.d.ts +53 -0
- package/vault/vault-config.service.js +57 -0
- package/vault/vault.module.d.ts +4 -0
- package/vault/vault.module.js +4 -0
- package/decorators/examples/validation-decorators.example.d.ts +0 -69
- package/decorators/examples/validation-decorators.example.js +0 -331
|
@@ -17,14 +17,47 @@ exports.UseRedisLockSmart = UseRedisLockSmart;
|
|
|
17
17
|
exports.UseRedisLockOrSkipSmart = UseRedisLockOrSkipSmart;
|
|
18
18
|
const common_1 = require("@nestjs/common");
|
|
19
19
|
const redis_lock_service_1 = require("./redis-lock.service");
|
|
20
|
+
/**
|
|
21
|
+
* Global LockService instance holder
|
|
22
|
+
* Will be set by RedisLockModule during initialization
|
|
23
|
+
*/
|
|
20
24
|
let globalLockService = null;
|
|
25
|
+
/**
|
|
26
|
+
* Set global LockService instance
|
|
27
|
+
* Called by RedisLockModule during initialization
|
|
28
|
+
*/
|
|
21
29
|
function setLockService(lockService) {
|
|
22
30
|
globalLockService = lockService;
|
|
31
|
+
// Also set the global instance in the service for backward compatibility
|
|
23
32
|
redis_lock_service_1.RedisLockService.setGlobalInstance(lockService);
|
|
24
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Get global LockService instance
|
|
36
|
+
*/
|
|
25
37
|
function getLockService() {
|
|
26
38
|
return globalLockService;
|
|
27
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Method decorator that wraps the method execution with a distributed Redis lock
|
|
42
|
+
*
|
|
43
|
+
* This decorator automatically acquires a lock before executing the method
|
|
44
|
+
* and releases it afterwards. If the lock cannot be acquired, the method
|
|
45
|
+
* execution is skipped and returns null (or the value specified in skipReturnValue).
|
|
46
|
+
*
|
|
47
|
+
* @param lockKey - The Redis lock key (required)
|
|
48
|
+
* @param options - Lock options
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* @Injectable()
|
|
53
|
+
* class MyService {
|
|
54
|
+
* @UseRedisLock('my-task', { ttl: 60000 })
|
|
55
|
+
* async processTask() {
|
|
56
|
+
* // This will only execute if the lock is acquired
|
|
57
|
+
* }
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
28
61
|
function UseRedisLock(lockKey, options = {}) {
|
|
29
62
|
return function (target, propertyKey, descriptor) {
|
|
30
63
|
const originalMethod = descriptor.value;
|
|
@@ -32,8 +65,11 @@ function UseRedisLock(lockKey, options = {}) {
|
|
|
32
65
|
descriptor.value = function (...args) {
|
|
33
66
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
67
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
68
|
+
// Try to get the injected lock service first
|
|
35
69
|
let lockService = getLockService();
|
|
70
|
+
// If no injected service, fall back to global instance
|
|
36
71
|
if (!lockService) {
|
|
72
|
+
// Import the service class to get global instance
|
|
37
73
|
const { RedisLockService } = yield Promise.resolve().then(() => require('./redis-lock.service'));
|
|
38
74
|
lockService = RedisLockService.getGlobalInstance();
|
|
39
75
|
if (!lockService) {
|
|
@@ -43,6 +79,7 @@ function UseRedisLock(lockKey, options = {}) {
|
|
|
43
79
|
}
|
|
44
80
|
const skipReturnValue = (_b = options.skipReturnValue) !== null && _b !== void 0 ? _b : null;
|
|
45
81
|
try {
|
|
82
|
+
// Try to acquire the lock
|
|
46
83
|
const lockResult = yield lockService.acquireLock(lockKey, options);
|
|
47
84
|
if (!lockResult.acquired) {
|
|
48
85
|
logger.log(`Lock '${lockKey}' is already held, skipping execution of ${String(propertyKey)}`);
|
|
@@ -50,6 +87,7 @@ function UseRedisLock(lockKey, options = {}) {
|
|
|
50
87
|
}
|
|
51
88
|
logger.debug(`Lock '${lockKey}' acquired, executing ${String(propertyKey)}`);
|
|
52
89
|
try {
|
|
90
|
+
// Execute the original method
|
|
53
91
|
return yield originalMethod.apply(this, args);
|
|
54
92
|
}
|
|
55
93
|
catch (error) {
|
|
@@ -57,19 +95,23 @@ function UseRedisLock(lockKey, options = {}) {
|
|
|
57
95
|
throw error;
|
|
58
96
|
}
|
|
59
97
|
finally {
|
|
98
|
+
// Clear auto-extension timer if it exists
|
|
60
99
|
if (lockResult.autoExtendTimer) {
|
|
61
100
|
clearInterval(lockResult.autoExtendTimer);
|
|
62
101
|
}
|
|
102
|
+
// Always release the lock
|
|
63
103
|
yield lockService.releaseLock(lockKey, lockResult.lockValue, options.keyPrefix);
|
|
64
104
|
logger.debug(`Lock '${lockKey}' released`);
|
|
65
105
|
}
|
|
66
106
|
}
|
|
67
107
|
catch (error) {
|
|
108
|
+
// Handle Redis client not configured errors gracefully
|
|
68
109
|
if ((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('requires a Redis client to be set')) {
|
|
69
110
|
logger.error(`Redis client not configured for RedisLock in ${lockKey}: ${error.message}. ` +
|
|
70
111
|
`Skipping execution to prevent issues.`);
|
|
71
112
|
return skipReturnValue;
|
|
72
113
|
}
|
|
114
|
+
// Handle Redis connection errors gracefully
|
|
73
115
|
if (((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('ECONNREFUSED')) ||
|
|
74
116
|
((_e = error.message) === null || _e === void 0 ? void 0 : _e.includes('ECONNRESET')) ||
|
|
75
117
|
((_f = error.message) === null || _f === void 0 ? void 0 : _f.includes('ETIMEDOUT')) ||
|
|
@@ -82,6 +124,7 @@ function UseRedisLock(lockKey, options = {}) {
|
|
|
82
124
|
`Skipping execution to prevent issues.`);
|
|
83
125
|
return skipReturnValue;
|
|
84
126
|
}
|
|
127
|
+
// Handle Redis server errors (e.g., Redis crashed or restarted)
|
|
85
128
|
if (((_j = error.message) === null || _j === void 0 ? void 0 : _j.includes('READONLY')) ||
|
|
86
129
|
((_k = error.message) === null || _k === void 0 ? void 0 : _k.includes('LOADING')) ||
|
|
87
130
|
((_l = error.message) === null || _l === void 0 ? void 0 : _l.includes('MASTERDOWN')) ||
|
|
@@ -90,11 +133,13 @@ function UseRedisLock(lockKey, options = {}) {
|
|
|
90
133
|
`Skipping execution to prevent issues.`);
|
|
91
134
|
return skipReturnValue;
|
|
92
135
|
}
|
|
136
|
+
// Handle network errors
|
|
93
137
|
if (((_o = error.message) === null || _o === void 0 ? void 0 : _o.includes('getaddrinfo')) || error.code === 'EAI_AGAIN') {
|
|
94
138
|
logger.error(`Network error connecting to Redis in ${lockKey}: ${error.message}. ` +
|
|
95
139
|
`Skipping execution to prevent issues.`);
|
|
96
140
|
return skipReturnValue;
|
|
97
141
|
}
|
|
142
|
+
// For any other errors, log and rethrow
|
|
98
143
|
logger.error(`Unexpected error in RedisLock for ${lockKey}: ${error.message}`, error.stack);
|
|
99
144
|
throw error;
|
|
100
145
|
}
|
|
@@ -103,20 +148,95 @@ function UseRedisLock(lockKey, options = {}) {
|
|
|
103
148
|
return descriptor;
|
|
104
149
|
};
|
|
105
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Simplified decorator for methods that should skip execution if lock cannot be acquired
|
|
153
|
+
* Returns false when skipped, true when executed successfully
|
|
154
|
+
*
|
|
155
|
+
* @param lockKey - The Redis lock key (required)
|
|
156
|
+
* @param ttl - Lock TTL in milliseconds (default: 300000 / 5 minutes)
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* @Injectable()
|
|
161
|
+
* class MyScheduler {
|
|
162
|
+
* @Cron('0 * * * *')
|
|
163
|
+
* @UseRedisLockOrSkip('hourly-task', 3600000)
|
|
164
|
+
* async hourlyTask() {
|
|
165
|
+
* // This will only execute on one instance
|
|
166
|
+
* }
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
106
170
|
function UseRedisLockOrSkip(lockKey, ttl = 300000) {
|
|
107
171
|
return UseRedisLock(lockKey, {
|
|
108
172
|
ttl,
|
|
109
173
|
skipReturnValue: false,
|
|
110
174
|
});
|
|
111
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Smart decorator that auto-generates lock key from class and method name
|
|
178
|
+
* Lock key format: ClassName:methodName
|
|
179
|
+
*
|
|
180
|
+
* This decorator is useful for simple cases where you don't need custom lock keys.
|
|
181
|
+
*
|
|
182
|
+
* @param options - Lock options
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* @Injectable()
|
|
187
|
+
* class MyService {
|
|
188
|
+
* // Lock key will be auto-generated as "MyService:processData"
|
|
189
|
+
* @UseRedisLockSmart({ ttl: 60000 })
|
|
190
|
+
* async processData() {
|
|
191
|
+
* // Business logic
|
|
192
|
+
* }
|
|
193
|
+
*
|
|
194
|
+
* // With strategy
|
|
195
|
+
* @UseRedisLockSmart({
|
|
196
|
+
* ttl: 120000,
|
|
197
|
+
* strategy: LockStrategy.WAIT,
|
|
198
|
+
* waitTimeout: 60000,
|
|
199
|
+
* })
|
|
200
|
+
* async generateReport() {
|
|
201
|
+
* // Business logic
|
|
202
|
+
* }
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
112
206
|
function UseRedisLockSmart(options = {}) {
|
|
113
207
|
return function (target, propertyKey, descriptor) {
|
|
208
|
+
// Auto-generate lock key from class and method name
|
|
114
209
|
const className = target.constructor.name;
|
|
115
210
|
const methodName = String(propertyKey);
|
|
116
211
|
const lockKey = `${className}:${methodName}`;
|
|
212
|
+
// Apply the original UseRedisLock decorator with auto-generated key
|
|
117
213
|
return UseRedisLock(lockKey, options)(target, propertyKey, descriptor);
|
|
118
214
|
};
|
|
119
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Smart decorator for simple skip-on-busy scenarios with auto-generated lock key
|
|
218
|
+
* Lock key format: ClassName:methodName
|
|
219
|
+
*
|
|
220
|
+
* @param ttl - Lock TTL in milliseconds (default: 300000 / 5 minutes)
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* @Injectable()
|
|
225
|
+
* class MyScheduler {
|
|
226
|
+
* @Cron('0 * * * *')
|
|
227
|
+
* @UseRedisLockOrSkipSmart(3600000) // 1 hour TTL
|
|
228
|
+
* async hourlyTask() {
|
|
229
|
+
* // Lock key: "MyScheduler:hourlyTask"
|
|
230
|
+
* }
|
|
231
|
+
*
|
|
232
|
+
* @Cron('0 0 * * *')
|
|
233
|
+
* @UseRedisLockOrSkipSmart() // Default 5 minutes TTL
|
|
234
|
+
* async dailyTask() {
|
|
235
|
+
* // Lock key: "MyScheduler:dailyTask"
|
|
236
|
+
* }
|
|
237
|
+
* }
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
120
240
|
function UseRedisLockOrSkipSmart(ttl = 300000) {
|
|
121
241
|
return UseRedisLockSmart({
|
|
122
242
|
ttl,
|
|
@@ -1,18 +1,78 @@
|
|
|
1
1
|
import { DynamicModule, OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import type { Redis } from 'ioredis';
|
|
3
|
+
/**
|
|
4
|
+
* Injection token for Redis Lock Service
|
|
5
|
+
*/
|
|
3
6
|
export declare const REDIS_LOCK_SERVICE: unique symbol;
|
|
7
|
+
/**
|
|
8
|
+
* Redis Lock module configuration options
|
|
9
|
+
*/
|
|
4
10
|
export interface RedisLockModuleOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Whether to make the module global
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
5
15
|
isGlobal?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Redis client instance (required)
|
|
18
|
+
* RedisLockService requires an external Redis client to function
|
|
19
|
+
*/
|
|
6
20
|
redisClient: Redis;
|
|
21
|
+
/**
|
|
22
|
+
* Default TTL for locks in milliseconds
|
|
23
|
+
*/
|
|
7
24
|
defaultTtl?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Default key prefix for locks
|
|
27
|
+
*/
|
|
8
28
|
defaultKeyPrefix?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Default retry count for lock acquisition
|
|
31
|
+
*/
|
|
9
32
|
defaultRetryCount?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Default retry delay in milliseconds
|
|
35
|
+
*/
|
|
10
36
|
defaultRetryDelay?: number;
|
|
11
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Redis Lock module with distributed locking support
|
|
40
|
+
*
|
|
41
|
+
* Provides RedisLockService and @UseRedisLock decorator for
|
|
42
|
+
* distributed locking mechanisms using Redis.
|
|
43
|
+
*
|
|
44
|
+
* Requires an external Redis client to function.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* // With Redis client injection
|
|
49
|
+
* import { RedisModule } from '@songkeys/nestjs-redis';
|
|
50
|
+
*
|
|
51
|
+
* @Module({
|
|
52
|
+
* imports: [
|
|
53
|
+
* RedisModule.forRoot({ ... }),
|
|
54
|
+
* RedisLockModule.forRootAsync({
|
|
55
|
+
* imports: [RedisModule],
|
|
56
|
+
* inject: [RedisService],
|
|
57
|
+
* useFactory: (redisService: RedisService) => ({
|
|
58
|
+
* redisClient: redisService.getClient()
|
|
59
|
+
* })
|
|
60
|
+
* })
|
|
61
|
+
* ]
|
|
62
|
+
* })
|
|
63
|
+
* export class AppModule {}
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
12
66
|
export declare class RedisLockModule implements OnModuleInit {
|
|
13
67
|
private redisLockService;
|
|
14
68
|
constructor();
|
|
69
|
+
/**
|
|
70
|
+
* Register Redis Lock module with options
|
|
71
|
+
*/
|
|
15
72
|
static forRoot(options: RedisLockModuleOptions): DynamicModule;
|
|
73
|
+
/**
|
|
74
|
+
* Register Redis Lock module asynchronously
|
|
75
|
+
*/
|
|
16
76
|
static forRootAsync(options: {
|
|
17
77
|
imports?: any[];
|
|
18
78
|
inject?: any[];
|
|
@@ -14,19 +14,55 @@ exports.RedisLockModule = exports.REDIS_LOCK_SERVICE = void 0;
|
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const redis_lock_service_1 = require("./redis-lock.service");
|
|
16
16
|
const redis_lock_decorator_1 = require("./redis-lock.decorator");
|
|
17
|
+
/**
|
|
18
|
+
* Injection token for Redis Lock Service
|
|
19
|
+
*/
|
|
17
20
|
exports.REDIS_LOCK_SERVICE = Symbol('REDIS_LOCK_SERVICE');
|
|
21
|
+
/**
|
|
22
|
+
* Redis Lock module with distributed locking support
|
|
23
|
+
*
|
|
24
|
+
* Provides RedisLockService and @UseRedisLock decorator for
|
|
25
|
+
* distributed locking mechanisms using Redis.
|
|
26
|
+
*
|
|
27
|
+
* Requires an external Redis client to function.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // With Redis client injection
|
|
32
|
+
* import { RedisModule } from '@songkeys/nestjs-redis';
|
|
33
|
+
*
|
|
34
|
+
* @Module({
|
|
35
|
+
* imports: [
|
|
36
|
+
* RedisModule.forRoot({ ... }),
|
|
37
|
+
* RedisLockModule.forRootAsync({
|
|
38
|
+
* imports: [RedisModule],
|
|
39
|
+
* inject: [RedisService],
|
|
40
|
+
* useFactory: (redisService: RedisService) => ({
|
|
41
|
+
* redisClient: redisService.getClient()
|
|
42
|
+
* })
|
|
43
|
+
* })
|
|
44
|
+
* ]
|
|
45
|
+
* })
|
|
46
|
+
* export class AppModule {}
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
18
49
|
let RedisLockModule = RedisLockModule_1 = class RedisLockModule {
|
|
19
50
|
constructor() { }
|
|
51
|
+
/**
|
|
52
|
+
* Register Redis Lock module with options
|
|
53
|
+
*/
|
|
20
54
|
static forRoot(options) {
|
|
21
55
|
const { isGlobal = true, redisClient, defaultTtl, defaultKeyPrefix, defaultRetryCount, defaultRetryDelay, } = options;
|
|
22
56
|
return {
|
|
23
57
|
module: RedisLockModule_1,
|
|
24
58
|
global: isGlobal,
|
|
25
59
|
providers: [
|
|
60
|
+
// Redis client provider
|
|
26
61
|
{
|
|
27
62
|
provide: 'REDIS_LOCK_CLIENT',
|
|
28
63
|
useValue: redisClient,
|
|
29
64
|
},
|
|
65
|
+
// Redis Lock Service
|
|
30
66
|
{
|
|
31
67
|
provide: exports.REDIS_LOCK_SERVICE,
|
|
32
68
|
useFactory: () => {
|
|
@@ -47,6 +83,7 @@ let RedisLockModule = RedisLockModule_1 = class RedisLockModule {
|
|
|
47
83
|
return service;
|
|
48
84
|
},
|
|
49
85
|
},
|
|
86
|
+
// Also provide the service class itself for direct injection
|
|
50
87
|
{
|
|
51
88
|
provide: redis_lock_service_1.RedisLockService,
|
|
52
89
|
useExisting: exports.REDIS_LOCK_SERVICE,
|
|
@@ -55,6 +92,9 @@ let RedisLockModule = RedisLockModule_1 = class RedisLockModule {
|
|
|
55
92
|
exports: [exports.REDIS_LOCK_SERVICE, redis_lock_service_1.RedisLockService],
|
|
56
93
|
};
|
|
57
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Register Redis Lock module asynchronously
|
|
97
|
+
*/
|
|
58
98
|
static forRootAsync(options) {
|
|
59
99
|
var _a;
|
|
60
100
|
return {
|
|
@@ -62,16 +102,19 @@ let RedisLockModule = RedisLockModule_1 = class RedisLockModule {
|
|
|
62
102
|
global: (_a = options.isGlobal) !== null && _a !== void 0 ? _a : true,
|
|
63
103
|
imports: options.imports || [],
|
|
64
104
|
providers: [
|
|
105
|
+
// Async options provider
|
|
65
106
|
{
|
|
66
107
|
provide: 'REDIS_LOCK_MODULE_OPTIONS',
|
|
67
108
|
useFactory: options.useFactory,
|
|
68
109
|
inject: options.inject || [],
|
|
69
110
|
},
|
|
111
|
+
// Redis client provider
|
|
70
112
|
{
|
|
71
113
|
provide: 'REDIS_LOCK_CLIENT',
|
|
72
114
|
useFactory: (moduleOptions) => moduleOptions.redisClient,
|
|
73
115
|
inject: ['REDIS_LOCK_MODULE_OPTIONS'],
|
|
74
116
|
},
|
|
117
|
+
// Redis Lock Service
|
|
75
118
|
{
|
|
76
119
|
provide: exports.REDIS_LOCK_SERVICE,
|
|
77
120
|
useFactory: (moduleOptions) => {
|
|
@@ -93,6 +136,7 @@ let RedisLockModule = RedisLockModule_1 = class RedisLockModule {
|
|
|
93
136
|
},
|
|
94
137
|
inject: ['REDIS_LOCK_MODULE_OPTIONS'],
|
|
95
138
|
},
|
|
139
|
+
// Also provide the service class itself for direct injection
|
|
96
140
|
{
|
|
97
141
|
provide: redis_lock_service_1.RedisLockService,
|
|
98
142
|
useExisting: exports.REDIS_LOCK_SERVICE,
|
|
@@ -102,6 +146,8 @@ let RedisLockModule = RedisLockModule_1 = class RedisLockModule {
|
|
|
102
146
|
};
|
|
103
147
|
}
|
|
104
148
|
onModuleInit() {
|
|
149
|
+
// Set global lock service for decorators
|
|
150
|
+
// Use the global instance that should have been created during module setup
|
|
105
151
|
const globalInstance = redis_lock_service_1.RedisLockService.getGlobalInstance();
|
|
106
152
|
if (globalInstance) {
|
|
107
153
|
this.redisLockService = globalInstance;
|