@nest-omni/core 4.1.3-2 → 4.1.3-22
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 +11 -0
- package/audit/audit.module.js +65 -1
- package/audit/controllers/audit.controller.d.ts +81 -1
- package/audit/controllers/audit.controller.js +67 -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 +9 -1
- package/audit/decorators/audit-controller.decorator.js +11 -2
- package/audit/decorators/audit-operation.decorator.d.ts +38 -0
- package/audit/decorators/audit-operation.decorator.js +42 -0
- package/audit/decorators/entity-audit.decorator.d.ts +85 -1
- package/audit/decorators/entity-audit.decorator.js +153 -3
- 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/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/index.d.ts +1 -0
- package/audit/dto/index.js +1 -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/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 +10 -2
- package/audit/entities/entity-audit-log.entity.js +48 -9
- package/audit/entities/entity-transaction.entity.d.ts +11 -2
- package/audit/entities/entity-transaction.entity.js +42 -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 +4 -2
- package/audit/entities/manual-operation-log.entity.js +12 -9
- 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 +29 -6
- package/audit/enums/audit.enums.js +31 -7
- 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 +38 -1
- package/audit/interceptors/audit-action.interceptor.d.ts +38 -0
- package/audit/interceptors/audit-action.interceptor.js +215 -0
- package/audit/interceptors/audit.interceptor.d.ts +16 -0
- package/audit/interceptors/audit.interceptor.js +41 -11
- package/audit/interceptors/index.d.ts +1 -0
- package/audit/interceptors/index.js +1 -0
- package/audit/interfaces/audit.interfaces.d.ts +174 -4
- package/audit/services/audit-action.service.d.ts +141 -0
- package/audit/services/audit-action.service.js +244 -0
- package/audit/services/audit-context.service.d.ts +106 -0
- package/audit/services/audit-context.service.js +185 -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 +273 -5
- package/audit/services/entity-audit.service.js +840 -60
- package/audit/services/index.d.ts +3 -0
- package/audit/services/index.js +3 -0
- package/audit/services/manual-audit-log.service.d.ts +133 -9
- package/audit/services/manual-audit-log.service.js +157 -42
- package/audit/services/multi-database.service.d.ts +9 -2
- package/audit/services/multi-database.service.js +9 -21
- package/audit/services/operation-description.service.d.ts +71 -2
- package/audit/services/operation-description.service.js +231 -20
- package/audit/services/transaction-audit.service.d.ts +30 -0
- package/audit/services/transaction-audit.service.js +53 -5
- package/audit/subscribers/entity-audit.subscriber.d.ts +20 -0
- package/audit/subscribers/entity-audit.subscriber.js +98 -6
- 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 +87 -2
- package/cache/cache.module.js +84 -11
- package/cache/cache.service.d.ts +143 -3
- package/cache/cache.service.js +173 -4
- 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 +83 -7
- package/cache/dependencies/db.dependency.js +89 -14
- package/cache/dependencies/file.dependency.d.ts +32 -0
- package/cache/dependencies/file.dependency.js +34 -0
- package/cache/dependencies/tag.dependency.d.ts +75 -4
- package/cache/dependencies/tag.dependency.js +145 -11
- package/cache/dependencies/time.dependency.d.ts +43 -0
- package/cache/dependencies/time.dependency.js +43 -0
- 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/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.d.ts +2 -1
- package/cache/index.js +28 -2
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +89 -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/index.d.ts +2 -1
- package/cache/providers/index.js +2 -1
- package/cache/providers/lrucache.provider.d.ts +76 -0
- package/cache/providers/lrucache.provider.js +226 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/providers/typeorm-cache.provider.d.ts +211 -0
- package/cache/providers/typeorm-cache.provider.js +483 -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 +143 -0
- package/common/boilerplate.polyfill.js +35 -1
- 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/helpers/validation-metadata-helper.d.ts +55 -0
- package/common/helpers/validation-metadata-helper.js +60 -0
- package/common/index.d.ts +1 -0
- package/common/index.js +4 -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.d.ts +72 -3
- package/decorators/field.decorators.js +155 -19
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -2
- package/decorators/transform.decorators.js +29 -23
- 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/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.js +19 -4
- 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 +20 -0
- package/http-client/config/http-client.config.js +48 -21
- package/http-client/decorators/http-client.decorators.d.ts +55 -14
- package/http-client/decorators/http-client.decorators.js +154 -78
- package/http-client/entities/http-log.entity.d.ts +217 -8
- package/http-client/entities/http-log.entity.js +7 -22
- 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 +40 -0
- package/http-client/examples/advanced-usage.example.js +53 -61
- 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/examples/proxy-from-environment.example.d.ts +133 -0
- package/http-client/examples/proxy-from-environment.example.js +409 -0
- package/http-client/http-client.module.d.ts +48 -2
- package/http-client/http-client.module.js +147 -68
- package/http-client/index.d.ts +1 -1
- package/http-client/index.js +8 -0
- package/http-client/interfaces/api-client-config.interface.d.ts +80 -45
- package/http-client/interfaces/api-client-config.interface.js +3 -0
- package/http-client/interfaces/http-client-config.interface.d.ts +109 -52
- package/http-client/services/api-client-registry.service.d.ts +50 -11
- package/http-client/services/api-client-registry.service.js +90 -250
- package/http-client/services/circuit-breaker.service.d.ts +115 -2
- package/http-client/services/circuit-breaker.service.js +237 -7
- package/http-client/services/http-client.service.d.ts +124 -14
- package/http-client/services/http-client.service.js +437 -148
- package/http-client/services/http-log-query.service.d.ts +83 -0
- package/http-client/services/http-log-query.service.js +121 -13
- 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/index.d.ts +0 -1
- package/http-client/services/index.js +0 -1
- 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 +116 -7
- package/http-client/services/logging.service.js +349 -86
- package/http-client/utils/call-stack-extractor.util.d.ts +63 -0
- package/http-client/utils/call-stack-extractor.util.js +83 -0
- package/http-client/utils/context-extractor.util.d.ts +49 -0
- package/http-client/utils/context-extractor.util.js +54 -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/index.d.ts +1 -0
- package/http-client/utils/index.js +1 -0
- package/http-client/utils/proxy-environment.util.d.ts +42 -0
- package/http-client/utils/proxy-environment.util.js +148 -0
- 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/http-client/utils/security-validator.util.d.ts +118 -0
- package/http-client/utils/security-validator.util.js +352 -0
- package/index.d.ts +3 -1
- package/index.js +12 -1
- package/interceptors/translation-interceptor.service.js +5 -0
- 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 +32 -29
- package/providers/context.provider.d.ts +9 -0
- package/providers/context.provider.js +15 -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 +80 -0
- package/redis-lock/lock-heartbeat.service.js +232 -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 +282 -0
- package/redis-lock/redis-lock.service.js +343 -20
- package/setup/bootstrap.setup.d.ts +2 -1
- package/setup/bootstrap.setup.js +22 -1
- package/setup/index.d.ts +1 -0
- package/setup/index.js +1 -0
- package/setup/mode.setup.d.ts +44 -0
- package/setup/mode.setup.js +44 -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 +227 -0
- package/setup/schedule.decorator.js +240 -12
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +97 -0
- package/shared/index.d.ts +1 -1
- package/shared/index.js +1 -1
- package/shared/{serviceRegistryModule.js → service-registry.module.js} +19 -18
- package/shared/services/api-config.service.d.ts +3 -0
- package/shared/services/api-config.service.js +21 -9
- package/shared/services/index.d.ts +0 -1
- package/shared/services/index.js +0 -1
- 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 +108 -0
- package/validators/custom-validate.validator.js +85 -0
- package/validators/file-mimetype.validator.d.ts +0 -2
- package/validators/file-mimetype.validator.js +4 -6
- package/validators/index.d.ts +1 -0
- package/validators/index.js +1 -0
- package/validators/is-exists.validator.d.ts +26 -6
- package/validators/is-exists.validator.js +30 -7
- package/validators/is-unique.validator.d.ts +33 -7
- package/validators/is-unique.validator.js +59 -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/cache/providers/memory-cache.provider.d.ts +0 -26
- package/cache/providers/memory-cache.provider.js +0 -171
- package/decorators/examples/validation-decorators.example.d.ts +0 -69
- package/decorators/examples/validation-decorators.example.js +0 -331
- package/http-client/services/cache.service.d.ts +0 -24
- package/http-client/services/cache.service.js +0 -264
- 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
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var LockHeartbeatService_1;
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.LockHeartbeatService = void 0;
|
|
23
|
+
const common_1 = require("@nestjs/common");
|
|
24
|
+
/**
|
|
25
|
+
* Lock heartbeat service
|
|
26
|
+
*
|
|
27
|
+
* Provides heartbeat mechanism for distributed lock instances.
|
|
28
|
+
* Each instance sends periodic heartbeats to Redis to indicate it's alive.
|
|
29
|
+
* Dead instances can be detected by checking if their heartbeat has expired.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* constructor(private heartbeatService: LockHeartbeatService) {}
|
|
34
|
+
*
|
|
35
|
+
* async isInstanceAlive(instanceId: string): Promise<boolean> {
|
|
36
|
+
* return this.heartbeatService.isInstanceAlive(instanceId);
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
let LockHeartbeatService = LockHeartbeatService_1 = class LockHeartbeatService {
|
|
41
|
+
constructor() {
|
|
42
|
+
this.logger = new common_1.Logger(LockHeartbeatService_1.name);
|
|
43
|
+
this.redis = null;
|
|
44
|
+
this.heartbeatTimer = null;
|
|
45
|
+
/**
|
|
46
|
+
* Heartbeat interval in milliseconds
|
|
47
|
+
* @default 5000 (5 seconds) - reduced for faster failure detection
|
|
48
|
+
*/
|
|
49
|
+
this.heartbeatInterval = 5000;
|
|
50
|
+
/**
|
|
51
|
+
* Heartbeat TTL in seconds (3x interval for safety)
|
|
52
|
+
* @default 15 (15 seconds) - adjusted to match new interval
|
|
53
|
+
*/
|
|
54
|
+
this.heartbeatTtl = 15;
|
|
55
|
+
this.instanceId = this.getInstanceId();
|
|
56
|
+
}
|
|
57
|
+
onModuleInit() {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
if (!this.redis) {
|
|
60
|
+
this.logger.warn('LockHeartbeatService initialized but no Redis client provided. Heartbeat functionality will not work.');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Send initial heartbeat
|
|
64
|
+
yield this.sendHeartbeat();
|
|
65
|
+
// Start periodic heartbeat
|
|
66
|
+
this.heartbeatTimer = setInterval(() => {
|
|
67
|
+
this.sendHeartbeat().catch((error) => {
|
|
68
|
+
this.logger.error('Failed to send heartbeat:', error);
|
|
69
|
+
});
|
|
70
|
+
}, this.heartbeatInterval);
|
|
71
|
+
this.logger.log(`Heartbeat started for instance: ${this.instanceId}`);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
onModuleDestroy() {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
// Stop heartbeat timer
|
|
77
|
+
if (this.heartbeatTimer) {
|
|
78
|
+
clearInterval(this.heartbeatTimer);
|
|
79
|
+
this.heartbeatTimer = null;
|
|
80
|
+
}
|
|
81
|
+
// Remove heartbeat record
|
|
82
|
+
yield this.removeHeartbeat();
|
|
83
|
+
this.logger.log('Heartbeat stopped');
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Set Redis client (required for dependency injection)
|
|
88
|
+
*/
|
|
89
|
+
setRedisClient(redis) {
|
|
90
|
+
this.redis = redis;
|
|
91
|
+
this.logger.log('Redis client set for LockHeartbeatService');
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Send heartbeat to Redis
|
|
95
|
+
* Stores instance information with TTL
|
|
96
|
+
*/
|
|
97
|
+
sendHeartbeat() {
|
|
98
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
+
if (!this.redis) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const key = `heartbeat:${this.instanceId}`;
|
|
103
|
+
const data = {
|
|
104
|
+
instanceId: this.instanceId,
|
|
105
|
+
timestamp: Date.now(),
|
|
106
|
+
pid: process.pid,
|
|
107
|
+
};
|
|
108
|
+
try {
|
|
109
|
+
// Set heartbeat with TTL (3x interval for safety)
|
|
110
|
+
yield this.redis.setex(key, this.heartbeatTtl, JSON.stringify(data));
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
this.logger.error('Error sending heartbeat:', error);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Remove heartbeat record from Redis
|
|
119
|
+
*/
|
|
120
|
+
removeHeartbeat() {
|
|
121
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
122
|
+
if (!this.redis) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const key = `heartbeat:${this.instanceId}`;
|
|
126
|
+
try {
|
|
127
|
+
yield this.redis.del(key);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
this.logger.error('Error removing heartbeat:', error);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if an instance is alive by checking its heartbeat
|
|
136
|
+
*
|
|
137
|
+
* @param instanceId - Instance identifier to check
|
|
138
|
+
* @returns True if instance is alive (heartbeat exists), false otherwise
|
|
139
|
+
*/
|
|
140
|
+
isInstanceAlive(instanceId) {
|
|
141
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
if (!this.redis) {
|
|
143
|
+
this.logger.warn('Redis client not available, cannot check instance status');
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
const key = `heartbeat:${instanceId}`;
|
|
147
|
+
try {
|
|
148
|
+
const exists = yield this.redis.exists(key);
|
|
149
|
+
return exists === 1;
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
this.logger.error(`Error checking instance ${instanceId} status:`, error);
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get heartbeat information for an instance
|
|
159
|
+
*
|
|
160
|
+
* @param instanceId - Instance identifier
|
|
161
|
+
* @returns Heartbeat data or null if not found
|
|
162
|
+
*/
|
|
163
|
+
getHeartbeatInfo(instanceId) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
if (!this.redis) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const key = `heartbeat:${instanceId}`;
|
|
169
|
+
try {
|
|
170
|
+
const data = yield this.redis.get(key);
|
|
171
|
+
if (!data) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
return JSON.parse(data);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
this.logger.error(`Error getting heartbeat info for ${instanceId}:`, error);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get all active instances (with heartbeat)
|
|
184
|
+
*
|
|
185
|
+
* **Note**: Uses SCAN command to avoid blocking Redis in production.
|
|
186
|
+
*
|
|
187
|
+
* @returns Array of instance IDs that are currently alive
|
|
188
|
+
*/
|
|
189
|
+
getActiveInstances() {
|
|
190
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
191
|
+
if (!this.redis) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
let cursor = '0';
|
|
196
|
+
const pattern = 'heartbeat:*';
|
|
197
|
+
const allKeys = [];
|
|
198
|
+
// Use SCAN to iterate through keys without blocking Redis
|
|
199
|
+
do {
|
|
200
|
+
const [nextCursor, keys] = yield this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
|
|
201
|
+
cursor = nextCursor;
|
|
202
|
+
allKeys.push(...keys);
|
|
203
|
+
} while (cursor !== '0');
|
|
204
|
+
return allKeys.map((key) => key.replace('heartbeat:', ''));
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
this.logger.error('Error getting active instances:', error);
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get current instance ID
|
|
214
|
+
*/
|
|
215
|
+
getInstanceId() {
|
|
216
|
+
// 1. Kubernetes Pod name
|
|
217
|
+
if (process.env.HOSTNAME) {
|
|
218
|
+
return process.env.HOSTNAME;
|
|
219
|
+
}
|
|
220
|
+
// 2. Custom instance ID
|
|
221
|
+
if (process.env.INSTANCE_ID) {
|
|
222
|
+
return process.env.INSTANCE_ID;
|
|
223
|
+
}
|
|
224
|
+
// 3. Generate unique ID
|
|
225
|
+
return `instance-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
exports.LockHeartbeatService = LockHeartbeatService;
|
|
229
|
+
exports.LockHeartbeatService = LockHeartbeatService = LockHeartbeatService_1 = __decorate([
|
|
230
|
+
(0, common_1.Injectable)(),
|
|
231
|
+
__metadata("design:paramtypes", [])
|
|
232
|
+
], LockHeartbeatService);
|
|
@@ -1,12 +1,113 @@
|
|
|
1
1
|
import type { LockOptions } from './redis-lock.service';
|
|
2
2
|
import { RedisLockService } from './redis-lock.service';
|
|
3
|
+
/**
|
|
4
|
+
* Set global LockService instance
|
|
5
|
+
* Called by RedisLockModule during initialization
|
|
6
|
+
*/
|
|
3
7
|
export declare function setLockService(lockService: RedisLockService): void;
|
|
8
|
+
/**
|
|
9
|
+
* Get global LockService instance
|
|
10
|
+
*/
|
|
4
11
|
export declare function getLockService(): RedisLockService | null;
|
|
12
|
+
/**
|
|
13
|
+
* Method decorator that wraps the method execution with a distributed Redis lock
|
|
14
|
+
*
|
|
15
|
+
* This decorator automatically acquires a lock before executing the method
|
|
16
|
+
* and releases it afterwards. If the lock cannot be acquired, the method
|
|
17
|
+
* execution is skipped and returns null (or the value specified in skipReturnValue).
|
|
18
|
+
*
|
|
19
|
+
* @param lockKey - The Redis lock key (required)
|
|
20
|
+
* @param options - Lock options
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* @Injectable()
|
|
25
|
+
* class MyService {
|
|
26
|
+
* @UseRedisLock('my-task', { ttl: 60000 })
|
|
27
|
+
* async processTask() {
|
|
28
|
+
* // This will only execute if the lock is acquired
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
5
33
|
export declare function UseRedisLock(lockKey: string, options?: LockOptions & {
|
|
6
34
|
skipReturnValue?: any;
|
|
7
35
|
}): MethodDecorator;
|
|
36
|
+
/**
|
|
37
|
+
* Simplified decorator for methods that should skip execution if lock cannot be acquired
|
|
38
|
+
* Returns false when skipped, true when executed successfully
|
|
39
|
+
*
|
|
40
|
+
* @param lockKey - The Redis lock key (required)
|
|
41
|
+
* @param ttl - Lock TTL in milliseconds (default: 300000 / 5 minutes)
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* @Injectable()
|
|
46
|
+
* class MyScheduler {
|
|
47
|
+
* @Cron('0 * * * *')
|
|
48
|
+
* @UseRedisLockOrSkip('hourly-task', 3600000)
|
|
49
|
+
* async hourlyTask() {
|
|
50
|
+
* // This will only execute on one instance
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
8
55
|
export declare function UseRedisLockOrSkip(lockKey: string, ttl?: number): MethodDecorator;
|
|
56
|
+
/**
|
|
57
|
+
* Smart decorator that auto-generates lock key from class and method name
|
|
58
|
+
* Lock key format: ClassName:methodName
|
|
59
|
+
*
|
|
60
|
+
* This decorator is useful for simple cases where you don't need custom lock keys.
|
|
61
|
+
*
|
|
62
|
+
* @param options - Lock options
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* @Injectable()
|
|
67
|
+
* class MyService {
|
|
68
|
+
* // Lock key will be auto-generated as "MyService:processData"
|
|
69
|
+
* @UseRedisLockSmart({ ttl: 60000 })
|
|
70
|
+
* async processData() {
|
|
71
|
+
* // Business logic
|
|
72
|
+
* }
|
|
73
|
+
*
|
|
74
|
+
* // With strategy
|
|
75
|
+
* @UseRedisLockSmart({
|
|
76
|
+
* ttl: 120000,
|
|
77
|
+
* strategy: LockStrategy.WAIT,
|
|
78
|
+
* waitTimeout: 60000,
|
|
79
|
+
* })
|
|
80
|
+
* async generateReport() {
|
|
81
|
+
* // Business logic
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
9
86
|
export declare function UseRedisLockSmart(options?: LockOptions & {
|
|
10
87
|
skipReturnValue?: any;
|
|
11
88
|
}): MethodDecorator;
|
|
89
|
+
/**
|
|
90
|
+
* Smart decorator for simple skip-on-busy scenarios with auto-generated lock key
|
|
91
|
+
* Lock key format: ClassName:methodName
|
|
92
|
+
*
|
|
93
|
+
* @param ttl - Lock TTL in milliseconds (default: 300000 / 5 minutes)
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* @Injectable()
|
|
98
|
+
* class MyScheduler {
|
|
99
|
+
* @Cron('0 * * * *')
|
|
100
|
+
* @UseRedisLockOrSkipSmart(3600000) // 1 hour TTL
|
|
101
|
+
* async hourlyTask() {
|
|
102
|
+
* // Lock key: "MyScheduler:hourlyTask"
|
|
103
|
+
* }
|
|
104
|
+
*
|
|
105
|
+
* @Cron('0 0 * * *')
|
|
106
|
+
* @UseRedisLockOrSkipSmart() // Default 5 minutes TTL
|
|
107
|
+
* async dailyTask() {
|
|
108
|
+
* // Lock key: "MyScheduler:dailyTask"
|
|
109
|
+
* }
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
12
113
|
export declare function UseRedisLockOrSkipSmart(ttl?: number): MethodDecorator;
|
|
@@ -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,84 @@
|
|
|
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;
|
|
37
|
+
/**
|
|
38
|
+
* Enable automatic lock cleanup on startup
|
|
39
|
+
* This includes heartbeat mechanism and comprehensive cleanup
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
enableCleanup?: boolean;
|
|
11
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Redis Lock module with distributed locking support
|
|
46
|
+
*
|
|
47
|
+
* Provides RedisLockService and @UseRedisLock decorator for
|
|
48
|
+
* distributed locking mechanisms using Redis.
|
|
49
|
+
*
|
|
50
|
+
* Requires an external Redis client to function.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* // With Redis client injection
|
|
55
|
+
* import { RedisModule } from '@songkeys/nestjs-redis';
|
|
56
|
+
*
|
|
57
|
+
* @Module({
|
|
58
|
+
* imports: [
|
|
59
|
+
* RedisModule.forRoot({ ... }),
|
|
60
|
+
* RedisLockModule.forRootAsync({
|
|
61
|
+
* imports: [RedisModule],
|
|
62
|
+
* inject: [RedisService],
|
|
63
|
+
* useFactory: (redisService: RedisService) => ({
|
|
64
|
+
* redisClient: redisService.getClient()
|
|
65
|
+
* })
|
|
66
|
+
* })
|
|
67
|
+
* ]
|
|
68
|
+
* })
|
|
69
|
+
* export class AppModule {}
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
12
72
|
export declare class RedisLockModule implements OnModuleInit {
|
|
13
73
|
private redisLockService;
|
|
14
74
|
constructor();
|
|
75
|
+
/**
|
|
76
|
+
* Register Redis Lock module with options
|
|
77
|
+
*/
|
|
15
78
|
static forRoot(options: RedisLockModuleOptions): DynamicModule;
|
|
79
|
+
/**
|
|
80
|
+
* Register Redis Lock module asynchronously
|
|
81
|
+
*/
|
|
16
82
|
static forRootAsync(options: {
|
|
17
83
|
imports?: any[];
|
|
18
84
|
inject?: any[];
|