@dyanet/nestjs-config-aws 1.0.1 → 1.2.0
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/README.md +213 -1013
- package/dist/cjs/config-aws/src/config-manager.js +366 -0
- package/dist/cjs/config-aws/src/errors/index.js +77 -0
- package/dist/cjs/config-aws/src/index.js +37 -0
- package/dist/cjs/config-aws/src/interfaces/config-loader.interface.js +3 -0
- package/dist/cjs/config-aws/src/interfaces/config-manager.interface.js +3 -0
- package/dist/cjs/config-aws/src/interfaces/env-file-loader.interface.js +3 -0
- package/dist/cjs/config-aws/src/interfaces/environment-loader.interface.js +3 -0
- package/dist/cjs/config-aws/src/interfaces/s3-loader.interface.js +3 -0
- package/dist/cjs/config-aws/src/interfaces/secrets-manager-loader.interface.js +3 -0
- package/dist/cjs/config-aws/src/interfaces/ssm-parameter-store-loader.interface.js +3 -0
- package/dist/cjs/config-aws/src/loaders/env-file.loader.js +169 -0
- package/dist/cjs/config-aws/src/loaders/environment.loader.js +85 -0
- package/dist/cjs/config-aws/src/loaders/s3.loader.js +145 -0
- package/dist/cjs/config-aws/src/loaders/secrets-manager.loader.js +169 -0
- package/dist/cjs/config-aws/src/loaders/ssm-parameter-store.loader.js +199 -0
- package/dist/cjs/config-aws/src/utils/env-file-parser.util.js +98 -0
- package/dist/cjs/config-aws/src/utils/validation.util.js +116 -0
- package/dist/cjs/nestjs-config-aws/src/config.module.js +175 -0
- package/dist/cjs/nestjs-config-aws/src/index.js +61 -0
- package/dist/cjs/{integration → nestjs-config-aws/src/integration}/index.js +1 -1
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.js +3 -0
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.js +3 -0
- package/dist/cjs/{integration → nestjs-config-aws/src/integration}/interfaces/index.js +1 -1
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/integration-options.interface.js +3 -0
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/integration-state.interface.js +3 -0
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.js +73 -0
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.js +3 -0
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.js +4 -0
- package/dist/cjs/nestjs-config-aws/src/integration/interfaces/utility-types.interface.js +52 -0
- package/dist/cjs/nestjs-config-aws/src/integration/nestjs-config-integration.module.js +124 -0
- package/dist/cjs/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.js +592 -0
- package/dist/cjs/nestjs-config-aws/src/integration/providers/configuration-factory.provider.js +385 -0
- package/dist/cjs/{integration → nestjs-config-aws/src/integration}/providers/index.js +1 -1
- package/dist/cjs/nestjs-config-aws/src/integration/services/async-config-helper.service.js +366 -0
- package/dist/cjs/nestjs-config-aws/src/integration/services/error-handler.service.js +267 -0
- package/dist/cjs/nestjs-config-aws/src/integration/services/factory-registration.service.js +517 -0
- package/dist/cjs/{integration → nestjs-config-aws/src/integration}/services/index.js +1 -1
- package/dist/cjs/nestjs-config-aws/src/integration/services/integration-state.service.js +81 -0
- package/dist/cjs/nestjs-config-aws/src/integration/services/namespace-handler.service.js +465 -0
- package/dist/cjs/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.js +318 -0
- package/dist/cjs/nestjs-config-aws/src/integration/services/precedence-handler.service.js +292 -0
- package/dist/cjs/nestjs-config-aws/src/integration/services/validation-integration.service.js +595 -0
- package/dist/cjs/nestjs-config-aws/src/integration/utils/config-integration.util.js +283 -0
- package/dist/cjs/{integration → nestjs-config-aws/src/integration}/utils/index.js +1 -1
- package/dist/cjs/nestjs-config-aws/src/interfaces/config-service.interface.js +11 -0
- package/dist/cjs/nestjs-config-aws/src/interfaces/default-schema.interface.js +63 -0
- package/dist/cjs/nestjs-config-aws/src/interfaces/index.js +30 -0
- package/dist/cjs/nestjs-config-aws/src/interfaces/module-options.interface.js +3 -0
- package/dist/cjs/nestjs-config-aws/src/services/config.service.js +142 -0
- package/dist/esm/config-aws/src/config-manager.js +362 -0
- package/dist/esm/config-aws/src/errors/index.js +69 -0
- package/dist/esm/config-aws/src/index.js +21 -0
- package/dist/esm/config-aws/src/interfaces/config-loader.interface.js +2 -0
- package/dist/esm/config-aws/src/interfaces/config-manager.interface.js +2 -0
- package/dist/esm/config-aws/src/interfaces/env-file-loader.interface.js +2 -0
- package/dist/esm/config-aws/src/interfaces/environment-loader.interface.js +2 -0
- package/dist/esm/config-aws/src/interfaces/s3-loader.interface.js +2 -0
- package/dist/esm/config-aws/src/interfaces/secrets-manager-loader.interface.js +2 -0
- package/dist/esm/config-aws/src/interfaces/ssm-parameter-store-loader.interface.js +2 -0
- package/dist/esm/config-aws/src/loaders/env-file.loader.js +132 -0
- package/dist/esm/config-aws/src/loaders/environment.loader.js +81 -0
- package/dist/esm/config-aws/src/loaders/s3.loader.js +141 -0
- package/dist/esm/config-aws/src/loaders/secrets-manager.loader.js +165 -0
- package/dist/esm/config-aws/src/loaders/ssm-parameter-store.loader.js +195 -0
- package/dist/esm/config-aws/src/utils/env-file-parser.util.js +94 -0
- package/dist/esm/config-aws/src/utils/validation.util.js +112 -0
- package/dist/esm/nestjs-config-aws/src/config.module.js +172 -0
- package/dist/esm/nestjs-config-aws/src/index.js +23 -0
- package/dist/esm/nestjs-config-aws/src/integration/index.js +7 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.js +2 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.js +2 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/index.js +10 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/integration-options.interface.js +2 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/integration-state.interface.js +2 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.js +64 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.js +2 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.js +3 -0
- package/dist/esm/nestjs-config-aws/src/integration/interfaces/utility-types.interface.js +44 -0
- package/dist/esm/nestjs-config-aws/src/integration/nestjs-config-integration.module.js +121 -0
- package/dist/esm/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.js +589 -0
- package/dist/esm/nestjs-config-aws/src/integration/providers/configuration-factory.provider.js +382 -0
- package/dist/esm/nestjs-config-aws/src/integration/providers/index.js +4 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/async-config-helper.service.js +363 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/error-handler.service.js +264 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/factory-registration.service.js +514 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/index.js +10 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/integration-state.service.js +78 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/namespace-handler.service.js +462 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.js +315 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/precedence-handler.service.js +289 -0
- package/dist/esm/nestjs-config-aws/src/integration/services/validation-integration.service.js +589 -0
- package/dist/esm/nestjs-config-aws/src/integration/utils/config-integration.util.js +240 -0
- package/dist/esm/nestjs-config-aws/src/integration/utils/index.js +3 -0
- package/dist/esm/nestjs-config-aws/src/interfaces/config-service.interface.js +7 -0
- package/dist/esm/nestjs-config-aws/src/interfaces/default-schema.interface.js +59 -0
- package/dist/esm/nestjs-config-aws/src/interfaces/index.js +8 -0
- package/dist/esm/nestjs-config-aws/src/interfaces/module-options.interface.js +2 -0
- package/dist/esm/nestjs-config-aws/src/services/config.service.js +139 -0
- package/dist/types/config-aws/src/config-manager.d.ts +119 -0
- package/dist/types/config-aws/src/config-manager.d.ts.map +1 -0
- package/dist/types/config-aws/src/errors/index.d.ts +43 -0
- package/dist/types/config-aws/src/errors/index.d.ts.map +1 -0
- package/dist/types/config-aws/src/index.d.ts +24 -0
- package/dist/types/config-aws/src/index.d.ts.map +1 -0
- package/dist/types/config-aws/src/interfaces/config-loader.interface.d.ts +33 -0
- package/dist/types/config-aws/src/interfaces/config-loader.interface.d.ts.map +1 -0
- package/dist/types/config-aws/src/interfaces/config-manager.interface.d.ts +86 -0
- package/dist/types/config-aws/src/interfaces/config-manager.interface.d.ts.map +1 -0
- package/dist/types/config-aws/src/interfaces/env-file-loader.interface.d.ts +12 -0
- package/dist/types/config-aws/src/interfaces/env-file-loader.interface.d.ts.map +1 -0
- package/dist/types/config-aws/src/interfaces/environment-loader.interface.d.ts +10 -0
- package/dist/types/config-aws/src/interfaces/environment-loader.interface.d.ts.map +1 -0
- package/dist/types/config-aws/src/interfaces/s3-loader.interface.d.ts +14 -0
- package/dist/types/config-aws/src/interfaces/s3-loader.interface.d.ts.map +1 -0
- package/dist/types/config-aws/src/interfaces/secrets-manager-loader.interface.d.ts +12 -0
- package/dist/types/config-aws/src/interfaces/secrets-manager-loader.interface.d.ts.map +1 -0
- package/dist/types/config-aws/src/interfaces/ssm-parameter-store-loader.interface.d.ts +14 -0
- package/dist/types/config-aws/src/interfaces/ssm-parameter-store-loader.interface.d.ts.map +1 -0
- package/dist/types/config-aws/src/loaders/env-file.loader.d.ts +69 -0
- package/dist/types/config-aws/src/loaders/env-file.loader.d.ts.map +1 -0
- package/dist/types/config-aws/src/loaders/environment.loader.d.ts +46 -0
- package/dist/types/config-aws/src/loaders/environment.loader.d.ts.map +1 -0
- package/dist/types/config-aws/src/loaders/s3.loader.d.ts +62 -0
- package/dist/types/config-aws/src/loaders/s3.loader.d.ts.map +1 -0
- package/dist/types/config-aws/src/loaders/secrets-manager.loader.d.ts +68 -0
- package/dist/types/config-aws/src/loaders/secrets-manager.loader.d.ts.map +1 -0
- package/dist/types/config-aws/src/loaders/ssm-parameter-store.loader.d.ts +78 -0
- package/dist/types/config-aws/src/loaders/ssm-parameter-store.loader.d.ts.map +1 -0
- package/dist/types/config-aws/src/utils/env-file-parser.util.d.ts +45 -0
- package/dist/types/config-aws/src/utils/env-file-parser.util.d.ts.map +1 -0
- package/dist/types/{utils → config-aws/src/utils}/validation.util.d.ts +10 -10
- package/dist/types/config-aws/src/utils/validation.util.d.ts.map +1 -0
- package/dist/types/{config.module.d.ts → nestjs-config-aws/src/config.module.d.ts} +1 -0
- package/dist/types/nestjs-config-aws/src/config.module.d.ts.map +1 -0
- package/dist/types/{index.d.ts → nestjs-config-aws/src/index.d.ts} +2 -4
- package/dist/types/nestjs-config-aws/src/index.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/index.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/index.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-options.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-state.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/interfaces/utility-types.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/nestjs-config-integration.module.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/providers/configuration-factory.provider.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/providers/index.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/async-config-helper.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/error-handler.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/factory-registration.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/index.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/integration-state.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/namespace-handler.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/precedence-handler.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/services/validation-integration.service.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/utils/config-integration.util.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/integration/utils/index.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/interfaces/config-service.interface.d.ts.map +1 -0
- package/dist/types/{interfaces → nestjs-config-aws/src/interfaces}/default-schema.interface.d.ts +28 -28
- package/dist/types/nestjs-config-aws/src/interfaces/default-schema.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/interfaces/index.d.ts +5 -0
- package/dist/types/nestjs-config-aws/src/interfaces/index.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/interfaces/module-options.interface.d.ts.map +1 -0
- package/dist/types/nestjs-config-aws/src/services/config.service.d.ts +88 -0
- package/dist/types/nestjs-config-aws/src/services/config.service.d.ts.map +1 -0
- package/package.json +20 -27
- package/LICENSE +0 -21
- package/dist/cjs/config.module.js +0 -178
- package/dist/cjs/config.module.js.map +0 -1
- package/dist/cjs/index.js +0 -47
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/integration/index.js.map +0 -1
- package/dist/cjs/integration/interfaces/configuration-factory.interface.js +0 -3
- package/dist/cjs/integration/interfaces/configuration-factory.interface.js.map +0 -1
- package/dist/cjs/integration/interfaces/configuration-source.interface.js +0 -3
- package/dist/cjs/integration/interfaces/configuration-source.interface.js.map +0 -1
- package/dist/cjs/integration/interfaces/index.js.map +0 -1
- package/dist/cjs/integration/interfaces/integration-options.interface.js +0 -3
- package/dist/cjs/integration/interfaces/integration-options.interface.js.map +0 -1
- package/dist/cjs/integration/interfaces/integration-state.interface.js +0 -3
- package/dist/cjs/integration/interfaces/integration-state.interface.js.map +0 -1
- package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js +0 -73
- package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js.map +0 -1
- package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js +0 -3
- package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js.map +0 -1
- package/dist/cjs/integration/interfaces/typed-configuration.interface.js +0 -4
- package/dist/cjs/integration/interfaces/typed-configuration.interface.js.map +0 -1
- package/dist/cjs/integration/interfaces/utility-types.interface.js +0 -52
- package/dist/cjs/integration/interfaces/utility-types.interface.js.map +0 -1
- package/dist/cjs/integration/nestjs-config-integration.module.js +0 -124
- package/dist/cjs/integration/nestjs-config-integration.module.js.map +0 -1
- package/dist/cjs/integration/providers/aws-configuration-loader.service.js +0 -591
- package/dist/cjs/integration/providers/aws-configuration-loader.service.js.map +0 -1
- package/dist/cjs/integration/providers/configuration-factory.provider.js +0 -383
- package/dist/cjs/integration/providers/configuration-factory.provider.js.map +0 -1
- package/dist/cjs/integration/providers/index.js.map +0 -1
- package/dist/cjs/integration/services/async-config-helper.service.js +0 -356
- package/dist/cjs/integration/services/async-config-helper.service.js.map +0 -1
- package/dist/cjs/integration/services/error-handler.service.js +0 -265
- package/dist/cjs/integration/services/error-handler.service.js.map +0 -1
- package/dist/cjs/integration/services/factory-registration.service.js +0 -512
- package/dist/cjs/integration/services/factory-registration.service.js.map +0 -1
- package/dist/cjs/integration/services/index.js.map +0 -1
- package/dist/cjs/integration/services/integration-state.service.js +0 -83
- package/dist/cjs/integration/services/integration-state.service.js.map +0 -1
- package/dist/cjs/integration/services/namespace-handler.service.js +0 -467
- package/dist/cjs/integration/services/namespace-handler.service.js.map +0 -1
- package/dist/cjs/integration/services/nestjs-config-integration.service.js +0 -316
- package/dist/cjs/integration/services/nestjs-config-integration.service.js.map +0 -1
- package/dist/cjs/integration/services/precedence-handler.service.js +0 -294
- package/dist/cjs/integration/services/precedence-handler.service.js.map +0 -1
- package/dist/cjs/integration/services/validation-integration.service.js +0 -591
- package/dist/cjs/integration/services/validation-integration.service.js.map +0 -1
- package/dist/cjs/integration/utils/config-integration.util.js +0 -283
- package/dist/cjs/integration/utils/config-integration.util.js.map +0 -1
- package/dist/cjs/integration/utils/index.js.map +0 -1
- package/dist/cjs/interfaces/config-loader.interface.js +0 -3
- package/dist/cjs/interfaces/config-loader.interface.js.map +0 -1
- package/dist/cjs/interfaces/config-service.interface.js +0 -11
- package/dist/cjs/interfaces/config-service.interface.js.map +0 -1
- package/dist/cjs/interfaces/default-schema.interface.js +0 -63
- package/dist/cjs/interfaces/default-schema.interface.js.map +0 -1
- package/dist/cjs/interfaces/errors.interface.js +0 -77
- package/dist/cjs/interfaces/errors.interface.js.map +0 -1
- package/dist/cjs/interfaces/index.js +0 -25
- package/dist/cjs/interfaces/index.js.map +0 -1
- package/dist/cjs/interfaces/module-options.interface.js +0 -3
- package/dist/cjs/interfaces/module-options.interface.js.map +0 -1
- package/dist/cjs/loaders/environment.loader.js +0 -59
- package/dist/cjs/loaders/environment.loader.js.map +0 -1
- package/dist/cjs/loaders/secrets-manager.loader.js +0 -122
- package/dist/cjs/loaders/secrets-manager.loader.js.map +0 -1
- package/dist/cjs/loaders/ssm-parameter-store.loader.js +0 -146
- package/dist/cjs/loaders/ssm-parameter-store.loader.js.map +0 -1
- package/dist/cjs/services/config.service.js +0 -297
- package/dist/cjs/services/config.service.js.map +0 -1
- package/dist/cjs/utils/validation.util.js +0 -114
- package/dist/cjs/utils/validation.util.js.map +0 -1
- package/dist/esm/config.module.js +0 -175
- package/dist/esm/config.module.js.map +0 -1
- package/dist/esm/index.js +0 -18
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/integration/index.js +0 -7
- package/dist/esm/integration/index.js.map +0 -1
- package/dist/esm/integration/interfaces/configuration-factory.interface.js +0 -2
- package/dist/esm/integration/interfaces/configuration-factory.interface.js.map +0 -1
- package/dist/esm/integration/interfaces/configuration-source.interface.js +0 -2
- package/dist/esm/integration/interfaces/configuration-source.interface.js.map +0 -1
- package/dist/esm/integration/interfaces/index.js +0 -10
- package/dist/esm/integration/interfaces/index.js.map +0 -1
- package/dist/esm/integration/interfaces/integration-options.interface.js +0 -2
- package/dist/esm/integration/interfaces/integration-options.interface.js.map +0 -1
- package/dist/esm/integration/interfaces/integration-state.interface.js +0 -2
- package/dist/esm/integration/interfaces/integration-state.interface.js.map +0 -1
- package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js +0 -64
- package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js.map +0 -1
- package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js +0 -2
- package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js.map +0 -1
- package/dist/esm/integration/interfaces/typed-configuration.interface.js +0 -3
- package/dist/esm/integration/interfaces/typed-configuration.interface.js.map +0 -1
- package/dist/esm/integration/interfaces/utility-types.interface.js +0 -44
- package/dist/esm/integration/interfaces/utility-types.interface.js.map +0 -1
- package/dist/esm/integration/nestjs-config-integration.module.js +0 -121
- package/dist/esm/integration/nestjs-config-integration.module.js.map +0 -1
- package/dist/esm/integration/providers/aws-configuration-loader.service.js +0 -588
- package/dist/esm/integration/providers/aws-configuration-loader.service.js.map +0 -1
- package/dist/esm/integration/providers/configuration-factory.provider.js +0 -380
- package/dist/esm/integration/providers/configuration-factory.provider.js.map +0 -1
- package/dist/esm/integration/providers/index.js +0 -4
- package/dist/esm/integration/providers/index.js.map +0 -1
- package/dist/esm/integration/services/async-config-helper.service.js +0 -353
- package/dist/esm/integration/services/async-config-helper.service.js.map +0 -1
- package/dist/esm/integration/services/error-handler.service.js +0 -262
- package/dist/esm/integration/services/error-handler.service.js.map +0 -1
- package/dist/esm/integration/services/factory-registration.service.js +0 -509
- package/dist/esm/integration/services/factory-registration.service.js.map +0 -1
- package/dist/esm/integration/services/index.js +0 -10
- package/dist/esm/integration/services/index.js.map +0 -1
- package/dist/esm/integration/services/integration-state.service.js +0 -80
- package/dist/esm/integration/services/integration-state.service.js.map +0 -1
- package/dist/esm/integration/services/namespace-handler.service.js +0 -464
- package/dist/esm/integration/services/namespace-handler.service.js.map +0 -1
- package/dist/esm/integration/services/nestjs-config-integration.service.js +0 -313
- package/dist/esm/integration/services/nestjs-config-integration.service.js.map +0 -1
- package/dist/esm/integration/services/precedence-handler.service.js +0 -291
- package/dist/esm/integration/services/precedence-handler.service.js.map +0 -1
- package/dist/esm/integration/services/validation-integration.service.js +0 -585
- package/dist/esm/integration/services/validation-integration.service.js.map +0 -1
- package/dist/esm/integration/utils/config-integration.util.js +0 -240
- package/dist/esm/integration/utils/config-integration.util.js.map +0 -1
- package/dist/esm/integration/utils/index.js +0 -3
- package/dist/esm/integration/utils/index.js.map +0 -1
- package/dist/esm/interfaces/config-loader.interface.js +0 -2
- package/dist/esm/interfaces/config-loader.interface.js.map +0 -1
- package/dist/esm/interfaces/config-service.interface.js +0 -7
- package/dist/esm/interfaces/config-service.interface.js.map +0 -1
- package/dist/esm/interfaces/default-schema.interface.js +0 -59
- package/dist/esm/interfaces/default-schema.interface.js.map +0 -1
- package/dist/esm/interfaces/errors.interface.js +0 -69
- package/dist/esm/interfaces/errors.interface.js.map +0 -1
- package/dist/esm/interfaces/index.js +0 -9
- package/dist/esm/interfaces/index.js.map +0 -1
- package/dist/esm/interfaces/module-options.interface.js +0 -2
- package/dist/esm/interfaces/module-options.interface.js.map +0 -1
- package/dist/esm/loaders/environment.loader.js +0 -55
- package/dist/esm/loaders/environment.loader.js.map +0 -1
- package/dist/esm/loaders/secrets-manager.loader.js +0 -118
- package/dist/esm/loaders/secrets-manager.loader.js.map +0 -1
- package/dist/esm/loaders/ssm-parameter-store.loader.js +0 -142
- package/dist/esm/loaders/ssm-parameter-store.loader.js.map +0 -1
- package/dist/esm/services/config.service.js +0 -261
- package/dist/esm/services/config.service.js.map +0 -1
- package/dist/esm/utils/validation.util.js +0 -110
- package/dist/esm/utils/validation.util.js.map +0 -1
- package/dist/types/config.module.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/integration/index.d.ts.map +0 -1
- package/dist/types/integration/interfaces/configuration-factory.interface.d.ts.map +0 -1
- package/dist/types/integration/interfaces/configuration-source.interface.d.ts.map +0 -1
- package/dist/types/integration/interfaces/index.d.ts.map +0 -1
- package/dist/types/integration/interfaces/integration-options.interface.d.ts.map +0 -1
- package/dist/types/integration/interfaces/integration-state.interface.d.ts.map +0 -1
- package/dist/types/integration/interfaces/nestjs-config-compatibility.interface.d.ts.map +0 -1
- package/dist/types/integration/interfaces/nestjs-config-integration.interface.d.ts.map +0 -1
- package/dist/types/integration/interfaces/typed-configuration.interface.d.ts.map +0 -1
- package/dist/types/integration/interfaces/utility-types.interface.d.ts.map +0 -1
- package/dist/types/integration/nestjs-config-integration.module.d.ts.map +0 -1
- package/dist/types/integration/providers/aws-configuration-loader.service.d.ts.map +0 -1
- package/dist/types/integration/providers/configuration-factory.provider.d.ts.map +0 -1
- package/dist/types/integration/providers/index.d.ts.map +0 -1
- package/dist/types/integration/services/async-config-helper.service.d.ts.map +0 -1
- package/dist/types/integration/services/error-handler.service.d.ts.map +0 -1
- package/dist/types/integration/services/factory-registration.service.d.ts.map +0 -1
- package/dist/types/integration/services/index.d.ts.map +0 -1
- package/dist/types/integration/services/integration-state.service.d.ts.map +0 -1
- package/dist/types/integration/services/namespace-handler.service.d.ts.map +0 -1
- package/dist/types/integration/services/nestjs-config-integration.service.d.ts.map +0 -1
- package/dist/types/integration/services/precedence-handler.service.d.ts.map +0 -1
- package/dist/types/integration/services/validation-integration.service.d.ts.map +0 -1
- package/dist/types/integration/utils/config-integration.util.d.ts.map +0 -1
- package/dist/types/integration/utils/index.d.ts.map +0 -1
- package/dist/types/interfaces/config-loader.interface.d.ts +0 -22
- package/dist/types/interfaces/config-loader.interface.d.ts.map +0 -1
- package/dist/types/interfaces/config-service.interface.d.ts.map +0 -1
- package/dist/types/interfaces/default-schema.interface.d.ts.map +0 -1
- package/dist/types/interfaces/errors.interface.d.ts +0 -38
- package/dist/types/interfaces/errors.interface.d.ts.map +0 -1
- package/dist/types/interfaces/index.d.ts +0 -6
- package/dist/types/interfaces/index.d.ts.map +0 -1
- package/dist/types/interfaces/module-options.interface.d.ts.map +0 -1
- package/dist/types/loaders/environment.loader.d.ts +0 -26
- package/dist/types/loaders/environment.loader.d.ts.map +0 -1
- package/dist/types/loaders/secrets-manager.loader.d.ts +0 -52
- package/dist/types/loaders/secrets-manager.loader.d.ts.map +0 -1
- package/dist/types/loaders/ssm-parameter-store.loader.d.ts +0 -68
- package/dist/types/loaders/ssm-parameter-store.loader.d.ts.map +0 -1
- package/dist/types/services/config.service.d.ts +0 -94
- package/dist/types/services/config.service.d.ts.map +0 -1
- package/dist/types/utils/validation.util.d.ts.map +0 -1
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/index.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/configuration-factory.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/configuration-source.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/index.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/integration-options.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/integration-state.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/nestjs-config-compatibility.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/nestjs-config-integration.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/typed-configuration.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/utility-types.interface.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/nestjs-config-integration.module.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/providers/aws-configuration-loader.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/providers/configuration-factory.provider.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/providers/index.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/async-config-helper.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/error-handler.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/factory-registration.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/index.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/integration-state.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/namespace-handler.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/nestjs-config-integration.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/precedence-handler.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/validation-integration.service.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/utils/config-integration.util.d.ts +0 -0
- /package/dist/types/{integration → nestjs-config-aws/src/integration}/utils/index.d.ts +0 -0
- /package/dist/types/{interfaces → nestjs-config-aws/src/interfaces}/config-service.interface.d.ts +0 -0
- /package/dist/types/{interfaces → nestjs-config-aws/src/interfaces}/module-options.interface.d.ts +0 -0
package/dist/esm/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.js
ADDED
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
var AwsConfigurationLoaderService_1;
|
|
14
|
+
import { Injectable, Logger, Inject, Optional } from '@nestjs/common';
|
|
15
|
+
import { SecretsManagerLoader, SSMParameterStoreLoader, EnvironmentLoader, } from '@dyanet/config-aws';
|
|
16
|
+
import { ErrorHandlerService } from '../services/error-handler.service';
|
|
17
|
+
/**
|
|
18
|
+
* Service for loading configuration from AWS sources for integration with @nestjs/config.
|
|
19
|
+
* Uses existing AWS loaders to fetch configuration and provides namespace-aware loading capabilities.
|
|
20
|
+
*/
|
|
21
|
+
let AwsConfigurationLoaderService = AwsConfigurationLoaderService_1 = class AwsConfigurationLoaderService {
|
|
22
|
+
logger = new Logger(AwsConfigurationLoaderService_1.name);
|
|
23
|
+
loaders;
|
|
24
|
+
options;
|
|
25
|
+
errorHandler;
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.options = options || {};
|
|
28
|
+
this.errorHandler = new ErrorHandlerService(this.options);
|
|
29
|
+
this.loaders = this.createLoaders();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Load configuration from AWS sources.
|
|
33
|
+
* @returns Promise resolving to configuration data
|
|
34
|
+
*/
|
|
35
|
+
async loadConfiguration() {
|
|
36
|
+
const mergedConfig = {};
|
|
37
|
+
const sources = [];
|
|
38
|
+
for (const loader of this.loaders) {
|
|
39
|
+
try {
|
|
40
|
+
// Check if loader is available in current environment with timeout
|
|
41
|
+
const isAvailable = await this.checkAvailabilityWithTimeout(loader);
|
|
42
|
+
if (!isAvailable) {
|
|
43
|
+
if (this.options.enableLogging) {
|
|
44
|
+
this.logger.debug(`Skipping ${loader.getName()} - not available in current environment`);
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (this.options.enableLogging) {
|
|
49
|
+
this.logger.debug(`Loading configuration from ${loader.getName()}`);
|
|
50
|
+
}
|
|
51
|
+
// Load configuration from this source with retry logic for AWS services
|
|
52
|
+
const loaderConfig = loader instanceof EnvironmentLoader
|
|
53
|
+
? await loader.load()
|
|
54
|
+
: await this.loadWithRetry(loader);
|
|
55
|
+
// Create configuration source metadata
|
|
56
|
+
const source = {
|
|
57
|
+
name: loader.getName(),
|
|
58
|
+
type: this.getSourceType(loader),
|
|
59
|
+
priority: this.getSourcePriority(loader),
|
|
60
|
+
data: loaderConfig,
|
|
61
|
+
loadedAt: new Date(),
|
|
62
|
+
};
|
|
63
|
+
sources.push(source);
|
|
64
|
+
// Merge with existing configuration based on precedence
|
|
65
|
+
Object.assign(mergedConfig, loaderConfig);
|
|
66
|
+
if (this.options.enableLogging) {
|
|
67
|
+
const keyCount = Object.keys(loaderConfig).length;
|
|
68
|
+
this.logger.debug(`Loaded ${keyCount} configuration values from ${loader.getName()}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const loaderError = error instanceof Error ? error : new Error(String(error));
|
|
73
|
+
// Log detailed error information for troubleshooting
|
|
74
|
+
this.errorHandler.logDetailedError(`loadConfiguration - ${loader.getName()}`, loaderError, {
|
|
75
|
+
loaderName: loader.getName(),
|
|
76
|
+
loaderType: this.getSourceType(loader),
|
|
77
|
+
});
|
|
78
|
+
// Handle specific error types
|
|
79
|
+
if (this.isAwsServiceError(loaderError)) {
|
|
80
|
+
const shouldContinue = this.handleAwsSpecificError(loader, loaderError);
|
|
81
|
+
if (!shouldContinue) {
|
|
82
|
+
throw loaderError;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Handle general configuration errors
|
|
87
|
+
const shouldContinue = this.errorHandler.handleConfigurationError(loader.getName(), loaderError);
|
|
88
|
+
if (!shouldContinue) {
|
|
89
|
+
throw loaderError;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Add error to source metadata
|
|
93
|
+
const errorSource = {
|
|
94
|
+
name: loader.getName(),
|
|
95
|
+
type: this.getSourceType(loader),
|
|
96
|
+
priority: this.getSourcePriority(loader),
|
|
97
|
+
data: {},
|
|
98
|
+
loadedAt: new Date(),
|
|
99
|
+
errors: [loaderError.message],
|
|
100
|
+
};
|
|
101
|
+
sources.push(errorSource);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return mergedConfig;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Load configuration for specific namespaces from AWS sources.
|
|
108
|
+
* @param namespaces - Array of namespace names to load
|
|
109
|
+
* @returns Promise resolving to namespaced configuration data
|
|
110
|
+
*/
|
|
111
|
+
async loadNamespacedConfiguration(namespaces) {
|
|
112
|
+
const result = {};
|
|
113
|
+
// Initialize all namespaces
|
|
114
|
+
for (const namespace of namespaces) {
|
|
115
|
+
result[namespace] = {};
|
|
116
|
+
}
|
|
117
|
+
for (const loader of this.loaders) {
|
|
118
|
+
try {
|
|
119
|
+
// Check if loader is available in current environment with timeout
|
|
120
|
+
const isAvailable = await this.checkAvailabilityWithTimeout(loader);
|
|
121
|
+
if (!isAvailable) {
|
|
122
|
+
if (this.options.enableLogging) {
|
|
123
|
+
this.logger.debug(`Skipping ${loader.getName()} for namespace loading - not available`);
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (this.options.enableLogging) {
|
|
128
|
+
this.logger.debug(`Loading namespaced configuration from ${loader.getName()}`);
|
|
129
|
+
}
|
|
130
|
+
// Load configuration from this source with retry logic for AWS services
|
|
131
|
+
const loaderConfig = loader instanceof EnvironmentLoader
|
|
132
|
+
? await loader.load()
|
|
133
|
+
: await this.loadWithRetry(loader);
|
|
134
|
+
// Distribute configuration to namespaces based on key prefixes or patterns
|
|
135
|
+
for (const namespace of namespaces) {
|
|
136
|
+
const namespacedConfig = this.extractNamespaceConfig(loaderConfig, namespace);
|
|
137
|
+
if (Object.keys(namespacedConfig).length > 0) {
|
|
138
|
+
Object.assign(result[namespace], namespacedConfig);
|
|
139
|
+
if (this.options.enableLogging) {
|
|
140
|
+
const keyCount = Object.keys(namespacedConfig).length;
|
|
141
|
+
this.logger.debug(`Loaded ${keyCount} values for namespace '${namespace}' from ${loader.getName()}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
const loaderError = error instanceof Error ? error : new Error(String(error));
|
|
148
|
+
// Log detailed error information for troubleshooting
|
|
149
|
+
this.errorHandler.logDetailedError(`loadNamespacedConfiguration - ${loader.getName()}`, loaderError, {
|
|
150
|
+
loaderName: loader.getName(),
|
|
151
|
+
loaderType: this.getSourceType(loader),
|
|
152
|
+
namespaces,
|
|
153
|
+
});
|
|
154
|
+
// Handle specific error types
|
|
155
|
+
if (this.isAwsServiceError(loaderError)) {
|
|
156
|
+
const shouldContinue = this.handleAwsSpecificError(loader, loaderError);
|
|
157
|
+
if (!shouldContinue) {
|
|
158
|
+
throw loaderError;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Handle general configuration errors
|
|
163
|
+
const shouldContinue = this.errorHandler.handleConfigurationError(loader.getName(), loaderError);
|
|
164
|
+
if (!shouldContinue) {
|
|
165
|
+
throw loaderError;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Create fallback configuration for each namespace
|
|
169
|
+
if (this.options.fallbackToLocal) {
|
|
170
|
+
for (const namespace of namespaces) {
|
|
171
|
+
const fallbackConfig = this.errorHandler.createFallbackConfiguration(namespace);
|
|
172
|
+
Object.assign(result[namespace], fallbackConfig);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if AWS services are available.
|
|
181
|
+
* @returns Promise resolving to availability status
|
|
182
|
+
*/
|
|
183
|
+
async isAvailable() {
|
|
184
|
+
try {
|
|
185
|
+
// Check if at least one AWS loader is available
|
|
186
|
+
const availabilityChecks = this.loaders
|
|
187
|
+
.filter(loader => !(loader instanceof EnvironmentLoader)) // Skip environment loader
|
|
188
|
+
.map(loader => this.checkAvailabilityWithTimeout(loader));
|
|
189
|
+
if (availabilityChecks.length === 0) {
|
|
190
|
+
// No AWS loaders configured
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
// Wait for all availability checks to complete
|
|
194
|
+
const results = await Promise.allSettled(availabilityChecks);
|
|
195
|
+
// Return true if at least one AWS service is available
|
|
196
|
+
return results.some(result => result.status === 'fulfilled' && result.value === true);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
const availabilityError = error instanceof Error ? error : new Error(String(error));
|
|
200
|
+
this.errorHandler.logDetailedError('isAvailable', availabilityError);
|
|
201
|
+
// Handle as AWS unavailable
|
|
202
|
+
this.errorHandler.handleAwsUnavailable('AWS Services', availabilityError);
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get all available configuration sources with their metadata.
|
|
208
|
+
* @returns Promise resolving to array of configuration sources
|
|
209
|
+
*/
|
|
210
|
+
async getAvailableSources() {
|
|
211
|
+
const sources = [];
|
|
212
|
+
for (const loader of this.loaders) {
|
|
213
|
+
try {
|
|
214
|
+
const isAvailable = await loader.isAvailable();
|
|
215
|
+
if (isAvailable) {
|
|
216
|
+
const loaderConfig = await loader.load();
|
|
217
|
+
const source = {
|
|
218
|
+
name: loader.getName(),
|
|
219
|
+
type: this.getSourceType(loader),
|
|
220
|
+
priority: this.getSourcePriority(loader),
|
|
221
|
+
data: loaderConfig,
|
|
222
|
+
loadedAt: new Date(),
|
|
223
|
+
};
|
|
224
|
+
sources.push(source);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
// Add source with error information
|
|
229
|
+
const source = {
|
|
230
|
+
name: loader.getName(),
|
|
231
|
+
type: this.getSourceType(loader),
|
|
232
|
+
priority: this.getSourcePriority(loader),
|
|
233
|
+
data: {},
|
|
234
|
+
loadedAt: new Date(),
|
|
235
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
236
|
+
};
|
|
237
|
+
sources.push(source);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return sources;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Create configuration loaders based on integration options.
|
|
244
|
+
* @returns Array of configuration loaders
|
|
245
|
+
*/
|
|
246
|
+
createLoaders() {
|
|
247
|
+
const loaders = [];
|
|
248
|
+
// Always include environment loader
|
|
249
|
+
loaders.push(new EnvironmentLoader({ prefix: this.options.envPrefix }));
|
|
250
|
+
// Add AWS Secrets Manager loader if configured
|
|
251
|
+
if (this.options.secretsManagerConfig?.enabled !== false) {
|
|
252
|
+
const secretsConfig = {
|
|
253
|
+
region: this.options.secretsManagerConfig?.region,
|
|
254
|
+
// Convert paths to secretName format expected by SecretsManagerLoader
|
|
255
|
+
secretName: this.getSecretsManagerPath(),
|
|
256
|
+
};
|
|
257
|
+
loaders.push(new SecretsManagerLoader(secretsConfig));
|
|
258
|
+
}
|
|
259
|
+
// Add SSM Parameter Store loader if configured
|
|
260
|
+
if (this.options.ssmConfig?.enabled !== false) {
|
|
261
|
+
const ssmConfig = {
|
|
262
|
+
region: this.options.ssmConfig?.region,
|
|
263
|
+
// Convert paths to parameterPath format expected by SSMParameterStoreLoader
|
|
264
|
+
parameterPath: this.getSSMParameterPath(),
|
|
265
|
+
withDecryption: this.options.ssmConfig?.decrypt ?? true,
|
|
266
|
+
};
|
|
267
|
+
loaders.push(new SSMParameterStoreLoader(ssmConfig));
|
|
268
|
+
}
|
|
269
|
+
return loaders;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get the source type for a given loader.
|
|
273
|
+
* @param loader - The configuration loader
|
|
274
|
+
* @returns The configuration source type
|
|
275
|
+
*/
|
|
276
|
+
getSourceType(loader) {
|
|
277
|
+
if (loader instanceof EnvironmentLoader) {
|
|
278
|
+
return 'environment';
|
|
279
|
+
}
|
|
280
|
+
else if (loader instanceof SecretsManagerLoader) {
|
|
281
|
+
return 'secrets-manager';
|
|
282
|
+
}
|
|
283
|
+
else if (loader instanceof SSMParameterStoreLoader) {
|
|
284
|
+
return 'ssm';
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
return 'local-file';
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Get the priority for a given loader based on precedence rules.
|
|
292
|
+
* @param loader - The configuration loader
|
|
293
|
+
* @returns The priority number (higher = higher priority)
|
|
294
|
+
*/
|
|
295
|
+
getSourcePriority(loader) {
|
|
296
|
+
const precedence = this.options.precedence || 'aws-first';
|
|
297
|
+
if (precedence === 'local-first') {
|
|
298
|
+
// Environment variables have highest priority
|
|
299
|
+
if (loader instanceof EnvironmentLoader)
|
|
300
|
+
return 100;
|
|
301
|
+
if (loader instanceof SecretsManagerLoader)
|
|
302
|
+
return 50;
|
|
303
|
+
if (loader instanceof SSMParameterStoreLoader)
|
|
304
|
+
return 40;
|
|
305
|
+
}
|
|
306
|
+
else if (precedence === 'aws-first') {
|
|
307
|
+
// AWS sources have higher priority
|
|
308
|
+
if (loader instanceof SecretsManagerLoader)
|
|
309
|
+
return 100;
|
|
310
|
+
if (loader instanceof SSMParameterStoreLoader)
|
|
311
|
+
return 90;
|
|
312
|
+
if (loader instanceof EnvironmentLoader)
|
|
313
|
+
return 50;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// merge - equal priority, order matters
|
|
317
|
+
return 50;
|
|
318
|
+
}
|
|
319
|
+
return 50;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Extract configuration for a specific namespace from loaded configuration.
|
|
323
|
+
* @param config - The loaded configuration
|
|
324
|
+
* @param namespace - The namespace to extract
|
|
325
|
+
* @returns Configuration values for the namespace
|
|
326
|
+
*/
|
|
327
|
+
extractNamespaceConfig(config, namespace) {
|
|
328
|
+
const namespaceConfig = {};
|
|
329
|
+
const namespacePrefix = namespace.toUpperCase();
|
|
330
|
+
// Strategy 1: Look for direct namespace key (e.g., config.database)
|
|
331
|
+
if (config[namespace]) {
|
|
332
|
+
Object.assign(namespaceConfig, config[namespace]);
|
|
333
|
+
}
|
|
334
|
+
// Strategy 2: Look for keys that start with the namespace prefix (e.g., DATABASE_HOST)
|
|
335
|
+
for (const [key, value] of Object.entries(config)) {
|
|
336
|
+
const upperKey = key.toUpperCase();
|
|
337
|
+
// Check if key starts with namespace prefix followed by underscore
|
|
338
|
+
if (upperKey.startsWith(`${namespacePrefix}_`)) {
|
|
339
|
+
// Remove namespace prefix and underscore, convert to camelCase
|
|
340
|
+
const namespacedKey = key.substring(namespace.length + 1);
|
|
341
|
+
const camelCaseKey = this.toCamelCase(namespacedKey);
|
|
342
|
+
if (camelCaseKey) {
|
|
343
|
+
namespaceConfig[camelCaseKey] = value;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Strategy 3: Look for nested namespace paths (e.g., /app/database/host)
|
|
348
|
+
const nestedConfig = this.extractNestedNamespaceConfig(config, namespace);
|
|
349
|
+
Object.assign(namespaceConfig, nestedConfig);
|
|
350
|
+
return namespaceConfig;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Extract nested namespace configuration from hierarchical keys.
|
|
354
|
+
* @param config - The loaded configuration
|
|
355
|
+
* @param namespace - The namespace to extract
|
|
356
|
+
* @returns Configuration values for the namespace
|
|
357
|
+
*/
|
|
358
|
+
extractNestedNamespaceConfig(config, namespace) {
|
|
359
|
+
const namespaceConfig = {};
|
|
360
|
+
const namespacePath = `/${namespace}/`;
|
|
361
|
+
for (const [key, value] of Object.entries(config)) {
|
|
362
|
+
// Check if key contains namespace path
|
|
363
|
+
if (key.includes(namespacePath)) {
|
|
364
|
+
// Extract the part after the namespace path
|
|
365
|
+
const pathIndex = key.indexOf(namespacePath);
|
|
366
|
+
const afterNamespace = key.substring(pathIndex + namespacePath.length);
|
|
367
|
+
if (afterNamespace) {
|
|
368
|
+
// Convert path segments to nested object structure
|
|
369
|
+
const nestedKey = this.pathToNestedKey(afterNamespace);
|
|
370
|
+
this.setNestedValue(namespaceConfig, nestedKey, value);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return namespaceConfig;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Convert snake_case or kebab-case to camelCase.
|
|
378
|
+
* @param str - String to convert
|
|
379
|
+
* @returns camelCase string
|
|
380
|
+
*/
|
|
381
|
+
toCamelCase(str) {
|
|
382
|
+
return str
|
|
383
|
+
.toLowerCase()
|
|
384
|
+
.replace(/[_-](.)/g, (_, char) => char.toUpperCase());
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Convert path segments to nested key structure.
|
|
388
|
+
* @param path - Path string (e.g., "host/port")
|
|
389
|
+
* @returns Nested key structure
|
|
390
|
+
*/
|
|
391
|
+
pathToNestedKey(path) {
|
|
392
|
+
return path
|
|
393
|
+
.split('/')
|
|
394
|
+
.map(segment => this.toCamelCase(segment))
|
|
395
|
+
.join('.');
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Set a nested value in an object using dot notation.
|
|
399
|
+
* @param obj - Target object
|
|
400
|
+
* @param path - Dot notation path
|
|
401
|
+
* @param value - Value to set
|
|
402
|
+
*/
|
|
403
|
+
setNestedValue(obj, path, value) {
|
|
404
|
+
const keys = path.split('.');
|
|
405
|
+
let current = obj;
|
|
406
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
407
|
+
const key = keys[i];
|
|
408
|
+
if (key && (!(key in current) || typeof current[key] !== 'object')) {
|
|
409
|
+
current[key] = {};
|
|
410
|
+
}
|
|
411
|
+
if (key) {
|
|
412
|
+
current = current[key];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const lastKey = keys[keys.length - 1];
|
|
416
|
+
if (lastKey) {
|
|
417
|
+
current[lastKey] = value;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Get the Secrets Manager path based on configuration.
|
|
422
|
+
* @returns The secrets manager path
|
|
423
|
+
*/
|
|
424
|
+
getSecretsManagerPath() {
|
|
425
|
+
const paths = this.options.secretsManagerConfig?.paths;
|
|
426
|
+
if (!paths) {
|
|
427
|
+
return '/nestjs-config-aws';
|
|
428
|
+
}
|
|
429
|
+
// Use the first available path or default
|
|
430
|
+
return paths.production || paths.development || paths.test || '/nestjs-config-aws';
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Get the SSM Parameter Store path based on configuration.
|
|
434
|
+
* @returns The SSM parameter path
|
|
435
|
+
*/
|
|
436
|
+
getSSMParameterPath() {
|
|
437
|
+
const paths = this.options.ssmConfig?.paths;
|
|
438
|
+
if (!paths) {
|
|
439
|
+
return '/nestjs-config-aws';
|
|
440
|
+
}
|
|
441
|
+
// Use the first available path or default
|
|
442
|
+
return paths.production || paths.development || paths.test || '/nestjs-config-aws';
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Check if an error is an AWS service error.
|
|
446
|
+
* @param error - The error to check
|
|
447
|
+
* @returns Whether the error is from an AWS service
|
|
448
|
+
*/
|
|
449
|
+
isAwsServiceError(error) {
|
|
450
|
+
// AWS SDK errors typically have specific names
|
|
451
|
+
const awsErrorNames = [
|
|
452
|
+
'AccessDeniedException',
|
|
453
|
+
'ResourceNotFoundException',
|
|
454
|
+
'InvalidRequestException',
|
|
455
|
+
'ThrottlingException',
|
|
456
|
+
'ServiceUnavailableException',
|
|
457
|
+
'NetworkingError',
|
|
458
|
+
'TimeoutError',
|
|
459
|
+
'CredentialsError',
|
|
460
|
+
'UnknownEndpoint',
|
|
461
|
+
];
|
|
462
|
+
return awsErrorNames.includes(error.name) || error.message.includes('AWS');
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Handle AWS-specific errors with appropriate strategies.
|
|
466
|
+
* @param loader - The loader that encountered the error
|
|
467
|
+
* @param error - The AWS error
|
|
468
|
+
* @returns Whether to continue processing
|
|
469
|
+
*/
|
|
470
|
+
handleAwsSpecificError(loader, error) {
|
|
471
|
+
const serviceName = this.getServiceName(loader);
|
|
472
|
+
switch (error.name) {
|
|
473
|
+
case 'AccessDeniedException':
|
|
474
|
+
return this.errorHandler.handlePermissionError(serviceName, this.getResourceName(loader), error);
|
|
475
|
+
case 'ResourceNotFoundException':
|
|
476
|
+
return this.errorHandler.handleResourceNotFound(serviceName, this.getResourceName(loader), error);
|
|
477
|
+
case 'NetworkingError':
|
|
478
|
+
case 'TimeoutError':
|
|
479
|
+
const networkResult = this.errorHandler.handleNetworkError(serviceName, error);
|
|
480
|
+
return networkResult.shouldContinue;
|
|
481
|
+
case 'ThrottlingException':
|
|
482
|
+
case 'TooManyRequestsException':
|
|
483
|
+
this.logger.warn(`Rate limiting encountered for ${serviceName}, continuing with other sources`);
|
|
484
|
+
return true;
|
|
485
|
+
case 'ServiceUnavailableException':
|
|
486
|
+
return this.errorHandler.handleAwsUnavailable(serviceName, error);
|
|
487
|
+
case 'CredentialsError':
|
|
488
|
+
this.logger.error(`AWS credentials error for ${serviceName}: ${error.message}`);
|
|
489
|
+
this.logger.error('Please check AWS credentials configuration');
|
|
490
|
+
return this.errorHandler.handleAwsUnavailable(serviceName, error);
|
|
491
|
+
default:
|
|
492
|
+
// Handle as general configuration error
|
|
493
|
+
return this.errorHandler.handleConfigurationError(serviceName, error);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Get the service name for a loader.
|
|
498
|
+
* @param loader - The configuration loader
|
|
499
|
+
* @returns The service name
|
|
500
|
+
*/
|
|
501
|
+
getServiceName(loader) {
|
|
502
|
+
if (loader instanceof SecretsManagerLoader) {
|
|
503
|
+
return 'AWS Secrets Manager';
|
|
504
|
+
}
|
|
505
|
+
else if (loader instanceof SSMParameterStoreLoader) {
|
|
506
|
+
return 'AWS Systems Manager Parameter Store';
|
|
507
|
+
}
|
|
508
|
+
else if (loader instanceof EnvironmentLoader) {
|
|
509
|
+
return 'Environment Variables';
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
return 'Unknown Service';
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Get the resource name for a loader.
|
|
517
|
+
* @param loader - The configuration loader
|
|
518
|
+
* @returns The resource name
|
|
519
|
+
*/
|
|
520
|
+
getResourceName(loader) {
|
|
521
|
+
if (loader instanceof SecretsManagerLoader) {
|
|
522
|
+
return this.getSecretsManagerPath();
|
|
523
|
+
}
|
|
524
|
+
else if (loader instanceof SSMParameterStoreLoader) {
|
|
525
|
+
return this.getSSMParameterPath();
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
return 'configuration';
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Load configuration with retry logic for retryable errors.
|
|
533
|
+
* @param loader - The configuration loader
|
|
534
|
+
* @param maxRetries - Maximum number of retries
|
|
535
|
+
* @returns Promise resolving to configuration data
|
|
536
|
+
*/
|
|
537
|
+
async loadWithRetry(loader, maxRetries = 3) {
|
|
538
|
+
let lastError = null;
|
|
539
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
540
|
+
try {
|
|
541
|
+
return await loader.load();
|
|
542
|
+
}
|
|
543
|
+
catch (error) {
|
|
544
|
+
const loaderError = error instanceof Error ? error : new Error(String(error));
|
|
545
|
+
lastError = loaderError;
|
|
546
|
+
// Check if error is retryable
|
|
547
|
+
if (!this.errorHandler.isRetryableError(loaderError) || attempt === maxRetries) {
|
|
548
|
+
throw loaderError;
|
|
549
|
+
}
|
|
550
|
+
// Wait before retrying
|
|
551
|
+
const delay = this.errorHandler.getRetryDelay(attempt);
|
|
552
|
+
this.logger.warn(`Retrying ${loader.getName()} in ${delay}ms (attempt ${attempt}/${maxRetries})`);
|
|
553
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
// This should never be reached, but just in case
|
|
557
|
+
throw lastError || new Error('Unknown error during retry');
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Check availability with timeout and error handling.
|
|
561
|
+
* @param loader - The configuration loader
|
|
562
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
563
|
+
* @returns Promise resolving to availability status
|
|
564
|
+
*/
|
|
565
|
+
async checkAvailabilityWithTimeout(loader, timeoutMs = 5000) {
|
|
566
|
+
try {
|
|
567
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
568
|
+
setTimeout(() => reject(new Error('Availability check timeout')), timeoutMs);
|
|
569
|
+
});
|
|
570
|
+
const availabilityPromise = loader.isAvailable();
|
|
571
|
+
return await Promise.race([availabilityPromise, timeoutPromise]);
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
const loaderError = error instanceof Error ? error : new Error(String(error));
|
|
575
|
+
if (this.options.enableLogging) {
|
|
576
|
+
this.logger.debug(`Availability check failed for ${loader.getName()}: ${loaderError.message}`);
|
|
577
|
+
}
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
AwsConfigurationLoaderService = AwsConfigurationLoaderService_1 = __decorate([
|
|
583
|
+
Injectable(),
|
|
584
|
+
__param(0, Optional()),
|
|
585
|
+
__param(0, Inject('INTEGRATION_OPTIONS')),
|
|
586
|
+
__metadata("design:paramtypes", [Object])
|
|
587
|
+
], AwsConfigurationLoaderService);
|
|
588
|
+
export { AwsConfigurationLoaderService };
|
|
589
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNvbmZpZ3VyYXRpb24tbG9hZGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvaW50ZWdyYXRpb24vcHJvdmlkZXJzL2F3cy1jb25maWd1cmF0aW9uLWxvYWRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEUsT0FBTyxFQUVMLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIsaUJBQWlCLEdBQ2xCLE1BQU0sb0JBQW9CLENBQUM7QUFJNUIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFeEU7OztHQUdHO0FBRUksSUFBTSw2QkFBNkIscUNBQW5DLE1BQU0sNkJBQTZCO0lBQ3ZCLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQywrQkFBNkIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxPQUFPLENBQWlCO0lBQ3hCLE9BQU8sQ0FBcUI7SUFDNUIsWUFBWSxDQUFzQjtJQUVuRCxZQUM2QyxPQUE0QjtRQUV2RSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQjtRQUNyQixNQUFNLFlBQVksR0FBd0IsRUFBRSxDQUFDO1FBQzdDLE1BQU0sT0FBTyxHQUEwQixFQUFFLENBQUM7UUFFMUMsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbEMs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QUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDL0UsQ0FBQyxDQUFDLENBQUM7WUFFSCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUVqRCxPQUFPLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLG1CQUFtQixFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLFdBQVcsR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBRTlFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUNBQWlDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNqRyxDQUFDO1lBRUQsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztDQUNGLENBQUE7QUEvbkJZLDZCQUE2QjtJQUR6QyxVQUFVLEVBQUU7SUFRUixXQUFBLFFBQVEsRUFBRSxDQUFBO0lBQUUsV0FBQSxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQTs7R0FQakMsNkJBQTZCLENBK25CekMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBMb2dnZXIsIEluamVjdCwgT3B0aW9uYWwgfSBmcm9tICdAbmVzdGpzL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQ29uZmlnTG9hZGVyLFxyXG4gIFNlY3JldHNNYW5hZ2VyTG9hZGVyLFxyXG4gIFNTTVBhcmFtZXRlclN0b3JlTG9hZGVyLFxyXG4gIEVudmlyb25tZW50TG9hZGVyLFxyXG59IGZyb20gJ0BkeWFuZXQvY29uZmlnLWF3cyc7XHJcbmltcG9ydCB7IEludGVncmF0aW9uT3B0aW9ucyB9IGZyb20gJy4uL2ludGVyZmFjZXMvaW50ZWdyYXRpb24tb3B0aW9ucy5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBDb25maWd1cmF0aW9uU291cmNlLCBDb25maWd1cmF0aW9uU291cmNlVHlwZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvY29uZmlndXJhdGlvbi1zb3VyY2UuaW50ZXJmYWNlJztcclxuXHJcbmltcG9ydCB7IEVycm9ySGFuZGxlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9lcnJvci1oYW5kbGVyLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNlcnZpY2UgZm9yIGxvYWRpbmcgY29uZmlndXJhdGlvbiBmcm9tIEFXUyBzb3VyY2VzIGZvciBpbnRlZ3JhdGlvbiB3aXRoIEBuZXN0anMvY29uZmlnLlxyXG4gKiBVc2VzIGV4aXN0aW5nIEFXUyBsb2FkZXJzIHRvIGZldGNoIGNvbmZpZ3VyYXRpb24gYW5kIHByb3ZpZGVzIG5hbWVzcGFjZS1hd2FyZSBsb2FkaW5nIGNhcGFiaWxpdGllcy5cclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEF3c0NvbmZpZ3VyYXRpb25Mb2FkZXJTZXJ2aWNlIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlciA9IG5ldyBMb2dnZXIoQXdzQ29uZmlndXJhdGlvbkxvYWRlclNlcnZpY2UubmFtZSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkZXJzOiBDb25maWdMb2FkZXJbXTtcclxuICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IEludGVncmF0aW9uT3B0aW9ucztcclxuICBwcml2YXRlIHJlYWRvbmx5IGVycm9ySGFuZGxlcjogRXJyb3JIYW5kbGVyU2VydmljZTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KCdJTlRFR1JBVElPTl9PUFRJT05TJykgb3B0aW9ucz86IEludGVncmF0aW9uT3B0aW9uc1xyXG4gICkge1xyXG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlclNlcnZpY2UodGhpcy5vcHRpb25zKTtcclxuICAgIHRoaXMubG9hZGVycyA9IHRoaXMuY3JlYXRlTG9hZGVycygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZCBjb25maWd1cmF0aW9uIGZyb20gQVdTIHNvdXJjZXMuXHJcbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgdG8gY29uZmlndXJhdGlvbiBkYXRhXHJcbiAgICovXHJcbiAgYXN5bmMgbG9hZENvbmZpZ3VyYXRpb24oKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XHJcbiAgICBjb25zdCBtZXJnZWRDb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcclxuICAgIGNvbnN0IHNvdXJjZXM6IENvbmZpZ3VyYXRpb25Tb3VyY2VbXSA9IFtdO1xyXG5cclxuICAgIGZvciAoY29uc3QgbG9hZGVyIG9mIHRoaXMubG9hZGVycykge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIC8vIENoZWNrIGlmIGxvYWRlciBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBlbnZpcm9ubWVudCB3aXRoIHRpbWVvdXRcclxuICAgICAgICBjb25zdCBpc0F2YWlsYWJsZSA9IGF3YWl0IHRoaXMuY2hlY2tBdmFpbGFiaWxpdHlXaXRoVGltZW91dChsb2FkZXIpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICghaXNBdmFpbGFibGUpIHtcclxuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTG9nZ2luZykge1xyXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgU2tpcHBpbmcgJHtsb2FkZXIuZ2V0TmFtZSgpfSAtIG5vdCBhdmFpbGFibGUgaW4gY3VycmVudCBlbnZpcm9ubWVudGApO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmVuYWJsZUxvZ2dpbmcpIHtcclxuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBMb2FkaW5nIGNvbmZpZ3VyYXRpb24gZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBMb2FkIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGlzIHNvdXJjZSB3aXRoIHJldHJ5IGxvZ2ljIGZvciBBV1Mgc2VydmljZXNcclxuICAgICAgICBjb25zdCBsb2FkZXJDb25maWcgPSBsb2FkZXIgaW5zdGFuY2VvZiBFbnZpcm9ubWVudExvYWRlciBcclxuICAgICAgICAgID8gYXdhaXQgbG9hZGVyLmxvYWQoKSBcclxuICAgICAgICAgIDogYXdhaXQgdGhpcy5sb2FkV2l0aFJldHJ5KGxvYWRlcik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gQ3JlYXRlIGNvbmZpZ3VyYXRpb24gc291cmNlIG1ldGFkYXRhXHJcbiAgICAgICAgY29uc3Qgc291cmNlOiBDb25maWd1cmF0aW9uU291cmNlID0ge1xyXG4gICAgICAgICAgbmFtZTogbG9hZGVyLmdldE5hbWUoKSxcclxuICAgICAgICAgIHR5cGU6IHRoaXMuZ2V0U291cmNlVHlwZShsb2FkZXIpLFxyXG4gICAgICAgICAgcHJpb3JpdHk6IHRoaXMuZ2V0U291cmNlUHJpb3JpdHkobG9hZGVyKSxcclxuICAgICAgICAgIGRhdGE6IGxvYWRlckNvbmZpZyxcclxuICAgICAgICAgIGxvYWRlZEF0OiBuZXcgRGF0ZSgpLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xyXG5cclxuICAgICAgICAvLyBNZXJnZSB3aXRoIGV4aXN0aW5nIGNvbmZpZ3VyYXRpb24gYmFzZWQgb24gcHJlY2VkZW5jZVxyXG4gICAgICAgIE9iamVjdC5hc3NpZ24obWVyZ2VkQ29uZmlnLCBsb2FkZXJDb25maWcpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTG9nZ2luZykge1xyXG4gICAgICAgICAgY29uc3Qga2V5Q291bnQgPSBPYmplY3Qua2V5cyhsb2FkZXJDb25maWcpLmxlbmd0aDtcclxuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBMb2FkZWQgJHtrZXlDb3VudH0gY29uZmlndXJhdGlvbiB2YWx1ZXMgZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnN0IGxvYWRlckVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIExvZyBkZXRhaWxlZCBlcnJvciBpbmZvcm1hdGlvbiBmb3IgdHJvdWJsZXNob290aW5nXHJcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubG9nRGV0YWlsZWRFcnJvcihgbG9hZENvbmZpZ3VyYXRpb24gLSAke2xvYWRlci5nZXROYW1lKCl9YCwgbG9hZGVyRXJyb3IsIHtcclxuICAgICAgICAgIGxvYWRlck5hbWU6IGxvYWRlci5nZXROYW1lKCksXHJcbiAgICAgICAgICBsb2FkZXJUeXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gSGFuZGxlIHNwZWNpZmljIGVycm9yIHR5cGVzXHJcbiAgICAgICAgaWYgKHRoaXMuaXNBd3NTZXJ2aWNlRXJyb3IobG9hZGVyRXJyb3IpKSB7XHJcbiAgICAgICAgICBjb25zdCBzaG91bGRDb250aW51ZSA9IHRoaXMuaGFuZGxlQXdzU3BlY2lmaWNFcnJvcihsb2FkZXIsIGxvYWRlckVycm9yKTtcclxuICAgICAgICAgIGlmICghc2hvdWxkQ29udGludWUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbG9hZGVyRXJyb3I7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIEhhbmRsZSBnZW5lcmFsIGNvbmZpZ3VyYXRpb24gZXJyb3JzXHJcbiAgICAgICAgICBjb25zdCBzaG91bGRDb250aW51ZSA9IHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZUNvbmZpZ3VyYXRpb25FcnJvcihsb2FkZXIuZ2V0TmFtZSgpLCBsb2FkZXJFcnJvcik7XHJcbiAgICAgICAgICBpZiAoIXNob3VsZENvbnRpbnVlKSB7XHJcbiAgICAgICAgICAgIHRocm93IGxvYWRlckVycm9yO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWRkIGVycm9yIHRvIHNvdXJjZSBtZXRhZGF0YVxyXG4gICAgICAgIGNvbnN0IGVycm9yU291cmNlOiBDb25maWd1cmF0aW9uU291cmNlID0ge1xyXG4gICAgICAgICAgbmFtZTogbG9hZGVyLmdldE5hbWUoKSxcclxuICAgICAgICAgIHR5cGU6IHRoaXMuZ2V0U291cmNlVHlwZShsb2FkZXIpLFxyXG4gICAgICAgICAgcHJpb3JpdHk6IHRoaXMuZ2V0U291cmNlUHJpb3JpdHkobG9hZGVyKSxcclxuICAgICAgICAgIGRhdGE6IHt9LFxyXG4gICAgICAgICAgbG9hZGVkQXQ6IG5ldyBEYXRlKCksXHJcbiAgICAgICAgICBlcnJvcnM6IFtsb2FkZXJFcnJvci5tZXNzYWdlXSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIHNvdXJjZXMucHVzaChlcnJvclNvdXJjZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbWVyZ2VkQ29uZmlnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZCBjb25maWd1cmF0aW9uIGZvciBzcGVjaWZpYyBuYW1lc3BhY2VzIGZyb20gQVdTIHNvdXJjZXMuXHJcbiAgICogQHBhcmFtIG5hbWVzcGFjZXMgLSBBcnJheSBvZiBuYW1lc3BhY2UgbmFtZXMgdG8gbG9hZFxyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIG5hbWVzcGFjZWQgY29uZmlndXJhdGlvbiBkYXRhXHJcbiAgICovXHJcbiAgYXN5bmMgbG9hZE5hbWVzcGFjZWRDb25maWd1cmF0aW9uKG5hbWVzcGFjZXM6IHN0cmluZ1tdKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+Pj4ge1xyXG4gICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+PiA9IHt9O1xyXG4gICAgXHJcbiAgICAvLyBJbml0aWFsaXplIGFsbCBuYW1lc3BhY2VzXHJcbiAgICBmb3IgKGNvbnN0IG5hbWVzcGFjZSBvZiBuYW1lc3BhY2VzKSB7XHJcbiAgICAgIHJlc3VsdFtuYW1lc3BhY2VdID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChjb25zdCBsb2FkZXIgb2YgdGhpcy5sb2FkZXJzKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgbG9hZGVyIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGVudmlyb25tZW50IHdpdGggdGltZW91dFxyXG4gICAgICAgIGNvbnN0IGlzQXZhaWxhYmxlID0gYXdhaXQgdGhpcy5jaGVja0F2YWlsYWJpbGl0eVdpdGhUaW1lb3V0KGxvYWRlcik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKCFpc0F2YWlsYWJsZSkge1xyXG4gICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5lbmFibGVMb2dnaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBTa2lwcGluZyAke2xvYWRlci5nZXROYW1lKCl9IGZvciBuYW1lc3BhY2UgbG9hZGluZyAtIG5vdCBhdmFpbGFibGVgKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5lbmFibGVMb2dnaW5nKSB7XHJcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgTG9hZGluZyBuYW1lc3BhY2VkIGNvbmZpZ3VyYXRpb24gZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBMb2FkIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGlzIHNvdXJjZSB3aXRoIHJldHJ5IGxvZ2ljIGZvciBBV1Mgc2VydmljZXNcclxuICAgICAgICBjb25zdCBsb2FkZXJDb25maWcgPSBsb2FkZXIgaW5zdGFuY2VvZiBFbnZpcm9ubWVudExvYWRlciBcclxuICAgICAgICAgID8gYXdhaXQgbG9hZGVyLmxvYWQoKSBcclxuICAgICAgICAgIDogYXdhaXQgdGhpcy5sb2FkV2l0aFJldHJ5KGxvYWRlcik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gRGlzdHJpYnV0ZSBjb25maWd1cmF0aW9uIHRvIG5hbWVzcGFjZXMgYmFzZWQgb24ga2V5IHByZWZpeGVzIG9yIHBhdHRlcm5zXHJcbiAgICAgICAgZm9yIChjb25zdCBuYW1lc3BhY2Ugb2YgbmFtZXNwYWNlcykge1xyXG4gICAgICAgICAgY29uc3QgbmFtZXNwYWNlZENvbmZpZyA9IHRoaXMuZXh0cmFjdE5hbWVzcGFjZUNvbmZpZyhsb2FkZXJDb25maWcsIG5hbWVzcGFjZSk7XHJcbiAgICAgICAgICBcclxuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhuYW1lc3BhY2VkQ29uZmlnKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocmVzdWx0W25hbWVzcGFjZV0hLCBuYW1lc3BhY2VkQ29uZmlnKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTG9nZ2luZykge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGtleUNvdW50ID0gT2JqZWN0LmtleXMobmFtZXNwYWNlZENvbmZpZykubGVuZ3RoO1xyXG4gICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBMb2FkZWQgJHtrZXlDb3VudH0gdmFsdWVzIGZvciBuYW1lc3BhY2UgJyR7bmFtZXNwYWNlfScgZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgY29uc3QgbG9hZGVyRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gTG9nIGRldGFpbGVkIGVycm9yIGluZm9ybWF0aW9uIGZvciB0cm91Ymxlc2hvb3RpbmdcclxuICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5sb2dEZXRhaWxlZEVycm9yKGBsb2FkTmFtZXNwYWNlZENvbmZpZ3VyYXRpb24gLSAke2xvYWRlci5nZXROYW1lKCl9YCwgbG9hZGVyRXJyb3IsIHtcclxuICAgICAgICAgIGxvYWRlck5hbWU6IGxvYWRlci5nZXROYW1lKCksXHJcbiAgICAgICAgICBsb2FkZXJUeXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICAgIG5hbWVzcGFjZXMsXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBzcGVjaWZpYyBlcnJvciB0eXBlc1xyXG4gICAgICAgIGlmICh0aGlzLmlzQXdzU2VydmljZUVycm9yKGxvYWRlckVycm9yKSkge1xyXG4gICAgICAgICAgY29uc3Qgc2hvdWxkQ29udGludWUgPSB0aGlzLmhhbmRsZUF3c1NwZWNpZmljRXJyb3IobG9hZGVyLCBsb2FkZXJFcnJvcik7XHJcbiAgICAgICAgICBpZiAoIXNob3VsZENvbnRpbnVlKSB7XHJcbiAgICAgICAgICAgIHRocm93IGxvYWRlckVycm9yO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyBIYW5kbGUgZ2VuZXJhbCBjb25maWd1cmF0aW9uIGVycm9yc1xyXG4gICAgICAgICAgY29uc3Qgc2hvdWxkQ29udGludWUgPSB0aGlzLmVycm9ySGFuZGxlci5oYW5kbGVDb25maWd1cmF0aW9uRXJyb3IobG9hZGVyLmdldE5hbWUoKSwgbG9hZGVyRXJyb3IpO1xyXG4gICAgICAgICAgaWYgKCFzaG91bGRDb250aW51ZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBsb2FkZXJFcnJvcjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBmYWxsYmFjayBjb25maWd1cmF0aW9uIGZvciBlYWNoIG5hbWVzcGFjZVxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZmFsbGJhY2tUb0xvY2FsKSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IG5hbWVzcGFjZSBvZiBuYW1lc3BhY2VzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZhbGxiYWNrQ29uZmlnID0gdGhpcy5lcnJvckhhbmRsZXIuY3JlYXRlRmFsbGJhY2tDb25maWd1cmF0aW9uKG5hbWVzcGFjZSk7XHJcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocmVzdWx0W25hbWVzcGFjZV0hLCBmYWxsYmFja0NvbmZpZyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIEFXUyBzZXJ2aWNlcyBhcmUgYXZhaWxhYmxlLlxyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGF2YWlsYWJpbGl0eSBzdGF0dXNcclxuICAgKi9cclxuICBhc3luYyBpc0F2YWlsYWJsZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIENoZWNrIGlmIGF0IGxlYXN0IG9uZSBBV1MgbG9hZGVyIGlzIGF2YWlsYWJsZVxyXG4gICAgICBjb25zdCBhdmFpbGFiaWxpdHlDaGVja3MgPSB0aGlzLmxvYWRlcnNcclxuICAgICAgICAuZmlsdGVyKGxvYWRlciA9PiAhKGxvYWRlciBpbnN0YW5jZW9mIEVudmlyb25tZW50TG9hZGVyKSkgLy8gU2tpcCBlbnZpcm9ubWVudCBsb2FkZXJcclxuICAgICAgICAubWFwKGxvYWRlciA9PiB0aGlzLmNoZWNrQXZhaWxhYmlsaXR5V2l0aFRpbWVvdXQobG9hZGVyKSk7XHJcblxyXG4gICAgICBpZiAoYXZhaWxhYmlsaXR5Q2hlY2tzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIC8vIE5vIEFXUyBsb2FkZXJzIGNvbmZpZ3VyZWRcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFdhaXQgZm9yIGFsbCBhdmFpbGFiaWxpdHkgY2hlY2tzIHRvIGNvbXBsZXRlXHJcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoYXZhaWxhYmlsaXR5Q2hlY2tzKTtcclxuICAgICAgXHJcbiAgICAgIC8vIFJldHVybiB0cnVlIGlmIGF0IGxlYXN0IG9uZSBBV1Mgc2VydmljZSBpcyBhdmFpbGFibGVcclxuICAgICAgcmV0dXJuIHJlc3VsdHMuc29tZShyZXN1bHQgPT4gcmVzdWx0LnN0YXR1cyA9PT0gJ2Z1bGZpbGxlZCcgJiYgcmVzdWx0LnZhbHVlID09PSB0cnVlKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnN0IGF2YWlsYWJpbGl0eUVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xyXG4gICAgICBcclxuICAgICAgdGhpcy5lcnJvckhhbmRsZXIubG9nRGV0YWlsZWRFcnJvcignaXNBdmFpbGFibGUnLCBhdmFpbGFiaWxpdHlFcnJvcik7XHJcbiAgICAgIFxyXG4gICAgICAvLyBIYW5kbGUgYXMgQVdTIHVuYXZhaWxhYmxlXHJcbiAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZUF3c1VuYXZhaWxhYmxlKCdBV1MgU2VydmljZXMnLCBhdmFpbGFiaWxpdHlFcnJvcik7XHJcbiAgICAgIFxyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYWxsIGF2YWlsYWJsZSBjb25maWd1cmF0aW9uIHNvdXJjZXMgd2l0aCB0aGVpciBtZXRhZGF0YS5cclxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmluZyB0byBhcnJheSBvZiBjb25maWd1cmF0aW9uIHNvdXJjZXNcclxuICAgKi9cclxuICBhc3luYyBnZXRBdmFpbGFibGVTb3VyY2VzKCk6IFByb21pc2U8Q29uZmlndXJhdGlvblNvdXJjZVtdPiB7XHJcbiAgICBjb25zdCBzb3VyY2VzOiBDb25maWd1cmF0aW9uU291cmNlW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGxvYWRlciBvZiB0aGlzLmxvYWRlcnMpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBpc0F2YWlsYWJsZSA9IGF3YWl0IGxvYWRlci5pc0F2YWlsYWJsZSgpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChpc0F2YWlsYWJsZSkge1xyXG4gICAgICAgICAgY29uc3QgbG9hZGVyQ29uZmlnID0gYXdhaXQgbG9hZGVyLmxvYWQoKTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgY29uc3Qgc291cmNlOiBDb25maWd1cmF0aW9uU291cmNlID0ge1xyXG4gICAgICAgICAgICBuYW1lOiBsb2FkZXIuZ2V0TmFtZSgpLFxyXG4gICAgICAgICAgICB0eXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICAgICAgcHJpb3JpdHk6IHRoaXMuZ2V0U291cmNlUHJpb3JpdHkobG9hZGVyKSxcclxuICAgICAgICAgICAgZGF0YTogbG9hZGVyQ29uZmlnLFxyXG4gICAgICAgICAgICBsb2FkZWRBdDogbmV3IERhdGUoKSxcclxuICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgc291cmNlcy5wdXNoKHNvdXJjZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIC8vIEFkZCBzb3VyY2Ugd2l0aCBlcnJvciBpbmZvcm1hdGlvblxyXG4gICAgICAgIGNvbnN0IHNvdXJjZTogQ29uZmlndXJhdGlvblNvdXJjZSA9IHtcclxuICAgICAgICAgIG5hbWU6IGxvYWRlci5nZXROYW1lKCksXHJcbiAgICAgICAgICB0eXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICAgIHByaW9yaXR5OiB0aGlzLmdldFNvdXJjZVByaW9yaXR5KGxvYWRlciksXHJcbiAgICAgICAgICBkYXRhOiB7fSxcclxuICAgICAgICAgIGxvYWRlZEF0OiBuZXcgRGF0ZSgpLFxyXG4gICAgICAgICAgZXJyb3JzOiBbZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXSxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBzb3VyY2VzLnB1c2goc291cmNlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzb3VyY2VzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGNvbmZpZ3VyYXRpb24gbG9hZGVycyBiYXNlZCBvbiBpbnRlZ3JhdGlvbiBvcHRpb25zLlxyXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIGNvbmZpZ3VyYXRpb24gbG9hZGVyc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgY3JlYXRlTG9hZGVycygpOiBDb25maWdMb2FkZXJbXSB7XHJcbiAgICBjb25zdCBsb2FkZXJzOiBDb25maWdMb2FkZXJbXSA9IFtdO1xyXG5cclxuICAgIC8vIEFsd2F5cyBpbmNsdWRlIGVudmlyb25tZW50IGxvYWRlclxyXG4gICAgbG9hZGVycy5wdXNoKG5ldyBFbnZpcm9ubWVudExvYWRlcih7IHByZWZpeDogdGhpcy5vcHRpb25zLmVudlByZWZpeCB9KSk7XHJcblxyXG4gICAgLy8gQWRkIEFXUyBTZWNyZXRzIE1hbmFnZXIgbG9hZGVyIGlmIGNvbmZpZ3VyZWRcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuc2VjcmV0c01hbmFnZXJDb25maWc/LmVuYWJsZWQgIT09IGZhbHNlKSB7XHJcbiAgICAgIGNvbnN0IHNlY3JldHNDb25maWcgPSB7XHJcbiAgICAgICAgcmVnaW9uOiB0aGlzLm9wdGlvbnMuc2VjcmV0c01hbmFnZXJDb25maWc/LnJlZ2lvbixcclxuICAgICAgICAvLyBDb252ZXJ0IHBhdGhzIHRvIHNlY3JldE5hbWUgZm9ybWF0IGV4cGVjdGVkIGJ5IFNlY3JldHNNYW5hZ2VyTG9hZGVyXHJcbiAgICAgICAgc2VjcmV0TmFtZTogdGhpcy5nZXRTZWNyZXRzTWFuYWdlclBhdGgoKSxcclxuICAgICAgfTtcclxuICAgICAgbG9hZGVycy5wdXNoKG5ldyBTZWNyZXRzTWFuYWdlckxvYWRlcihzZWNyZXRzQ29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWRkIFNTTSBQYXJhbWV0ZXIgU3RvcmUgbG9hZGVyIGlmIGNvbmZpZ3VyZWRcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuc3NtQ29uZmlnPy5lbmFibGVkICE9PSBmYWxzZSkge1xyXG4gICAgICBjb25zdCBzc21Db25maWcgPSB7XHJcbiAgICAgICAgcmVnaW9uOiB0aGlzLm9wdGlvbnMuc3NtQ29uZmlnPy5yZWdpb24sXHJcbiAgICAgICAgLy8gQ29udmVydCBwYXRocyB0byBwYXJhbWV0ZXJQYXRoIGZvcm1hdCBleHBlY3RlZCBieSBTU01QYXJhbWV0ZXJTdG9yZUxvYWRlclxyXG4gICAgICAgIHBhcmFtZXRlclBhdGg6IHRoaXMuZ2V0U1NNUGFyYW1ldGVyUGF0aCgpLFxyXG4gICAgICAgIHdpdGhEZWNyeXB0aW9uOiB0aGlzLm9wdGlvbnMuc3NtQ29uZmlnPy5kZWNyeXB0ID8/IHRydWUsXHJcbiAgICAgIH07XHJcbiAgICAgIGxvYWRlcnMucHVzaChuZXcgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIoc3NtQ29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxvYWRlcnM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIHNvdXJjZSB0eXBlIGZvciBhIGdpdmVuIGxvYWRlci5cclxuICAgKiBAcGFyYW0gbG9hZGVyIC0gVGhlIGNvbmZpZ3VyYXRpb24gbG9hZGVyXHJcbiAgICogQHJldHVybnMgVGhlIGNvbmZpZ3VyYXRpb24gc291cmNlIHR5cGVcclxuICAgKi9cclxuICBwcml2YXRlIGdldFNvdXJjZVR5cGUobG9hZGVyOiBDb25maWdMb2FkZXIpOiBDb25maWd1cmF0aW9uU291cmNlVHlwZSB7XHJcbiAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgRW52aXJvbm1lbnRMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdlbnZpcm9ubWVudCc7XHJcbiAgICB9IGVsc2UgaWYgKGxvYWRlciBpbnN0YW5jZW9mIFNlY3JldHNNYW5hZ2VyTG9hZGVyKSB7XHJcbiAgICAgIHJldHVybiAnc2VjcmV0cy1tYW5hZ2VyJztcclxuICAgIH0gZWxzZSBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdzc20nO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuICdsb2NhbC1maWxlJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgcHJpb3JpdHkgZm9yIGEgZ2l2ZW4gbG9hZGVyIGJhc2VkIG9uIHByZWNlZGVuY2UgcnVsZXMuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEByZXR1cm5zIFRoZSBwcmlvcml0eSBudW1iZXIgKGhpZ2hlciA9IGhpZ2hlciBwcmlvcml0eSlcclxuICAgKi9cclxuICBwcml2YXRlIGdldFNvdXJjZVByaW9yaXR5KGxvYWRlcjogQ29uZmlnTG9hZGVyKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IHByZWNlZGVuY2UgPSB0aGlzLm9wdGlvbnMucHJlY2VkZW5jZSB8fCAnYXdzLWZpcnN0JztcclxuICAgIFxyXG4gICAgaWYgKHByZWNlZGVuY2UgPT09ICdsb2NhbC1maXJzdCcpIHtcclxuICAgICAgLy8gRW52aXJvbm1lbnQgdmFyaWFibGVzIGhhdmUgaGlnaGVzdCBwcmlvcml0eVxyXG4gICAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgRW52aXJvbm1lbnRMb2FkZXIpIHJldHVybiAxMDA7XHJcbiAgICAgIGlmIChsb2FkZXIgaW5zdGFuY2VvZiBTZWNyZXRzTWFuYWdlckxvYWRlcikgcmV0dXJuIDUwO1xyXG4gICAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHJldHVybiA0MDtcclxuICAgIH0gZWxzZSBpZiAocHJlY2VkZW5jZSA9PT0gJ2F3cy1maXJzdCcpIHtcclxuICAgICAgLy8gQVdTIHNvdXJjZXMgaGF2ZSBoaWdoZXIgcHJpb3JpdHlcclxuICAgICAgaWYgKGxvYWRlciBpbnN0YW5jZW9mIFNlY3JldHNNYW5hZ2VyTG9hZGVyKSByZXR1cm4gMTAwO1xyXG4gICAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHJldHVybiA5MDtcclxuICAgICAgaWYgKGxvYWRlciBpbnN0YW5jZW9mIEVudmlyb25tZW50TG9hZGVyKSByZXR1cm4gNTA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBtZXJnZSAtIGVxdWFsIHByaW9yaXR5LCBvcmRlciBtYXR0ZXJzXHJcbiAgICAgIHJldHVybiA1MDtcclxuICAgIH1cclxuICAgIFxyXG4gICAgcmV0dXJuIDUwO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBjb25maWd1cmF0aW9uIGZvciBhIHNwZWNpZmljIG5hbWVzcGFjZSBmcm9tIGxvYWRlZCBjb25maWd1cmF0aW9uLlxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBUaGUgbG9hZGVkIGNvbmZpZ3VyYXRpb25cclxuICAgKiBAcGFyYW0gbmFtZXNwYWNlIC0gVGhlIG5hbWVzcGFjZSB0byBleHRyYWN0XHJcbiAgICogQHJldHVybnMgQ29uZmlndXJhdGlvbiB2YWx1ZXMgZm9yIHRoZSBuYW1lc3BhY2VcclxuICAgKi9cclxuICBwcml2YXRlIGV4dHJhY3ROYW1lc3BhY2VDb25maWcoY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBuYW1lc3BhY2U6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xyXG4gICAgY29uc3QgbmFtZXNwYWNlQ29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XHJcbiAgICBjb25zdCBuYW1lc3BhY2VQcmVmaXggPSBuYW1lc3BhY2UudG9VcHBlckNhc2UoKTtcclxuXHJcbiAgICAvLyBTdHJhdGVneSAxOiBMb29rIGZvciBkaXJlY3QgbmFtZXNwYWNlIGtleSAoZS5nLiwgY29uZmlnLmRhdGFiYXNlKVxyXG4gICAgaWYgKGNvbmZpZ1tuYW1lc3BhY2VdKSB7XHJcbiAgICAgIE9iamVjdC5hc3NpZ24obmFtZXNwYWNlQ29uZmlnLCBjb25maWdbbmFtZXNwYWNlXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU3RyYXRlZ3kgMjogTG9vayBmb3Iga2V5cyB0aGF0IHN0YXJ0IHdpdGggdGhlIG5hbWVzcGFjZSBwcmVmaXggKGUuZy4sIERBVEFCQVNFX0hPU1QpXHJcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhjb25maWcpKSB7XHJcbiAgICAgIGNvbnN0IHVwcGVyS2V5ID0ga2V5LnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgIFxyXG4gICAgICAvLyBDaGVjayBpZiBrZXkgc3RhcnRzIHdpdGggbmFtZXNwYWNlIHByZWZpeCBmb2xsb3dlZCBieSB1bmRlcnNjb3JlXHJcbiAgICAgIGlmICh1cHBlcktleS5zdGFydHNXaXRoKGAke25hbWVzcGFjZVByZWZpeH1fYCkpIHtcclxuICAgICAgICAvLyBSZW1vdmUgbmFtZXNwYWNlIHByZWZpeCBhbmQgdW5kZXJzY29yZSwgY29udmVydCB0byBjYW1lbENhc2VcclxuICAgICAgICBjb25zdCBuYW1lc3BhY2VkS2V5ID0ga2V5LnN1YnN0cmluZyhuYW1lc3BhY2UubGVuZ3RoICsgMSk7XHJcbiAgICAgICAgY29uc3QgY2FtZWxDYXNlS2V5ID0gdGhpcy50b0NhbWVsQ2FzZShuYW1lc3BhY2VkS2V5KTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoY2FtZWxDYXNlS2V5KSB7XHJcbiAgICAgICAgICBuYW1lc3BhY2VDb25maWdbY2FtZWxDYXNlS2V5XSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFN0cmF0ZWd5IDM6IExvb2sgZm9yIG5lc3RlZCBuYW1lc3BhY2UgcGF0aHMgKGUuZy4sIC9hcHAvZGF0YWJhc2UvaG9zdClcclxuICAgIGNvbnN0IG5lc3RlZENvbmZpZyA9IHRoaXMuZXh0cmFjdE5lc3RlZE5hbWVzcGFjZUNvbmZpZyhjb25maWcsIG5hbWVzcGFjZSk7XHJcbiAgICBPYmplY3QuYXNzaWduKG5hbWVzcGFjZUNvbmZpZywgbmVzdGVkQ29uZmlnKTtcclxuXHJcbiAgICByZXR1cm4gbmFtZXNwYWNlQ29uZmlnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBuZXN0ZWQgbmFtZXNwYWNlIGNvbmZpZ3VyYXRpb24gZnJvbSBoaWVyYXJjaGljYWwga2V5cy5cclxuICAgKiBAcGFyYW0gY29uZmlnIC0gVGhlIGxvYWRlZCBjb25maWd1cmF0aW9uXHJcbiAgICogQHBhcmFtIG5hbWVzcGFjZSAtIFRoZSBuYW1lc3BhY2UgdG8gZXh0cmFjdFxyXG4gICAqIEByZXR1cm5zIENvbmZpZ3VyYXRpb24gdmFsdWVzIGZvciB0aGUgbmFtZXNwYWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBleHRyYWN0TmVzdGVkTmFtZXNwYWNlQ29uZmlnKGNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55PiwgbmFtZXNwYWNlOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcclxuICAgIGNvbnN0IG5hbWVzcGFjZUNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xyXG4gICAgY29uc3QgbmFtZXNwYWNlUGF0aCA9IGAvJHtuYW1lc3BhY2V9L2A7XHJcblxyXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnKSkge1xyXG4gICAgICAvLyBDaGVjayBpZiBrZXkgY29udGFpbnMgbmFtZXNwYWNlIHBhdGhcclxuICAgICAgaWYgKGtleS5pbmNsdWRlcyhuYW1lc3BhY2VQYXRoKSkge1xyXG4gICAgICAgIC8vIEV4dHJhY3QgdGhlIHBhcnQgYWZ0ZXIgdGhlIG5hbWVzcGFjZSBwYXRoXHJcbiAgICAgICAgY29uc3QgcGF0aEluZGV4ID0ga2V5LmluZGV4T2YobmFtZXNwYWNlUGF0aCk7XHJcbiAgICAgICAgY29uc3QgYWZ0ZXJOYW1lc3BhY2UgPSBrZXkuc3Vic3RyaW5nKHBhdGhJbmRleCArIG5hbWVzcGFjZVBhdGgubGVuZ3RoKTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoYWZ0ZXJOYW1lc3BhY2UpIHtcclxuICAgICAgICAgIC8vIENvbnZlcnQgcGF0aCBzZWdtZW50cyB0byBuZXN0ZWQgb2JqZWN0IHN0cnVjdHVyZVxyXG4gICAgICAgICAgY29uc3QgbmVzdGVkS2V5ID0gdGhpcy5wYXRoVG9OZXN0ZWRLZXkoYWZ0ZXJOYW1lc3BhY2UpO1xyXG4gICAgICAgICAgdGhpcy5zZXROZXN0ZWRWYWx1ZShuYW1lc3BhY2VDb25maWcsIG5lc3RlZEtleSwgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBuYW1lc3BhY2VDb25maWc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb252ZXJ0IHNuYWtlX2Nhc2Ugb3Iga2ViYWItY2FzZSB0byBjYW1lbENhc2UuXHJcbiAgICogQHBhcmFtIHN0ciAtIFN0cmluZyB0byBjb252ZXJ0XHJcbiAgICogQHJldHVybnMgY2FtZWxDYXNlIHN0cmluZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgdG9DYW1lbENhc2Uoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHN0clxyXG4gICAgICAudG9Mb3dlckNhc2UoKVxyXG4gICAgICAucmVwbGFjZSgvW18tXSguKS9nLCAoXywgY2hhcikgPT4gY2hhci50b1VwcGVyQ2FzZSgpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnZlcnQgcGF0aCBzZWdtZW50cyB0byBuZXN0ZWQga2V5IHN0cnVjdHVyZS5cclxuICAgKiBAcGFyYW0gcGF0aCAtIFBhdGggc3RyaW5nIChlLmcuLCBcImhvc3QvcG9ydFwiKVxyXG4gICAqIEByZXR1cm5zIE5lc3RlZCBrZXkgc3RydWN0dXJlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBwYXRoVG9OZXN0ZWRLZXkocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBwYXRoXHJcbiAgICAgIC5zcGxpdCgnLycpXHJcbiAgICAgIC5tYXAoc2VnbWVudCA9PiB0aGlzLnRvQ2FtZWxDYXNlKHNlZ21lbnQpKVxyXG4gICAgICAuam9pbignLicpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2V0IGEgbmVzdGVkIHZhbHVlIGluIGFuIG9iamVjdCB1c2luZyBkb3Qgbm90YXRpb24uXHJcbiAgICogQHBhcmFtIG9iaiAtIFRhcmdldCBvYmplY3RcclxuICAgKiBAcGFyYW0gcGF0aCAtIERvdCBub3RhdGlvbiBwYXRoXHJcbiAgICogQHBhcmFtIHZhbHVlIC0gVmFsdWUgdG8gc2V0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXROZXN0ZWRWYWx1ZShvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sIHBhdGg6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoJy4nKTtcclxuICAgIGxldCBjdXJyZW50ID0gb2JqO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggLSAxOyBpKyspIHtcclxuICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcclxuICAgICAgaWYgKGtleSAmJiAoIShrZXkgaW4gY3VycmVudCkgfHwgdHlwZW9mIGN1cnJlbnRba2V5XSAhPT0gJ29iamVjdCcpKSB7XHJcbiAgICAgICAgY3VycmVudFtrZXldID0ge307XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGtleSkge1xyXG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBsYXN0S2V5ID0ga2V5c1trZXlzLmxlbmd0aCAtIDFdO1xyXG4gICAgaWYgKGxhc3RLZXkpIHtcclxuICAgICAgY3VycmVudFtsYXN0S2V5XSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBTZWNyZXRzIE1hbmFnZXIgcGF0aCBiYXNlZCBvbiBjb25maWd1cmF0aW9uLlxyXG4gICAqIEByZXR1cm5zIFRoZSBzZWNyZXRzIG1hbmFnZXIgcGF0aFxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0U2VjcmV0c01hbmFnZXJQYXRoKCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBwYXRocyA9IHRoaXMub3B0aW9ucy5zZWNyZXRzTWFuYWdlckNvbmZpZz8ucGF0aHM7XHJcbiAgICBpZiAoIXBhdGhzKSB7XHJcbiAgICAgIHJldHVybiAnL25lc3Rqcy1jb25maWctYXdzJztcclxuICAgIH1cclxuXHJcbiAgICAvLyBVc2UgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYXRoIG9yIGRlZmF1bHRcclxuICAgIHJldHVybiBwYXRocy5wcm9kdWN0aW9uIHx8IHBhdGhzLmRldmVsb3BtZW50IHx8IHBhdGhzLnRlc3QgfHwgJy9uZXN0anMtY29uZmlnLWF3cyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIFNTTSBQYXJhbWV0ZXIgU3RvcmUgcGF0aCBiYXNlZCBvbiBjb25maWd1cmF0aW9uLlxyXG4gICAqIEByZXR1cm5zIFRoZSBTU00gcGFyYW1ldGVyIHBhdGhcclxuICAgKi9cclxuICBwcml2YXRlIGdldFNTTVBhcmFtZXRlclBhdGgoKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHBhdGhzID0gdGhpcy5vcHRpb25zLnNzbUNvbmZpZz8ucGF0aHM7XHJcbiAgICBpZiAoIXBhdGhzKSB7XHJcbiAgICAgIHJldHVybiAnL25lc3Rqcy1jb25maWctYXdzJztcclxuICAgIH1cclxuXHJcbiAgICAvLyBVc2UgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYXRoIG9yIGRlZmF1bHRcclxuICAgIHJldHVybiBwYXRocy5wcm9kdWN0aW9uIHx8IHBhdGhzLmRldmVsb3BtZW50IHx8IHBhdGhzLnRlc3QgfHwgJy9uZXN0anMtY29uZmlnLWF3cyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiBhbiBlcnJvciBpcyBhbiBBV1Mgc2VydmljZSBlcnJvci5cclxuICAgKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gY2hlY2tcclxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBlcnJvciBpcyBmcm9tIGFuIEFXUyBzZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpc0F3c1NlcnZpY2VFcnJvcihlcnJvcjogRXJyb3IpOiBib29sZWFuIHtcclxuICAgIC8vIEFXUyBTREsgZXJyb3JzIHR5cGljYWxseSBoYXZlIHNwZWNpZmljIG5hbWVzXHJcbiAgICBjb25zdCBhd3NFcnJvck5hbWVzID0gW1xyXG4gICAgICAnQWNjZXNzRGVuaWVkRXhjZXB0aW9uJyxcclxuICAgICAgJ1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24nLFxyXG4gICAgICAnSW52YWxpZFJlcXVlc3RFeGNlcHRpb24nLFxyXG4gICAgICAnVGhyb3R0bGluZ0V4Y2VwdGlvbicsXHJcbiAgICAgICdTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24nLFxyXG4gICAgICAnTmV0d29ya2luZ0Vycm9yJyxcclxuICAgICAgJ1RpbWVvdXRFcnJvcicsXHJcbiAgICAgICdDcmVkZW50aWFsc0Vycm9yJyxcclxuICAgICAgJ1Vua25vd25FbmRwb2ludCcsXHJcbiAgICBdO1xyXG5cclxuICAgIHJldHVybiBhd3NFcnJvck5hbWVzLmluY2x1ZGVzKGVycm9yLm5hbWUpIHx8IGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0FXUycpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIEFXUy1zcGVjaWZpYyBlcnJvcnMgd2l0aCBhcHByb3ByaWF0ZSBzdHJhdGVnaWVzLlxyXG4gICAqIEBwYXJhbSBsb2FkZXIgLSBUaGUgbG9hZGVyIHRoYXQgZW5jb3VudGVyZWQgdGhlIGVycm9yXHJcbiAgICogQHBhcmFtIGVycm9yIC0gVGhlIEFXUyBlcnJvclxyXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdG8gY29udGludWUgcHJvY2Vzc2luZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlQXdzU3BlY2lmaWNFcnJvcihsb2FkZXI6IENvbmZpZ0xvYWRlciwgZXJyb3I6IEVycm9yKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBzZXJ2aWNlTmFtZSA9IHRoaXMuZ2V0U2VydmljZU5hbWUobG9hZGVyKTtcclxuXHJcbiAgICBzd2l0Y2ggKGVycm9yLm5hbWUpIHtcclxuICAgICAgY2FzZSAnQWNjZXNzRGVuaWVkRXhjZXB0aW9uJzpcclxuICAgICAgICByZXR1cm4gdGhpcy5lcnJvckhhbmRsZXIuaGFuZGxlUGVybWlzc2lvbkVycm9yKFxyXG4gICAgICAgICAgc2VydmljZU5hbWUsXHJcbiAgICAgICAgICB0aGlzLmdldFJlc291cmNlTmFtZShsb2FkZXIpLFxyXG4gICAgICAgICAgZXJyb3JcclxuICAgICAgICApO1xyXG5cclxuICAgICAgY2FzZSAnUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbic6XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZVJlc291cmNlTm90Rm91bmQoXHJcbiAgICAgICAgICBzZXJ2aWNlTmFtZSxcclxuICAgICAgICAgIHRoaXMuZ2V0UmVzb3VyY2VOYW1lKGxvYWRlciksXHJcbiAgICAgICAgICBlcnJvclxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICBjYXNlICdOZXR3b3JraW5nRXJyb3InOlxyXG4gICAgICBjYXNlICdUaW1lb3V0RXJyb3InOlxyXG4gICAgICAgIGNvbnN0IG5ldHdvcmtSZXN1bHQgPSB0aGlzLmVycm9ySGFuZGxlci5oYW5kbGVOZXR3b3JrRXJyb3Ioc2VydmljZU5hbWUsIGVycm9yKTtcclxuICAgICAgICByZXR1cm4gbmV0d29ya1Jlc3VsdC5zaG91bGRDb250aW51ZTtcclxuXHJcbiAgICAgIGNhc2UgJ1Rocm90dGxpbmdFeGNlcHRpb24nOlxyXG4gICAgICBjYXNlICdUb29NYW55UmVxdWVzdHNFeGNlcHRpb24nOlxyXG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oYFJhdGUgbGltaXRpbmcgZW5jb3VudGVyZWQgZm9yICR7c2VydmljZU5hbWV9LCBjb250aW51aW5nIHdpdGggb3RoZXIgc291cmNlc2ApO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgY2FzZSAnU2VydmljZVVuYXZhaWxhYmxlRXhjZXB0aW9uJzpcclxuICAgICAgICByZXR1cm4gdGhpcy5lcnJvckhhbmRsZXIuaGFuZGxlQXdzVW5hdmFpbGFibGUoc2VydmljZU5hbWUsIGVycm9yKTtcclxuXHJcbiAgICAgIGNhc2UgJ0NyZWRlbnRpYWxzRXJyb3InOlxyXG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGBBV1MgY3JlZGVudGlhbHMgZXJyb3IgZm9yICR7c2VydmljZU5hbWV9OiAke2Vycm9yLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoJ1BsZWFzZSBjaGVjayBBV1MgY3JlZGVudGlhbHMgY29uZmlndXJhdGlvbicpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVycm9ySGFuZGxlci5oYW5kbGVBd3NVbmF2YWlsYWJsZShzZXJ2aWNlTmFtZSwgZXJyb3IpO1xyXG5cclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICAvLyBIYW5kbGUgYXMgZ2VuZXJhbCBjb25maWd1cmF0aW9uIGVycm9yXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZUNvbmZpZ3VyYXRpb25FcnJvcihzZXJ2aWNlTmFtZSwgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBzZXJ2aWNlIG5hbWUgZm9yIGEgbG9hZGVyLlxyXG4gICAqIEBwYXJhbSBsb2FkZXIgLSBUaGUgY29uZmlndXJhdGlvbiBsb2FkZXJcclxuICAgKiBAcmV0dXJucyBUaGUgc2VydmljZSBuYW1lXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRTZXJ2aWNlTmFtZShsb2FkZXI6IENvbmZpZ0xvYWRlcik6IHN0cmluZyB7XHJcbiAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgU2VjcmV0c01hbmFnZXJMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdBV1MgU2VjcmV0cyBNYW5hZ2VyJztcclxuICAgIH0gZWxzZSBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdBV1MgU3lzdGVtcyBNYW5hZ2VyIFBhcmFtZXRlciBTdG9yZSc7XHJcbiAgICB9IGVsc2UgaWYgKGxvYWRlciBpbnN0YW5jZW9mIEVudmlyb25tZW50TG9hZGVyKSB7XHJcbiAgICAgIHJldHVybiAnRW52aXJvbm1lbnQgVmFyaWFibGVzJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAnVW5rbm93biBTZXJ2aWNlJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgcmVzb3VyY2UgbmFtZSBmb3IgYSBsb2FkZXIuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEByZXR1cm5zIFRoZSByZXNvdXJjZSBuYW1lXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRSZXNvdXJjZU5hbWUobG9hZGVyOiBDb25maWdMb2FkZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKGxvYWRlciBpbnN0YW5jZW9mIFNlY3JldHNNYW5hZ2VyTG9hZGVyKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmdldFNlY3JldHNNYW5hZ2VyUGF0aCgpO1xyXG4gICAgfSBlbHNlIGlmIChsb2FkZXIgaW5zdGFuY2VvZiBTU01QYXJhbWV0ZXJTdG9yZUxvYWRlcikge1xyXG4gICAgICByZXR1cm4gdGhpcy5nZXRTU01QYXJhbWV0ZXJQYXRoKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gJ2NvbmZpZ3VyYXRpb24nO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZCBjb25maWd1cmF0aW9uIHdpdGggcmV0cnkgbG9naWMgZm9yIHJldHJ5YWJsZSBlcnJvcnMuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEBwYXJhbSBtYXhSZXRyaWVzIC0gTWF4aW11bSBudW1iZXIgb2YgcmV0cmllc1xyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGNvbmZpZ3VyYXRpb24gZGF0YVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgbG9hZFdpdGhSZXRyeShsb2FkZXI6IENvbmZpZ0xvYWRlciwgbWF4UmV0cmllczogbnVtYmVyID0gMyk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xyXG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBtYXhSZXRyaWVzOyBhdHRlbXB0KyspIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICByZXR1cm4gYXdhaXQgbG9hZGVyLmxvYWQoKTtcclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBjb25zdCBsb2FkZXJFcnJvciA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKTtcclxuICAgICAgICBsYXN0RXJyb3IgPSBsb2FkZXJFcnJvcjtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgZXJyb3IgaXMgcmV0cnlhYmxlXHJcbiAgICAgICAgaWYgKCF0aGlzLmVycm9ySGFuZGxlci5pc1JldHJ5YWJsZUVycm9yKGxvYWRlckVycm9yKSB8fCBhdHRlbXB0ID09PSBtYXhSZXRyaWVzKSB7XHJcbiAgICAgICAgICB0aHJvdyBsb2FkZXJFcnJvcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFdhaXQgYmVmb3JlIHJldHJ5aW5nXHJcbiAgICAgICAgY29uc3QgZGVsYXkgPSB0aGlzLmVycm9ySGFuZGxlci5nZXRSZXRyeURlbGF5KGF0dGVtcHQpO1xyXG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oYFJldHJ5aW5nICR7bG9hZGVyLmdldE5hbWUoKX0gaW4gJHtkZWxheX1tcyAoYXR0ZW1wdCAke2F0dGVtcHR9LyR7bWF4UmV0cmllc30pYCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGRlbGF5KSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBiZSByZWFjaGVkLCBidXQganVzdCBpbiBjYXNlXHJcbiAgICB0aHJvdyBsYXN0RXJyb3IgfHwgbmV3IEVycm9yKCdVbmtub3duIGVycm9yIGR1cmluZyByZXRyeScpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgYXZhaWxhYmlsaXR5IHdpdGggdGltZW91dCBhbmQgZXJyb3IgaGFuZGxpbmcuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEBwYXJhbSB0aW1lb3V0TXMgLSBUaW1lb3V0IGluIG1pbGxpc2Vjb25kc1xyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGF2YWlsYWJpbGl0eSBzdGF0dXNcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGNoZWNrQXZhaWxhYmlsaXR5V2l0aFRpbWVvdXQobG9hZGVyOiBDb25maWdMb2FkZXIsIHRpbWVvdXRNczogbnVtYmVyID0gNTAwMCk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZTxib29sZWFuPigoXywgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiByZWplY3QobmV3IEVycm9yKCdBdmFpbGFiaWxpdHkgY2hlY2sgdGltZW91dCcpKSwgdGltZW91dE1zKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBjb25zdCBhdmFpbGFiaWxpdHlQcm9taXNlID0gbG9hZGVyLmlzQXZhaWxhYmxlKCk7XHJcblxyXG4gICAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5yYWNlKFthdmFpbGFiaWxpdHlQcm9taXNlLCB0aW1lb3V0UHJvbWlzZV0pO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc3QgbG9hZGVyRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XHJcbiAgICAgIFxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmVuYWJsZUxvZ2dpbmcpIHtcclxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgQXZhaWxhYmlsaXR5IGNoZWNrIGZhaWxlZCBmb3IgJHtsb2FkZXIuZ2V0TmFtZSgpfTogJHtsb2FkZXJFcnJvci5tZXNzYWdlfWApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG59Il19
|