@nest-omni/core 4.1.3-1 → 4.1.3-11
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 +39 -1
- 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 +9 -1
- package/audit/decorators/audit-controller.decorator.js +11 -2
- 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 +76 -1
- package/audit/decorators/entity-audit.decorator.js +135 -3
- package/audit/decorators/index.d.ts +1 -0
- package/audit/decorators/index.js +1 -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 +8 -0
- package/audit/entities/entity-audit-log.entity.js +33 -1
- package/audit/entities/entity-transaction.entity.d.ts +10 -0
- package/audit/entities/entity-transaction.entity.js +33 -1
- package/audit/entities/index.d.ts +2 -0
- package/audit/entities/index.js +2 -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 +45 -5
- package/audit/enums/audit.enums.js +47 -4
- package/audit/index.d.ts +3 -1
- package/audit/index.js +30 -1
- package/audit/interceptors/audit.interceptor.d.ts +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interfaces/audit.interfaces.d.ts +182 -2
- 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 +129 -3
- package/audit/services/entity-audit.service.js +301 -6
- package/audit/services/index.d.ts +2 -0
- package/audit/services/index.js +2 -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 -4
- package/common/boilerplate.polyfill.js +24 -100
- 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 +20 -5
- 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/i18n/en_US/validation.json +2 -1
- package/i18n/zh_CN/validation.json +2 -1
- 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/comprehensive-lock-cleanup.service.d.ts +94 -0
- package/redis-lock/comprehensive-lock-cleanup.service.js +253 -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.d.ts +2 -0
- package/redis-lock/index.js +8 -1
- package/redis-lock/lock-heartbeat.service.d.ts +78 -0
- package/redis-lock/lock-heartbeat.service.js +222 -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 +66 -0
- package/redis-lock/redis-lock.module.js +175 -70
- package/redis-lock/redis-lock.service.d.ts +278 -0
- package/redis-lock/redis-lock.service.js +282 -12
- 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 +227 -0
- package/setup/schedule.decorator.js +235 -12
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +88 -0
- package/shared/serviceRegistryModule.js +27 -14
- 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 +96 -0
- package/validators/custom-validate.examples.js +400 -0
- package/validators/custom-validate.validator.d.ts +134 -0
- package/validators/custom-validate.validator.js +214 -0
- package/validators/index.d.ts +2 -0
- package/validators/index.js +2 -0
- package/validators/is-exists.validator.d.ts +18 -4
- package/validators/is-exists.validator.js +67 -6
- package/validators/is-unique.validator.d.ts +32 -5
- package/validators/is-unique.validator.js +99 -17
- 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
|
@@ -1,2 +1,36 @@
|
|
|
1
1
|
import type { CachePutOptions } from '../interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* @CachePut decorator - Update cache with method result
|
|
4
|
+
*
|
|
5
|
+
* This decorator always executes the method and updates the cache with the result.
|
|
6
|
+
* Unlike @Cacheable which skips method execution if cache exists, @CachePut
|
|
7
|
+
* always runs the method and updates cache afterwards.
|
|
8
|
+
*
|
|
9
|
+
* Useful for update operations where you want to refresh the cache.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Cache put options
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* class UserService {
|
|
16
|
+
* @CachePut({
|
|
17
|
+
* key: (id) => `user:${id}`,
|
|
18
|
+
* ttl: 300_000
|
|
19
|
+
* })
|
|
20
|
+
* async updateUser(id: string, data: UpdateUserDto) {
|
|
21
|
+
* await this.repo.update(id, data);
|
|
22
|
+
* return await this.repo.findOne({ where: { id } });
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* // Conditional cache update
|
|
26
|
+
* @CachePut({
|
|
27
|
+
* key: (id) => `user:${id}`,
|
|
28
|
+
* condition: (id, data) => data.important === true
|
|
29
|
+
* })
|
|
30
|
+
* async updateUserProfile(id: string, data: any) {
|
|
31
|
+
* return await this.repo.update(id, data);
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
2
36
|
export declare function CachePut(options?: CachePutOptions): MethodDecorator;
|
|
@@ -13,6 +13,40 @@ exports.CachePut = CachePut;
|
|
|
13
13
|
const common_1 = require("@nestjs/common");
|
|
14
14
|
const utils_1 = require("../utils");
|
|
15
15
|
const cacheable_decorator_1 = require("./cacheable.decorator");
|
|
16
|
+
/**
|
|
17
|
+
* @CachePut decorator - Update cache with method result
|
|
18
|
+
*
|
|
19
|
+
* This decorator always executes the method and updates the cache with the result.
|
|
20
|
+
* Unlike @Cacheable which skips method execution if cache exists, @CachePut
|
|
21
|
+
* always runs the method and updates cache afterwards.
|
|
22
|
+
*
|
|
23
|
+
* Useful for update operations where you want to refresh the cache.
|
|
24
|
+
*
|
|
25
|
+
* @param options - Cache put options
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* class UserService {
|
|
30
|
+
* @CachePut({
|
|
31
|
+
* key: (id) => `user:${id}`,
|
|
32
|
+
* ttl: 300_000
|
|
33
|
+
* })
|
|
34
|
+
* async updateUser(id: string, data: UpdateUserDto) {
|
|
35
|
+
* await this.repo.update(id, data);
|
|
36
|
+
* return await this.repo.findOne({ where: { id } });
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* // Conditional cache update
|
|
40
|
+
* @CachePut({
|
|
41
|
+
* key: (id) => `user:${id}`,
|
|
42
|
+
* condition: (id, data) => data.important === true
|
|
43
|
+
* })
|
|
44
|
+
* async updateUserProfile(id: string, data: any) {
|
|
45
|
+
* return await this.repo.update(id, data);
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
16
50
|
function CachePut(options = {}) {
|
|
17
51
|
const logger = new common_1.Logger('CachePutDecorator');
|
|
18
52
|
return function (target, propertyKey, descriptor) {
|
|
@@ -26,19 +60,24 @@ function CachePut(options = {}) {
|
|
|
26
60
|
return originalMethod.apply(this, args);
|
|
27
61
|
}
|
|
28
62
|
try {
|
|
63
|
+
// Always execute the original method
|
|
29
64
|
const result = yield originalMethod.apply(this, args);
|
|
65
|
+
// Check condition
|
|
30
66
|
if (options.condition) {
|
|
31
67
|
const shouldCache = yield Promise.resolve(options.condition(...args));
|
|
32
68
|
if (!shouldCache) {
|
|
33
69
|
return result;
|
|
34
70
|
}
|
|
35
71
|
}
|
|
72
|
+
// Generate cache key
|
|
36
73
|
const key = utils_1.KeyGenerator.generate(options, args);
|
|
74
|
+
// Update cache with result
|
|
37
75
|
yield cacheService.set(key, result, options);
|
|
38
76
|
return result;
|
|
39
77
|
}
|
|
40
78
|
catch (error) {
|
|
41
79
|
logger.error(`Cache put error in ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
// Re-throw the error (cache update failure shouldn't hide method errors)
|
|
42
81
|
throw error;
|
|
43
82
|
}
|
|
44
83
|
});
|
|
@@ -1,4 +1,44 @@
|
|
|
1
1
|
import type { CacheableOptions } from '../interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Set global CacheService instance
|
|
4
|
+
* Called by CacheModule during initialization
|
|
5
|
+
*/
|
|
2
6
|
export declare function setCacheService(cacheService: any): void;
|
|
7
|
+
/**
|
|
8
|
+
* Get global CacheService instance
|
|
9
|
+
*/
|
|
3
10
|
export declare function getCacheService(): any;
|
|
11
|
+
/**
|
|
12
|
+
* @Cacheable decorator - Cache method results
|
|
13
|
+
*
|
|
14
|
+
* This decorator automatically caches the return value of a method.
|
|
15
|
+
* On subsequent calls with the same arguments, the cached value is returned.
|
|
16
|
+
*
|
|
17
|
+
* @param options - Cacheable options
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* class UserService {
|
|
22
|
+
* @Cacheable({
|
|
23
|
+
* key: (id) => `user:${id}`,
|
|
24
|
+
* ttl: 300_000, // 5 minutes
|
|
25
|
+
* layers: [CacheLayer.MEMORY, CacheLayer.REDIS]
|
|
26
|
+
* })
|
|
27
|
+
* async getUserById(id: string) {
|
|
28
|
+
* return await this.repo.findOne({ where: { id } });
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* // With dependencies
|
|
32
|
+
* @Cacheable({
|
|
33
|
+
* key: (id) => `user:${id}:profile`,
|
|
34
|
+
* dependencies: [
|
|
35
|
+
* new DbDependency('SELECT updated_at FROM users WHERE id = ?', (id) => [id])
|
|
36
|
+
* ]
|
|
37
|
+
* })
|
|
38
|
+
* async getUserProfile(id: string) {
|
|
39
|
+
* return await this.fetchProfile(id);
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
4
44
|
export declare function Cacheable(options?: CacheableOptions): MethodDecorator;
|
|
@@ -14,13 +14,57 @@ exports.getCacheService = getCacheService;
|
|
|
14
14
|
exports.Cacheable = Cacheable;
|
|
15
15
|
const common_1 = require("@nestjs/common");
|
|
16
16
|
const utils_1 = require("../utils");
|
|
17
|
+
/**
|
|
18
|
+
* Global CacheService instance holder
|
|
19
|
+
* Will be set by CacheModule during initialization
|
|
20
|
+
*/
|
|
17
21
|
let globalCacheService = null;
|
|
22
|
+
/**
|
|
23
|
+
* Set global CacheService instance
|
|
24
|
+
* Called by CacheModule during initialization
|
|
25
|
+
*/
|
|
18
26
|
function setCacheService(cacheService) {
|
|
19
27
|
globalCacheService = cacheService;
|
|
20
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Get global CacheService instance
|
|
31
|
+
*/
|
|
21
32
|
function getCacheService() {
|
|
22
33
|
return globalCacheService;
|
|
23
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* @Cacheable decorator - Cache method results
|
|
37
|
+
*
|
|
38
|
+
* This decorator automatically caches the return value of a method.
|
|
39
|
+
* On subsequent calls with the same arguments, the cached value is returned.
|
|
40
|
+
*
|
|
41
|
+
* @param options - Cacheable options
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* class UserService {
|
|
46
|
+
* @Cacheable({
|
|
47
|
+
* key: (id) => `user:${id}`,
|
|
48
|
+
* ttl: 300_000, // 5 minutes
|
|
49
|
+
* layers: [CacheLayer.MEMORY, CacheLayer.REDIS]
|
|
50
|
+
* })
|
|
51
|
+
* async getUserById(id: string) {
|
|
52
|
+
* return await this.repo.findOne({ where: { id } });
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* // With dependencies
|
|
56
|
+
* @Cacheable({
|
|
57
|
+
* key: (id) => `user:${id}:profile`,
|
|
58
|
+
* dependencies: [
|
|
59
|
+
* new DbDependency('SELECT updated_at FROM users WHERE id = ?', (id) => [id])
|
|
60
|
+
* ]
|
|
61
|
+
* })
|
|
62
|
+
* async getUserProfile(id: string) {
|
|
63
|
+
* return await this.fetchProfile(id);
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
24
68
|
function Cacheable(options = {}) {
|
|
25
69
|
const logger = new common_1.Logger('CacheableDecorator');
|
|
26
70
|
return function (target, propertyKey, descriptor) {
|
|
@@ -34,20 +78,25 @@ function Cacheable(options = {}) {
|
|
|
34
78
|
return originalMethod.apply(this, args);
|
|
35
79
|
}
|
|
36
80
|
try {
|
|
81
|
+
// Generate cache key
|
|
37
82
|
const key = utils_1.KeyGenerator.generate(options, args);
|
|
83
|
+
// Check condition
|
|
38
84
|
if (options.condition) {
|
|
39
85
|
const shouldCache = yield Promise.resolve(options.condition(...args));
|
|
40
86
|
if (!shouldCache) {
|
|
41
87
|
return originalMethod.apply(this, args);
|
|
42
88
|
}
|
|
43
89
|
}
|
|
90
|
+
// Resolve dependencies with context
|
|
44
91
|
const dependencies = options.dependencies
|
|
45
92
|
? yield resolveDependenciesWithContext(options.dependencies, args)
|
|
46
93
|
: undefined;
|
|
94
|
+
// Try to get from cache using getOrSet
|
|
47
95
|
return yield cacheService.getOrSet(key, () => originalMethod.apply(this, args), Object.assign(Object.assign({}, options), { dependencies }));
|
|
48
96
|
}
|
|
49
97
|
catch (error) {
|
|
50
98
|
logger.error(`Cache error in ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
99
|
+
// Fallback to original method on error
|
|
51
100
|
return originalMethod.apply(this, args);
|
|
52
101
|
}
|
|
53
102
|
});
|
|
@@ -55,10 +104,16 @@ function Cacheable(options = {}) {
|
|
|
55
104
|
return descriptor;
|
|
56
105
|
};
|
|
57
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Resolve dependencies that may need method arguments
|
|
109
|
+
* Some dependencies (like DbDependency) may use method args in their factory
|
|
110
|
+
*/
|
|
58
111
|
function resolveDependenciesWithContext(dependencies, args) {
|
|
59
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60
113
|
return dependencies.map((dep) => {
|
|
114
|
+
// If dependency has a params factory, bind it to current args
|
|
61
115
|
if (dep.paramsFactory && typeof dep.paramsFactory === 'function') {
|
|
116
|
+
// Create a new instance with resolved params
|
|
62
117
|
const params = dep.paramsFactory(...args);
|
|
63
118
|
return new dep.constructor(dep.sql, () => params, dep.name);
|
|
64
119
|
}
|
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
2
|
+
/**
|
|
3
|
+
* Callback-based cache dependency
|
|
4
|
+
*
|
|
5
|
+
* This dependency uses a callback function to determine if cache is still valid.
|
|
6
|
+
* When the callback's return value changes, the cache becomes invalid.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Cache config, invalidate when version changes
|
|
11
|
+
* @Cacheable({
|
|
12
|
+
* key: 'app:config',
|
|
13
|
+
* dependencies: [
|
|
14
|
+
* new CallbackDependency(() => ConfigService.get('app.version'))
|
|
15
|
+
* ]
|
|
16
|
+
* })
|
|
17
|
+
* async getConfig() { }
|
|
18
|
+
*
|
|
19
|
+
* // Cache based on feature flag
|
|
20
|
+
* @Cacheable({
|
|
21
|
+
* key: 'features',
|
|
22
|
+
* dependencies: [
|
|
23
|
+
* new CallbackDependency(() => FeatureService.getHash())
|
|
24
|
+
* ]
|
|
25
|
+
* })
|
|
26
|
+
* async getFeatures() { }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
2
29
|
export declare class CallbackDependency implements CacheDependency {
|
|
3
30
|
private readonly callback;
|
|
4
31
|
private readonly name?;
|
|
@@ -6,6 +33,12 @@ export declare class CallbackDependency implements CacheDependency {
|
|
|
6
33
|
getKey(): string;
|
|
7
34
|
getData(): Promise<any>;
|
|
8
35
|
isChanged(oldData: any): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Deep equality check for primitive values, objects, and arrays
|
|
38
|
+
*/
|
|
9
39
|
private isEqual;
|
|
40
|
+
/**
|
|
41
|
+
* Simple hash code generation for strings
|
|
42
|
+
*/
|
|
10
43
|
private hashCode;
|
|
11
44
|
}
|
|
@@ -10,6 +10,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.CallbackDependency = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Callback-based cache dependency
|
|
15
|
+
*
|
|
16
|
+
* This dependency uses a callback function to determine if cache is still valid.
|
|
17
|
+
* When the callback's return value changes, the cache becomes invalid.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Cache config, invalidate when version changes
|
|
22
|
+
* @Cacheable({
|
|
23
|
+
* key: 'app:config',
|
|
24
|
+
* dependencies: [
|
|
25
|
+
* new CallbackDependency(() => ConfigService.get('app.version'))
|
|
26
|
+
* ]
|
|
27
|
+
* })
|
|
28
|
+
* async getConfig() { }
|
|
29
|
+
*
|
|
30
|
+
* // Cache based on feature flag
|
|
31
|
+
* @Cacheable({
|
|
32
|
+
* key: 'features',
|
|
33
|
+
* dependencies: [
|
|
34
|
+
* new CallbackDependency(() => FeatureService.getHash())
|
|
35
|
+
* ]
|
|
36
|
+
* })
|
|
37
|
+
* async getFeatures() { }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
13
40
|
class CallbackDependency {
|
|
14
41
|
constructor(callback, name) {
|
|
15
42
|
this.callback = callback;
|
|
@@ -19,6 +46,7 @@ class CallbackDependency {
|
|
|
19
46
|
}
|
|
20
47
|
}
|
|
21
48
|
getKey() {
|
|
49
|
+
// Use function name or provided name, fallback to hash
|
|
22
50
|
const callbackName = this.name || this.callback.name || 'anonymous';
|
|
23
51
|
return `callback:${callbackName}:${this.hashCode(this.callback.toString())}`;
|
|
24
52
|
}
|
|
@@ -28,6 +56,7 @@ class CallbackDependency {
|
|
|
28
56
|
return yield Promise.resolve(this.callback());
|
|
29
57
|
}
|
|
30
58
|
catch (error) {
|
|
59
|
+
// If callback fails, consider it as changed to be safe
|
|
31
60
|
throw new Error(`CallbackDependency getData failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
32
61
|
}
|
|
33
62
|
});
|
|
@@ -39,10 +68,14 @@ class CallbackDependency {
|
|
|
39
68
|
return !this.isEqual(oldData, currentData);
|
|
40
69
|
}
|
|
41
70
|
catch (_a) {
|
|
71
|
+
// If we can't get current data, consider it changed
|
|
42
72
|
return true;
|
|
43
73
|
}
|
|
44
74
|
});
|
|
45
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Deep equality check for primitive values, objects, and arrays
|
|
78
|
+
*/
|
|
46
79
|
isEqual(a, b) {
|
|
47
80
|
if (a === b) {
|
|
48
81
|
return true;
|
|
@@ -56,6 +89,7 @@ class CallbackDependency {
|
|
|
56
89
|
if (typeof a !== 'object') {
|
|
57
90
|
return a === b;
|
|
58
91
|
}
|
|
92
|
+
// Handle arrays
|
|
59
93
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
60
94
|
if (a.length !== b.length) {
|
|
61
95
|
return false;
|
|
@@ -67,6 +101,7 @@ class CallbackDependency {
|
|
|
67
101
|
}
|
|
68
102
|
return true;
|
|
69
103
|
}
|
|
104
|
+
// Handle objects
|
|
70
105
|
const keysA = Object.keys(a);
|
|
71
106
|
const keysB = Object.keys(b);
|
|
72
107
|
if (keysA.length !== keysB.length) {
|
|
@@ -79,12 +114,15 @@ class CallbackDependency {
|
|
|
79
114
|
}
|
|
80
115
|
return true;
|
|
81
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Simple hash code generation for strings
|
|
119
|
+
*/
|
|
82
120
|
hashCode(str) {
|
|
83
121
|
let hash = 0;
|
|
84
122
|
for (let i = 0; i < str.length; i++) {
|
|
85
123
|
const char = str.charCodeAt(i);
|
|
86
124
|
hash = (hash << 5) - hash + char;
|
|
87
|
-
hash = hash & hash;
|
|
125
|
+
hash = hash & hash; // Convert to 32bit integer
|
|
88
126
|
}
|
|
89
127
|
return Math.abs(hash).toString(36);
|
|
90
128
|
}
|
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
2
|
+
/**
|
|
3
|
+
* Chain dependency - combines multiple dependencies
|
|
4
|
+
*
|
|
5
|
+
* The cache is invalidated when ANY of the dependencies change.
|
|
6
|
+
* This allows you to create complex invalidation logic by combining simpler dependencies.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Invalidate when either user data changes OR config changes
|
|
11
|
+
* @Cacheable({
|
|
12
|
+
* key: (id) => `user:${id}:view`,
|
|
13
|
+
* dependencies: [
|
|
14
|
+
* new ChainDependency([
|
|
15
|
+
* new TagDependency(['user-data']),
|
|
16
|
+
* new CallbackDependency(() => ConfigService.get('app.version')),
|
|
17
|
+
* new DbDependency('SELECT updated_at FROM users WHERE id = ?', (id) => [id])
|
|
18
|
+
* ])
|
|
19
|
+
* ]
|
|
20
|
+
* })
|
|
21
|
+
* async getUserView(id: string) { }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
2
24
|
export declare class ChainDependency implements CacheDependency {
|
|
3
25
|
private readonly dependencies;
|
|
4
26
|
constructor(dependencies: CacheDependency[]);
|
|
@@ -12,7 +34,13 @@ export declare class ChainDependency implements CacheDependency {
|
|
|
12
34
|
data: any;
|
|
13
35
|
}>): Promise<boolean>;
|
|
14
36
|
reset(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Get all dependencies in this chain
|
|
39
|
+
*/
|
|
15
40
|
getDependencies(): CacheDependency[];
|
|
41
|
+
/**
|
|
42
|
+
* Check which dependencies have changed
|
|
43
|
+
*/
|
|
16
44
|
getChangedDependencies(oldData: Array<{
|
|
17
45
|
key: string;
|
|
18
46
|
data: any;
|
|
@@ -10,12 +10,35 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.ChainDependency = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Chain dependency - combines multiple dependencies
|
|
15
|
+
*
|
|
16
|
+
* The cache is invalidated when ANY of the dependencies change.
|
|
17
|
+
* This allows you to create complex invalidation logic by combining simpler dependencies.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Invalidate when either user data changes OR config changes
|
|
22
|
+
* @Cacheable({
|
|
23
|
+
* key: (id) => `user:${id}:view`,
|
|
24
|
+
* dependencies: [
|
|
25
|
+
* new ChainDependency([
|
|
26
|
+
* new TagDependency(['user-data']),
|
|
27
|
+
* new CallbackDependency(() => ConfigService.get('app.version')),
|
|
28
|
+
* new DbDependency('SELECT updated_at FROM users WHERE id = ?', (id) => [id])
|
|
29
|
+
* ])
|
|
30
|
+
* ]
|
|
31
|
+
* })
|
|
32
|
+
* async getUserView(id: string) { }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
13
35
|
class ChainDependency {
|
|
14
36
|
constructor(dependencies) {
|
|
15
37
|
this.dependencies = dependencies;
|
|
16
38
|
if (!Array.isArray(dependencies) || dependencies.length === 0) {
|
|
17
39
|
throw new Error('ChainDependency requires at least one dependency');
|
|
18
40
|
}
|
|
41
|
+
// Validate all dependencies implement the interface
|
|
19
42
|
for (const dep of dependencies) {
|
|
20
43
|
if (!dep.getKey || !dep.getData || !dep.isChanged) {
|
|
21
44
|
throw new Error('All dependencies must implement CacheDependency interface');
|
|
@@ -38,6 +61,7 @@ class ChainDependency {
|
|
|
38
61
|
});
|
|
39
62
|
}
|
|
40
63
|
catch (error) {
|
|
64
|
+
// If any dependency fails to get data, store the error
|
|
41
65
|
results.push({
|
|
42
66
|
key: dep.getKey(),
|
|
43
67
|
data: {
|
|
@@ -55,19 +79,23 @@ class ChainDependency {
|
|
|
55
79
|
oldData.length !== this.dependencies.length) {
|
|
56
80
|
return true;
|
|
57
81
|
}
|
|
82
|
+
// Check each dependency
|
|
58
83
|
for (let i = 0; i < this.dependencies.length; i++) {
|
|
59
84
|
const dep = this.dependencies[i];
|
|
60
85
|
const oldDepData = oldData[i];
|
|
86
|
+
// Key mismatch means dependencies changed
|
|
61
87
|
if (oldDepData.key !== dep.getKey()) {
|
|
62
88
|
return true;
|
|
63
89
|
}
|
|
64
90
|
try {
|
|
91
|
+
// Check if this dependency has changed
|
|
65
92
|
const changed = yield dep.isChanged(oldDepData.data);
|
|
66
93
|
if (changed) {
|
|
67
94
|
return true;
|
|
68
95
|
}
|
|
69
96
|
}
|
|
70
97
|
catch (_a) {
|
|
98
|
+
// If check fails, consider it changed
|
|
71
99
|
return true;
|
|
72
100
|
}
|
|
73
101
|
}
|
|
@@ -83,9 +111,15 @@ class ChainDependency {
|
|
|
83
111
|
}
|
|
84
112
|
});
|
|
85
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Get all dependencies in this chain
|
|
116
|
+
*/
|
|
86
117
|
getDependencies() {
|
|
87
118
|
return [...this.dependencies];
|
|
88
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Check which dependencies have changed
|
|
122
|
+
*/
|
|
89
123
|
getChangedDependencies(oldData) {
|
|
90
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
125
|
if (!Array.isArray(oldData) ||
|
|
@@ -1,15 +1,60 @@
|
|
|
1
1
|
import { DataSource } from 'typeorm';
|
|
2
2
|
import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
3
|
+
/**
|
|
4
|
+
* Database-based cache dependency
|
|
5
|
+
*
|
|
6
|
+
* This dependency monitors database query results. When the query result changes,
|
|
7
|
+
* the cache becomes invalid.
|
|
8
|
+
*
|
|
9
|
+
* Common use case: Monitor MAX(updated_at) or COUNT(*) to detect data changes.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Invalidate cache when user data changes
|
|
14
|
+
* @Cacheable({
|
|
15
|
+
* key: (id) => `user:${id}:profile`,
|
|
16
|
+
* dependencies: [
|
|
17
|
+
* new DbDependency(
|
|
18
|
+
* 'SELECT updated_at FROM users WHERE id = ?',
|
|
19
|
+
* (id) => [id]
|
|
20
|
+
* )
|
|
21
|
+
* ]
|
|
22
|
+
* })
|
|
23
|
+
* async getUserProfile(id: string) { }
|
|
24
|
+
*
|
|
25
|
+
* // Invalidate when any user in tenant changes
|
|
26
|
+
* @Cacheable({
|
|
27
|
+
* key: (tenantId) => `users:list:${tenantId}`,
|
|
28
|
+
* dependencies: [
|
|
29
|
+
* new DbDependency(
|
|
30
|
+
* 'SELECT MAX(updated_at) FROM users WHERE tenant_id = ?',
|
|
31
|
+
* (tenantId) => [tenantId]
|
|
32
|
+
* )
|
|
33
|
+
* ]
|
|
34
|
+
* })
|
|
35
|
+
* async getUserList(tenantId: string) { }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
3
38
|
export declare class DbDependency implements CacheDependency {
|
|
4
39
|
private readonly sql;
|
|
5
40
|
private readonly paramsFactory?;
|
|
6
41
|
private readonly name?;
|
|
7
42
|
private static dataSource;
|
|
8
43
|
constructor(sql: string, paramsFactory?: (...args: any[]) => any[], name?: string);
|
|
44
|
+
/**
|
|
45
|
+
* Set the TypeORM DataSource for database queries
|
|
46
|
+
* This should be called once during application initialization
|
|
47
|
+
*/
|
|
9
48
|
static setDataSource(dataSource: DataSource): void;
|
|
49
|
+
/**
|
|
50
|
+
* Get the current DataSource
|
|
51
|
+
*/
|
|
10
52
|
static getDataSource(): DataSource | null;
|
|
11
53
|
getKey(): string;
|
|
12
54
|
getData(): Promise<any>;
|
|
13
55
|
isChanged(oldData: any): Promise<boolean>;
|
|
56
|
+
/**
|
|
57
|
+
* Simple hash code generation for strings
|
|
58
|
+
*/
|
|
14
59
|
private hashCode;
|
|
15
60
|
}
|
|
@@ -10,6 +10,41 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.DbDependency = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Database-based cache dependency
|
|
15
|
+
*
|
|
16
|
+
* This dependency monitors database query results. When the query result changes,
|
|
17
|
+
* the cache becomes invalid.
|
|
18
|
+
*
|
|
19
|
+
* Common use case: Monitor MAX(updated_at) or COUNT(*) to detect data changes.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Invalidate cache when user data changes
|
|
24
|
+
* @Cacheable({
|
|
25
|
+
* key: (id) => `user:${id}:profile`,
|
|
26
|
+
* dependencies: [
|
|
27
|
+
* new DbDependency(
|
|
28
|
+
* 'SELECT updated_at FROM users WHERE id = ?',
|
|
29
|
+
* (id) => [id]
|
|
30
|
+
* )
|
|
31
|
+
* ]
|
|
32
|
+
* })
|
|
33
|
+
* async getUserProfile(id: string) { }
|
|
34
|
+
*
|
|
35
|
+
* // Invalidate when any user in tenant changes
|
|
36
|
+
* @Cacheable({
|
|
37
|
+
* key: (tenantId) => `users:list:${tenantId}`,
|
|
38
|
+
* dependencies: [
|
|
39
|
+
* new DbDependency(
|
|
40
|
+
* 'SELECT MAX(updated_at) FROM users WHERE tenant_id = ?',
|
|
41
|
+
* (tenantId) => [tenantId]
|
|
42
|
+
* )
|
|
43
|
+
* ]
|
|
44
|
+
* })
|
|
45
|
+
* async getUserList(tenantId: string) { }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
13
48
|
class DbDependency {
|
|
14
49
|
constructor(sql, paramsFactory, name) {
|
|
15
50
|
this.sql = sql;
|
|
@@ -19,9 +54,16 @@ class DbDependency {
|
|
|
19
54
|
throw new Error('DbDependency requires a valid SQL query');
|
|
20
55
|
}
|
|
21
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Set the TypeORM DataSource for database queries
|
|
59
|
+
* This should be called once during application initialization
|
|
60
|
+
*/
|
|
22
61
|
static setDataSource(dataSource) {
|
|
23
62
|
this.dataSource = dataSource;
|
|
24
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the current DataSource
|
|
66
|
+
*/
|
|
25
67
|
static getDataSource() {
|
|
26
68
|
return this.dataSource;
|
|
27
69
|
}
|
|
@@ -39,6 +81,7 @@ class DbDependency {
|
|
|
39
81
|
try {
|
|
40
82
|
const params = ((_a = this.paramsFactory) === null || _a === void 0 ? void 0 : _a.call(this)) || [];
|
|
41
83
|
const result = yield DbDependency.dataSource.query(this.sql, params);
|
|
84
|
+
// Serialize result for comparison
|
|
42
85
|
return JSON.stringify(result);
|
|
43
86
|
}
|
|
44
87
|
catch (error) {
|
|
@@ -53,16 +96,20 @@ class DbDependency {
|
|
|
53
96
|
return oldData !== currentData;
|
|
54
97
|
}
|
|
55
98
|
catch (_a) {
|
|
99
|
+
// If query fails, consider it changed to be safe
|
|
56
100
|
return true;
|
|
57
101
|
}
|
|
58
102
|
});
|
|
59
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Simple hash code generation for strings
|
|
106
|
+
*/
|
|
60
107
|
hashCode(str) {
|
|
61
108
|
let hash = 0;
|
|
62
109
|
for (let i = 0; i < str.length; i++) {
|
|
63
110
|
const char = str.charCodeAt(i);
|
|
64
111
|
hash = (hash << 5) - hash + char;
|
|
65
|
-
hash = hash & hash;
|
|
112
|
+
hash = hash & hash; // Convert to 32bit integer
|
|
66
113
|
}
|
|
67
114
|
return Math.abs(hash).toString(36);
|
|
68
115
|
}
|