@nest-omni/core 4.1.3-2 → 4.1.3-20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/audit/audit.module.d.ts +10 -0
- package/audit/audit.module.js +63 -1
- package/audit/controllers/audit.controller.d.ts +88 -0
- package/audit/controllers/audit.controller.js +74 -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 +45 -0
- package/audit/decorators/audit-operation.decorator.js +49 -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-log-query.dto.d.ts +3 -0
- package/audit/dto/audit-log-query.dto.js +3 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +3 -0
- package/audit/dto/compare-entities.dto.d.ts +3 -0
- package/audit/dto/compare-entities.dto.js +3 -0
- package/audit/dto/pre-check-restore.dto.d.ts +3 -0
- package/audit/dto/pre-check-restore.dto.js +3 -0
- package/audit/dto/restore-entity.dto.d.ts +3 -0
- package/audit/dto/restore-entity.dto.js +3 -0
- package/audit/entities/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 +11 -0
- package/audit/entities/entity-audit-log.entity.js +57 -2
- 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 -0
- package/audit/entities/manual-operation-log.entity.js +12 -1
- 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 +37 -6
- package/audit/enums/audit.enums.js +40 -7
- package/audit/index.d.ts +4 -1
- package/audit/index.js +34 -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 +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interceptors/index.d.ts +1 -0
- package/audit/interceptors/index.js +1 -0
- package/audit/interfaces/audit.interfaces.d.ts +187 -2
- 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 +97 -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 +230 -3
- package/audit/services/entity-audit.service.js +607 -14
- package/audit/services/index.d.ts +3 -0
- package/audit/services/index.js +3 -0
- package/audit/services/manual-audit-log.service.d.ts +134 -9
- package/audit/services/manual-audit-log.service.js +157 -40
- 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 +19 -0
- package/audit/subscribers/entity-audit.subscriber.js +76 -1
- package/cache/cache-metrics.service.d.ts +67 -0
- package/cache/cache-metrics.service.js +68 -4
- package/cache/cache-serialization.service.d.ts +31 -0
- package/cache/cache-serialization.service.js +25 -0
- package/cache/cache.constants.d.ts +9 -0
- package/cache/cache.constants.js +9 -0
- package/cache/cache.health.d.ts +26 -0
- package/cache/cache.health.js +30 -0
- package/cache/cache.module.d.ts +82 -2
- package/cache/cache.module.js +76 -5
- package/cache/cache.service.d.ts +140 -0
- package/cache/cache.service.js +169 -0
- package/cache/cache.warmup.service.d.ts +39 -0
- package/cache/cache.warmup.service.js +32 -0
- package/cache/decorators/cache-evict.decorator.d.ts +47 -0
- package/cache/decorators/cache-evict.decorator.js +56 -0
- package/cache/decorators/cache-put.decorator.d.ts +34 -0
- package/cache/decorators/cache-put.decorator.js +39 -0
- package/cache/decorators/cacheable.decorator.d.ts +40 -0
- package/cache/decorators/cacheable.decorator.js +55 -0
- package/cache/dependencies/callback.dependency.d.ts +33 -0
- package/cache/dependencies/callback.dependency.js +39 -1
- package/cache/dependencies/chain.dependency.d.ts +28 -0
- package/cache/dependencies/chain.dependency.js +34 -0
- package/cache/dependencies/db.dependency.d.ts +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/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.js +9 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +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/memory-cache.provider.d.ts +43 -0
- package/cache/providers/memory-cache.provider.js +66 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/utils/dependency-manager.util.d.ts +52 -0
- package/cache/utils/dependency-manager.util.js +59 -0
- package/cache/utils/key-generator.util.d.ts +42 -0
- package/cache/utils/key-generator.util.js +53 -1
- package/common/abstract.entity.d.ts +14 -0
- package/common/abstract.entity.js +14 -0
- package/common/boilerplate.polyfill.d.ts +142 -0
- package/common/boilerplate.polyfill.js +18 -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/utils.d.ts +15 -0
- package/common/utils.js +15 -0
- package/constants/language-code.js +1 -0
- package/decorators/field.decorators.d.ts +1 -1
- package/decorators/field.decorators.js +8 -1
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -0
- package/decorators/transform.decorators.js +29 -0
- package/decorators/translate.decorator.js +1 -0
- package/decorators/user.decorator.js +1 -0
- package/decorators/validator.decorators.d.ts +8 -18
- package/decorators/validator.decorators.js +22 -190
- package/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/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 +52 -0
- package/http-client/utils/curl-generator.util.d.ts +21 -0
- package/http-client/utils/curl-generator.util.js +44 -3
- package/http-client/utils/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/package.json +11 -7
- package/providers/context.provider.js +2 -0
- package/providers/generator.provider.d.ts +4 -0
- package/providers/generator.provider.js +4 -0
- package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
- package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
- package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
- package/redis-lock/examples/lock-strategy.examples.js +130 -15
- package/redis-lock/index.d.ts +2 -0
- package/redis-lock/index.js +8 -1
- package/redis-lock/lock-heartbeat.service.d.ts +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 +1 -0
- package/setup/bootstrap.setup.js +21 -0
- 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 -17
- 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/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
|
@@ -22,21 +22,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
22
22
|
exports.HttpClientService = void 0;
|
|
23
23
|
const common_1 = require("@nestjs/common");
|
|
24
24
|
const axios_retry_1 = require("axios-retry");
|
|
25
|
-
const
|
|
25
|
+
const api_client_config_interface_1 = require("../interfaces/api-client-config.interface");
|
|
26
26
|
const circuit_breaker_service_1 = require("./circuit-breaker.service");
|
|
27
27
|
const logging_service_1 = require("./logging.service");
|
|
28
|
-
const cache_service_1 = require("./cache.service");
|
|
29
28
|
const decorators_1 = require("../decorators");
|
|
30
29
|
const context_extractor_util_1 = require("../utils/context-extractor.util");
|
|
31
30
|
const curl_generator_util_1 = require("../utils/curl-generator.util");
|
|
31
|
+
const call_stack_extractor_util_1 = require("../utils/call-stack-extractor.util");
|
|
32
32
|
const retry_recorder_util_1 = require("../utils/retry-recorder.util");
|
|
33
33
|
const request_id_util_1 = require("../utils/request-id.util");
|
|
34
|
+
const proxy_environment_util_1 = require("../utils/proxy-environment.util");
|
|
34
35
|
const redis_lock_service_1 = require("../../redis-lock/redis-lock.service");
|
|
36
|
+
const security_validator_util_1 = require("../utils/security-validator.util");
|
|
37
|
+
/**
|
|
38
|
+
* HTTP客户端服务
|
|
39
|
+
* 基于Spring RestTemplate的设计理念,集成axios-retry库
|
|
40
|
+
* 支持两种创建模式:
|
|
41
|
+
* 1. 直接创建: 用于简单的HTTP请求场景
|
|
42
|
+
* 2. API客户端模式: 用于需要认证、统计等高级功能的API客户端
|
|
43
|
+
*/
|
|
35
44
|
let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
36
|
-
constructor(circuitBreakerService, loggingService,
|
|
45
|
+
constructor(circuitBreakerService, loggingService, redisLockService, config = {}, clientName, authConfig) {
|
|
37
46
|
this.circuitBreakerService = circuitBreakerService;
|
|
38
47
|
this.loggingService = loggingService;
|
|
39
|
-
this.cacheService = cacheService;
|
|
40
48
|
this.redisLockService = redisLockService;
|
|
41
49
|
this.logger = new common_1.Logger(HttpClientService_1.name);
|
|
42
50
|
this.requestStats = {
|
|
@@ -44,158 +52,265 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
44
52
|
successfulRequests: 0,
|
|
45
53
|
failedRequests: 0,
|
|
46
54
|
totalResponseTime: 0,
|
|
55
|
+
averageResponseTime: 0,
|
|
47
56
|
requestsByMethod: {},
|
|
48
57
|
requestsByStatus: {},
|
|
49
58
|
};
|
|
50
59
|
this.defaultConfig = this.mergeWithDefaults(config);
|
|
60
|
+
this.clientName = clientName;
|
|
61
|
+
this.authConfig = authConfig;
|
|
51
62
|
this.axiosInstance = this.createAxiosInstance();
|
|
52
63
|
}
|
|
53
|
-
|
|
64
|
+
/**
|
|
65
|
+
* 静态工厂方法:创建API客户端模式的 HttpClientService
|
|
66
|
+
* @param dependencies 依赖服务
|
|
67
|
+
* @param config API客户端配置
|
|
68
|
+
* @returns HttpClientService 实例
|
|
69
|
+
*/
|
|
70
|
+
static createApiClient(dependencies, config) {
|
|
71
|
+
return new HttpClientService_1(dependencies.circuitBreakerService, dependencies.loggingService, dependencies.redisLockService, Object.assign({ baseURL: config.baseURL, timeout: config.timeout || 30000 }, config.httpConfig), config.name, config.auth);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 执行HTTP请求
|
|
75
|
+
*/
|
|
76
|
+
request(config, decoratorContext, clientName) {
|
|
54
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
78
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
79
|
+
// Use the instance's clientName as fallback if not provided
|
|
80
|
+
const effectiveClientName = clientName || this.clientName;
|
|
81
|
+
// If no decorator context provided, try to get it from CallStackExtractor
|
|
82
|
+
// This allows decorators on service methods to pass context to HTTP client
|
|
83
|
+
const effectiveDecoratorContext = decoratorContext || call_stack_extractor_util_1.CallStackExtractor.getDecoratorContext();
|
|
84
|
+
// ========== 安全验证开始 ==========
|
|
85
|
+
// 构造完整URL进行验证
|
|
86
|
+
const fullURL = config.url || '';
|
|
87
|
+
const baseURL = config.baseURL || this.defaultConfig.baseURL || '';
|
|
88
|
+
// 执行URL安全验证
|
|
89
|
+
const sanitizeResult = security_validator_util_1.SecurityValidator.sanitizeURL(fullURL, {
|
|
90
|
+
urlConfig: (_a = this.defaultConfig.security) === null || _a === void 0 ? void 0 : _a.urlValidation,
|
|
91
|
+
ssrfConfig: (_b = this.defaultConfig.security) === null || _b === void 0 ? void 0 : _b.ssrfProtection,
|
|
92
|
+
});
|
|
93
|
+
if (!sanitizeResult.valid) {
|
|
94
|
+
const error = new Error(`URL validation failed: ${sanitizeResult.error}`);
|
|
95
|
+
this.logger.error(`URL validation failed for ${fullURL}: ${sanitizeResult.error}`);
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
// 如果URL被修改,更新配置
|
|
99
|
+
if (sanitizeResult.url !== fullURL) {
|
|
100
|
+
config.url = sanitizeResult.url;
|
|
101
|
+
this.logger.debug(`URL sanitized from "${fullURL}" to "${sanitizeResult.url}"`);
|
|
102
|
+
}
|
|
103
|
+
// ========== 安全验证结束 ==========
|
|
104
|
+
// Capture the calling context information
|
|
105
|
+
const callingContext = this.captureCallingContext();
|
|
56
106
|
const startTime = Date.now();
|
|
57
107
|
const retryRecorder = retry_recorder_util_1.RetryRecorder.create();
|
|
58
108
|
let requestId;
|
|
59
109
|
let circuitBreakerState;
|
|
60
|
-
let cacheHit = false;
|
|
61
110
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
111
|
+
// 应用认证配置
|
|
112
|
+
let authConfig = yield this.applyAuthToConfig(config);
|
|
113
|
+
// 应用装饰器配置
|
|
114
|
+
const enhancedConfig = this.applyDecoratorConfig(authConfig, decoratorContext);
|
|
115
|
+
// 将 retryRecorder 存储到 config metadata 中,供 onRetry 回调使用
|
|
116
|
+
enhancedConfig.metadata = enhancedConfig.metadata || {};
|
|
117
|
+
enhancedConfig.metadata.retryRecorder = retryRecorder;
|
|
118
|
+
// 获取装饰器配置
|
|
119
|
+
const decoratorConfigs = effectiveDecoratorContext
|
|
120
|
+
? decorators_1.HttpDecoratorUtils.getAllDecoratorConfigs(effectiveDecoratorContext.target, effectiveDecoratorContext.propertyKey)
|
|
65
121
|
: {};
|
|
66
|
-
|
|
122
|
+
// 日志记录开始
|
|
123
|
+
const decoratorLogging = decoratorConfigs.logging || {};
|
|
124
|
+
this.logger.debug(`Logging config merge: decoratorLogging=${JSON.stringify(decoratorLogging)}, defaultLogging=${JSON.stringify(this.defaultConfig.logging)}`);
|
|
125
|
+
const loggingOptions = Object.assign(Object.assign(Object.assign({}, this.defaultConfig.logging), decoratorLogging), { databaseLogging: (_c = this.defaultConfig.logging) === null || _c === void 0 ? void 0 : _c.databaseLogging });
|
|
126
|
+
this.logger.debug(`Merged loggingOptions: databaseLog=${loggingOptions.databaseLog}, hasDatabaseLogging=${!!loggingOptions.databaseLogging}`);
|
|
67
127
|
if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
|
|
68
128
|
requestId = this.loggingService.logRequestStart(enhancedConfig, loggingOptions);
|
|
129
|
+
// 将requestId保存到config中
|
|
69
130
|
enhancedConfig.metadata = enhancedConfig.metadata || {};
|
|
70
131
|
enhancedConfig.metadata.requestId = requestId;
|
|
71
132
|
}
|
|
72
|
-
|
|
73
|
-
if ((cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.enabled) &&
|
|
74
|
-
this.shouldCacheRequest(enhancedConfig, cacheConfig)) {
|
|
75
|
-
const cachedResponse = yield this.cacheService.get(enhancedConfig, cacheConfig);
|
|
76
|
-
if (cachedResponse) {
|
|
77
|
-
cacheHit = true;
|
|
78
|
-
if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
|
|
79
|
-
const databaseLogging = (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.databaseLog) ||
|
|
80
|
-
((_b = (_a = this.defaultConfig.logging) === null || _a === void 0 ? void 0 : _a.databaseLogging) === null || _b === void 0 ? void 0 : _b.enabled);
|
|
81
|
-
this.loggingService.logRequestSuccess(cachedResponse, startTime, requestId, loggingOptions, databaseLogging, undefined, cacheHit, undefined, decoratorContext);
|
|
82
|
-
}
|
|
83
|
-
return cachedResponse.data;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
133
|
+
// 应用超时配置
|
|
86
134
|
const timeout = decoratorConfigs.timeout || this.defaultConfig.timeout;
|
|
87
135
|
if (timeout) {
|
|
88
136
|
enhancedConfig.timeout = timeout;
|
|
89
137
|
}
|
|
138
|
+
// 应用代理配置
|
|
90
139
|
const proxyConfig = decoratorConfigs.proxy || this.defaultConfig.proxy;
|
|
91
140
|
if (proxyConfig === null || proxyConfig === void 0 ? void 0 : proxyConfig.enabled) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
auth: proxyConfig.auth,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
if ((_c = this.defaultConfig.retry) === null || _c === void 0 ? void 0 : _c.enabled) {
|
|
100
|
-
const originalOnRetry = this.defaultConfig.retry.onRetry;
|
|
101
|
-
this.defaultConfig.retry.onRetry = (retryCount, error, requestConfig) => {
|
|
102
|
-
const retryRecord = retry_recorder_util_1.RetryRecorder.recordRetry(retryCount, error, requestConfig, this.calculateRetryDelay(retryCount, this.defaultConfig.retry));
|
|
103
|
-
retryRecorder.addRecord(retryRecord);
|
|
104
|
-
if (originalOnRetry) {
|
|
105
|
-
originalOnRetry(retryCount, error, requestConfig);
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
const response = yield this.executeWithFeatures(enhancedConfig, decoratorConfigs, requestId, startTime, retryRecorder, (state) => {
|
|
110
|
-
circuitBreakerState = state;
|
|
111
|
-
});
|
|
112
|
-
if ((cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.enabled) &&
|
|
113
|
-
this.shouldCacheRequest(enhancedConfig, cacheConfig)) {
|
|
114
|
-
yield this.cacheService.set(enhancedConfig, response, cacheConfig);
|
|
141
|
+
const resolvedProxy = this.resolveProxyConfig(proxyConfig, enhancedConfig.url);
|
|
142
|
+
if (resolvedProxy !== false) {
|
|
143
|
+
enhancedConfig.proxy = resolvedProxy;
|
|
144
|
+
}
|
|
115
145
|
}
|
|
146
|
+
// 执行请求(带重试和熔断器)
|
|
147
|
+
const { response, circuitBreakerState: state } = yield this.executeWithFeatures(enhancedConfig, decoratorConfigs, requestId, startTime, retryRecorder);
|
|
148
|
+
// 更新 circuitBreakerState 变量
|
|
149
|
+
circuitBreakerState = state;
|
|
150
|
+
this.logger.debug(`Request completed, circuitBreakerState: ${circuitBreakerState || 'undefined'}`);
|
|
151
|
+
// 成功日志
|
|
116
152
|
if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
|
|
117
|
-
const databaseLogging = (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.
|
|
153
|
+
const databaseLogging = (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.databaseLogging) ||
|
|
118
154
|
((_e = (_d = this.defaultConfig.logging) === null || _d === void 0 ? void 0 : _d.databaseLogging) === null || _e === void 0 ? void 0 : _e.enabled);
|
|
119
|
-
this.
|
|
155
|
+
this.logger.debug(`Logging request success with circuitBreakerState: ${circuitBreakerState || 'undefined'}`);
|
|
156
|
+
this.loggingService.logRequestSuccess(response, startTime, requestId, loggingOptions, databaseLogging, retryRecorder.getRecords(), circuitBreakerState, decoratorContext, effectiveClientName, callingContext);
|
|
120
157
|
}
|
|
158
|
+
// 更新统计信息
|
|
159
|
+
this.updateRequestStats(true, Date.now() - startTime, response.config.method, response.status);
|
|
121
160
|
return response.data;
|
|
122
161
|
}
|
|
123
162
|
catch (error) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
163
|
+
// 错误日志
|
|
164
|
+
const decoratorLogging = effectiveDecoratorContext
|
|
165
|
+
? decorators_1.HttpDecoratorUtils.getLoggingOptions(effectiveDecoratorContext.target, effectiveDecoratorContext.propertyKey)
|
|
166
|
+
: {};
|
|
167
|
+
const loggingOptions = Object.assign(Object.assign(Object.assign({}, this.defaultConfig.logging), decoratorLogging), { databaseLogging: (_f = this.defaultConfig.logging) === null || _f === void 0 ? void 0 : _f.databaseLogging });
|
|
127
168
|
if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
|
|
128
169
|
const databaseLogging = (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.databaseLog) ||
|
|
129
|
-
((
|
|
130
|
-
|
|
170
|
+
((_h = (_g = this.defaultConfig.logging) === null || _g === void 0 ? void 0 : _g.databaseLogging) === null || _h === void 0 ? void 0 : _h.enabled);
|
|
171
|
+
const records = retryRecorder.getRecords();
|
|
172
|
+
this.loggingService.logRequestError(error, startTime, requestId, (records === null || records === void 0 ? void 0 : records.length) ? Math.max(...records.map((r) => r.attempt)) + 1 : 1, loggingOptions, databaseLogging, records, circuitBreakerState, effectiveDecoratorContext, effectiveClientName, callingContext);
|
|
131
173
|
}
|
|
174
|
+
// 更新统计信息
|
|
175
|
+
const errorMethod = (_j = error.config) === null || _j === void 0 ? void 0 : _j.method;
|
|
176
|
+
const errorStatus = (_k = error.response) === null || _k === void 0 ? void 0 : _k.status;
|
|
177
|
+
this.updateRequestStats(false, Date.now() - startTime, errorMethod, errorStatus);
|
|
132
178
|
throw error;
|
|
133
179
|
}
|
|
134
180
|
});
|
|
135
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* 生成curl命令(动态生成,不存储)
|
|
184
|
+
*/
|
|
136
185
|
generateCurlCommand(config) {
|
|
137
186
|
return curl_generator_util_1.CurlGenerator.generateSimplifiedCurl(config);
|
|
138
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* 生成调试curl命令(动态生成,不存储)
|
|
190
|
+
*/
|
|
139
191
|
generateDebugCurlCommand(config, response) {
|
|
140
192
|
return curl_generator_util_1.CurlGenerator.generateDebugCurl(config, response);
|
|
141
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* 获取请求统计信息
|
|
196
|
+
*/
|
|
142
197
|
getStats() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
:
|
|
146
|
-
|
|
198
|
+
return {
|
|
199
|
+
totalRequests: this.requestStats.totalRequests,
|
|
200
|
+
successfulRequests: this.requestStats.successfulRequests,
|
|
201
|
+
failedRequests: this.requestStats.failedRequests,
|
|
202
|
+
totalResponseTime: this.requestStats.totalResponseTime,
|
|
203
|
+
averageResponseTime: this.requestStats.averageResponseTime,
|
|
204
|
+
successRate: this.requestStats.totalRequests > 0
|
|
147
205
|
? (this.requestStats.successfulRequests /
|
|
148
206
|
this.requestStats.totalRequests) *
|
|
149
207
|
100
|
|
150
|
-
: 0,
|
|
208
|
+
: 0,
|
|
209
|
+
requestsByMethod: this.requestStats.requestsByMethod,
|
|
210
|
+
requestsByStatus: this.requestStats.requestsByStatus,
|
|
211
|
+
circuitBreakerStats: this.circuitBreakerService.getAllStates(),
|
|
212
|
+
};
|
|
151
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* 重置统计信息
|
|
216
|
+
*/
|
|
152
217
|
resetStats() {
|
|
153
218
|
this.requestStats = {
|
|
154
219
|
totalRequests: 0,
|
|
155
220
|
successfulRequests: 0,
|
|
156
221
|
failedRequests: 0,
|
|
157
222
|
totalResponseTime: 0,
|
|
223
|
+
averageResponseTime: 0,
|
|
158
224
|
requestsByMethod: {},
|
|
159
225
|
requestsByStatus: {},
|
|
160
226
|
};
|
|
161
227
|
}
|
|
162
|
-
|
|
228
|
+
/**
|
|
229
|
+
* 获取客户端名称
|
|
230
|
+
*/
|
|
231
|
+
getName() {
|
|
232
|
+
return this.clientName;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Capture calling context information
|
|
236
|
+
* @returns Calling context with service class and method name
|
|
237
|
+
*/
|
|
238
|
+
captureCallingContext() {
|
|
239
|
+
try {
|
|
240
|
+
// Use CallStackExtractor to get the calling context
|
|
241
|
+
const stackInfo = call_stack_extractor_util_1.CallStackExtractor.getCallInfo();
|
|
242
|
+
// Skip internal HTTP client calls
|
|
243
|
+
if (stackInfo.serviceClass && stackInfo.methodName) {
|
|
244
|
+
// Check if it's an internal call
|
|
245
|
+
const isInternal = call_stack_extractor_util_1.CallStackExtractor['isInternalCall'](stackInfo.serviceClass);
|
|
246
|
+
if (!isInternal) {
|
|
247
|
+
return {
|
|
248
|
+
serviceClass: stackInfo.serviceClass,
|
|
249
|
+
methodName: stackInfo.methodName,
|
|
250
|
+
operationName: stackInfo.operationName,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// If no useful context found, return empty
|
|
255
|
+
return {};
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
this.logger.warn('Failed to capture calling context:', error.message);
|
|
259
|
+
return {};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// 便捷方法
|
|
263
|
+
get(url, config, clientName) {
|
|
163
264
|
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
-
return this.request(Object.assign(Object.assign({}, config), { method: 'GET', url }));
|
|
265
|
+
return this.request(Object.assign(Object.assign({}, config), { method: 'GET', url }), undefined, clientName);
|
|
165
266
|
});
|
|
166
267
|
}
|
|
167
|
-
post(url, data, config) {
|
|
268
|
+
post(url, data, config, clientName) {
|
|
168
269
|
return __awaiter(this, void 0, void 0, function* () {
|
|
169
|
-
return this.request(Object.assign(Object.assign({}, config), { method: 'POST', url, data }));
|
|
270
|
+
return this.request(Object.assign(Object.assign({}, config), { method: 'POST', url, data }), undefined, clientName);
|
|
170
271
|
});
|
|
171
272
|
}
|
|
172
|
-
put(url, data, config) {
|
|
273
|
+
put(url, data, config, clientName) {
|
|
173
274
|
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
-
return this.request(Object.assign(Object.assign({}, config), { method: 'PUT', url, data }));
|
|
275
|
+
return this.request(Object.assign(Object.assign({}, config), { method: 'PUT', url, data }), undefined, clientName);
|
|
175
276
|
});
|
|
176
277
|
}
|
|
177
|
-
patch(url, data, config) {
|
|
278
|
+
patch(url, data, config, clientName) {
|
|
178
279
|
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
-
return this.request(Object.assign(Object.assign({}, config), { method: 'PATCH', url, data }));
|
|
280
|
+
return this.request(Object.assign(Object.assign({}, config), { method: 'PATCH', url, data }), undefined, clientName);
|
|
180
281
|
});
|
|
181
282
|
}
|
|
182
|
-
delete(url, config) {
|
|
283
|
+
delete(url, config, clientName) {
|
|
183
284
|
return __awaiter(this, void 0, void 0, function* () {
|
|
184
|
-
return this.request(Object.assign(Object.assign({}, config), { method: 'DELETE', url }));
|
|
285
|
+
return this.request(Object.assign(Object.assign({}, config), { method: 'DELETE', url }), undefined, clientName);
|
|
185
286
|
});
|
|
186
287
|
}
|
|
187
|
-
|
|
288
|
+
/**
|
|
289
|
+
* 带等待锁的认证请求方法
|
|
290
|
+
* 用于需要确保只有一个进程执行认证相关操作的场景
|
|
291
|
+
*
|
|
292
|
+
* @param config 请求配置
|
|
293
|
+
* @param tokenProvider token提供函数
|
|
294
|
+
* @param options 等待锁选项
|
|
295
|
+
* @returns 响应数据
|
|
296
|
+
*/
|
|
297
|
+
authRequest(config, tokenProvider, options, clientName) {
|
|
188
298
|
return __awaiter(this, void 0, void 0, function* () {
|
|
299
|
+
const effectiveClientName = clientName || this.clientName;
|
|
189
300
|
if (!this.redisLockService) {
|
|
190
301
|
this.logger.warn('RedisLockService not available, proceeding without lock');
|
|
191
|
-
return this.request(config);
|
|
302
|
+
return this.request(config, undefined, effectiveClientName);
|
|
192
303
|
}
|
|
193
304
|
const { lockKey = `auth-request:${(0, request_id_util_1.generateRequestId)()}`, lockTimeout = 30000, waitTimeout = 60000, enableRetry = true, } = options || {};
|
|
194
305
|
try {
|
|
306
|
+
// 尝试获取锁并执行请求
|
|
195
307
|
const result = yield this.redisLockService.withLock(lockKey, () => __awaiter(this, void 0, void 0, function* () {
|
|
308
|
+
// 获取token
|
|
196
309
|
const token = yield tokenProvider();
|
|
310
|
+
// 添加认证头
|
|
197
311
|
const authConfig = Object.assign(Object.assign({}, config), { headers: Object.assign(Object.assign({}, config.headers), { Authorization: `Bearer ${token}` }) });
|
|
198
|
-
|
|
312
|
+
// 执行请求
|
|
313
|
+
return this.request(authConfig, undefined, effectiveClientName);
|
|
199
314
|
}), {
|
|
200
315
|
ttl: lockTimeout,
|
|
201
316
|
retryCount: enableRetry ? 3 : 0,
|
|
@@ -209,25 +324,37 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
209
324
|
}
|
|
210
325
|
catch (error) {
|
|
211
326
|
this.logger.error(`Auth request failed with lock ${lockKey}`, error);
|
|
327
|
+
// 如果是锁获取失败且启用重试,尝试无锁执行
|
|
212
328
|
if (enableRetry && error.message.includes('Failed to acquire lock')) {
|
|
213
329
|
this.logger.warn('Retrying auth request without lock');
|
|
214
330
|
const token = yield tokenProvider();
|
|
215
331
|
const authConfig = Object.assign(Object.assign({}, config), { headers: Object.assign(Object.assign({}, config.headers), { Authorization: `Bearer ${token}` }) });
|
|
216
|
-
return this.request(authConfig);
|
|
332
|
+
return this.request(authConfig, undefined, effectiveClientName);
|
|
217
333
|
}
|
|
218
334
|
throw error;
|
|
219
335
|
}
|
|
220
336
|
});
|
|
221
337
|
}
|
|
222
|
-
|
|
338
|
+
/**
|
|
339
|
+
* 带等待锁的批量认证请求
|
|
340
|
+
* 用于需要批量执行认证相关操作但避免重复认证的场景
|
|
341
|
+
*
|
|
342
|
+
* @param requests 请求数组
|
|
343
|
+
* @param tokenProvider token提供函数
|
|
344
|
+
* @param options 等待锁选项
|
|
345
|
+
* @returns 响应数组
|
|
346
|
+
*/
|
|
347
|
+
authBatchRequest(requests, tokenProvider, options, clientName) {
|
|
223
348
|
return __awaiter(this, void 0, void 0, function* () {
|
|
349
|
+
const effectiveClientName = clientName || this.clientName;
|
|
224
350
|
if (!this.redisLockService) {
|
|
225
351
|
this.logger.warn('RedisLockService not available, proceeding batch auth requests without lock');
|
|
352
|
+
// 无锁批量执行
|
|
226
353
|
const token = yield tokenProvider();
|
|
227
354
|
const promises = requests.map((request) => __awaiter(this, void 0, void 0, function* () {
|
|
228
355
|
try {
|
|
229
356
|
const authConfig = Object.assign(Object.assign({}, request.config), { headers: Object.assign(Object.assign({}, request.config.headers), { Authorization: `Bearer ${token}` }) });
|
|
230
|
-
return yield this.request(authConfig);
|
|
357
|
+
return yield this.request(authConfig, undefined, effectiveClientName);
|
|
231
358
|
}
|
|
232
359
|
catch (error) {
|
|
233
360
|
this.logger.error(`Batch auth request failed for key: ${request.key}`, error);
|
|
@@ -238,15 +365,18 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
238
365
|
}
|
|
239
366
|
const { lockKey = `batch-auth-request:${(0, request_id_util_1.generateRequestId)()}`, lockTimeout = 60000, waitTimeout = 120000, maxConcurrency = 5, } = options || {};
|
|
240
367
|
try {
|
|
368
|
+
// 使用锁获取token并执行批量请求
|
|
241
369
|
const results = yield this.redisLockService.withLock(lockKey, () => __awaiter(this, void 0, void 0, function* () {
|
|
370
|
+
// 获取token(只获取一次)
|
|
242
371
|
const token = yield tokenProvider();
|
|
372
|
+
// 创建并发请求
|
|
243
373
|
const semaphore = new Array(maxConcurrency).fill(null);
|
|
244
374
|
const results = new Array(requests.length);
|
|
245
375
|
const executing = new Set();
|
|
246
376
|
const executeRequest = (requestConfig, key, index) => __awaiter(this, void 0, void 0, function* () {
|
|
247
377
|
try {
|
|
248
378
|
const authConfig = Object.assign(Object.assign({}, requestConfig), { headers: Object.assign(Object.assign({}, requestConfig.headers), { Authorization: `Bearer ${token}` }) });
|
|
249
|
-
const result = yield this.request(authConfig);
|
|
379
|
+
const result = yield this.request(authConfig, undefined, effectiveClientName);
|
|
250
380
|
results[index] = result;
|
|
251
381
|
return result;
|
|
252
382
|
}
|
|
@@ -259,6 +389,7 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
259
389
|
executing.delete(key);
|
|
260
390
|
}
|
|
261
391
|
});
|
|
392
|
+
// 创建并发的请求Promise
|
|
262
393
|
const promises = requests.map((request, index) => __awaiter(this, void 0, void 0, function* () {
|
|
263
394
|
return new Promise((resolve, reject) => {
|
|
264
395
|
const checkSlot = () => {
|
|
@@ -301,21 +432,18 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
301
432
|
}
|
|
302
433
|
});
|
|
303
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* 创建Axios实例并配置axios-retry
|
|
437
|
+
*/
|
|
304
438
|
createAxiosInstance() {
|
|
305
|
-
var _a
|
|
439
|
+
var _a;
|
|
306
440
|
const instance = require('axios').create({
|
|
307
441
|
baseURL: this.defaultConfig.baseURL,
|
|
308
442
|
timeout: this.defaultConfig.timeout,
|
|
309
|
-
proxy: (
|
|
310
|
-
? {
|
|
311
|
-
host: this.defaultConfig.proxy.host,
|
|
312
|
-
port: this.defaultConfig.proxy.port,
|
|
313
|
-
protocol: this.defaultConfig.proxy.protocol,
|
|
314
|
-
auth: this.defaultConfig.proxy.auth,
|
|
315
|
-
}
|
|
316
|
-
: undefined,
|
|
443
|
+
proxy: this.resolveProxyConfig(this.defaultConfig.proxy),
|
|
317
444
|
});
|
|
318
|
-
|
|
445
|
+
// 配置axios-retry
|
|
446
|
+
if ((_a = this.defaultConfig.retry) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
319
447
|
(0, axios_retry_1.default)(instance, {
|
|
320
448
|
retries: this.defaultConfig.retry.retries || 3,
|
|
321
449
|
retryDelay: this.defaultConfig.retry.retryDelay ||
|
|
@@ -323,26 +451,46 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
323
451
|
retryCondition: this.defaultConfig.retry.retryCondition ||
|
|
324
452
|
((error) => {
|
|
325
453
|
if (!error.response)
|
|
326
|
-
return true;
|
|
454
|
+
return true; // 网络错误
|
|
327
455
|
const status = error.response.status;
|
|
328
|
-
return status >= 500 || status === 429;
|
|
456
|
+
return status >= 500 || status === 429; // 5xx错误或429限流
|
|
329
457
|
}),
|
|
330
458
|
shouldResetTimeout: this.defaultConfig.retry.shouldResetTimeout !== false,
|
|
331
|
-
onRetry:
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
459
|
+
onRetry: (retryCount, error, requestConfig) => {
|
|
460
|
+
var _a, _b, _c, _d;
|
|
461
|
+
// 从 request config metadata 中获取 retryRecorder
|
|
462
|
+
const retryRecorder = (_a = requestConfig.metadata) === null || _a === void 0 ? void 0 : _a.retryRecorder;
|
|
463
|
+
if (retryRecorder) {
|
|
464
|
+
this.logger.debug(`Recording retry attempt ${retryCount} for ${(_b = requestConfig.method) === null || _b === void 0 ? void 0 : _b.toUpperCase()} ${requestConfig.url}`);
|
|
465
|
+
const retryRecord = retry_recorder_util_1.RetryRecorder.recordRetry(retryCount, error, requestConfig, this.calculateRetryDelay(retryCount, this.defaultConfig.retry));
|
|
466
|
+
retryRecorder.addRecord(retryRecord);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
this.logger.warn(`RetryRecorder not found in request config metadata for ${(_c = requestConfig.method) === null || _c === void 0 ? void 0 : _c.toUpperCase()} ${requestConfig.url}. Retry records will not be saved.`);
|
|
470
|
+
}
|
|
471
|
+
// 调用用户自定义的 onRetry 回调
|
|
472
|
+
if (this.defaultConfig.retry.onRetry) {
|
|
473
|
+
this.defaultConfig.retry.onRetry(retryCount, error, requestConfig);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
// 默认日志
|
|
477
|
+
this.logger.warn(`Retrying request (attempt ${retryCount}): ${(_d = requestConfig.method) === null || _d === void 0 ? void 0 : _d.toUpperCase()} ${requestConfig.url}`);
|
|
478
|
+
}
|
|
479
|
+
},
|
|
336
480
|
});
|
|
337
481
|
}
|
|
482
|
+
// 设置请求拦截器
|
|
338
483
|
instance.interceptors.request.use((config) => {
|
|
339
484
|
config.headers = config.headers || {};
|
|
485
|
+
// 从ContextProvider获取上下文信息
|
|
340
486
|
const context = context_extractor_util_1.ContextExtractor.getHttpContext();
|
|
341
487
|
const requestId = context.requestId || (0, request_id_util_1.generateRequestId)();
|
|
342
488
|
config.headers['X-Request-ID'] = requestId;
|
|
343
489
|
if (context.userId) {
|
|
344
490
|
config.headers['X-User-ID'] = context.userId;
|
|
345
491
|
}
|
|
492
|
+
// 存储requestId到config metadata中供后续使用
|
|
493
|
+
// 注意:不要覆盖已存在的 metadata,保留 retryRecorder 等其他数据
|
|
346
494
|
config.metadata = config.metadata || {};
|
|
347
495
|
config.metadata.requestId = requestId;
|
|
348
496
|
return config;
|
|
@@ -350,83 +498,86 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
350
498
|
this.logger.error('Request interceptor error', error);
|
|
351
499
|
return Promise.reject(error);
|
|
352
500
|
});
|
|
501
|
+
// 设置响应拦截器
|
|
502
|
+
// 注意: 统计信息已移至 request() 方法中统一管理,避免双重计数
|
|
353
503
|
instance.interceptors.response.use((response) => {
|
|
354
|
-
|
|
504
|
+
// 不再在这里更新统计,由 request() 方法统一管理
|
|
355
505
|
return response;
|
|
356
506
|
}, (error) => {
|
|
357
|
-
|
|
507
|
+
// 不再在这里更新统计,由 request() 方法统一管理
|
|
358
508
|
return Promise.reject(error);
|
|
359
509
|
});
|
|
360
510
|
return instance;
|
|
361
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* 执行带特性的请求(重试、熔断器等)
|
|
514
|
+
* 返回响应和熔断器状态
|
|
515
|
+
*/
|
|
362
516
|
executeWithFeatures(config, decoratorConfigs, requestId, startTime, retryRecorder, onCircuitBreakerStateChange) {
|
|
363
517
|
return __awaiter(this, void 0, void 0, function* () {
|
|
364
518
|
const requestFn = () => this.axiosInstance.request(config);
|
|
519
|
+
// 熔断器保护
|
|
365
520
|
const circuitBreakerConfig = decoratorConfigs.circuitBreaker || this.defaultConfig.circuitBreaker;
|
|
366
521
|
if (circuitBreakerConfig === null || circuitBreakerConfig === void 0 ? void 0 : circuitBreakerConfig.enabled) {
|
|
367
522
|
const circuitBreakerKey = this.generateCircuitBreakerKey(config);
|
|
368
|
-
|
|
523
|
+
this.logger.debug(`Circuit breaker key: ${circuitBreakerKey}`);
|
|
524
|
+
// 执行请求
|
|
525
|
+
const result = yield this.circuitBreakerService.executeWithCircuitBreaker(circuitBreakerKey, requestFn, circuitBreakerConfig, onCircuitBreakerStateChange);
|
|
526
|
+
// 请求完成后,主动获取当前熔断器状态
|
|
527
|
+
const currentState = this.circuitBreakerService.getCircuitBreakerState(circuitBreakerKey);
|
|
528
|
+
this.logger.debug(`After request, circuit breaker state: ${currentState || 'undefined'}`);
|
|
529
|
+
return { response: result, circuitBreakerState: currentState };
|
|
369
530
|
}
|
|
370
531
|
else {
|
|
371
|
-
|
|
532
|
+
const result = yield requestFn();
|
|
533
|
+
return { response: result, circuitBreakerState: undefined };
|
|
372
534
|
}
|
|
373
535
|
});
|
|
374
536
|
}
|
|
537
|
+
/**
|
|
538
|
+
* 计算重试延迟
|
|
539
|
+
*/
|
|
375
540
|
calculateRetryDelay(retryCount, retryConfig) {
|
|
376
541
|
if (retryConfig.retryDelay) {
|
|
377
542
|
return retryConfig.retryDelay(retryCount);
|
|
378
543
|
}
|
|
544
|
+
// 默认指数退避
|
|
379
545
|
return Math.pow(2, retryCount) * 1000;
|
|
380
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* 应用装饰器配置
|
|
549
|
+
*/
|
|
381
550
|
applyDecoratorConfig(config, decoratorContext) {
|
|
382
551
|
if (!decoratorContext)
|
|
383
552
|
return Object.assign({}, config);
|
|
384
553
|
const httpClientConfig = decorators_1.HttpDecoratorUtils.getHttpClientOptions(decoratorContext.target);
|
|
385
554
|
return Object.assign(Object.assign({}, config), httpClientConfig);
|
|
386
555
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
556
|
+
// Note: applyDecoratorConfig is not currently being called in executeWithFeatures
|
|
557
|
+
// The decorator config is already being applied via effectiveDecoratorContext
|
|
558
|
+
/**
|
|
559
|
+
* 生成熔断器键
|
|
560
|
+
*/
|
|
392
561
|
generateCircuitBreakerKey(config) {
|
|
393
562
|
var _a;
|
|
394
563
|
const method = ((_a = config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'UNKNOWN';
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
var _a, _b;
|
|
400
|
-
this.requestStats.totalRequests++;
|
|
401
|
-
this.requestStats.successfulRequests++;
|
|
402
|
-
const method = ((_a = response.config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'UNKNOWN';
|
|
403
|
-
const status = response.status;
|
|
404
|
-
this.requestStats.requestsByMethod[method] =
|
|
405
|
-
(this.requestStats.requestsByMethod[method] || 0) + 1;
|
|
406
|
-
this.requestStats.requestsByStatus[status] =
|
|
407
|
-
(this.requestStats.requestsByStatus[status] || 0) + 1;
|
|
408
|
-
if ((_b = response.config.metadata) === null || _b === void 0 ? void 0 : _b.startTime) {
|
|
409
|
-
const responseTime = Date.now() -
|
|
410
|
-
response.config.metadata
|
|
411
|
-
.startTime;
|
|
412
|
-
this.requestStats.totalResponseTime += responseTime;
|
|
564
|
+
let url;
|
|
565
|
+
try {
|
|
566
|
+
// Try to construct URL with proper base
|
|
567
|
+
url = new URL(config.url || '', this.defaultConfig.baseURL || 'http://localhost');
|
|
413
568
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const method = ((_a = error.config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'UNKNOWN';
|
|
421
|
-
this.requestStats.requestsByMethod[method] =
|
|
422
|
-
(this.requestStats.requestsByMethod[method] || 0) + 1;
|
|
423
|
-
if (error.response) {
|
|
424
|
-
const status = error.response.status;
|
|
425
|
-
this.requestStats.requestsByStatus[status] =
|
|
426
|
-
(this.requestStats.requestsByStatus[status] || 0) + 1;
|
|
427
|
-
}
|
|
569
|
+
catch (error) {
|
|
570
|
+
// If URL construction fails, fall back to simple string format
|
|
571
|
+
this.logger.warn(`Failed to construct URL for circuit breaker key: ${config.url}, using fallback format`);
|
|
572
|
+
const baseURL = this.defaultConfig.baseURL || 'http://localhost';
|
|
573
|
+
const urlPath = config.url || '/';
|
|
574
|
+
return `${method}:${baseURL}${urlPath}`;
|
|
428
575
|
}
|
|
576
|
+
return `${method}:${url.host}${url.pathname}`;
|
|
429
577
|
}
|
|
578
|
+
/**
|
|
579
|
+
* 合并默认配置
|
|
580
|
+
*/
|
|
430
581
|
mergeWithDefaults(config) {
|
|
431
582
|
const defaults = {
|
|
432
583
|
baseURL: process.env.HTTP_CLIENT_BASE_URL,
|
|
@@ -451,15 +602,6 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
451
602
|
minimumThroughputThreshold: 10,
|
|
452
603
|
countHalfOpenCalls: true,
|
|
453
604
|
},
|
|
454
|
-
cache: {
|
|
455
|
-
enabled: true,
|
|
456
|
-
defaultTtl: 300000,
|
|
457
|
-
cacheableMethods: ['get'],
|
|
458
|
-
cacheableStatusCodes: [200, 201, 202, 204, 301, 302, 304],
|
|
459
|
-
options: {
|
|
460
|
-
layers: [cache_1.CacheLayer.MEMORY, cache_1.CacheLayer.REDIS],
|
|
461
|
-
},
|
|
462
|
-
},
|
|
463
605
|
logging: {
|
|
464
606
|
enabled: true,
|
|
465
607
|
logRequests: true,
|
|
@@ -471,14 +613,16 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
471
613
|
sanitizeHeaders: ['authorization', 'apikey', 'password', 'token'],
|
|
472
614
|
logLevel: 'info',
|
|
473
615
|
databaseLogging: {
|
|
474
|
-
enabled:
|
|
616
|
+
enabled: true,
|
|
475
617
|
dataSource: 'default',
|
|
476
|
-
tableName: 'http_logs',
|
|
477
618
|
},
|
|
478
619
|
},
|
|
479
620
|
};
|
|
480
621
|
return this.deepMerge(defaults, config);
|
|
481
622
|
}
|
|
623
|
+
/**
|
|
624
|
+
* 深度合并对象
|
|
625
|
+
*/
|
|
482
626
|
deepMerge(target, source) {
|
|
483
627
|
const result = Object.assign({}, target);
|
|
484
628
|
for (const key in source) {
|
|
@@ -493,12 +637,157 @@ let HttpClientService = HttpClientService_1 = class HttpClientService {
|
|
|
493
637
|
}
|
|
494
638
|
return result;
|
|
495
639
|
}
|
|
640
|
+
/**
|
|
641
|
+
* 解析代理配置
|
|
642
|
+
* 支持从环境变量或手动配置中读取
|
|
643
|
+
* @param proxyConfig 代理配置
|
|
644
|
+
* @param targetUrl 目标 URL(用于 NO_PROXY 检查)
|
|
645
|
+
* @returns 解析后的代理配置,如果不应使用代理则返回 false 或 undefined
|
|
646
|
+
*/
|
|
647
|
+
resolveProxyConfig(proxyConfig, targetUrl) {
|
|
648
|
+
var _a, _b, _c, _d;
|
|
649
|
+
if (!(proxyConfig === null || proxyConfig === void 0 ? void 0 : proxyConfig.enabled)) {
|
|
650
|
+
return undefined;
|
|
651
|
+
}
|
|
652
|
+
// 如果启用从环境变量读取
|
|
653
|
+
if (proxyConfig.fromEnvironment) {
|
|
654
|
+
// 确定目标协议
|
|
655
|
+
let protocol = 'http';
|
|
656
|
+
if (targetUrl) {
|
|
657
|
+
try {
|
|
658
|
+
const url = new URL(targetUrl, this.defaultConfig.baseURL);
|
|
659
|
+
protocol = url.protocol === 'https:' ? 'https' : 'http';
|
|
660
|
+
}
|
|
661
|
+
catch (error) {
|
|
662
|
+
this.logger.warn(`Failed to parse target URL: ${error.message}`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
// 从环境变量解析
|
|
666
|
+
const fullUrl = targetUrl
|
|
667
|
+
? new URL(targetUrl, this.defaultConfig.baseURL).href
|
|
668
|
+
: undefined;
|
|
669
|
+
const envProxy = proxy_environment_util_1.ProxyEnvironmentParser.parseFromEnvironment(protocol, fullUrl);
|
|
670
|
+
if (envProxy === false) {
|
|
671
|
+
this.logger.debug('Proxy bypassed based on environment configuration');
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
const result = {
|
|
675
|
+
host: envProxy.host,
|
|
676
|
+
port: envProxy.port,
|
|
677
|
+
protocol: envProxy.protocol,
|
|
678
|
+
};
|
|
679
|
+
// 只有当 auth 存在且包含有效值时才添加
|
|
680
|
+
if (((_a = envProxy.auth) === null || _a === void 0 ? void 0 : _a.username) && ((_b = envProxy.auth) === null || _b === void 0 ? void 0 : _b.password)) {
|
|
681
|
+
result.auth = {
|
|
682
|
+
username: envProxy.auth.username,
|
|
683
|
+
password: envProxy.auth.password,
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
return result;
|
|
687
|
+
}
|
|
688
|
+
// 使用手动配置
|
|
689
|
+
if (proxyConfig.host && proxyConfig.port) {
|
|
690
|
+
const result = {
|
|
691
|
+
host: proxyConfig.host,
|
|
692
|
+
port: proxyConfig.port,
|
|
693
|
+
protocol: proxyConfig.protocol,
|
|
694
|
+
};
|
|
695
|
+
// 只有当 auth 存在且包含有效值时才添加
|
|
696
|
+
if (((_c = proxyConfig.auth) === null || _c === void 0 ? void 0 : _c.username) && ((_d = proxyConfig.auth) === null || _d === void 0 ? void 0 : _d.password)) {
|
|
697
|
+
result.auth = {
|
|
698
|
+
username: proxyConfig.auth.username,
|
|
699
|
+
password: proxyConfig.auth.password,
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
return result;
|
|
703
|
+
}
|
|
704
|
+
this.logger.warn('Proxy is enabled but neither fromEnvironment nor manual configuration is provided');
|
|
705
|
+
return undefined;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* 应用认证配置到请求配置
|
|
709
|
+
*/
|
|
710
|
+
applyAuthToConfig(config) {
|
|
711
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
712
|
+
if (!this.authConfig) {
|
|
713
|
+
return config;
|
|
714
|
+
}
|
|
715
|
+
// Create a new config object to avoid type issues
|
|
716
|
+
const authConfig = Object.assign({}, config);
|
|
717
|
+
switch (this.authConfig.type) {
|
|
718
|
+
case api_client_config_interface_1.AuthType.NONE:
|
|
719
|
+
break;
|
|
720
|
+
case api_client_config_interface_1.AuthType.API_KEY:
|
|
721
|
+
const apiKeyConfig = this.authConfig.config;
|
|
722
|
+
if (apiKeyConfig.location === 'header') {
|
|
723
|
+
const headerName = apiKeyConfig.name || 'X-API-Key';
|
|
724
|
+
const value = apiKeyConfig.prefix
|
|
725
|
+
? `${apiKeyConfig.prefix} ${apiKeyConfig.key}`
|
|
726
|
+
: apiKeyConfig.key;
|
|
727
|
+
authConfig.headers = Object.assign(Object.assign({}, authConfig.headers), { [headerName]: value });
|
|
728
|
+
}
|
|
729
|
+
else if (apiKeyConfig.location === 'query') {
|
|
730
|
+
const paramName = apiKeyConfig.name || 'api_key';
|
|
731
|
+
authConfig.params = Object.assign(Object.assign({}, authConfig.params), { [paramName]: apiKeyConfig.key });
|
|
732
|
+
}
|
|
733
|
+
break;
|
|
734
|
+
case api_client_config_interface_1.AuthType.BEARER_TOKEN:
|
|
735
|
+
const bearerConfig = this.authConfig.config;
|
|
736
|
+
const scheme = bearerConfig.scheme || 'Bearer';
|
|
737
|
+
authConfig.headers = Object.assign(Object.assign({}, authConfig.headers), { Authorization: `${scheme} ${bearerConfig.token}` });
|
|
738
|
+
break;
|
|
739
|
+
case api_client_config_interface_1.AuthType.BASIC_AUTH:
|
|
740
|
+
const basicConfig = this.authConfig.config;
|
|
741
|
+
const credentials = Buffer.from(`${basicConfig.username}:${basicConfig.password}`).toString('base64');
|
|
742
|
+
authConfig.headers = Object.assign(Object.assign({}, authConfig.headers), { Authorization: `Basic ${credentials}` });
|
|
743
|
+
break;
|
|
744
|
+
case api_client_config_interface_1.AuthType.OAUTH2:
|
|
745
|
+
const oauthConfig = this.authConfig.config;
|
|
746
|
+
// For now, using the access token directly if available
|
|
747
|
+
if (oauthConfig.accessToken) {
|
|
748
|
+
authConfig.headers = Object.assign(Object.assign({}, authConfig.headers), { Authorization: `Bearer ${oauthConfig.accessToken}` });
|
|
749
|
+
}
|
|
750
|
+
break;
|
|
751
|
+
case api_client_config_interface_1.AuthType.CUSTOM:
|
|
752
|
+
// Handle CUSTOM authentication which requires async processing
|
|
753
|
+
const customConfig = this.authConfig.config;
|
|
754
|
+
return yield customConfig.authenticator(authConfig);
|
|
755
|
+
}
|
|
756
|
+
return authConfig;
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* 更新请求统计信息
|
|
761
|
+
* 统一管理所有统计,避免在拦截器中重复统计
|
|
762
|
+
*/
|
|
763
|
+
updateRequestStats(success, responseTime, method, status) {
|
|
764
|
+
this.requestStats.totalRequests++;
|
|
765
|
+
if (success) {
|
|
766
|
+
this.requestStats.successfulRequests++;
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
this.requestStats.failedRequests++;
|
|
770
|
+
}
|
|
771
|
+
this.requestStats.totalResponseTime += responseTime;
|
|
772
|
+
this.requestStats.averageResponseTime =
|
|
773
|
+
this.requestStats.totalResponseTime / this.requestStats.totalRequests;
|
|
774
|
+
// 统计方法分布
|
|
775
|
+
if (method) {
|
|
776
|
+
const normalizedMethod = method.toUpperCase();
|
|
777
|
+
this.requestStats.requestsByMethod[normalizedMethod] =
|
|
778
|
+
(this.requestStats.requestsByMethod[normalizedMethod] || 0) + 1;
|
|
779
|
+
}
|
|
780
|
+
// 统计状态码分布
|
|
781
|
+
if (status) {
|
|
782
|
+
this.requestStats.requestsByStatus[status] =
|
|
783
|
+
(this.requestStats.requestsByStatus[status] || 0) + 1;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
496
786
|
};
|
|
497
787
|
exports.HttpClientService = HttpClientService;
|
|
498
788
|
exports.HttpClientService = HttpClientService = HttpClientService_1 = __decorate([
|
|
499
789
|
(0, common_1.Injectable)(),
|
|
500
790
|
__metadata("design:paramtypes", [circuit_breaker_service_1.HttpCircuitBreakerService,
|
|
501
791
|
logging_service_1.HttpLoggingService,
|
|
502
|
-
|
|
503
|
-
redis_lock_service_1.RedisLockService, Object])
|
|
792
|
+
redis_lock_service_1.RedisLockService, Object, String, Object])
|
|
504
793
|
], HttpClientService);
|