@nest-omni/core 4.1.3-3 → 4.1.3-30
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 +1 -0
- package/audit/audit.module.js +51 -2
- package/audit/controllers/audit.controller.d.ts +57 -1
- package/audit/controllers/audit.controller.js +43 -0
- package/audit/decorators/audit-action.decorator.d.ts +74 -0
- package/audit/decorators/audit-action.decorator.js +42 -0
- package/audit/decorators/audit-controller.decorator.d.ts +1 -1
- package/audit/decorators/audit-controller.decorator.js +2 -2
- package/audit/decorators/audit-operation.decorator.d.ts +0 -7
- package/audit/decorators/audit-operation.decorator.js +0 -7
- package/audit/decorators/entity-audit.decorator.d.ts +78 -2
- package/audit/decorators/entity-audit.decorator.js +145 -4
- package/audit/decorators/index.d.ts +2 -0
- package/audit/decorators/index.js +2 -0
- package/audit/dto/audit-action-query.dto.d.ts +13 -0
- package/audit/dto/audit-action-query.dto.js +77 -0
- package/audit/dto/index.d.ts +1 -0
- package/audit/dto/index.js +1 -0
- package/audit/entities/audit-action-summary.entity.d.ts +23 -0
- package/audit/entities/audit-action-summary.entity.js +101 -0
- package/audit/entities/entity-audit-log.entity.d.ts +7 -2
- package/audit/entities/entity-audit-log.entity.js +45 -9
- package/audit/entities/entity-transaction.entity.d.ts +8 -2
- package/audit/entities/entity-transaction.entity.js +39 -3
- package/audit/entities/index.d.ts +3 -0
- package/audit/entities/index.js +3 -0
- package/audit/entities/manual-operation-log.entity.d.ts +0 -2
- package/audit/entities/manual-operation-log.entity.js +8 -9
- package/audit/enums/audit.enums.d.ts +14 -6
- package/audit/enums/audit.enums.js +18 -9
- package/audit/examples/decorator-value-mapping.example.d.ts +70 -0
- package/audit/examples/decorator-value-mapping.example.js +414 -0
- package/audit/index.d.ts +5 -1
- package/audit/index.js +29 -2
- package/audit/interceptors/audit-action.interceptor.d.ts +39 -0
- package/audit/interceptors/audit-action.interceptor.js +217 -0
- package/audit/interceptors/audit.interceptor.d.ts +1 -0
- package/audit/interceptors/audit.interceptor.js +19 -11
- package/audit/interceptors/index.d.ts +1 -0
- package/audit/interceptors/index.js +1 -0
- package/audit/interfaces/audit.interfaces.d.ts +132 -4
- package/audit/services/audit-action.service.d.ts +142 -0
- package/audit/services/audit-action.service.js +246 -0
- package/audit/services/audit-context.service.d.ts +91 -0
- package/audit/services/audit-context.service.js +170 -0
- package/audit/services/entity-audit.service.d.ts +220 -9
- package/audit/services/entity-audit.service.js +761 -72
- package/audit/services/index.d.ts +3 -0
- package/audit/services/index.js +3 -0
- package/audit/services/manual-audit-log.service.d.ts +23 -23
- package/audit/services/manual-audit-log.service.js +34 -57
- package/audit/services/multi-database.service.d.ts +0 -5
- package/audit/services/multi-database.service.js +0 -24
- package/audit/services/operation-description.service.d.ts +14 -3
- package/audit/services/operation-description.service.js +165 -26
- package/audit/services/transaction-audit.service.d.ts +1 -0
- package/audit/services/transaction-audit.service.js +12 -9
- package/audit/subscribers/entity-audit.subscriber.d.ts +5 -0
- package/audit/subscribers/entity-audit.subscriber.js +69 -5
- package/cache/cache.module.d.ts +7 -8
- package/cache/cache.module.js +15 -13
- package/cache/cache.service.d.ts +6 -4
- package/cache/cache.service.js +24 -12
- package/cache/decorators/cache-put.decorator.js +5 -4
- package/cache/dependencies/callback.dependency.js +9 -0
- package/cache/dependencies/db.dependency.d.ts +43 -12
- package/cache/dependencies/db.dependency.js +46 -18
- package/cache/dependencies/tag.dependency.d.ts +31 -4
- package/cache/dependencies/tag.dependency.js +100 -11
- package/cache/entities/index.d.ts +1 -0
- package/cache/entities/index.js +17 -0
- package/cache/entities/typeorm-cache.entity.d.ts +71 -0
- package/cache/entities/typeorm-cache.entity.js +110 -0
- package/cache/index.d.ts +2 -1
- package/cache/index.js +19 -2
- package/cache/interfaces/cache-options.interface.d.ts +8 -0
- package/cache/providers/index.d.ts +2 -1
- package/cache/providers/index.js +2 -1
- package/cache/providers/lrucache.provider.d.ts +77 -0
- package/cache/providers/lrucache.provider.js +228 -0
- package/cache/providers/redis-cache.provider.d.ts +1 -0
- package/cache/providers/redis-cache.provider.js +8 -6
- package/cache/providers/typeorm-cache.provider.d.ts +211 -0
- package/cache/providers/typeorm-cache.provider.js +483 -0
- package/common/boilerplate.polyfill.d.ts +1 -0
- package/common/boilerplate.polyfill.js +18 -1
- package/common/helpers/validation-metadata-helper.d.ts +112 -0
- package/common/helpers/validation-metadata-helper.js +164 -0
- package/common/index.d.ts +1 -0
- package/common/index.js +4 -0
- package/decorators/examples/field-i18n.example.d.ts +294 -0
- package/decorators/examples/field-i18n.example.js +478 -0
- package/decorators/field.decorators.d.ts +95 -3
- package/decorators/field.decorators.js +152 -18
- package/decorators/transform.decorators.d.ts +0 -2
- package/decorators/transform.decorators.js +0 -23
- package/decorators/translate.decorator.d.ts +26 -0
- package/decorators/translate.decorator.js +26 -1
- package/email-log/email-log.constants.d.ts +8 -0
- package/email-log/email-log.constants.js +11 -0
- package/email-log/email-log.module.d.ts +47 -0
- package/email-log/email-log.module.js +140 -0
- package/email-log/index.d.ts +11 -0
- package/email-log/index.js +48 -0
- package/email-log/interfaces/email-log-options.interface.d.ts +61 -0
- package/email-log/interfaces/email-log-options.interface.js +134 -0
- package/email-log/interfaces/email-log-transport.interface.d.ts +20 -0
- package/email-log/interfaces/email-log-transport.interface.js +2 -0
- package/email-log/interfaces/index.d.ts +2 -0
- package/email-log/interfaces/index.js +18 -0
- package/email-log/providers/email-provider.d.ts +42 -0
- package/email-log/providers/email-provider.js +127 -0
- package/email-log/providers/index.d.ts +1 -0
- package/email-log/providers/index.js +17 -0
- package/email-log/services/email-log-alert.service.d.ts +46 -0
- package/email-log/services/email-log-alert.service.js +162 -0
- package/email-log/services/email-log-formatter.service.d.ts +78 -0
- package/email-log/services/email-log-formatter.service.js +442 -0
- package/email-log/services/email-log-logger.service.d.ts +85 -0
- package/email-log/services/email-log-logger.service.js +168 -0
- package/email-log/services/email-log-rate-limiter.service.d.ts +42 -0
- package/email-log/services/email-log-rate-limiter.service.js +110 -0
- package/email-log/services/email-log-transport.service.d.ts +80 -0
- package/email-log/services/email-log-transport.service.js +271 -0
- package/email-log/services/index.d.ts +5 -0
- package/email-log/services/index.js +21 -0
- package/email-log/transports/index.d.ts +1 -0
- package/email-log/transports/index.js +17 -0
- package/email-log/transports/pino-email.transport.d.ts +56 -0
- package/email-log/transports/pino-email.transport.js +188 -0
- package/email-log/utils/index.d.ts +2 -0
- package/email-log/utils/index.js +18 -0
- package/email-log/utils/log-level.helper.d.ts +46 -0
- package/email-log/utils/log-level.helper.js +74 -0
- package/email-log/utils/pino-transport.utils.d.ts +135 -0
- package/email-log/utils/pino-transport.utils.js +238 -0
- package/file-upload/controllers/file-access.controller.d.ts +23 -0
- package/file-upload/controllers/file-access.controller.js +128 -0
- package/file-upload/decorators/column.decorator.d.ts +151 -0
- package/file-upload/decorators/column.decorator.js +273 -0
- package/file-upload/decorators/csv-data.decorator.d.ts +30 -0
- package/file-upload/decorators/csv-data.decorator.js +85 -0
- package/file-upload/decorators/csv-import.decorator.d.ts +34 -0
- package/file-upload/decorators/csv-import.decorator.js +24 -0
- package/file-upload/decorators/examples/column-mapping.example.d.ts +76 -0
- package/file-upload/decorators/examples/column-mapping.example.js +122 -0
- package/file-upload/decorators/excel-data.decorator.d.ts +30 -0
- package/file-upload/decorators/excel-data.decorator.js +85 -0
- package/file-upload/decorators/file-upload.decorator.d.ts +83 -0
- package/file-upload/decorators/file-upload.decorator.js +172 -0
- package/file-upload/decorators/index.d.ts +5 -0
- package/file-upload/decorators/index.js +38 -0
- package/file-upload/decorators/process.decorator.d.ts +40 -0
- package/file-upload/decorators/process.decorator.js +52 -0
- package/file-upload/decorators/validate-data.decorator.d.ts +91 -0
- package/file-upload/decorators/validate-data.decorator.js +39 -0
- package/file-upload/dto/create-file.dto.d.ts +24 -0
- package/file-upload/dto/create-file.dto.js +112 -0
- package/file-upload/dto/find-files.dto.d.ts +15 -0
- package/file-upload/dto/find-files.dto.js +76 -0
- package/file-upload/dto/index.d.ts +4 -0
- package/file-upload/dto/index.js +20 -0
- package/file-upload/dto/pagination.dto.d.ts +7 -0
- package/file-upload/dto/pagination.dto.js +39 -0
- package/file-upload/dto/update-file.dto.d.ts +15 -0
- package/file-upload/dto/update-file.dto.js +67 -0
- package/file-upload/entities/file-metadata.entity.d.ts +25 -0
- package/file-upload/entities/file-metadata.entity.js +76 -0
- package/file-upload/entities/file.entity.d.ts +114 -0
- package/file-upload/entities/file.entity.js +350 -0
- package/file-upload/entities/index.d.ts +2 -0
- package/file-upload/entities/index.js +18 -0
- package/file-upload/enums/file-type.enum.d.ts +72 -0
- package/file-upload/enums/file-type.enum.js +212 -0
- package/file-upload/exceptions/file-upload.exception.d.ts +57 -0
- package/file-upload/exceptions/file-upload.exception.js +120 -0
- package/file-upload/exceptions/index.d.ts +1 -0
- package/file-upload/exceptions/index.js +17 -0
- package/file-upload/file-upload.module.d.ts +89 -0
- package/file-upload/file-upload.module.js +292 -0
- package/file-upload/index.d.ts +37 -0
- package/file-upload/index.js +77 -0
- package/file-upload/interceptors/file-upload.interceptor.d.ts +101 -0
- package/file-upload/interceptors/file-upload.interceptor.js +594 -0
- package/file-upload/interceptors/index.d.ts +1 -0
- package/file-upload/interceptors/index.js +17 -0
- package/file-upload/interfaces/custom-file-type.interface.d.ts +72 -0
- package/file-upload/interfaces/custom-file-type.interface.js +2 -0
- package/file-upload/interfaces/file-buffer.interface.d.ts +72 -0
- package/file-upload/interfaces/file-buffer.interface.js +2 -0
- package/file-upload/interfaces/file-entity.interface.d.ts +142 -0
- package/file-upload/interfaces/file-entity.interface.js +28 -0
- package/file-upload/interfaces/file-metadata.interface.d.ts +21 -0
- package/file-upload/interfaces/file-metadata.interface.js +2 -0
- package/file-upload/interfaces/file-processor.interface.d.ts +93 -0
- package/file-upload/interfaces/file-processor.interface.js +2 -0
- package/file-upload/interfaces/file-upload-options.interface.d.ts +74 -0
- package/file-upload/interfaces/file-upload-options.interface.js +5 -0
- package/file-upload/interfaces/index.d.ts +7 -0
- package/file-upload/interfaces/index.js +24 -0
- package/file-upload/interfaces/processor-options.interface.d.ts +102 -0
- package/file-upload/interfaces/processor-options.interface.js +2 -0
- package/file-upload/interfaces/storage-provider.interface.d.ts +239 -0
- package/file-upload/interfaces/storage-provider.interface.js +2 -0
- package/file-upload/interfaces/upload-options.interface.d.ts +19 -0
- package/file-upload/interfaces/upload-options.interface.js +2 -0
- package/file-upload/processors/csv.processor.d.ts +98 -0
- package/file-upload/processors/csv.processor.js +391 -0
- package/file-upload/processors/excel.processor.d.ts +130 -0
- package/file-upload/processors/excel.processor.js +547 -0
- package/file-upload/processors/image.processor.d.ts +199 -0
- package/file-upload/processors/image.processor.js +377 -0
- package/file-upload/providers/index.d.ts +2 -0
- package/file-upload/providers/index.js +18 -0
- package/file-upload/providers/local-storage.provider.d.ts +98 -0
- package/file-upload/providers/local-storage.provider.js +484 -0
- package/file-upload/providers/s3-storage.provider.d.ts +87 -0
- package/file-upload/providers/s3-storage.provider.js +455 -0
- package/file-upload/services/file-signature-validator.service.d.ts +118 -0
- package/file-upload/services/file-signature-validator.service.js +376 -0
- package/file-upload/services/file.service.d.ts +193 -0
- package/file-upload/services/file.service.js +638 -0
- package/file-upload/services/index.d.ts +4 -0
- package/file-upload/services/index.js +20 -0
- package/file-upload/services/malicious-file-detector.service.d.ts +300 -0
- package/file-upload/services/malicious-file-detector.service.js +1234 -0
- package/file-upload/services/mime-registry.service.d.ts +47 -0
- package/file-upload/services/mime-registry.service.js +167 -0
- package/file-upload/utils/checksum.util.d.ts +28 -0
- package/file-upload/utils/checksum.util.js +65 -0
- package/file-upload/utils/dynamic-import.util.d.ts +54 -0
- package/file-upload/utils/dynamic-import.util.js +156 -0
- package/file-upload/utils/filename.util.d.ts +59 -0
- package/file-upload/utils/filename.util.js +184 -0
- package/file-upload/utils/filepath.util.d.ts +70 -0
- package/file-upload/utils/filepath.util.js +152 -0
- package/file-upload/utils/index.d.ts +4 -0
- package/file-upload/utils/index.js +20 -0
- package/filters/bad-request.filter.d.ts +9 -0
- package/filters/bad-request.filter.js +57 -16
- package/http-client/config/http-client.config.d.ts +5 -0
- package/http-client/config/http-client.config.js +27 -14
- package/http-client/decorators/http-client.decorators.d.ts +7 -28
- package/http-client/decorators/http-client.decorators.js +124 -99
- package/http-client/entities/http-log.entity.d.ts +0 -20
- package/http-client/entities/http-log.entity.js +1 -21
- package/http-client/examples/advanced-usage.example.d.ts +4 -5
- package/http-client/examples/advanced-usage.example.js +7 -59
- package/http-client/examples/axios-config-extended.example.d.ts +17 -0
- package/http-client/examples/axios-config-extended.example.js +311 -0
- package/http-client/examples/flexible-response-example.d.ts +28 -0
- package/http-client/examples/flexible-response-example.js +120 -0
- package/http-client/examples/index.d.ts +2 -0
- package/http-client/examples/index.js +2 -0
- package/http-client/examples/proxy-from-environment.example.d.ts +133 -0
- package/http-client/examples/proxy-from-environment.example.js +409 -0
- package/http-client/examples/ssl-certificate.example.d.ts +47 -0
- package/http-client/examples/ssl-certificate.example.js +432 -0
- package/http-client/http-client.module.d.ts +43 -2
- package/http-client/http-client.module.js +150 -90
- package/http-client/index.d.ts +1 -1
- package/http-client/interfaces/api-client-config.interface.d.ts +24 -103
- package/http-client/interfaces/http-client-config.interface.d.ts +137 -62
- package/http-client/services/api-client-registry.service.d.ts +8 -21
- package/http-client/services/api-client-registry.service.js +31 -282
- package/http-client/services/circuit-breaker.service.d.ts +69 -2
- package/http-client/services/circuit-breaker.service.js +185 -7
- package/http-client/services/http-client.service.d.ts +85 -23
- package/http-client/services/http-client.service.js +512 -168
- package/http-client/services/http-log-query.service.js +0 -13
- package/http-client/services/index.d.ts +0 -1
- package/http-client/services/index.js +0 -1
- package/http-client/services/logging.service.d.ts +69 -16
- package/http-client/services/logging.service.js +290 -170
- package/http-client/utils/call-stack-extractor.util.d.ts +26 -0
- package/http-client/utils/call-stack-extractor.util.js +35 -0
- package/http-client/utils/context-extractor.util.d.ts +2 -0
- package/http-client/utils/context-extractor.util.js +17 -3
- package/http-client/utils/curl-generator.util.js +2 -5
- package/http-client/utils/index.d.ts +2 -0
- package/http-client/utils/index.js +2 -0
- package/http-client/utils/proxy-environment.util.d.ts +42 -0
- package/http-client/utils/proxy-environment.util.js +154 -0
- package/http-client/utils/retry-recorder.util.d.ts +0 -4
- package/http-client/utils/retry-recorder.util.js +2 -27
- package/http-client/utils/sanitize.util.d.ts +58 -0
- package/http-client/utils/sanitize.util.js +188 -0
- package/http-client/utils/security-validator.util.d.ts +118 -0
- package/http-client/utils/security-validator.util.js +354 -0
- package/index.d.ts +4 -1
- package/index.js +6 -1
- package/interceptors/translation-interceptor.service.d.ts +7 -0
- package/interceptors/translation-interceptor.service.js +40 -8
- package/ip-filter/constants.d.ts +21 -0
- package/ip-filter/constants.js +24 -0
- package/ip-filter/decorators/index.d.ts +1 -0
- package/ip-filter/decorators/index.js +17 -0
- package/ip-filter/decorators/ip-filter.decorator.d.ts +58 -0
- package/ip-filter/decorators/ip-filter.decorator.js +79 -0
- package/ip-filter/guards/index.d.ts +1 -0
- package/ip-filter/guards/index.js +17 -0
- package/ip-filter/guards/ip-filter.guard.d.ts +62 -0
- package/ip-filter/guards/ip-filter.guard.js +174 -0
- package/ip-filter/index.d.ts +7 -0
- package/ip-filter/index.js +23 -0
- package/ip-filter/interfaces/index.d.ts +4 -0
- package/ip-filter/interfaces/index.js +20 -0
- package/ip-filter/interfaces/ip-filter-async-options.interface.d.ts +15 -0
- package/ip-filter/interfaces/ip-filter-async-options.interface.js +2 -0
- package/ip-filter/interfaces/ip-filter-metadata.interface.d.ts +26 -0
- package/ip-filter/interfaces/ip-filter-metadata.interface.js +2 -0
- package/ip-filter/interfaces/ip-filter-options.interface.d.ts +34 -0
- package/ip-filter/interfaces/ip-filter-options.interface.js +2 -0
- package/ip-filter/interfaces/ip-rule.interface.d.ts +36 -0
- package/ip-filter/interfaces/ip-rule.interface.js +2 -0
- package/ip-filter/ip-filter.module.d.ts +55 -0
- package/ip-filter/ip-filter.module.js +105 -0
- package/ip-filter/services/index.d.ts +1 -0
- package/ip-filter/services/index.js +17 -0
- package/ip-filter/services/ip-filter.service.d.ts +92 -0
- package/ip-filter/services/ip-filter.service.js +238 -0
- package/ip-filter/utils/index.d.ts +1 -0
- package/ip-filter/utils/index.js +17 -0
- package/ip-filter/utils/ip-utils.d.ts +61 -0
- package/ip-filter/utils/ip-utils.js +162 -0
- package/package.json +34 -29
- package/providers/context.provider.d.ts +9 -0
- package/providers/context.provider.js +13 -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/index.d.ts +2 -0
- package/redis-lock/index.js +5 -1
- package/redis-lock/lock-heartbeat.service.d.ts +80 -0
- package/redis-lock/lock-heartbeat.service.js +232 -0
- package/redis-lock/redis-lock.module.d.ts +6 -0
- package/redis-lock/redis-lock.module.js +136 -77
- package/redis-lock/redis-lock.service.d.ts +31 -0
- package/redis-lock/redis-lock.service.js +124 -17
- package/setup/bootstrap.setup.d.ts +2 -1
- package/setup/bootstrap.setup.js +3 -2
- package/setup/index.d.ts +1 -0
- package/setup/index.js +1 -0
- package/setup/run-in-mode.decorator.d.ts +56 -0
- package/setup/run-in-mode.decorator.js +92 -0
- package/setup/schedule.decorator.d.ts +1 -0
- package/setup/schedule.decorator.js +28 -13
- package/setup/worker.decorator.js +10 -1
- package/shared/index.d.ts +1 -1
- package/shared/index.js +1 -1
- package/shared/{serviceRegistryModule.js → service-registry.module.js} +28 -17
- package/shared/services/api-config.service.d.ts +41 -0
- package/shared/services/api-config.service.js +166 -8
- package/shared/services/index.d.ts +0 -1
- package/shared/services/index.js +0 -1
- package/validators/custom-validate.validator.d.ts +1 -0
- package/validators/custom-validate.validator.js +1 -0
- package/validators/file-mimetype.validator.d.ts +0 -2
- package/validators/file-mimetype.validator.js +4 -6
- package/validators/is-exists.validator.d.ts +15 -6
- package/validators/is-exists.validator.js +8 -7
- package/validators/is-unique.validator.d.ts +22 -7
- package/validators/is-unique.validator.js +41 -17
- package/vault/vault-config.service.js +1 -1
- package/cache/providers/memory-cache.provider.d.ts +0 -49
- package/cache/providers/memory-cache.provider.js +0 -197
- package/http-client/services/cache.service.d.ts +0 -76
- package/http-client/services/cache.service.js +0 -333
- package/shared/services/validator.service.d.ts +0 -3
- package/shared/services/validator.service.js +0 -20
- /package/shared/{serviceRegistryModule.d.ts → service-registry.module.d.ts} +0 -0
package/cache/cache.service.d.ts
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import type { CacheOptions, CacheStats } from './interfaces';
|
|
2
2
|
import { CacheLayer } from './interfaces';
|
|
3
|
-
import { ClsCacheProvider,
|
|
3
|
+
import { ClsCacheProvider, LRUCacheProvider, RedisCacheProvider } from './providers';
|
|
4
|
+
import { CacheSerializationService } from './cache-serialization.service';
|
|
4
5
|
/**
|
|
5
6
|
* Unified cache service with three-tier architecture
|
|
6
7
|
*
|
|
7
8
|
* L1: CLS (request-level)
|
|
8
|
-
* L2:
|
|
9
|
+
* L2: LRU (process-level with automatic eviction)
|
|
9
10
|
* L3: Redis (distributed)
|
|
10
11
|
*
|
|
11
12
|
* Supports automatic fallback, backfill, and dependency-based invalidation.
|
|
12
13
|
*/
|
|
13
14
|
export declare class CacheService {
|
|
14
15
|
private readonly clsProvider;
|
|
15
|
-
private readonly
|
|
16
|
+
private readonly lruProvider;
|
|
16
17
|
private readonly redisProvider;
|
|
17
18
|
private readonly enableCompression;
|
|
18
19
|
private readonly compressionThreshold;
|
|
20
|
+
private readonly serializationService;
|
|
19
21
|
private readonly logger;
|
|
20
22
|
private readonly providers;
|
|
21
23
|
private readonly stats;
|
|
22
|
-
constructor(clsProvider: ClsCacheProvider,
|
|
24
|
+
constructor(clsProvider: ClsCacheProvider, lruProvider: LRUCacheProvider, redisProvider: RedisCacheProvider, enableCompression?: boolean, compressionThreshold?: number, serializationService?: CacheSerializationService);
|
|
23
25
|
/**
|
|
24
26
|
* Get or set cache value with factory function
|
|
25
27
|
*
|
package/cache/cache.service.js
CHANGED
|
@@ -34,18 +34,19 @@ const cache_constants_1 = require("./cache.constants");
|
|
|
34
34
|
* Unified cache service with three-tier architecture
|
|
35
35
|
*
|
|
36
36
|
* L1: CLS (request-level)
|
|
37
|
-
* L2:
|
|
37
|
+
* L2: LRU (process-level with automatic eviction)
|
|
38
38
|
* L3: Redis (distributed)
|
|
39
39
|
*
|
|
40
40
|
* Supports automatic fallback, backfill, and dependency-based invalidation.
|
|
41
41
|
*/
|
|
42
42
|
let CacheService = CacheService_1 = class CacheService {
|
|
43
|
-
constructor(clsProvider,
|
|
43
|
+
constructor(clsProvider, lruProvider, redisProvider, enableCompression = false, compressionThreshold = 1024, serializationService = new cache_serialization_service_1.CacheSerializationService()) {
|
|
44
44
|
this.clsProvider = clsProvider;
|
|
45
|
-
this.
|
|
45
|
+
this.lruProvider = lruProvider;
|
|
46
46
|
this.redisProvider = redisProvider;
|
|
47
47
|
this.enableCompression = enableCompression;
|
|
48
48
|
this.compressionThreshold = compressionThreshold;
|
|
49
|
+
this.serializationService = serializationService;
|
|
49
50
|
this.logger = new common_1.Logger(CacheService_1.name);
|
|
50
51
|
this.providers = new Map();
|
|
51
52
|
this.stats = {
|
|
@@ -59,7 +60,7 @@ let CacheService = CacheService_1 = class CacheService {
|
|
|
59
60
|
totalClears: 0,
|
|
60
61
|
};
|
|
61
62
|
this.providers.set(interfaces_1.CacheLayer.CLS, clsProvider);
|
|
62
|
-
this.providers.set(interfaces_1.CacheLayer.MEMORY,
|
|
63
|
+
this.providers.set(interfaces_1.CacheLayer.MEMORY, lruProvider);
|
|
63
64
|
this.providers.set(interfaces_1.CacheLayer.REDIS, redisProvider);
|
|
64
65
|
this.initializeStats();
|
|
65
66
|
}
|
|
@@ -125,8 +126,7 @@ let CacheService = CacheService_1 = class CacheService {
|
|
|
125
126
|
if (value !== null) {
|
|
126
127
|
// Check if value is compressed and decompress if needed
|
|
127
128
|
if (this.enableCompression && Buffer.isBuffer(value)) {
|
|
128
|
-
const
|
|
129
|
-
const decompressed = yield serializationService.deserialize(value);
|
|
129
|
+
const decompressed = yield this.serializationService.deserialize(value);
|
|
130
130
|
value = decompressed.data;
|
|
131
131
|
}
|
|
132
132
|
// Cache hit
|
|
@@ -206,14 +206,14 @@ let CacheService = CacheService_1 = class CacheService {
|
|
|
206
206
|
return __awaiter(this, void 0, void 0, function* () {
|
|
207
207
|
this.stats.totalDeletes++;
|
|
208
208
|
const targetLayers = layers || this.getDefaultLayers();
|
|
209
|
-
const keys = Array.isArray(key) ? key : [key];
|
|
210
209
|
const promises = targetLayers.map((layer) => __awaiter(this, void 0, void 0, function* () {
|
|
211
210
|
const provider = this.providers.get(layer);
|
|
212
211
|
if (!provider) {
|
|
213
212
|
return;
|
|
214
213
|
}
|
|
215
214
|
try {
|
|
216
|
-
|
|
215
|
+
// Pass the key directly (string or array) to the provider
|
|
216
|
+
yield provider.delete(key);
|
|
217
217
|
}
|
|
218
218
|
catch (error) {
|
|
219
219
|
this.logger.warn(`Failed to delete from ${layer} cache: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -333,6 +333,18 @@ let CacheService = CacheService_1 = class CacheService {
|
|
|
333
333
|
setWithOptions(key, value, options) {
|
|
334
334
|
return __awaiter(this, void 0, void 0, function* () {
|
|
335
335
|
this.stats.totalSets++;
|
|
336
|
+
// Validate TTL if provided
|
|
337
|
+
if ((options === null || options === void 0 ? void 0 : options.ttl) !== undefined) {
|
|
338
|
+
if (typeof options.ttl !== 'number' || options.ttl < 0) {
|
|
339
|
+
this.logger.warn(`Invalid TTL value: ${options.ttl}. TTL must be a non-negative number. Using default behavior.`);
|
|
340
|
+
// Continue without TTL
|
|
341
|
+
options.ttl = undefined;
|
|
342
|
+
}
|
|
343
|
+
else if (options.ttl === 0) {
|
|
344
|
+
// TTL of 0 means no expiration
|
|
345
|
+
options.ttl = undefined;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
336
348
|
// Check condition
|
|
337
349
|
if ((options === null || options === void 0 ? void 0 : options.condition) && !(yield Promise.resolve(options.condition()))) {
|
|
338
350
|
return;
|
|
@@ -345,8 +357,7 @@ let CacheService = CacheService_1 = class CacheService {
|
|
|
345
357
|
value !== null &&
|
|
346
358
|
value !== undefined &&
|
|
347
359
|
JSON.stringify(value).length >= this.compressionThreshold) {
|
|
348
|
-
const
|
|
349
|
-
const compressed = yield serializationService.serialize(value, {
|
|
360
|
+
const compressed = yield this.serializationService.serialize(value, {
|
|
350
361
|
compress: true,
|
|
351
362
|
compressThreshold: this.compressionThreshold,
|
|
352
363
|
});
|
|
@@ -459,7 +470,8 @@ exports.CacheService = CacheService = CacheService_1 = __decorate([
|
|
|
459
470
|
__param(3, (0, common_1.Inject)(cache_constants_1.CACHE_COMPRESSION_ENABLED)),
|
|
460
471
|
__param(4, (0, common_1.Optional)()),
|
|
461
472
|
__param(4, (0, common_1.Inject)(cache_constants_1.CACHE_COMPRESSION_THRESHOLD)),
|
|
473
|
+
__param(5, (0, common_1.Optional)()),
|
|
462
474
|
__metadata("design:paramtypes", [providers_1.ClsCacheProvider,
|
|
463
|
-
providers_1.
|
|
464
|
-
providers_1.RedisCacheProvider, Boolean, Number])
|
|
475
|
+
providers_1.LRUCacheProvider,
|
|
476
|
+
providers_1.RedisCacheProvider, Boolean, Number, cache_serialization_service_1.CacheSerializationService])
|
|
465
477
|
], CacheService);
|
|
@@ -71,13 +71,14 @@ function CachePut(options = {}) {
|
|
|
71
71
|
}
|
|
72
72
|
// Generate cache key
|
|
73
73
|
const key = utils_1.KeyGenerator.generate(options, args);
|
|
74
|
-
// Update cache with result
|
|
75
|
-
|
|
74
|
+
// Update cache with result - don't await, let it happen in background
|
|
75
|
+
cacheService.set(key, result, options).catch((error) => {
|
|
76
|
+
logger.warn(`Failed to update cache for ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
77
|
+
});
|
|
76
78
|
return result;
|
|
77
79
|
}
|
|
78
80
|
catch (error) {
|
|
79
|
-
|
|
80
|
-
// Re-throw the error (cache update failure shouldn't hide method errors)
|
|
81
|
+
// Method execution error - rethrow it
|
|
81
82
|
throw error;
|
|
82
83
|
}
|
|
83
84
|
});
|
|
@@ -65,6 +65,11 @@ class CallbackDependency {
|
|
|
65
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
66
|
try {
|
|
67
67
|
const currentData = yield this.getData();
|
|
68
|
+
// If oldData is null or undefined, consider it as changed
|
|
69
|
+
// (no previous valid data exists)
|
|
70
|
+
if (oldData === null || oldData === undefined) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
68
73
|
return !this.isEqual(oldData, currentData);
|
|
69
74
|
}
|
|
70
75
|
catch (_a) {
|
|
@@ -86,6 +91,10 @@ class CallbackDependency {
|
|
|
86
91
|
if (typeof a !== typeof b) {
|
|
87
92
|
return false;
|
|
88
93
|
}
|
|
94
|
+
// Handle Date objects
|
|
95
|
+
if (a instanceof Date && b instanceof Date) {
|
|
96
|
+
return a.getTime() === b.getTime();
|
|
97
|
+
}
|
|
89
98
|
if (typeof a !== 'object') {
|
|
90
99
|
return a === b;
|
|
91
100
|
}
|
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { CacheDependency } from '../interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Options for DbDependency
|
|
4
|
+
*/
|
|
5
|
+
export interface DbDependencyOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Name for this dependency (used in cache key generation)
|
|
8
|
+
* Default: 'db'
|
|
9
|
+
*/
|
|
10
|
+
name?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Data source name to use for querying
|
|
13
|
+
* If not specified, uses the default data source
|
|
14
|
+
*/
|
|
15
|
+
dataSourceName?: string;
|
|
16
|
+
}
|
|
3
17
|
/**
|
|
4
18
|
* Database-based cache dependency
|
|
5
19
|
*
|
|
@@ -33,23 +47,40 @@ import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
|
33
47
|
* ]
|
|
34
48
|
* })
|
|
35
49
|
* async getUserList(tenantId: string) { }
|
|
50
|
+
*
|
|
51
|
+
* // Use specific data source
|
|
52
|
+
* @Cacheable({
|
|
53
|
+
* key: (id) => `product:${id}:details`,
|
|
54
|
+
* dependencies: [
|
|
55
|
+
* new DbDependency(
|
|
56
|
+
* 'SELECT updated_at FROM products WHERE id = ?',
|
|
57
|
+
* (id) => [id],
|
|
58
|
+
* { dataSourceName: 'readReplicas' }
|
|
59
|
+
* )
|
|
60
|
+
* ]
|
|
61
|
+
* })
|
|
62
|
+
* async getProductDetails(id: string) { }
|
|
63
|
+
*
|
|
64
|
+
* // With custom name and data source
|
|
65
|
+
* new DbDependency(
|
|
66
|
+
* 'SELECT COUNT(*) FROM events',
|
|
67
|
+
* [],
|
|
68
|
+
* { name: 'eventCount', dataSourceName: 'analytics' }
|
|
69
|
+
* )
|
|
36
70
|
* ```
|
|
37
71
|
*/
|
|
38
72
|
export declare class DbDependency implements CacheDependency {
|
|
39
73
|
private readonly sql;
|
|
40
74
|
private readonly paramsFactory?;
|
|
41
|
-
private readonly
|
|
42
|
-
private static
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* Set the TypeORM DataSource for database queries
|
|
46
|
-
* This should be called once during application initialization
|
|
47
|
-
*/
|
|
48
|
-
static setDataSource(dataSource: DataSource): void;
|
|
75
|
+
private readonly options?;
|
|
76
|
+
private static fallbackDataSource;
|
|
77
|
+
private static defaultDataSourceName;
|
|
78
|
+
constructor(sql: string, paramsFactory?: (...args: any[]) => any[], options?: DbDependencyOptions);
|
|
49
79
|
/**
|
|
50
|
-
* Get
|
|
80
|
+
* Get DataSource for executing queries
|
|
81
|
+
* Priority: 1. Specific dataSourceName from options, 2. Default from getDataSourceByName, 3. Fallback
|
|
51
82
|
*/
|
|
52
|
-
|
|
83
|
+
private getDataSource;
|
|
53
84
|
getKey(): string;
|
|
54
85
|
getData(): Promise<any>;
|
|
55
86
|
isChanged(oldData: any): Promise<boolean>;
|
|
@@ -10,6 +10,7 @@ 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
|
+
const transaction_1 = require("@nest-omni/transaction");
|
|
13
14
|
/**
|
|
14
15
|
* Database-based cache dependency
|
|
15
16
|
*
|
|
@@ -43,44 +44,70 @@ exports.DbDependency = void 0;
|
|
|
43
44
|
* ]
|
|
44
45
|
* })
|
|
45
46
|
* async getUserList(tenantId: string) { }
|
|
47
|
+
*
|
|
48
|
+
* // Use specific data source
|
|
49
|
+
* @Cacheable({
|
|
50
|
+
* key: (id) => `product:${id}:details`,
|
|
51
|
+
* dependencies: [
|
|
52
|
+
* new DbDependency(
|
|
53
|
+
* 'SELECT updated_at FROM products WHERE id = ?',
|
|
54
|
+
* (id) => [id],
|
|
55
|
+
* { dataSourceName: 'readReplicas' }
|
|
56
|
+
* )
|
|
57
|
+
* ]
|
|
58
|
+
* })
|
|
59
|
+
* async getProductDetails(id: string) { }
|
|
60
|
+
*
|
|
61
|
+
* // With custom name and data source
|
|
62
|
+
* new DbDependency(
|
|
63
|
+
* 'SELECT COUNT(*) FROM events',
|
|
64
|
+
* [],
|
|
65
|
+
* { name: 'eventCount', dataSourceName: 'analytics' }
|
|
66
|
+
* )
|
|
46
67
|
* ```
|
|
47
68
|
*/
|
|
48
69
|
class DbDependency {
|
|
49
|
-
constructor(sql, paramsFactory,
|
|
70
|
+
constructor(sql, paramsFactory, options) {
|
|
50
71
|
this.sql = sql;
|
|
51
72
|
this.paramsFactory = paramsFactory;
|
|
52
|
-
this.
|
|
73
|
+
this.options = options;
|
|
53
74
|
if (!sql || typeof sql !== 'string') {
|
|
54
75
|
throw new Error('DbDependency requires a valid SQL query');
|
|
55
76
|
}
|
|
56
77
|
}
|
|
57
78
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*/
|
|
61
|
-
static setDataSource(dataSource) {
|
|
62
|
-
this.dataSource = dataSource;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Get the current DataSource
|
|
79
|
+
* Get DataSource for executing queries
|
|
80
|
+
* Priority: 1. Specific dataSourceName from options, 2. Default from getDataSourceByName, 3. Fallback
|
|
66
81
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
82
|
+
getDataSource() {
|
|
83
|
+
var _a;
|
|
84
|
+
// Try to get from getDataSourceByName first
|
|
85
|
+
const dsName = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.dataSourceName) || DbDependency.defaultDataSourceName;
|
|
86
|
+
const dataSource = (0, transaction_1.getDataSource)(dsName);
|
|
87
|
+
if (dataSource) {
|
|
88
|
+
return dataSource;
|
|
89
|
+
}
|
|
90
|
+
// Fallback to static dataSource for backward compatibility
|
|
91
|
+
if (DbDependency.fallbackDataSource) {
|
|
92
|
+
return DbDependency.fallbackDataSource;
|
|
93
|
+
}
|
|
94
|
+
throw new Error(`DbDependency requires DataSource '${dsName}' to be registered. ` +
|
|
95
|
+
`Use DataSourceUtil.registerDataSource('${dsName}', dataSource) ` +
|
|
96
|
+
`or DbDependency.setDataSource(dataSource) for fallback.`);
|
|
69
97
|
}
|
|
70
98
|
getKey() {
|
|
99
|
+
var _a;
|
|
71
100
|
const queryHash = this.hashCode(this.sql);
|
|
72
|
-
const name = this.name || 'db';
|
|
101
|
+
const name = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.name) || 'db';
|
|
73
102
|
return `db:${name}:${queryHash}`;
|
|
74
103
|
}
|
|
75
104
|
getData() {
|
|
76
105
|
return __awaiter(this, void 0, void 0, function* () {
|
|
77
106
|
var _a;
|
|
78
|
-
if (!DbDependency.dataSource) {
|
|
79
|
-
throw new Error('DbDependency requires DataSource to be set. Call DbDependency.setDataSource(dataSource) during app initialization.');
|
|
80
|
-
}
|
|
81
107
|
try {
|
|
108
|
+
const dataSource = this.getDataSource();
|
|
82
109
|
const params = ((_a = this.paramsFactory) === null || _a === void 0 ? void 0 : _a.call(this)) || [];
|
|
83
|
-
const result = yield
|
|
110
|
+
const result = yield dataSource.query(this.sql, params);
|
|
84
111
|
// Serialize result for comparison
|
|
85
112
|
return JSON.stringify(result);
|
|
86
113
|
}
|
|
@@ -115,4 +142,5 @@ class DbDependency {
|
|
|
115
142
|
}
|
|
116
143
|
}
|
|
117
144
|
exports.DbDependency = DbDependency;
|
|
118
|
-
DbDependency.
|
|
145
|
+
DbDependency.fallbackDataSource = null;
|
|
146
|
+
DbDependency.defaultDataSourceName = 'default';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
2
|
+
import type Redis from 'ioredis';
|
|
2
3
|
/**
|
|
3
4
|
* Tag-based cache dependency
|
|
4
5
|
*
|
|
@@ -7,6 +8,9 @@ import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
|
7
8
|
*
|
|
8
9
|
* This is the most commonly used dependency type for managing related cache entries.
|
|
9
10
|
*
|
|
11
|
+
* **Distributed Support**: Tag versions are stored in Redis for multi-instance deployments.
|
|
12
|
+
* Falls back to in-memory storage if Redis is not available.
|
|
13
|
+
*
|
|
10
14
|
* @example
|
|
11
15
|
* ```typescript
|
|
12
16
|
* // Cache user list with tag dependency
|
|
@@ -23,26 +27,49 @@ import type { CacheDependency } from '../interfaces/cache-dependency.interface';
|
|
|
23
27
|
export declare class TagDependency implements CacheDependency {
|
|
24
28
|
private readonly tags;
|
|
25
29
|
private static readonly PREFIX;
|
|
30
|
+
private static readonly REDIS_KEY_PREFIX;
|
|
31
|
+
private static readonly logger;
|
|
26
32
|
private static tagVersions;
|
|
33
|
+
private static redis;
|
|
27
34
|
constructor(tags: string[]);
|
|
35
|
+
/**
|
|
36
|
+
* Set Redis client for distributed tag version storage
|
|
37
|
+
* Called by CacheModule during initialization
|
|
38
|
+
*
|
|
39
|
+
* @param redis - Redis client instance
|
|
40
|
+
*/
|
|
41
|
+
static setRedisClient(redis: Redis): void;
|
|
28
42
|
/**
|
|
29
43
|
* Get current version of a tag
|
|
44
|
+
* Prioritizes Redis, falls back to in-memory storage
|
|
45
|
+
*
|
|
46
|
+
* @param tag - Tag name
|
|
47
|
+
* @returns Current tag version
|
|
30
48
|
*/
|
|
31
|
-
static getTagVersion(tag: string): number
|
|
49
|
+
static getTagVersion(tag: string): Promise<number>;
|
|
32
50
|
/**
|
|
33
51
|
* Invalidate a tag (increment its version)
|
|
52
|
+
* Updates both Redis and in-memory storage
|
|
53
|
+
*
|
|
54
|
+
* @param tag - Tag name to invalidate
|
|
34
55
|
*/
|
|
35
|
-
static invalidateTag(tag: string): void
|
|
56
|
+
static invalidateTag(tag: string): Promise<void>;
|
|
36
57
|
/**
|
|
37
58
|
* Invalidate multiple tags
|
|
59
|
+
*
|
|
60
|
+
* @param tags - Array of tag names to invalidate
|
|
38
61
|
*/
|
|
39
|
-
static invalidateTags(tags: string[]): void
|
|
62
|
+
static invalidateTags(tags: string[]): Promise<void>;
|
|
40
63
|
/**
|
|
41
64
|
* Reset all tag versions (useful for testing)
|
|
65
|
+
* Clears both Redis and in-memory storage
|
|
42
66
|
*/
|
|
43
|
-
static resetAllTags(): void
|
|
67
|
+
static resetAllTags(): Promise<void>;
|
|
44
68
|
/**
|
|
45
69
|
* Get all tags and their versions
|
|
70
|
+
* Note: This only returns in-memory tags for backward compatibility
|
|
71
|
+
*
|
|
72
|
+
* @returns Map of tag names to versions
|
|
46
73
|
*/
|
|
47
74
|
static getAllTags(): Map<string, number>;
|
|
48
75
|
getKey(): string;
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.TagDependency = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
13
14
|
/**
|
|
14
15
|
* Tag-based cache dependency
|
|
15
16
|
*
|
|
@@ -18,6 +19,9 @@ exports.TagDependency = void 0;
|
|
|
18
19
|
*
|
|
19
20
|
* This is the most commonly used dependency type for managing related cache entries.
|
|
20
21
|
*
|
|
22
|
+
* **Distributed Support**: Tag versions are stored in Redis for multi-instance deployments.
|
|
23
|
+
* Falls back to in-memory storage if Redis is not available.
|
|
24
|
+
*
|
|
21
25
|
* @example
|
|
22
26
|
* ```typescript
|
|
23
27
|
* // Cache user list with tag dependency
|
|
@@ -38,38 +42,118 @@ class TagDependency {
|
|
|
38
42
|
throw new Error('TagDependency requires at least one tag');
|
|
39
43
|
}
|
|
40
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Set Redis client for distributed tag version storage
|
|
47
|
+
* Called by CacheModule during initialization
|
|
48
|
+
*
|
|
49
|
+
* @param redis - Redis client instance
|
|
50
|
+
*/
|
|
51
|
+
static setRedisClient(redis) {
|
|
52
|
+
TagDependency.redis = redis;
|
|
53
|
+
}
|
|
41
54
|
/**
|
|
42
55
|
* Get current version of a tag
|
|
56
|
+
* Prioritizes Redis, falls back to in-memory storage
|
|
57
|
+
*
|
|
58
|
+
* @param tag - Tag name
|
|
59
|
+
* @returns Current tag version
|
|
43
60
|
*/
|
|
44
61
|
static getTagVersion(tag) {
|
|
45
|
-
return this
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
// Try to get from Redis first
|
|
64
|
+
if (TagDependency.redis) {
|
|
65
|
+
try {
|
|
66
|
+
const key = `${TagDependency.REDIS_KEY_PREFIX}:${tag}`;
|
|
67
|
+
const result = yield TagDependency.redis.get(key);
|
|
68
|
+
if (result !== null) {
|
|
69
|
+
const version = parseInt(result, 10);
|
|
70
|
+
// Cache in memory for faster access
|
|
71
|
+
TagDependency.tagVersions.set(tag, version);
|
|
72
|
+
return version;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
// Log warning but don't throw - fall back to memory
|
|
77
|
+
TagDependency.logger.warn(`Failed to get tag version from Redis: ${error instanceof Error ? error.message : String(error)}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Fall back to in-memory storage
|
|
81
|
+
return TagDependency.tagVersions.get(tag) || 0;
|
|
82
|
+
});
|
|
46
83
|
}
|
|
47
84
|
/**
|
|
48
85
|
* Invalidate a tag (increment its version)
|
|
86
|
+
* Updates both Redis and in-memory storage
|
|
87
|
+
*
|
|
88
|
+
* @param tag - Tag name to invalidate
|
|
49
89
|
*/
|
|
50
90
|
static invalidateTag(tag) {
|
|
51
|
-
|
|
52
|
-
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
const currentVersion = TagDependency.tagVersions.get(tag) || 0;
|
|
93
|
+
const newVersion = currentVersion + 1;
|
|
94
|
+
// Update in-memory storage
|
|
95
|
+
TagDependency.tagVersions.set(tag, newVersion);
|
|
96
|
+
// Update Redis if available
|
|
97
|
+
if (TagDependency.redis) {
|
|
98
|
+
try {
|
|
99
|
+
const key = `${TagDependency.REDIS_KEY_PREFIX}:${tag}`;
|
|
100
|
+
yield TagDependency.redis.set(key, newVersion.toString());
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
TagDependency.logger.error(`Failed to invalidate tag in Redis: ${error instanceof Error ? error.message : String(error)}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
53
107
|
}
|
|
54
108
|
/**
|
|
55
109
|
* Invalidate multiple tags
|
|
110
|
+
*
|
|
111
|
+
* @param tags - Array of tag names to invalidate
|
|
56
112
|
*/
|
|
57
113
|
static invalidateTags(tags) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
114
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
yield Promise.all(tags.map((tag) => TagDependency.invalidateTag(tag)));
|
|
116
|
+
});
|
|
61
117
|
}
|
|
62
118
|
/**
|
|
63
119
|
* Reset all tag versions (useful for testing)
|
|
120
|
+
* Clears both Redis and in-memory storage
|
|
64
121
|
*/
|
|
65
122
|
static resetAllTags() {
|
|
66
|
-
this
|
|
123
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
// Clear in-memory storage
|
|
125
|
+
TagDependency.tagVersions.clear();
|
|
126
|
+
// Clear Redis storage
|
|
127
|
+
if (TagDependency.redis) {
|
|
128
|
+
try {
|
|
129
|
+
let cursor = '0';
|
|
130
|
+
const pattern = `${TagDependency.REDIS_KEY_PREFIX}:*`;
|
|
131
|
+
const keysToDelete = [];
|
|
132
|
+
// Use SCAN to find all tag version keys
|
|
133
|
+
do {
|
|
134
|
+
const [nextCursor, keys] = yield TagDependency.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
|
|
135
|
+
cursor = nextCursor;
|
|
136
|
+
keysToDelete.push(...keys);
|
|
137
|
+
} while (cursor !== '0');
|
|
138
|
+
// Delete all found keys
|
|
139
|
+
if (keysToDelete.length > 0) {
|
|
140
|
+
yield TagDependency.redis.del(...keysToDelete);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
TagDependency.logger.error(`Failed to reset tags in Redis: ${error instanceof Error ? error.message : String(error)}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
67
148
|
}
|
|
68
149
|
/**
|
|
69
150
|
* Get all tags and their versions
|
|
151
|
+
* Note: This only returns in-memory tags for backward compatibility
|
|
152
|
+
*
|
|
153
|
+
* @returns Map of tag names to versions
|
|
70
154
|
*/
|
|
71
155
|
static getAllTags() {
|
|
72
|
-
return new Map(
|
|
156
|
+
return new Map(TagDependency.tagVersions);
|
|
73
157
|
}
|
|
74
158
|
getKey() {
|
|
75
159
|
return `tag:${this.tags.sort().join(',')}`;
|
|
@@ -78,7 +162,7 @@ class TagDependency {
|
|
|
78
162
|
return __awaiter(this, void 0, void 0, function* () {
|
|
79
163
|
const data = {};
|
|
80
164
|
for (const tag of this.tags) {
|
|
81
|
-
data[tag] = TagDependency.getTagVersion(tag);
|
|
165
|
+
data[tag] = yield TagDependency.getTagVersion(tag);
|
|
82
166
|
}
|
|
83
167
|
return data;
|
|
84
168
|
});
|
|
@@ -89,7 +173,7 @@ class TagDependency {
|
|
|
89
173
|
return true;
|
|
90
174
|
}
|
|
91
175
|
for (const tag of this.tags) {
|
|
92
|
-
const currentVersion = TagDependency.getTagVersion(tag);
|
|
176
|
+
const currentVersion = yield TagDependency.getTagVersion(tag);
|
|
93
177
|
const oldVersion = oldData[tag];
|
|
94
178
|
if (currentVersion !== oldVersion) {
|
|
95
179
|
return true;
|
|
@@ -101,11 +185,16 @@ class TagDependency {
|
|
|
101
185
|
reset() {
|
|
102
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
103
187
|
for (const tag of this.tags) {
|
|
104
|
-
TagDependency.invalidateTag(tag);
|
|
188
|
+
yield TagDependency.invalidateTag(tag);
|
|
105
189
|
}
|
|
106
190
|
});
|
|
107
191
|
}
|
|
108
192
|
}
|
|
109
193
|
exports.TagDependency = TagDependency;
|
|
110
194
|
TagDependency.PREFIX = 'cache:tag:';
|
|
195
|
+
TagDependency.REDIS_KEY_PREFIX = 'cache:tag:versions';
|
|
196
|
+
TagDependency.logger = new common_1.Logger(TagDependency.name);
|
|
197
|
+
// In-memory fallback for when Redis is not available
|
|
111
198
|
TagDependency.tagVersions = new Map();
|
|
199
|
+
// Redis client for distributed tag version storage
|
|
200
|
+
TagDependency.redis = null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './typeorm-cache.entity';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./typeorm-cache.entity"), exports);
|