@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.
Files changed (391) hide show
  1. package/README.md +213 -1013
  2. package/dist/cjs/config-aws/src/config-manager.js +366 -0
  3. package/dist/cjs/config-aws/src/errors/index.js +77 -0
  4. package/dist/cjs/config-aws/src/index.js +37 -0
  5. package/dist/cjs/config-aws/src/interfaces/config-loader.interface.js +3 -0
  6. package/dist/cjs/config-aws/src/interfaces/config-manager.interface.js +3 -0
  7. package/dist/cjs/config-aws/src/interfaces/env-file-loader.interface.js +3 -0
  8. package/dist/cjs/config-aws/src/interfaces/environment-loader.interface.js +3 -0
  9. package/dist/cjs/config-aws/src/interfaces/s3-loader.interface.js +3 -0
  10. package/dist/cjs/config-aws/src/interfaces/secrets-manager-loader.interface.js +3 -0
  11. package/dist/cjs/config-aws/src/interfaces/ssm-parameter-store-loader.interface.js +3 -0
  12. package/dist/cjs/config-aws/src/loaders/env-file.loader.js +169 -0
  13. package/dist/cjs/config-aws/src/loaders/environment.loader.js +85 -0
  14. package/dist/cjs/config-aws/src/loaders/s3.loader.js +145 -0
  15. package/dist/cjs/config-aws/src/loaders/secrets-manager.loader.js +169 -0
  16. package/dist/cjs/config-aws/src/loaders/ssm-parameter-store.loader.js +199 -0
  17. package/dist/cjs/config-aws/src/utils/env-file-parser.util.js +98 -0
  18. package/dist/cjs/config-aws/src/utils/validation.util.js +116 -0
  19. package/dist/cjs/nestjs-config-aws/src/config.module.js +175 -0
  20. package/dist/cjs/nestjs-config-aws/src/index.js +61 -0
  21. package/dist/cjs/{integration → nestjs-config-aws/src/integration}/index.js +1 -1
  22. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.js +3 -0
  23. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.js +3 -0
  24. package/dist/cjs/{integration → nestjs-config-aws/src/integration}/interfaces/index.js +1 -1
  25. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/integration-options.interface.js +3 -0
  26. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/integration-state.interface.js +3 -0
  27. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.js +73 -0
  28. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.js +3 -0
  29. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.js +4 -0
  30. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/utility-types.interface.js +52 -0
  31. package/dist/cjs/nestjs-config-aws/src/integration/nestjs-config-integration.module.js +124 -0
  32. package/dist/cjs/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.js +592 -0
  33. package/dist/cjs/nestjs-config-aws/src/integration/providers/configuration-factory.provider.js +385 -0
  34. package/dist/cjs/{integration → nestjs-config-aws/src/integration}/providers/index.js +1 -1
  35. package/dist/cjs/nestjs-config-aws/src/integration/services/async-config-helper.service.js +366 -0
  36. package/dist/cjs/nestjs-config-aws/src/integration/services/error-handler.service.js +267 -0
  37. package/dist/cjs/nestjs-config-aws/src/integration/services/factory-registration.service.js +517 -0
  38. package/dist/cjs/{integration → nestjs-config-aws/src/integration}/services/index.js +1 -1
  39. package/dist/cjs/nestjs-config-aws/src/integration/services/integration-state.service.js +81 -0
  40. package/dist/cjs/nestjs-config-aws/src/integration/services/namespace-handler.service.js +465 -0
  41. package/dist/cjs/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.js +318 -0
  42. package/dist/cjs/nestjs-config-aws/src/integration/services/precedence-handler.service.js +292 -0
  43. package/dist/cjs/nestjs-config-aws/src/integration/services/validation-integration.service.js +595 -0
  44. package/dist/cjs/nestjs-config-aws/src/integration/utils/config-integration.util.js +283 -0
  45. package/dist/cjs/{integration → nestjs-config-aws/src/integration}/utils/index.js +1 -1
  46. package/dist/cjs/nestjs-config-aws/src/interfaces/config-service.interface.js +11 -0
  47. package/dist/cjs/nestjs-config-aws/src/interfaces/default-schema.interface.js +63 -0
  48. package/dist/cjs/nestjs-config-aws/src/interfaces/index.js +30 -0
  49. package/dist/cjs/nestjs-config-aws/src/interfaces/module-options.interface.js +3 -0
  50. package/dist/cjs/nestjs-config-aws/src/services/config.service.js +142 -0
  51. package/dist/esm/config-aws/src/config-manager.js +362 -0
  52. package/dist/esm/config-aws/src/errors/index.js +69 -0
  53. package/dist/esm/config-aws/src/index.js +21 -0
  54. package/dist/esm/config-aws/src/interfaces/config-loader.interface.js +2 -0
  55. package/dist/esm/config-aws/src/interfaces/config-manager.interface.js +2 -0
  56. package/dist/esm/config-aws/src/interfaces/env-file-loader.interface.js +2 -0
  57. package/dist/esm/config-aws/src/interfaces/environment-loader.interface.js +2 -0
  58. package/dist/esm/config-aws/src/interfaces/s3-loader.interface.js +2 -0
  59. package/dist/esm/config-aws/src/interfaces/secrets-manager-loader.interface.js +2 -0
  60. package/dist/esm/config-aws/src/interfaces/ssm-parameter-store-loader.interface.js +2 -0
  61. package/dist/esm/config-aws/src/loaders/env-file.loader.js +132 -0
  62. package/dist/esm/config-aws/src/loaders/environment.loader.js +81 -0
  63. package/dist/esm/config-aws/src/loaders/s3.loader.js +141 -0
  64. package/dist/esm/config-aws/src/loaders/secrets-manager.loader.js +165 -0
  65. package/dist/esm/config-aws/src/loaders/ssm-parameter-store.loader.js +195 -0
  66. package/dist/esm/config-aws/src/utils/env-file-parser.util.js +94 -0
  67. package/dist/esm/config-aws/src/utils/validation.util.js +112 -0
  68. package/dist/esm/nestjs-config-aws/src/config.module.js +172 -0
  69. package/dist/esm/nestjs-config-aws/src/index.js +23 -0
  70. package/dist/esm/nestjs-config-aws/src/integration/index.js +7 -0
  71. package/dist/esm/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.js +2 -0
  72. package/dist/esm/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.js +2 -0
  73. package/dist/esm/nestjs-config-aws/src/integration/interfaces/index.js +10 -0
  74. package/dist/esm/nestjs-config-aws/src/integration/interfaces/integration-options.interface.js +2 -0
  75. package/dist/esm/nestjs-config-aws/src/integration/interfaces/integration-state.interface.js +2 -0
  76. package/dist/esm/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.js +64 -0
  77. package/dist/esm/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.js +2 -0
  78. package/dist/esm/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.js +3 -0
  79. package/dist/esm/nestjs-config-aws/src/integration/interfaces/utility-types.interface.js +44 -0
  80. package/dist/esm/nestjs-config-aws/src/integration/nestjs-config-integration.module.js +121 -0
  81. package/dist/esm/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.js +589 -0
  82. package/dist/esm/nestjs-config-aws/src/integration/providers/configuration-factory.provider.js +382 -0
  83. package/dist/esm/nestjs-config-aws/src/integration/providers/index.js +4 -0
  84. package/dist/esm/nestjs-config-aws/src/integration/services/async-config-helper.service.js +363 -0
  85. package/dist/esm/nestjs-config-aws/src/integration/services/error-handler.service.js +264 -0
  86. package/dist/esm/nestjs-config-aws/src/integration/services/factory-registration.service.js +514 -0
  87. package/dist/esm/nestjs-config-aws/src/integration/services/index.js +10 -0
  88. package/dist/esm/nestjs-config-aws/src/integration/services/integration-state.service.js +78 -0
  89. package/dist/esm/nestjs-config-aws/src/integration/services/namespace-handler.service.js +462 -0
  90. package/dist/esm/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.js +315 -0
  91. package/dist/esm/nestjs-config-aws/src/integration/services/precedence-handler.service.js +289 -0
  92. package/dist/esm/nestjs-config-aws/src/integration/services/validation-integration.service.js +589 -0
  93. package/dist/esm/nestjs-config-aws/src/integration/utils/config-integration.util.js +240 -0
  94. package/dist/esm/nestjs-config-aws/src/integration/utils/index.js +3 -0
  95. package/dist/esm/nestjs-config-aws/src/interfaces/config-service.interface.js +7 -0
  96. package/dist/esm/nestjs-config-aws/src/interfaces/default-schema.interface.js +59 -0
  97. package/dist/esm/nestjs-config-aws/src/interfaces/index.js +8 -0
  98. package/dist/esm/nestjs-config-aws/src/interfaces/module-options.interface.js +2 -0
  99. package/dist/esm/nestjs-config-aws/src/services/config.service.js +139 -0
  100. package/dist/types/config-aws/src/config-manager.d.ts +119 -0
  101. package/dist/types/config-aws/src/config-manager.d.ts.map +1 -0
  102. package/dist/types/config-aws/src/errors/index.d.ts +43 -0
  103. package/dist/types/config-aws/src/errors/index.d.ts.map +1 -0
  104. package/dist/types/config-aws/src/index.d.ts +24 -0
  105. package/dist/types/config-aws/src/index.d.ts.map +1 -0
  106. package/dist/types/config-aws/src/interfaces/config-loader.interface.d.ts +33 -0
  107. package/dist/types/config-aws/src/interfaces/config-loader.interface.d.ts.map +1 -0
  108. package/dist/types/config-aws/src/interfaces/config-manager.interface.d.ts +86 -0
  109. package/dist/types/config-aws/src/interfaces/config-manager.interface.d.ts.map +1 -0
  110. package/dist/types/config-aws/src/interfaces/env-file-loader.interface.d.ts +12 -0
  111. package/dist/types/config-aws/src/interfaces/env-file-loader.interface.d.ts.map +1 -0
  112. package/dist/types/config-aws/src/interfaces/environment-loader.interface.d.ts +10 -0
  113. package/dist/types/config-aws/src/interfaces/environment-loader.interface.d.ts.map +1 -0
  114. package/dist/types/config-aws/src/interfaces/s3-loader.interface.d.ts +14 -0
  115. package/dist/types/config-aws/src/interfaces/s3-loader.interface.d.ts.map +1 -0
  116. package/dist/types/config-aws/src/interfaces/secrets-manager-loader.interface.d.ts +12 -0
  117. package/dist/types/config-aws/src/interfaces/secrets-manager-loader.interface.d.ts.map +1 -0
  118. package/dist/types/config-aws/src/interfaces/ssm-parameter-store-loader.interface.d.ts +14 -0
  119. package/dist/types/config-aws/src/interfaces/ssm-parameter-store-loader.interface.d.ts.map +1 -0
  120. package/dist/types/config-aws/src/loaders/env-file.loader.d.ts +69 -0
  121. package/dist/types/config-aws/src/loaders/env-file.loader.d.ts.map +1 -0
  122. package/dist/types/config-aws/src/loaders/environment.loader.d.ts +46 -0
  123. package/dist/types/config-aws/src/loaders/environment.loader.d.ts.map +1 -0
  124. package/dist/types/config-aws/src/loaders/s3.loader.d.ts +62 -0
  125. package/dist/types/config-aws/src/loaders/s3.loader.d.ts.map +1 -0
  126. package/dist/types/config-aws/src/loaders/secrets-manager.loader.d.ts +68 -0
  127. package/dist/types/config-aws/src/loaders/secrets-manager.loader.d.ts.map +1 -0
  128. package/dist/types/config-aws/src/loaders/ssm-parameter-store.loader.d.ts +78 -0
  129. package/dist/types/config-aws/src/loaders/ssm-parameter-store.loader.d.ts.map +1 -0
  130. package/dist/types/config-aws/src/utils/env-file-parser.util.d.ts +45 -0
  131. package/dist/types/config-aws/src/utils/env-file-parser.util.d.ts.map +1 -0
  132. package/dist/types/{utils → config-aws/src/utils}/validation.util.d.ts +10 -10
  133. package/dist/types/config-aws/src/utils/validation.util.d.ts.map +1 -0
  134. package/dist/types/{config.module.d.ts → nestjs-config-aws/src/config.module.d.ts} +1 -0
  135. package/dist/types/nestjs-config-aws/src/config.module.d.ts.map +1 -0
  136. package/dist/types/{index.d.ts → nestjs-config-aws/src/index.d.ts} +2 -4
  137. package/dist/types/nestjs-config-aws/src/index.d.ts.map +1 -0
  138. package/dist/types/nestjs-config-aws/src/integration/index.d.ts.map +1 -0
  139. package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.d.ts.map +1 -0
  140. package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.d.ts.map +1 -0
  141. package/dist/types/nestjs-config-aws/src/integration/interfaces/index.d.ts.map +1 -0
  142. package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-options.interface.d.ts.map +1 -0
  143. package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-state.interface.d.ts.map +1 -0
  144. package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.d.ts.map +1 -0
  145. package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.d.ts.map +1 -0
  146. package/dist/types/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.d.ts.map +1 -0
  147. package/dist/types/nestjs-config-aws/src/integration/interfaces/utility-types.interface.d.ts.map +1 -0
  148. package/dist/types/nestjs-config-aws/src/integration/nestjs-config-integration.module.d.ts.map +1 -0
  149. package/dist/types/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.d.ts.map +1 -0
  150. package/dist/types/nestjs-config-aws/src/integration/providers/configuration-factory.provider.d.ts.map +1 -0
  151. package/dist/types/nestjs-config-aws/src/integration/providers/index.d.ts.map +1 -0
  152. package/dist/types/nestjs-config-aws/src/integration/services/async-config-helper.service.d.ts.map +1 -0
  153. package/dist/types/nestjs-config-aws/src/integration/services/error-handler.service.d.ts.map +1 -0
  154. package/dist/types/nestjs-config-aws/src/integration/services/factory-registration.service.d.ts.map +1 -0
  155. package/dist/types/nestjs-config-aws/src/integration/services/index.d.ts.map +1 -0
  156. package/dist/types/nestjs-config-aws/src/integration/services/integration-state.service.d.ts.map +1 -0
  157. package/dist/types/nestjs-config-aws/src/integration/services/namespace-handler.service.d.ts.map +1 -0
  158. package/dist/types/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.d.ts.map +1 -0
  159. package/dist/types/nestjs-config-aws/src/integration/services/precedence-handler.service.d.ts.map +1 -0
  160. package/dist/types/nestjs-config-aws/src/integration/services/validation-integration.service.d.ts.map +1 -0
  161. package/dist/types/nestjs-config-aws/src/integration/utils/config-integration.util.d.ts.map +1 -0
  162. package/dist/types/nestjs-config-aws/src/integration/utils/index.d.ts.map +1 -0
  163. package/dist/types/nestjs-config-aws/src/interfaces/config-service.interface.d.ts.map +1 -0
  164. package/dist/types/{interfaces → nestjs-config-aws/src/interfaces}/default-schema.interface.d.ts +28 -28
  165. package/dist/types/nestjs-config-aws/src/interfaces/default-schema.interface.d.ts.map +1 -0
  166. package/dist/types/nestjs-config-aws/src/interfaces/index.d.ts +5 -0
  167. package/dist/types/nestjs-config-aws/src/interfaces/index.d.ts.map +1 -0
  168. package/dist/types/nestjs-config-aws/src/interfaces/module-options.interface.d.ts.map +1 -0
  169. package/dist/types/nestjs-config-aws/src/services/config.service.d.ts +88 -0
  170. package/dist/types/nestjs-config-aws/src/services/config.service.d.ts.map +1 -0
  171. package/package.json +20 -27
  172. package/LICENSE +0 -21
  173. package/dist/cjs/config.module.js +0 -178
  174. package/dist/cjs/config.module.js.map +0 -1
  175. package/dist/cjs/index.js +0 -47
  176. package/dist/cjs/index.js.map +0 -1
  177. package/dist/cjs/integration/index.js.map +0 -1
  178. package/dist/cjs/integration/interfaces/configuration-factory.interface.js +0 -3
  179. package/dist/cjs/integration/interfaces/configuration-factory.interface.js.map +0 -1
  180. package/dist/cjs/integration/interfaces/configuration-source.interface.js +0 -3
  181. package/dist/cjs/integration/interfaces/configuration-source.interface.js.map +0 -1
  182. package/dist/cjs/integration/interfaces/index.js.map +0 -1
  183. package/dist/cjs/integration/interfaces/integration-options.interface.js +0 -3
  184. package/dist/cjs/integration/interfaces/integration-options.interface.js.map +0 -1
  185. package/dist/cjs/integration/interfaces/integration-state.interface.js +0 -3
  186. package/dist/cjs/integration/interfaces/integration-state.interface.js.map +0 -1
  187. package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js +0 -73
  188. package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js.map +0 -1
  189. package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js +0 -3
  190. package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js.map +0 -1
  191. package/dist/cjs/integration/interfaces/typed-configuration.interface.js +0 -4
  192. package/dist/cjs/integration/interfaces/typed-configuration.interface.js.map +0 -1
  193. package/dist/cjs/integration/interfaces/utility-types.interface.js +0 -52
  194. package/dist/cjs/integration/interfaces/utility-types.interface.js.map +0 -1
  195. package/dist/cjs/integration/nestjs-config-integration.module.js +0 -124
  196. package/dist/cjs/integration/nestjs-config-integration.module.js.map +0 -1
  197. package/dist/cjs/integration/providers/aws-configuration-loader.service.js +0 -591
  198. package/dist/cjs/integration/providers/aws-configuration-loader.service.js.map +0 -1
  199. package/dist/cjs/integration/providers/configuration-factory.provider.js +0 -383
  200. package/dist/cjs/integration/providers/configuration-factory.provider.js.map +0 -1
  201. package/dist/cjs/integration/providers/index.js.map +0 -1
  202. package/dist/cjs/integration/services/async-config-helper.service.js +0 -356
  203. package/dist/cjs/integration/services/async-config-helper.service.js.map +0 -1
  204. package/dist/cjs/integration/services/error-handler.service.js +0 -265
  205. package/dist/cjs/integration/services/error-handler.service.js.map +0 -1
  206. package/dist/cjs/integration/services/factory-registration.service.js +0 -512
  207. package/dist/cjs/integration/services/factory-registration.service.js.map +0 -1
  208. package/dist/cjs/integration/services/index.js.map +0 -1
  209. package/dist/cjs/integration/services/integration-state.service.js +0 -83
  210. package/dist/cjs/integration/services/integration-state.service.js.map +0 -1
  211. package/dist/cjs/integration/services/namespace-handler.service.js +0 -467
  212. package/dist/cjs/integration/services/namespace-handler.service.js.map +0 -1
  213. package/dist/cjs/integration/services/nestjs-config-integration.service.js +0 -316
  214. package/dist/cjs/integration/services/nestjs-config-integration.service.js.map +0 -1
  215. package/dist/cjs/integration/services/precedence-handler.service.js +0 -294
  216. package/dist/cjs/integration/services/precedence-handler.service.js.map +0 -1
  217. package/dist/cjs/integration/services/validation-integration.service.js +0 -591
  218. package/dist/cjs/integration/services/validation-integration.service.js.map +0 -1
  219. package/dist/cjs/integration/utils/config-integration.util.js +0 -283
  220. package/dist/cjs/integration/utils/config-integration.util.js.map +0 -1
  221. package/dist/cjs/integration/utils/index.js.map +0 -1
  222. package/dist/cjs/interfaces/config-loader.interface.js +0 -3
  223. package/dist/cjs/interfaces/config-loader.interface.js.map +0 -1
  224. package/dist/cjs/interfaces/config-service.interface.js +0 -11
  225. package/dist/cjs/interfaces/config-service.interface.js.map +0 -1
  226. package/dist/cjs/interfaces/default-schema.interface.js +0 -63
  227. package/dist/cjs/interfaces/default-schema.interface.js.map +0 -1
  228. package/dist/cjs/interfaces/errors.interface.js +0 -77
  229. package/dist/cjs/interfaces/errors.interface.js.map +0 -1
  230. package/dist/cjs/interfaces/index.js +0 -25
  231. package/dist/cjs/interfaces/index.js.map +0 -1
  232. package/dist/cjs/interfaces/module-options.interface.js +0 -3
  233. package/dist/cjs/interfaces/module-options.interface.js.map +0 -1
  234. package/dist/cjs/loaders/environment.loader.js +0 -59
  235. package/dist/cjs/loaders/environment.loader.js.map +0 -1
  236. package/dist/cjs/loaders/secrets-manager.loader.js +0 -122
  237. package/dist/cjs/loaders/secrets-manager.loader.js.map +0 -1
  238. package/dist/cjs/loaders/ssm-parameter-store.loader.js +0 -146
  239. package/dist/cjs/loaders/ssm-parameter-store.loader.js.map +0 -1
  240. package/dist/cjs/services/config.service.js +0 -297
  241. package/dist/cjs/services/config.service.js.map +0 -1
  242. package/dist/cjs/utils/validation.util.js +0 -114
  243. package/dist/cjs/utils/validation.util.js.map +0 -1
  244. package/dist/esm/config.module.js +0 -175
  245. package/dist/esm/config.module.js.map +0 -1
  246. package/dist/esm/index.js +0 -18
  247. package/dist/esm/index.js.map +0 -1
  248. package/dist/esm/integration/index.js +0 -7
  249. package/dist/esm/integration/index.js.map +0 -1
  250. package/dist/esm/integration/interfaces/configuration-factory.interface.js +0 -2
  251. package/dist/esm/integration/interfaces/configuration-factory.interface.js.map +0 -1
  252. package/dist/esm/integration/interfaces/configuration-source.interface.js +0 -2
  253. package/dist/esm/integration/interfaces/configuration-source.interface.js.map +0 -1
  254. package/dist/esm/integration/interfaces/index.js +0 -10
  255. package/dist/esm/integration/interfaces/index.js.map +0 -1
  256. package/dist/esm/integration/interfaces/integration-options.interface.js +0 -2
  257. package/dist/esm/integration/interfaces/integration-options.interface.js.map +0 -1
  258. package/dist/esm/integration/interfaces/integration-state.interface.js +0 -2
  259. package/dist/esm/integration/interfaces/integration-state.interface.js.map +0 -1
  260. package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js +0 -64
  261. package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js.map +0 -1
  262. package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js +0 -2
  263. package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js.map +0 -1
  264. package/dist/esm/integration/interfaces/typed-configuration.interface.js +0 -3
  265. package/dist/esm/integration/interfaces/typed-configuration.interface.js.map +0 -1
  266. package/dist/esm/integration/interfaces/utility-types.interface.js +0 -44
  267. package/dist/esm/integration/interfaces/utility-types.interface.js.map +0 -1
  268. package/dist/esm/integration/nestjs-config-integration.module.js +0 -121
  269. package/dist/esm/integration/nestjs-config-integration.module.js.map +0 -1
  270. package/dist/esm/integration/providers/aws-configuration-loader.service.js +0 -588
  271. package/dist/esm/integration/providers/aws-configuration-loader.service.js.map +0 -1
  272. package/dist/esm/integration/providers/configuration-factory.provider.js +0 -380
  273. package/dist/esm/integration/providers/configuration-factory.provider.js.map +0 -1
  274. package/dist/esm/integration/providers/index.js +0 -4
  275. package/dist/esm/integration/providers/index.js.map +0 -1
  276. package/dist/esm/integration/services/async-config-helper.service.js +0 -353
  277. package/dist/esm/integration/services/async-config-helper.service.js.map +0 -1
  278. package/dist/esm/integration/services/error-handler.service.js +0 -262
  279. package/dist/esm/integration/services/error-handler.service.js.map +0 -1
  280. package/dist/esm/integration/services/factory-registration.service.js +0 -509
  281. package/dist/esm/integration/services/factory-registration.service.js.map +0 -1
  282. package/dist/esm/integration/services/index.js +0 -10
  283. package/dist/esm/integration/services/index.js.map +0 -1
  284. package/dist/esm/integration/services/integration-state.service.js +0 -80
  285. package/dist/esm/integration/services/integration-state.service.js.map +0 -1
  286. package/dist/esm/integration/services/namespace-handler.service.js +0 -464
  287. package/dist/esm/integration/services/namespace-handler.service.js.map +0 -1
  288. package/dist/esm/integration/services/nestjs-config-integration.service.js +0 -313
  289. package/dist/esm/integration/services/nestjs-config-integration.service.js.map +0 -1
  290. package/dist/esm/integration/services/precedence-handler.service.js +0 -291
  291. package/dist/esm/integration/services/precedence-handler.service.js.map +0 -1
  292. package/dist/esm/integration/services/validation-integration.service.js +0 -585
  293. package/dist/esm/integration/services/validation-integration.service.js.map +0 -1
  294. package/dist/esm/integration/utils/config-integration.util.js +0 -240
  295. package/dist/esm/integration/utils/config-integration.util.js.map +0 -1
  296. package/dist/esm/integration/utils/index.js +0 -3
  297. package/dist/esm/integration/utils/index.js.map +0 -1
  298. package/dist/esm/interfaces/config-loader.interface.js +0 -2
  299. package/dist/esm/interfaces/config-loader.interface.js.map +0 -1
  300. package/dist/esm/interfaces/config-service.interface.js +0 -7
  301. package/dist/esm/interfaces/config-service.interface.js.map +0 -1
  302. package/dist/esm/interfaces/default-schema.interface.js +0 -59
  303. package/dist/esm/interfaces/default-schema.interface.js.map +0 -1
  304. package/dist/esm/interfaces/errors.interface.js +0 -69
  305. package/dist/esm/interfaces/errors.interface.js.map +0 -1
  306. package/dist/esm/interfaces/index.js +0 -9
  307. package/dist/esm/interfaces/index.js.map +0 -1
  308. package/dist/esm/interfaces/module-options.interface.js +0 -2
  309. package/dist/esm/interfaces/module-options.interface.js.map +0 -1
  310. package/dist/esm/loaders/environment.loader.js +0 -55
  311. package/dist/esm/loaders/environment.loader.js.map +0 -1
  312. package/dist/esm/loaders/secrets-manager.loader.js +0 -118
  313. package/dist/esm/loaders/secrets-manager.loader.js.map +0 -1
  314. package/dist/esm/loaders/ssm-parameter-store.loader.js +0 -142
  315. package/dist/esm/loaders/ssm-parameter-store.loader.js.map +0 -1
  316. package/dist/esm/services/config.service.js +0 -261
  317. package/dist/esm/services/config.service.js.map +0 -1
  318. package/dist/esm/utils/validation.util.js +0 -110
  319. package/dist/esm/utils/validation.util.js.map +0 -1
  320. package/dist/types/config.module.d.ts.map +0 -1
  321. package/dist/types/index.d.ts.map +0 -1
  322. package/dist/types/integration/index.d.ts.map +0 -1
  323. package/dist/types/integration/interfaces/configuration-factory.interface.d.ts.map +0 -1
  324. package/dist/types/integration/interfaces/configuration-source.interface.d.ts.map +0 -1
  325. package/dist/types/integration/interfaces/index.d.ts.map +0 -1
  326. package/dist/types/integration/interfaces/integration-options.interface.d.ts.map +0 -1
  327. package/dist/types/integration/interfaces/integration-state.interface.d.ts.map +0 -1
  328. package/dist/types/integration/interfaces/nestjs-config-compatibility.interface.d.ts.map +0 -1
  329. package/dist/types/integration/interfaces/nestjs-config-integration.interface.d.ts.map +0 -1
  330. package/dist/types/integration/interfaces/typed-configuration.interface.d.ts.map +0 -1
  331. package/dist/types/integration/interfaces/utility-types.interface.d.ts.map +0 -1
  332. package/dist/types/integration/nestjs-config-integration.module.d.ts.map +0 -1
  333. package/dist/types/integration/providers/aws-configuration-loader.service.d.ts.map +0 -1
  334. package/dist/types/integration/providers/configuration-factory.provider.d.ts.map +0 -1
  335. package/dist/types/integration/providers/index.d.ts.map +0 -1
  336. package/dist/types/integration/services/async-config-helper.service.d.ts.map +0 -1
  337. package/dist/types/integration/services/error-handler.service.d.ts.map +0 -1
  338. package/dist/types/integration/services/factory-registration.service.d.ts.map +0 -1
  339. package/dist/types/integration/services/index.d.ts.map +0 -1
  340. package/dist/types/integration/services/integration-state.service.d.ts.map +0 -1
  341. package/dist/types/integration/services/namespace-handler.service.d.ts.map +0 -1
  342. package/dist/types/integration/services/nestjs-config-integration.service.d.ts.map +0 -1
  343. package/dist/types/integration/services/precedence-handler.service.d.ts.map +0 -1
  344. package/dist/types/integration/services/validation-integration.service.d.ts.map +0 -1
  345. package/dist/types/integration/utils/config-integration.util.d.ts.map +0 -1
  346. package/dist/types/integration/utils/index.d.ts.map +0 -1
  347. package/dist/types/interfaces/config-loader.interface.d.ts +0 -22
  348. package/dist/types/interfaces/config-loader.interface.d.ts.map +0 -1
  349. package/dist/types/interfaces/config-service.interface.d.ts.map +0 -1
  350. package/dist/types/interfaces/default-schema.interface.d.ts.map +0 -1
  351. package/dist/types/interfaces/errors.interface.d.ts +0 -38
  352. package/dist/types/interfaces/errors.interface.d.ts.map +0 -1
  353. package/dist/types/interfaces/index.d.ts +0 -6
  354. package/dist/types/interfaces/index.d.ts.map +0 -1
  355. package/dist/types/interfaces/module-options.interface.d.ts.map +0 -1
  356. package/dist/types/loaders/environment.loader.d.ts +0 -26
  357. package/dist/types/loaders/environment.loader.d.ts.map +0 -1
  358. package/dist/types/loaders/secrets-manager.loader.d.ts +0 -52
  359. package/dist/types/loaders/secrets-manager.loader.d.ts.map +0 -1
  360. package/dist/types/loaders/ssm-parameter-store.loader.d.ts +0 -68
  361. package/dist/types/loaders/ssm-parameter-store.loader.d.ts.map +0 -1
  362. package/dist/types/services/config.service.d.ts +0 -94
  363. package/dist/types/services/config.service.d.ts.map +0 -1
  364. package/dist/types/utils/validation.util.d.ts.map +0 -1
  365. /package/dist/types/{integration → nestjs-config-aws/src/integration}/index.d.ts +0 -0
  366. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/configuration-factory.interface.d.ts +0 -0
  367. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/configuration-source.interface.d.ts +0 -0
  368. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/index.d.ts +0 -0
  369. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/integration-options.interface.d.ts +0 -0
  370. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/integration-state.interface.d.ts +0 -0
  371. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/nestjs-config-compatibility.interface.d.ts +0 -0
  372. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/nestjs-config-integration.interface.d.ts +0 -0
  373. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/typed-configuration.interface.d.ts +0 -0
  374. /package/dist/types/{integration → nestjs-config-aws/src/integration}/interfaces/utility-types.interface.d.ts +0 -0
  375. /package/dist/types/{integration → nestjs-config-aws/src/integration}/nestjs-config-integration.module.d.ts +0 -0
  376. /package/dist/types/{integration → nestjs-config-aws/src/integration}/providers/aws-configuration-loader.service.d.ts +0 -0
  377. /package/dist/types/{integration → nestjs-config-aws/src/integration}/providers/configuration-factory.provider.d.ts +0 -0
  378. /package/dist/types/{integration → nestjs-config-aws/src/integration}/providers/index.d.ts +0 -0
  379. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/async-config-helper.service.d.ts +0 -0
  380. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/error-handler.service.d.ts +0 -0
  381. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/factory-registration.service.d.ts +0 -0
  382. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/index.d.ts +0 -0
  383. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/integration-state.service.d.ts +0 -0
  384. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/namespace-handler.service.d.ts +0 -0
  385. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/nestjs-config-integration.service.d.ts +0 -0
  386. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/precedence-handler.service.d.ts +0 -0
  387. /package/dist/types/{integration → nestjs-config-aws/src/integration}/services/validation-integration.service.d.ts +0 -0
  388. /package/dist/types/{integration → nestjs-config-aws/src/integration}/utils/config-integration.util.d.ts +0 -0
  389. /package/dist/types/{integration → nestjs-config-aws/src/integration}/utils/index.d.ts +0 -0
  390. /package/dist/types/{interfaces → nestjs-config-aws/src/interfaces}/config-service.interface.d.ts +0 -0
  391. /package/dist/types/{interfaces → nestjs-config-aws/src/interfaces}/module-options.interface.d.ts +0 -0
@@ -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