@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,595 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var ValidationIntegrationService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.ValidationIntegrationService = exports.CustomValidationProvider = exports.ClassValidatorProvider = exports.JoiValidationProvider = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ /**
16
+ * Joi validation schema provider.
17
+ */
18
+ class JoiValidationProvider {
19
+ name = 'joi';
20
+ joi;
21
+ constructor() {
22
+ try {
23
+ // Try to import Joi dynamically
24
+ this.joi = require('joi');
25
+ }
26
+ catch {
27
+ // Joi is not available
28
+ this.joi = null;
29
+ }
30
+ }
31
+ isAvailable() {
32
+ return this.joi !== null;
33
+ }
34
+ validate(config, schema) {
35
+ if (!this.joi) {
36
+ return { isValid: false, errors: ['Joi is not available'] };
37
+ }
38
+ try {
39
+ // Use joi.attempt which throws on validation error, or fall back to schema.validate
40
+ if (this.joi.attempt) {
41
+ this.joi.attempt(config, schema);
42
+ return { isValid: true, errors: [] };
43
+ }
44
+ const { error } = schema.validate(config);
45
+ if (error) {
46
+ const errors = error.details?.map((detail) => detail.message) || [error.message];
47
+ return { isValid: false, errors };
48
+ }
49
+ return { isValid: true, errors: [] };
50
+ }
51
+ catch (error) {
52
+ const validationError = error instanceof Error ? error : new Error(String(error));
53
+ return { isValid: false, errors: [validationError.message] };
54
+ }
55
+ }
56
+ }
57
+ exports.JoiValidationProvider = JoiValidationProvider;
58
+ /**
59
+ * Class-validator validation schema provider.
60
+ */
61
+ class ClassValidatorProvider {
62
+ name = 'class-validator';
63
+ classValidator;
64
+ classTransformer;
65
+ constructor() {
66
+ try {
67
+ // Try to import class-validator and class-transformer dynamically
68
+ this.classValidator = require('class-validator');
69
+ this.classTransformer = require('class-transformer');
70
+ }
71
+ catch {
72
+ // class-validator is not available
73
+ this.classValidator = null;
74
+ this.classTransformer = null;
75
+ }
76
+ }
77
+ isAvailable() {
78
+ return this.classValidator !== null && this.classTransformer !== null;
79
+ }
80
+ validate(config, schemaClass) {
81
+ if (!this.classValidator || !this.classTransformer) {
82
+ return { isValid: false, errors: ['class-validator or class-transformer is not available'] };
83
+ }
84
+ try {
85
+ // Transform plain object to class instance
86
+ const instance = this.classTransformer.plainToClass(schemaClass, config);
87
+ // Validate the instance
88
+ const errors = this.classValidator.validateSync(instance);
89
+ if (errors && errors.length > 0) {
90
+ const errorMessages = errors.map((error) => {
91
+ const constraints = error.constraints || {};
92
+ return Object.values(constraints).join(', ');
93
+ }).filter((msg) => msg.length > 0);
94
+ return { isValid: false, errors: errorMessages };
95
+ }
96
+ return { isValid: true, errors: [] };
97
+ }
98
+ catch (error) {
99
+ const validationError = error instanceof Error ? error : new Error(String(error));
100
+ return { isValid: false, errors: [validationError.message] };
101
+ }
102
+ }
103
+ }
104
+ exports.ClassValidatorProvider = ClassValidatorProvider;
105
+ /**
106
+ * Custom validation function provider.
107
+ */
108
+ class CustomValidationProvider {
109
+ name = 'custom';
110
+ isAvailable() {
111
+ return true;
112
+ }
113
+ validate(config, validationFn) {
114
+ try {
115
+ const result = validationFn(config);
116
+ if (Array.isArray(result) && result.length > 0) {
117
+ return { isValid: false, errors: result };
118
+ }
119
+ return { isValid: true, errors: [] };
120
+ }
121
+ catch (error) {
122
+ const validationError = error instanceof Error ? error : new Error(String(error));
123
+ return { isValid: false, errors: [validationError.message] };
124
+ }
125
+ }
126
+ }
127
+ exports.CustomValidationProvider = CustomValidationProvider;
128
+ /**
129
+ * Service for integrating AWS-sourced configuration with @nestjs/config validation.
130
+ * Supports Joi, class-validator, and custom validation functions.
131
+ */
132
+ let ValidationIntegrationService = ValidationIntegrationService_1 = class ValidationIntegrationService {
133
+ logger = new common_1.Logger(ValidationIntegrationService_1.name);
134
+ validationProviders = new Map();
135
+ constructor() {
136
+ // Register available validation providers
137
+ this.registerValidationProviders();
138
+ }
139
+ /**
140
+ * Create a validated configuration factory.
141
+ * This factory will validate AWS-sourced configuration before returning it.
142
+ *
143
+ * @param namespace - Optional namespace for the configuration
144
+ * @param config - Configuration data to validate
145
+ * @param validationSchema - Validation schema (Joi schema, class-validator class, or custom function)
146
+ * @param validationType - Type of validation ('joi', 'class-validator', or 'custom')
147
+ * @param sources - Configuration sources metadata
148
+ * @returns Validated configuration factory
149
+ */
150
+ createValidatedFactory(namespace, config, validationSchema, validationType, sources) {
151
+ this.logger.debug(`Creating validated factory for namespace: ${namespace || 'default'} with ${validationType} validation`);
152
+ const factory = () => {
153
+ this.logger.debug(`Validated factory called for namespace: ${namespace || 'default'}`);
154
+ // Validate configuration
155
+ const validationResult = this.validateConfiguration(config, validationSchema, validationType, sources);
156
+ if (!validationResult.isValid) {
157
+ const errorMessage = `Configuration validation failed for ${namespace || 'default'}: ${validationResult.errors.join(', ')}`;
158
+ this.logger.error(errorMessage);
159
+ // Create detailed error with source information
160
+ const detailedError = this.createValidationError(namespace || 'default', validationResult.errors, sources);
161
+ throw detailedError;
162
+ }
163
+ this.logger.debug(`Configuration validation passed for namespace: ${namespace || 'default'}`);
164
+ return config;
165
+ };
166
+ // Add validation metadata
167
+ factory.__isValidatedFactory = true;
168
+ factory.__validationType = validationType;
169
+ factory.__namespace = namespace;
170
+ factory.__sources = sources?.map(s => s.name) || [];
171
+ return factory;
172
+ }
173
+ /**
174
+ * Validate configuration using the specified validation type and schema.
175
+ *
176
+ * @param config - Configuration to validate
177
+ * @param schema - Validation schema
178
+ * @param validationType - Type of validation
179
+ * @param sources - Configuration sources for error reporting
180
+ * @returns Validation result
181
+ */
182
+ validateConfiguration(config, schema, validationType, sources) {
183
+ const provider = this.validationProviders.get(validationType);
184
+ if (!provider) {
185
+ return {
186
+ isValid: false,
187
+ errors: [`Validation provider '${validationType}' is not available`],
188
+ warnings: []
189
+ };
190
+ }
191
+ if (!provider.isAvailable()) {
192
+ return {
193
+ isValid: false,
194
+ errors: [`Validation provider '${validationType}' is not properly configured`],
195
+ warnings: []
196
+ };
197
+ }
198
+ try {
199
+ const result = provider.validate(config, schema);
200
+ // Add source information to errors
201
+ const enhancedErrors = result.errors.map(error => this.enhanceErrorWithSourceInfo(error, sources));
202
+ return {
203
+ isValid: result.isValid,
204
+ errors: enhancedErrors,
205
+ warnings: []
206
+ };
207
+ }
208
+ catch (error) {
209
+ const validationError = error instanceof Error ? error : new Error(String(error));
210
+ return {
211
+ isValid: false,
212
+ errors: [validationError.message],
213
+ warnings: []
214
+ };
215
+ }
216
+ }
217
+ /**
218
+ * Create a factory that validates configuration and provides fallback values.
219
+ *
220
+ * @param namespace - Optional namespace
221
+ * @param config - Configuration data
222
+ * @param validationSchema - Validation schema
223
+ * @param validationType - Type of validation
224
+ * @param fallbackConfig - Fallback configuration to use if validation fails
225
+ * @param sources - Configuration sources
226
+ * @returns Factory with validation and fallback
227
+ */
228
+ createValidatedFactoryWithFallback(namespace, config, validationSchema, validationType, fallbackConfig, sources) {
229
+ this.logger.debug(`Creating validated factory with fallback for namespace: ${namespace || 'default'}`);
230
+ const factory = () => {
231
+ this.logger.debug(`Validated factory with fallback called for namespace: ${namespace || 'default'}`);
232
+ // Validate configuration
233
+ const validationResult = this.validateConfiguration(config, validationSchema, validationType, sources);
234
+ if (!validationResult.isValid) {
235
+ this.logger.warn(`Configuration validation failed for ${namespace || 'default'}, using fallback: ${validationResult.errors.join(', ')}`);
236
+ // Validate fallback configuration
237
+ const fallbackValidation = this.validateConfiguration(fallbackConfig, validationSchema, validationType);
238
+ if (fallbackValidation.isValid) {
239
+ return fallbackConfig;
240
+ }
241
+ else {
242
+ // Both primary and fallback failed
243
+ const errorMessage = `Both primary and fallback configuration validation failed for ${namespace || 'default'}`;
244
+ this.logger.error(errorMessage);
245
+ const detailedError = this.createValidationError(namespace || 'default', [...validationResult.errors, ...fallbackValidation.errors], sources);
246
+ throw detailedError;
247
+ }
248
+ }
249
+ this.logger.debug(`Configuration validation passed for namespace: ${namespace || 'default'}`);
250
+ return config;
251
+ };
252
+ // Add metadata
253
+ factory.__isValidatedFactory = true;
254
+ factory.__hasFallback = true;
255
+ factory.__validationType = validationType;
256
+ factory.__namespace = namespace;
257
+ factory.__sources = sources?.map(s => s.name) || [];
258
+ return factory;
259
+ }
260
+ /**
261
+ * Validate multiple namespace configurations.
262
+ *
263
+ * @param namespacedConfig - Configuration organized by namespace
264
+ * @param validationSchemas - Validation schemas for each namespace
265
+ * @param validationType - Type of validation
266
+ * @param sources - Configuration sources
267
+ * @returns Validation results for each namespace
268
+ */
269
+ validateNamespacedConfiguration(namespacedConfig, validationSchemas, validationType, sources) {
270
+ const results = {};
271
+ for (const [namespace, config] of Object.entries(namespacedConfig)) {
272
+ const schema = validationSchemas[namespace];
273
+ if (schema) {
274
+ results[namespace] = this.validateConfiguration(config, schema, validationType, sources);
275
+ }
276
+ else {
277
+ results[namespace] = {
278
+ isValid: true,
279
+ errors: [],
280
+ warnings: [`No validation schema provided for namespace: ${namespace}`]
281
+ };
282
+ }
283
+ }
284
+ return results;
285
+ }
286
+ /**
287
+ * Check which validation providers are available.
288
+ *
289
+ * @returns Object indicating availability of each provider
290
+ */
291
+ getAvailableValidationProviders() {
292
+ const availability = {};
293
+ for (const [name, provider] of this.validationProviders) {
294
+ availability[name] = provider.isAvailable();
295
+ }
296
+ return availability;
297
+ }
298
+ /**
299
+ * Get validation recommendations based on configuration structure.
300
+ *
301
+ * @param config - Configuration to analyze
302
+ * @returns Validation recommendations
303
+ */
304
+ getValidationRecommendations(config) {
305
+ const analysis = this.analyzeConfigurationStructure(config);
306
+ let recommendedProvider = 'custom';
307
+ const reasons = [];
308
+ const examples = {};
309
+ // Determine best validation approach
310
+ if (analysis.hasComplexNesting || analysis.hasArrays) {
311
+ if (this.validationProviders.get('joi')?.isAvailable()) {
312
+ recommendedProvider = 'joi';
313
+ reasons.push('Complex nested structure detected - Joi provides excellent nested validation');
314
+ examples['joi'] = this.generateJoiExample(config);
315
+ }
316
+ }
317
+ if (analysis.hasTypedValues && this.validationProviders.get('class-validator')?.isAvailable()) {
318
+ recommendedProvider = 'class-validator';
319
+ reasons.push('Typed values detected - class-validator provides strong type safety');
320
+ examples['class-validator'] = this.generateClassValidatorExample(config);
321
+ }
322
+ // Always provide custom example
323
+ examples['custom'] = this.generateCustomValidationExample(config);
324
+ return {
325
+ recommendedProvider,
326
+ reasons,
327
+ examples
328
+ };
329
+ }
330
+ /**
331
+ * Register validation providers.
332
+ */
333
+ registerValidationProviders() {
334
+ this.validationProviders.set('joi', new JoiValidationProvider());
335
+ this.validationProviders.set('class-validator', new ClassValidatorProvider());
336
+ this.validationProviders.set('custom', new CustomValidationProvider());
337
+ // Log available providers
338
+ const available = Array.from(this.validationProviders.entries())
339
+ .filter(([_, provider]) => provider.isAvailable())
340
+ .map(([name]) => name);
341
+ this.logger.debug(`Available validation providers: ${available.join(', ')}`);
342
+ }
343
+ /**
344
+ * Create a detailed validation error with source information.
345
+ *
346
+ * @param namespace - Namespace that failed validation
347
+ * @param errors - Validation errors
348
+ * @param sources - Configuration sources
349
+ * @returns Detailed error
350
+ */
351
+ createValidationError(namespace, errors, sources) {
352
+ let message = `Configuration validation failed for namespace '${namespace}':\n`;
353
+ message += errors.map(error => ` - ${error}`).join('\n');
354
+ if (sources && sources.length > 0) {
355
+ message += '\n\nConfiguration sources:\n';
356
+ message += sources.map(source => ` - ${source.name} (${source.type}): ${Object.keys(source.data).length} keys`).join('\n');
357
+ }
358
+ const error = new Error(message);
359
+ error.name = 'ConfigurationValidationError';
360
+ error.namespace = namespace;
361
+ error.validationErrors = errors;
362
+ error.sources = sources;
363
+ return error;
364
+ }
365
+ /**
366
+ * Enhance error message with source information.
367
+ *
368
+ * @param error - Original error message
369
+ * @param sources - Configuration sources
370
+ * @returns Enhanced error message
371
+ */
372
+ enhanceErrorWithSourceInfo(error, sources) {
373
+ if (!sources || sources.length === 0) {
374
+ return error;
375
+ }
376
+ const sourceNames = sources.map(s => s.name).join(', ');
377
+ return `${error} (from sources: ${sourceNames})`;
378
+ }
379
+ /**
380
+ * Analyze configuration structure for validation recommendations.
381
+ *
382
+ * @param config - Configuration to analyze
383
+ * @returns Structure analysis
384
+ */
385
+ analyzeConfigurationStructure(config) {
386
+ let hasComplexNesting = false;
387
+ let hasArrays = false;
388
+ let hasTypedValues = false;
389
+ let maxDepth = 0;
390
+ const analyze = (obj, depth = 0) => {
391
+ maxDepth = Math.max(maxDepth, depth);
392
+ if (depth > 2) {
393
+ hasComplexNesting = true;
394
+ }
395
+ for (const value of Object.values(obj)) {
396
+ if (Array.isArray(value)) {
397
+ hasArrays = true;
398
+ }
399
+ else if (typeof value === 'object' && value !== null) {
400
+ analyze(value, depth + 1);
401
+ }
402
+ else if (typeof value === 'number' || typeof value === 'boolean') {
403
+ hasTypedValues = true;
404
+ }
405
+ }
406
+ };
407
+ analyze(config);
408
+ return {
409
+ hasComplexNesting,
410
+ hasArrays,
411
+ hasTypedValues,
412
+ depth: maxDepth
413
+ };
414
+ }
415
+ /**
416
+ * Generate Joi validation example.
417
+ *
418
+ * @param config - Configuration to generate example for
419
+ * @returns Joi validation example
420
+ */
421
+ generateJoiExample(config) {
422
+ const schema = this.generateJoiSchemaFromConfig(config);
423
+ return `const Joi = require('joi');
424
+
425
+ const schema = ${schema};
426
+
427
+ // Usage in factory
428
+ const factory = () => {
429
+ const config = loadAwsConfig();
430
+ const { error, value } = schema.validate(config);
431
+ if (error) throw error;
432
+ return value;
433
+ };`;
434
+ }
435
+ /**
436
+ * Generate class-validator example.
437
+ *
438
+ * @param config - Configuration to generate example for
439
+ * @returns class-validator example
440
+ */
441
+ generateClassValidatorExample(config) {
442
+ const classDefinition = this.generateClassFromConfig(config);
443
+ return `import { IsString, IsNumber, IsOptional, validateSync } from 'class-validator';
444
+ import { plainToClass } from 'class-transformer';
445
+
446
+ ${classDefinition}
447
+
448
+ // Usage in factory
449
+ const factory = () => {
450
+ const config = loadAwsConfig();
451
+ const instance = plainToClass(ConfigClass, config);
452
+ const errors = validateSync(instance);
453
+ if (errors.length > 0) throw new Error('Validation failed');
454
+ return config;
455
+ };`;
456
+ }
457
+ /**
458
+ * Generate custom validation example.
459
+ *
460
+ * @param config - Configuration to generate example for
461
+ * @returns Custom validation example
462
+ */
463
+ generateCustomValidationExample(config) {
464
+ const validationChecks = this.generateValidationChecks(config);
465
+ return `const validateConfig = (config) => {
466
+ const errors = [];
467
+
468
+ ${validationChecks}
469
+
470
+ return errors;
471
+ };
472
+
473
+ // Usage in factory
474
+ const factory = () => {
475
+ const config = loadAwsConfig();
476
+ const errors = validateConfig(config);
477
+ if (errors.length > 0) throw new Error(\`Validation failed: \${errors.join(', ')}\`);
478
+ return config;
479
+ };`;
480
+ }
481
+ /**
482
+ * Generate Joi schema from configuration structure.
483
+ *
484
+ * @param config - Configuration object
485
+ * @returns Joi schema string
486
+ */
487
+ generateJoiSchemaFromConfig(config) {
488
+ const generateSchema = (obj) => {
489
+ if (typeof obj === 'string')
490
+ return 'Joi.string()';
491
+ if (typeof obj === 'number')
492
+ return 'Joi.number()';
493
+ if (typeof obj === 'boolean')
494
+ return 'Joi.boolean()';
495
+ if (Array.isArray(obj))
496
+ return 'Joi.array()';
497
+ if (typeof obj === 'object' && obj !== null) {
498
+ const properties = Object.entries(obj)
499
+ .map(([key, value]) => ` ${key}: ${generateSchema(value)}`)
500
+ .join(',\n');
501
+ return `Joi.object({\n${properties}\n})`;
502
+ }
503
+ return 'Joi.any()';
504
+ };
505
+ return generateSchema(config);
506
+ }
507
+ /**
508
+ * Generate class definition from configuration structure.
509
+ *
510
+ * @param config - Configuration object
511
+ * @returns Class definition string
512
+ */
513
+ generateClassFromConfig(config) {
514
+ const properties = Object.entries(config)
515
+ .map(([key, value]) => {
516
+ const decorator = this.getClassValidatorDecorator(value);
517
+ return ` ${decorator}\n ${key}: ${this.getTypeScriptType(value)};`;
518
+ })
519
+ .join('\n\n');
520
+ return `class ConfigClass {\n${properties}\n}`;
521
+ }
522
+ /**
523
+ * Generate validation checks for custom validation.
524
+ *
525
+ * @param config - Configuration object
526
+ * @returns Validation checks string
527
+ */
528
+ generateValidationChecks(config) {
529
+ return Object.entries(config)
530
+ .map(([key, value]) => {
531
+ const check = this.getValidationCheck(key, value);
532
+ return ` ${check}`;
533
+ })
534
+ .join('\n');
535
+ }
536
+ /**
537
+ * Get class-validator decorator for a value.
538
+ *
539
+ * @param value - Value to get decorator for
540
+ * @returns Decorator string
541
+ */
542
+ getClassValidatorDecorator(value) {
543
+ if (typeof value === 'string')
544
+ return '@IsString()';
545
+ if (typeof value === 'number')
546
+ return '@IsNumber()';
547
+ if (typeof value === 'boolean')
548
+ return '@IsBoolean()';
549
+ return '@IsOptional()';
550
+ }
551
+ /**
552
+ * Get TypeScript type for a value.
553
+ *
554
+ * @param value - Value to get type for
555
+ * @returns TypeScript type string
556
+ */
557
+ getTypeScriptType(value) {
558
+ if (typeof value === 'string')
559
+ return 'string';
560
+ if (typeof value === 'number')
561
+ return 'number';
562
+ if (typeof value === 'boolean')
563
+ return 'boolean';
564
+ if (Array.isArray(value))
565
+ return 'any[]';
566
+ if (typeof value === 'object')
567
+ return 'object';
568
+ return 'any';
569
+ }
570
+ /**
571
+ * Get validation check for custom validation.
572
+ *
573
+ * @param key - Configuration key
574
+ * @param value - Configuration value
575
+ * @returns Validation check string
576
+ */
577
+ getValidationCheck(key, value) {
578
+ if (typeof value === 'string') {
579
+ return `if (!config.${key} || typeof config.${key} !== 'string') errors.push('${key} must be a string');`;
580
+ }
581
+ if (typeof value === 'number') {
582
+ return `if (config.${key} === undefined || typeof config.${key} !== 'number') errors.push('${key} must be a number');`;
583
+ }
584
+ if (typeof value === 'boolean') {
585
+ return `if (config.${key} === undefined || typeof config.${key} !== 'boolean') errors.push('${key} must be a boolean');`;
586
+ }
587
+ return `if (config.${key} === undefined) errors.push('${key} is required');`;
588
+ }
589
+ };
590
+ exports.ValidationIntegrationService = ValidationIntegrationService;
591
+ exports.ValidationIntegrationService = ValidationIntegrationService = ValidationIntegrationService_1 = __decorate([
592
+ (0, common_1.Injectable)(),
593
+ __metadata("design:paramtypes", [])
594
+ ], ValidationIntegrationService);
595
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1pbnRlZ3JhdGlvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2ludGVncmF0aW9uL3NlcnZpY2VzL3ZhbGlkYXRpb24taW50ZWdyYXRpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUEsMkNBQW9EO0FBYXBEOztHQUVHO0FBQ0gsTUFBYSxxQkFBcUI7SUFDaEMsSUFBSSxHQUFHLEtBQUssQ0FBQztJQUNMLEdBQUcsQ0FBTTtJQUVqQjtRQUNFLElBQUksQ0FBQztZQUNILGdDQUFnQztZQUNoQyxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsdUJBQXVCO1lBQ3ZCLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7SUFDM0IsQ0FBQztJQUVELFFBQVEsQ0FBQyxNQUFXLEVBQUUsTUFBVztRQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2QsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsc0JBQXNCLENBQUMsRUFBRSxDQUFDO1FBQzlELENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxvRkFBb0Y7WUFDcEYsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNyQixJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQztZQUN2QyxDQUFDO1lBRUQsTUFBTSxFQUFFLEtB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Z0MsR0FBRyx1QkFBdUIsQ0FBQztRQUMzSCxDQUFDO1FBQ0QsT0FBTyxjQUFjLEdBQUcsZ0NBQWdDLEdBQUcsaUJBQWlCLENBQUM7SUFDL0UsQ0FBQztDQUNGLENBQUE7QUE1aUJZLG9FQUE0Qjt1Q0FBNUIsNEJBQTRCO0lBRHhDLElBQUEsbUJBQVUsR0FBRTs7R0FDQSw0QkFBNEIsQ0E0aUJ4QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIExvZ2dlciB9IGZyb20gJ0BuZXN0anMvY29tbW9uJztcclxuaW1wb3J0IHsgQ29uZmlnRmFjdG9yeSB9IGZyb20gJ0BuZXN0anMvY29uZmlnJztcclxuaW1wb3J0IHsgQ29uZmlndXJhdGlvblNvdXJjZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvY29uZmlndXJhdGlvbi1zb3VyY2UuaW50ZXJmYWNlJztcclxuXHJcbi8qKlxyXG4gKiBJbnRlcmZhY2UgZm9yIHZhbGlkYXRpb24gc2NoZW1hIHByb3ZpZGVycy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdGlvblNjaGVtYVByb3ZpZGVyIHtcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgdmFsaWRhdGUoY29uZmlnOiBhbnksIHNjaGVtYTogYW55KTogeyBpc1ZhbGlkOiBib29sZWFuOyBlcnJvcnM6IHN0cmluZ1tdIH07XHJcbiAgaXNBdmFpbGFibGUoKTogYm9vbGVhbjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEpvaSB2YWxpZGF0aW9uIHNjaGVtYSBwcm92aWRlci5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBKb2lWYWxpZGF0aW9uUHJvdmlkZXIgaW1wbGVtZW50cyBWYWxpZGF0aW9uU2NoZW1hUHJvdmlkZXIge1xyXG4gIG5hbWUgPSAnam9pJztcclxuICBwcml2YXRlIGpvaTogYW55O1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIFRyeSB0byBpbXBvcnQgSm9pIGR5bmFtaWNhbGx5XHJcbiAgICAgIHRoaXMuam9pID0gcmVxdWlyZSgnam9pJyk7XHJcbiAgICB9IGNhdGNoIHtcclxuICAgICAgLy8gSm9pIGlzIG5vdCBhdmFpbGFibGVcclxuICAgICAgdGhpcy5qb2kgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaXNBdmFpbGFibGUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5qb2kgIT09IG51bGw7XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZShjb25maWc6IGFueSwgc2NoZW1hOiBhbnkpOiB7IGlzVmFsaWQ6IGJvb2xlYW47IGVycm9yczogc3RyaW5nW10gfSB7XHJcbiAgICBpZiAoIXRoaXMuam9pKSB7XHJcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBlcnJvcnM6IFsnSm9pIGlzIG5vdCBhdmFpbGFibGUnXSB9O1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIFVzZSBqb2kuYXR0ZW1wdCB3aGljaCB0aHJvd3Mgb24gdmFsaWRhdGlvbiBlcnJvciwgb3IgZmFsbCBiYWNrIHRvIHNjaGVtYS52YWxpZGF0ZVxyXG4gICAgICBpZiAodGhpcy5qb2kuYXR0ZW1wdCkge1xyXG4gICAgICAgIHRoaXMuam9pLmF0dGVtcHQoY29uZmlnLCBzY2hlbWEpO1xyXG4gICAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGVycm9yczogW10gfTtcclxuICAgICAgfVxyXG4gICAgICBcclxuICAgICAgY29uc3QgeyBlcnJvciB9ID0gc2NoZW1hLnZhbGlkYXRlKGNvbmZpZyk7XHJcbiAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgIGNvbnN0IGVycm9ycyA9IGVycm9yLmRldGFpbHM/Lm1hcCgoZGV0YWlsOiBhbnkpID0+IGRldGFpbC5tZXNzYWdlKSB8fCBbZXJyb3IubWVzc2FnZV07XHJcbiAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIGVycm9ycyB9O1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlLCBlcnJvcnM6IFtdIH07XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XHJcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBlcnJvcnM6IFt2YWxpZGF0aW9uRXJyb3IubWVzc2FnZV0gfTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDbGFzcy12YWxpZGF0b3IgdmFsaWRhdGlvbiBzY2hlbWEgcHJvdmlkZXIuXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgQ2xhc3NWYWxpZGF0b3JQcm92aWRlciBpbXBsZW1lbnRzIFZhbGlkYXRpb25TY2hlbWFQcm92aWRlciB7XHJcbiAgbmFtZSA9ICdjbGFzcy12YWxpZGF0b3InO1xyXG4gIHByaXZhdGUgY2xhc3NWYWxpZGF0b3I6IGFueTtcclxuICBwcml2YXRlIGNsYXNzVHJhbnNmb3JtZXI6IGFueTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAvLyBUcnkgdG8gaW1wb3J0IGNsYXNzLXZhbGlkYXRvciBhbmQgY2xhc3MtdHJhbnNmb3JtZXIgZHluYW1pY2FsbHlcclxuICAgICAgdGhpcy5jbGFzc1ZhbGlkYXRvciA9IHJlcXVpcmUoJ2NsYXNzLXZhbGlkYXRvcicpO1xyXG4gICAgICB0aGlzLmNsYXNzVHJhbnNmb3JtZXIgPSByZXF1aXJlKCdjbGFzcy10cmFuc2Zvcm1lcicpO1xyXG4gICAgfSBjYXRjaCB7XHJcbiAgICAgIC8vIGNsYXNzLXZhbGlkYXRvciBpcyBub3QgYXZhaWxhYmxlXHJcbiAgICAgIHRoaXMuY2xhc3NWYWxpZGF0b3IgPSBudWxsO1xyXG4gICAgICB0aGlzLmNsYXNzVHJhbnNmb3JtZXIgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaXNBdmFpbGFibGUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5jbGFzc1ZhbGlkYXRvciAhPT0gbnVsbCAmJiB0aGlzLmNsYXNzVHJhbnNmb3JtZXIgIT09IG51bGw7XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZShjb25maWc6IGFueSwgc2NoZW1hQ2xhc3M6IGFueSk6IHsgaXNWYWxpZDogYm9vbGVhbjsgZXJyb3JzOiBzdHJpbmdbXSB9IHtcclxuICAgIGlmICghdGhpcy5jbGFzc1ZhbGlkYXRvciB8fCAhdGhpcy5jbGFzc1RyYW5zZm9ybWVyKSB7XHJcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBlcnJvcnM6IFsnY2xhc3MtdmFsaWRhdG9yIG9yIGNsYXNzLXRyYW5zZm9ybWVyIGlzIG5vdCBhdmFpbGFibGUnXSB9O1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIFRyYW5zZm9ybSBwbGFpbiBvYmplY3QgdG8gY2xhc3MgaW5zdGFuY2VcclxuICAgICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLmNsYXNzVHJhbnNmb3JtZXIucGxhaW5Ub0NsYXNzKHNjaGVtYUNsYXNzLCBjb25maWcpO1xyXG4gICAgICBcclxuICAgICAgLy8gVmFsaWRhdGUgdGhlIGluc3RhbmNlXHJcbiAgICAgIGNvbnN0IGVycm9ycyA9IHRoaXMuY2xhc3NWYWxpZGF0b3IudmFsaWRhdGVTeW5jKGluc3RhbmNlKTtcclxuICAgICAgXHJcbiAgICAgIGlmIChlcnJvcnMgJiYgZXJyb3JzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2VzID0gZXJyb3JzLm1hcCgoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgY29uc3RyYWludHMgPSBlcnJvci5jb25zdHJhaW50cyB8fCB7fTtcclxuICAgICAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKGNvbnN0cmFpbnRzKS5qb2luKCcsICcpO1xyXG4gICAgICAgIH0pLmZpbHRlcigobXNnOiBzdHJpbmcpID0+IG1zZy5sZW5ndGggPiAwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIGVycm9yczogZXJyb3JNZXNzYWdlcyB9O1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlLCBlcnJvcnM6IFtdIH07XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XHJcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBlcnJvcnM6IFt2YWxpZGF0aW9uRXJyb3IubWVzc2FnZV0gfTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDdXN0b20gdmFsaWRhdGlvbiBmdW5jdGlvbiBwcm92aWRlci5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBDdXN0b21WYWxpZGF0aW9uUHJvdmlkZXIgaW1wbGVtZW50cyBWYWxpZGF0aW9uU2NoZW1hUHJvdmlkZXIge1xyXG4gIG5hbWUgPSAnY3VzdG9tJztcclxuXHJcbiAgaXNBdmFpbGFibGUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHZhbGlkYXRlKGNvbmZpZzogYW55LCB2YWxpZGF0aW9uRm46IChjb25maWc6IGFueSkgPT4gc3RyaW5nW10gfCB2b2lkKTogeyBpc1ZhbGlkOiBib29sZWFuOyBlcnJvcnM6IHN0cmluZ1tdIH0ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsaWRhdGlvbkZuKGNvbmZpZyk7XHJcbiAgICAgIFxyXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpICYmIHJlc3VsdC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIGVycm9yczogcmVzdWx0IH07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGVycm9yczogW10gfTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvciA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKTtcclxuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIGVycm9yczogW3ZhbGlkYXRpb25FcnJvci5tZXNzYWdlXSB9O1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFNlcnZpY2UgZm9yIGludGVncmF0aW5nIEFXUy1zb3VyY2VkIGNvbmZpZ3VyYXRpb24gd2l0aCBAbmVzdGpzL2NvbmZpZyB2YWxpZGF0aW9uLlxyXG4gKiBTdXBwb3J0cyBKb2ksIGNsYXNzLXZhbGlkYXRvciwgYW5kIGN1c3RvbSB2YWxpZGF0aW9uIGZ1bmN0aW9ucy5cclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25JbnRlZ3JhdGlvblNlcnZpY2Uge1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyID0gbmV3IExvZ2dlcihWYWxpZGF0aW9uSW50ZWdyYXRpb25TZXJ2aWNlLm5hbWUpO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgdmFsaWRhdGlvblByb3ZpZGVyczogTWFwPHN0cmluZywgVmFsaWRhdGlvblNjaGVtYVByb3ZpZGVyPiA9IG5ldyBNYXAoKTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAvLyBSZWdpc3RlciBhdmFpbGFibGUgdmFsaWRhdGlvbiBwcm92aWRlcnNcclxuICAgIHRoaXMucmVnaXN0ZXJWYWxpZGF0aW9uUHJvdmlkZXJzKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGUgYSB2YWxpZGF0ZWQgY29uZmlndXJhdGlvbiBmYWN0b3J5LlxyXG4gICAqIFRoaXMgZmFjdG9yeSB3aWxsIHZhbGlkYXRlIEFXUy1zb3VyY2VkIGNvbmZpZ3VyYXRpb24gYmVmb3JlIHJldHVybmluZyBpdC5cclxuICAgKiBcclxuICAgKiBAcGFyYW0gbmFtZXNwYWNlIC0gT3B0aW9uYWwgbmFtZXNwYWNlIGZvciB0aGUgY29uZmlndXJhdGlvblxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIGRhdGEgdG8gdmFsaWRhdGVcclxuICAgKiBAcGFyYW0gdmFsaWRhdGlvblNjaGVtYSAtIFZhbGlkYXRpb24gc2NoZW1hIChKb2kgc2NoZW1hLCBjbGFzcy12YWxpZGF0b3IgY2xhc3MsIG9yIGN1c3RvbSBmdW5jdGlvbilcclxuICAgKiBAcGFyYW0gdmFsaWRhdGlvblR5cGUgLSBUeXBlIG9mIHZhbGlkYXRpb24gKCdqb2knLCAnY2xhc3MtdmFsaWRhdG9yJywgb3IgJ2N1c3RvbScpXHJcbiAgICogQHBhcmFtIHNvdXJjZXMgLSBDb25maWd1cmF0aW9uIHNvdXJjZXMgbWV0YWRhdGFcclxuICAgKiBAcmV0dXJucyBWYWxpZGF0ZWQgY29uZmlndXJhdGlvbiBmYWN0b3J5XHJcbiAgICovXHJcbiAgY3JlYXRlVmFsaWRhdGVkRmFjdG9yeShcclxuICAgIG5hbWVzcGFjZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxyXG4gICAgY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxyXG4gICAgdmFsaWRhdGlvblNjaGVtYTogYW55LFxyXG4gICAgdmFsaWRhdGlvblR5cGU6ICdqb2knIHwgJ2NsYXNzLXZhbGlkYXRvcicgfCAnY3VzdG9tJyxcclxuICAgIHNvdXJjZXM/OiBDb25maWd1cmF0aW9uU291cmNlW11cclxuICApOiBDb25maWdGYWN0b3J5IHtcclxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBDcmVhdGluZyB2YWxpZGF0ZWQgZmFjdG9yeSBmb3IgbmFtZXNwYWNlOiAke25hbWVzcGFjZSB8fCAnZGVmYXVsdCd9IHdpdGggJHt2YWxpZGF0aW9uVHlwZX0gdmFsaWRhdGlvbmApO1xyXG5cclxuICAgIGNvbnN0IGZhY3RvcnkgPSAoKSA9PiB7XHJcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBWYWxpZGF0ZWQgZmFjdG9yeSBjYWxsZWQgZm9yIG5hbWVzcGFjZTogJHtuYW1lc3BhY2UgfHwgJ2RlZmF1bHQnfWApO1xyXG5cclxuICAgICAgLy8gVmFsaWRhdGUgY29uZmlndXJhdGlvblxyXG4gICAgICBjb25zdCB2YWxpZGF0aW9uUmVzdWx0ID0gdGhpcy52YWxpZGF0ZUNvbmZpZ3VyYXRpb24oY29uZmlnLCB2YWxpZGF0aW9uU2NoZW1hLCB2YWxpZGF0aW9uVHlwZSwgc291cmNlcyk7XHJcblxyXG4gICAgICBpZiAoIXZhbGlkYXRpb25SZXN1bHQuaXNWYWxpZCkge1xyXG4gICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGBDb25maWd1cmF0aW9uIHZhbGlkYXRpb24gZmFpbGVkIGZvciAke25hbWVzcGFjZSB8fCAnZGVmYXVsdCd9OiAke3ZhbGlkYXRpb25SZXN1bHQuZXJyb3JzLmpvaW4oJywgJyl9YDtcclxuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihlcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIENyZWF0ZSBkZXRhaWxlZCBlcnJvciB3aXRoIHNvdXJjZSBpbmZvcm1hdGlvblxyXG4gICAgICAgIGNvbnN0IGRldGFpbGVkRXJyb3IgPSB0aGlzLmNyZWF0ZVZhbGlkYXRpb25FcnJvcihcclxuICAgICAgICAgIG5hbWVzcGFjZSB8fCAnZGVmYXVsdCcsXHJcbiAgICAgICAgICB2YWxpZGF0aW9uUmVzdWx0LmVycm9ycyxcclxuICAgICAgICAgIHNvdXJjZXNcclxuICAgICAgICApO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRocm93IGRldGFpbGVkRXJyb3I7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBDb25maWd1cmF0aW9uIHZhbGlkYXRpb24gcGFzc2VkIGZvciBuYW1lc3BhY2U6ICR7bmFtZXNwYWNlIHx8ICdkZWZhdWx0J31gKTtcclxuICAgICAgcmV0dXJuIGNvbmZpZztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkIHZhbGlkYXRpb24gbWV0YWRhdGFcclxuICAgIChmYWN0b3J5IGFzIGFueSkuX19pc1ZhbGlkYXRlZEZhY3RvcnkgPSB0cnVlO1xyXG4gICAgKGZhY3RvcnkgYXMgYW55KS5fX3ZhbGlkYXRpb25UeXBlID0gdmFsaWRhdGlvblR5cGU7XHJcbiAgICAoZmFjdG9yeSBhcyBhbnkpLl9fbmFtZXNwYWNlID0gbmFtZXNwYWNlO1xyXG4gICAgKGZhY3RvcnkgYXMgYW55KS5fX3NvdXJjZXMgPSBzb3VyY2VzPy5tYXAocyA9PiBzLm5hbWUpIHx8IFtdO1xyXG5cclxuICAgIHJldHVybiBmYWN0b3J5O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVmFsaWRhdGUgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHZhbGlkYXRpb24gdHlwZSBhbmQgc2NoZW1hLlxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIHRvIHZhbGlkYXRlXHJcbiAgICogQHBhcmFtIHNjaGVtYSAtIFZhbGlkYXRpb24gc2NoZW1hXHJcbiAgICogQHBhcmFtIHZhbGlkYXRpb25UeXBlIC0gVHlwZSBvZiB2YWxpZGF0aW9uXHJcbiAgICogQHBhcmFtIHNvdXJjZXMgLSBDb25maWd1cmF0aW9uIHNvdXJjZXMgZm9yIGVycm9yIHJlcG9ydGluZ1xyXG4gICAqIEByZXR1cm5zIFZhbGlkYXRpb24gcmVzdWx0XHJcbiAgICovXHJcbiAgdmFsaWRhdGVDb25maWd1cmF0aW9uKFxyXG4gICAgY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxyXG4gICAgc2NoZW1hOiBhbnksXHJcbiAgICB2YWxpZGF0aW9uVHlwZTogJ2pvaScgfCAnY2xhc3MtdmFsaWRhdG9yJyB8ICdjdXN0b20nLFxyXG4gICAgc291cmNlcz86IENvbmZpZ3VyYXRpb25Tb3VyY2VbXVxyXG4gICk6IHsgaXNWYWxpZDogYm9vbGVhbjsgZXJyb3JzOiBzdHJpbmdbXTsgd2FybmluZ3M6IHN0cmluZ1tdIH0ge1xyXG4gICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLnZhbGlkYXRpb25Qcm92aWRlcnMuZ2V0KHZhbGlkYXRpb25UeXBlKTtcclxuICAgIFxyXG4gICAgaWYgKCFwcm92aWRlcikge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGlzVmFsaWQ6IGZhbHNlLFxyXG4gICAgICAgIGVycm9yczogW2BWYWxpZGF0aW9uIHByb3ZpZGVyICcke3ZhbGlkYXRpb25UeXBlfScgaXMgbm90IGF2YWlsYWJsZWBdLFxyXG4gICAgICAgIHdhcm5pbmdzOiBbXVxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghcHJvdmlkZXIuaXNBdmFpbGFibGUoKSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGlzVmFsaWQ6IGZhbHNlLFxyXG4gICAgICAgIGVycm9yczogW2BWYWxpZGF0aW9uIHByb3ZpZGVyICcke3ZhbGlkYXRpb25UeXBlfScgaXMgbm90IHByb3Blcmx5IGNvbmZpZ3VyZWRgXSxcclxuICAgICAgICB3YXJuaW5nczogW11cclxuICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSBwcm92aWRlci52YWxpZGF0ZShjb25maWcsIHNjaGVtYSk7XHJcbiAgICAgIFxyXG4gICAgICAvLyBBZGQgc291cmNlIGluZm9ybWF0aW9uIHRvIGVycm9yc1xyXG4gICAgICBjb25zdCBlbmhhbmNlZEVycm9ycyA9IHJlc3VsdC5lcnJvcnMubWFwKGVycm9yID0+IFxyXG4gICAgICAgIHRoaXMuZW5oYW5jZUVycm9yV2l0aFNvdXJjZUluZm8oZXJyb3IsIHNvdXJjZXMpXHJcbiAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGlzVmFsaWQ6IHJlc3VsdC5pc1ZhbGlkLFxyXG4gICAgICAgIGVycm9yczogZW5oYW5jZWRFcnJvcnMsXHJcbiAgICAgICAgd2FybmluZ3M6IFtdXHJcbiAgICAgIH07XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgaXNWYWxpZDogZmFsc2UsXHJcbiAgICAgICAgZXJyb3JzOiBbdmFsaWRhdGlvbkVycm9yLm1lc3NhZ2VdLFxyXG4gICAgICAgIHdhcm5pbmdzOiBbXVxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGEgZmFjdG9yeSB0aGF0IHZhbGlkYXRlcyBjb25maWd1cmF0aW9uIGFuZCBwcm92aWRlcyBmYWxsYmFjayB2YWx1ZXMuXHJcbiAgICogXHJcbiAgICogQHBhcmFtIG5hbWVzcGFjZSAtIE9wdGlvbmFsIG5hbWVzcGFjZVxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIGRhdGFcclxuICAgKiBAcGFyYW0gdmFsaWRhdGlvblNjaGVtYSAtIFZhbGlkYXRpb24gc2NoZW1hXHJcbiAgICogQHBhcmFtIHZhbGlkYXRpb25UeXBlIC0gVHlwZSBvZiB2YWxpZGF0aW9uXHJcbiAgICogQHBhcmFtIGZhbGxiYWNrQ29uZmlnIC0gRmFsbGJhY2sgY29uZmlndXJhdGlvbiB0byB1c2UgaWYgdmFsaWRhdGlvbiBmYWlsc1xyXG4gICAqIEBwYXJhbSBzb3VyY2VzIC0gQ29uZmlndXJhdGlvbiBzb3VyY2VzXHJcbiAgICogQHJldHVybnMgRmFjdG9yeSB3aXRoIHZhbGlkYXRpb24gYW5kIGZhbGxiYWNrXHJcbiAgICovXHJcbiAgY3JlYXRlVmFsaWRhdGVkRmFjdG9yeVdpdGhGYWxsYmFjayhcclxuICAgIG5hbWVzcGFjZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxyXG4gICAgY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxyXG4gICAgdmFsaWRhdGlvblNjaGVtYTogYW55LFxyXG4gICAgdmFsaWRhdGlvblR5cGU6ICdqb2knIHwgJ2NsYXNzLXZhbGlkYXRvcicgfCAnY3VzdG9tJyxcclxuICAgIGZhbGxiYWNrQ29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxyXG4gICAgc291cmNlcz86IENvbmZpZ3VyYXRpb25Tb3VyY2VbXVxyXG4gICk6IENvbmZpZ0ZhY3Rvcnkge1xyXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYENyZWF0aW5nIHZhbGlkYXRlZCBmYWN0b3J5IHdpdGggZmFsbGJhY2sgZm9yIG5hbWVzcGFjZTogJHtuYW1lc3BhY2UgfHwgJ2RlZmF1bHQnfWApO1xyXG5cclxuICAgIGNvbnN0IGZhY3RvcnkgPSAoKSA9PiB7XHJcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBWYWxpZGF0ZWQgZmFjdG9yeSB3aXRoIGZhbGxiYWNrIGNhbGxlZCBmb3IgbmFtZXNwYWNlOiAke25hbWVzcGFjZSB8fCAnZGVmYXVsdCd9YCk7XHJcblxyXG4gICAgICAvLyBWYWxpZGF0ZSBjb25maWd1cmF0aW9uXHJcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25SZXN1bHQgPSB0aGlzLnZhbGlkYXRlQ29uZmlndXJhdGlvbihjb25maWcsIHZhbGlkYXRpb25TY2hlbWEsIHZhbGlkYXRpb25UeXBlLCBzb3VyY2VzKTtcclxuXHJcbiAgICAgIGlmICghdmFsaWRhdGlvblJlc3VsdC5pc1ZhbGlkKSB7XHJcbiAgICAgICAgdGhpcy5sb2dnZXIud2FybihgQ29uZmlndXJhdGlvbiB2YWxpZGF0aW9uIGZhaWxlZCBmb3IgJHtuYW1lc3BhY2UgfHwgJ2RlZmF1bHQnfSwgdXNpbmcgZmFsbGJhY2s6ICR7dmFsaWRhdGlvblJlc3VsdC5lcnJvcnMuam9pbignLCAnKX1gKTtcclxuICAgICAgICBcclxuICAgICAgICAvLyBWYWxpZGF0ZSBmYWxsYmFjayBjb25maWd1cmF0aW9uXHJcbiAgICAgICAgY29uc3QgZmFsbGJhY2tWYWxpZGF0aW9uID0gdGhpcy52YWxpZGF0ZUNvbmZpZ3VyYXRpb24oZmFsbGJhY2tDb25maWcsIHZhbGlkYXRpb25TY2hlbWEsIHZhbGlkYXRpb25UeXBlKTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoZmFsbGJhY2tWYWxpZGF0aW9uLmlzVmFsaWQpIHtcclxuICAgICAgICAgIHJldHVybiBmYWxsYmFja0NvbmZpZztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gQm90aCBwcmltYXJ5IGFuZCBmYWxsYmFjayBmYWlsZWRcclxuICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGBCb3RoIHByaW1hcnkgYW5kIGZhbGxiYWNrIGNvbmZpZ3VyYXRpb24gdmFsaWRhdGlvbiBmYWlsZWQgZm9yICR7bmFtZXNwYWNlIHx8ICdkZWZhdWx0J31gO1xyXG4gICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoZXJyb3JNZXNzYWdlKTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgY29uc3QgZGV0YWlsZWRFcnJvciA9IHRoaXMuY3JlYXRlVmFsaWRhdGlvbkVycm9yKFxyXG4gICAgICAgICAgICBuYW1lc3BhY2UgfHwgJ2RlZmF1bHQnLFxyXG4gICAgICAgICAgICBbLi4udmFsaWRhdGlvblJlc3VsdC5lcnJvcnMsIC4uLmZhbGxiYWNrVmFsaWRhdGlvbi5lcnJvcnNdLFxyXG4gICAgICAgICAgICBzb3VyY2VzXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICB0aHJvdyBkZXRhaWxlZEVycm9yO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYENvbmZpZ3VyYXRpb24gdmFsaWRhdGlvbiBwYXNzZWQgZm9yIG5hbWVzcGFjZTogJHtuYW1lc3BhY2UgfHwgJ2RlZmF1bHQnfWApO1xyXG4gICAgICByZXR1cm4gY29uZmlnO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBBZGQgbWV0YWRhdGFcclxuICAgIChmYWN0b3J5IGFzIGFueSkuX19pc1ZhbGlkYXRlZEZhY3RvcnkgPSB0cnVlO1xyXG4gICAgKGZhY3RvcnkgYXMgYW55KS5fX2hhc0ZhbGxiYWNrID0gdHJ1ZTtcclxuICAgIChmYWN0b3J5IGFzIGFueSkuX192YWxpZGF0aW9uVHlwZSA9IHZhbGlkYXRpb25UeXBlO1xyXG4gICAgKGZhY3RvcnkgYXMgYW55KS5fX25hbWVzcGFjZSA9IG5hbWVzcGFjZTtcclxuICAgIChmYWN0b3J5IGFzIGFueSkuX19zb3VyY2VzID0gc291cmNlcz8ubWFwKHMgPT4gcy5uYW1lKSB8fCBbXTtcclxuXHJcbiAgICByZXR1cm4gZmFjdG9yeTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFZhbGlkYXRlIG11bHRpcGxlIG5hbWVzcGFjZSBjb25maWd1cmF0aW9ucy5cclxuICAgKiBcclxuICAgKiBAcGFyYW0gbmFtZXNwYWNlZENvbmZpZyAtIENvbmZpZ3VyYXRpb24gb3JnYW5pemVkIGJ5IG5hbWVzcGFjZVxyXG4gICAqIEBwYXJhbSB2YWxpZGF0aW9uU2NoZW1hcyAtIFZhbGlkYXRpb24gc2NoZW1hcyBmb3IgZWFjaCBuYW1lc3BhY2VcclxuICAgKiBAcGFyYW0gdmFsaWRhdGlvblR5cGUgLSBUeXBlIG9mIHZhbGlkYXRpb25cclxuICAgKiBAcGFyYW0gc291cmNlcyAtIENvbmZpZ3VyYXRpb24gc291cmNlc1xyXG4gICAqIEByZXR1cm5zIFZhbGlkYXRpb24gcmVzdWx0cyBmb3IgZWFjaCBuYW1lc3BhY2VcclxuICAgKi9cclxuICB2YWxpZGF0ZU5hbWVzcGFjZWRDb25maWd1cmF0aW9uKFxyXG4gICAgbmFtZXNwYWNlZENvbmZpZzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55Pj4sXHJcbiAgICB2YWxpZGF0aW9uU2NoZW1hczogUmVjb3JkPHN0cmluZywgYW55PixcclxuICAgIHZhbGlkYXRpb25UeXBlOiAnam9pJyB8ICdjbGFzcy12YWxpZGF0b3InIHwgJ2N1c3RvbScsXHJcbiAgICBzb3VyY2VzPzogQ29uZmlndXJhdGlvblNvdXJjZVtdXHJcbiAgKTogUmVjb3JkPHN0cmluZywgeyBpc1ZhbGlkOiBib29sZWFuOyBlcnJvcnM6IHN0cmluZ1tdOyB3YXJuaW5nczogc3RyaW5nW10gfT4ge1xyXG4gICAgY29uc3QgcmVzdWx0czogUmVjb3JkPHN0cmluZywgeyBpc1ZhbGlkOiBib29sZWFuOyBlcnJvcnM6IHN0cmluZ1tdOyB3YXJuaW5nczogc3RyaW5nW10gfT4gPSB7fTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IFtuYW1lc3BhY2UsIGNvbmZpZ10gb2YgT2JqZWN0LmVudHJpZXMobmFtZXNwYWNlZENvbmZpZykpIHtcclxuICAgICAgY29uc3Qgc2NoZW1hID0gdmFsaWRhdGlvblNjaGVtYXNbbmFtZXNwYWNlXTtcclxuICAgICAgXHJcbiAgICAgIGlmIChzY2hlbWEpIHtcclxuICAgICAgICByZXN1bHRzW25hbWVzcGFjZV0gPSB0aGlzLnZhbGlkYXRlQ29uZmlndXJhdGlvbihjb25maWcsIHNjaGVtYSwgdmFsaWRhdGlvblR5cGUsIHNvdXJjZXMpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJlc3VsdHNbbmFtZXNwYWNlXSA9IHtcclxuICAgICAgICAgIGlzVmFsaWQ6IHRydWUsXHJcbiAgICAgICAgICBlcnJvcnM6IFtdLFxyXG4gICAgICAgICAgd2FybmluZ3M6IFtgTm8gdmFsaWRhdGlvbiBzY2hlbWEgcHJvdmlkZWQgZm9yIG5hbWVzcGFjZTogJHtuYW1lc3BhY2V9YF1cclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdHM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayB3aGljaCB2YWxpZGF0aW9uIHByb3ZpZGVycyBhcmUgYXZhaWxhYmxlLlxyXG4gICAqIFxyXG4gICAqIEByZXR1cm5zIE9iamVjdCBpbmRpY2F0aW5nIGF2YWlsYWJpbGl0eSBvZiBlYWNoIHByb3ZpZGVyXHJcbiAgICovXHJcbiAgZ2V0QXZhaWxhYmxlVmFsaWRhdGlvblByb3ZpZGVycygpOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiB7XHJcbiAgICBjb25zdCBhdmFpbGFiaWxpdHk6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge307XHJcbiAgICBcclxuICAgIGZvciAoY29uc3QgW25hbWUsIHByb3ZpZGVyXSBvZiB0aGlzLnZhbGlkYXRpb25Qcm92aWRlcnMpIHtcclxuICAgICAgYXZhaWxhYmlsaXR5W25hbWVdID0gcHJvdmlkZXIuaXNBdmFpbGFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gYXZhaWxhYmlsaXR5O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHZhbGlkYXRpb24gcmVjb21tZW5kYXRpb25zIGJhc2VkIG9uIGNvbmZpZ3VyYXRpb24gc3RydWN0dXJlLlxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIHRvIGFuYWx5emVcclxuICAgKiBAcmV0dXJucyBWYWxpZGF0aW9uIHJlY29tbWVuZGF0aW9uc1xyXG4gICAqL1xyXG4gIGdldFZhbGlkYXRpb25SZWNvbW1lbmRhdGlvbnMoY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KToge1xyXG4gICAgcmVjb21tZW5kZWRQcm92aWRlcjogc3RyaW5nO1xyXG4gICAgcmVhc29uczogc3RyaW5nW107XHJcbiAgICBleGFtcGxlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcclxuICB9IHtcclxuICAgIGNvbnN0IGFuYWx5c2lzID0gdGhpcy5hbmFseXplQ29uZmlndXJhdGlvblN0cnVjdHVyZShjb25maWcpO1xyXG4gICAgXHJcbiAgICBsZXQgcmVjb21tZW5kZWRQcm92aWRlciA9ICdjdXN0b20nO1xyXG4gICAgY29uc3QgcmVhc29uczogc3RyaW5nW10gPSBbXTtcclxuICAgIGNvbnN0IGV4YW1wbGVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XHJcblxyXG4gICAgLy8gRGV0ZXJtaW5lIGJlc3QgdmFsaWRhdGlvbiBhcHByb2FjaFxyXG4gICAgaWYgKGFuYWx5c2lzLmhhc0NvbXBsZXhOZXN0aW5nIHx8IGFuYWx5c2lzLmhhc0FycmF5cykge1xyXG4gICAgICBpZiAodGhpcy52YWxpZGF0aW9uUHJvdmlkZXJzLmdldCgnam9pJyk/LmlzQXZhaWxhYmxlKCkpIHtcclxuICAgICAgICByZWNvbW1lbmRlZFByb3ZpZGVyID0gJ2pvaSc7XHJcbiAgICAgICAgcmVhc29ucy5wdXNoKCdDb21wbGV4IG5lc3RlZCBzdHJ1Y3R1cmUgZGV0ZWN0ZWQgLSBKb2kgcHJvdmlkZXMgZXhjZWxsZW50IG5lc3RlZCB2YWxpZGF0aW9uJyk7XHJcbiAgICAgICAgZXhhbXBsZXNbJ2pvaSddID0gdGhpcy5nZW5lcmF0ZUpvaUV4YW1wbGUoY29uZmlnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChhbmFseXNpcy5oYXNUeXBlZFZhbHVlcyAmJiB0aGlzLnZhbGlkYXRpb25Qcm92aWRlcnMuZ2V0KCdjbGFzcy12YWxpZGF0b3InKT8uaXNBdmFpbGFibGUoKSkge1xyXG4gICAgICByZWNvbW1lbmRlZFByb3ZpZGVyID0gJ2NsYXNzLXZhbGlkYXRvcic7XHJcbiAgICAgIHJlYXNvbnMucHVzaCgnVHlwZWQgdmFsdWVzIGRldGVjdGVkIC0gY2xhc3MtdmFsaWRhdG9yIHByb3ZpZGVzIHN0cm9uZyB0eXBlIHNhZmV0eScpO1xyXG4gICAgICBleGFtcGxlc1snY2xhc3MtdmFsaWRhdG9yJ10gPSB0aGlzLmdlbmVyYXRlQ2xhc3NWYWxpZGF0b3JFeGFtcGxlKGNvbmZpZyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWx3YXlzIHByb3ZpZGUgY3VzdG9tIGV4YW1wbGVcclxuICAgIGV4YW1wbGVzWydjdXN0b20nXSA9IHRoaXMuZ2VuZXJhdGVDdXN0b21WYWxpZGF0aW9uRXhhbXBsZShjb25maWcpO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIHJlY29tbWVuZGVkUHJvdmlkZXIsXHJcbiAgICAgIHJlYXNvbnMsXHJcbiAgICAgIGV4YW1wbGVzXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVnaXN0ZXIgdmFsaWRhdGlvbiBwcm92aWRlcnMuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZWdpc3RlclZhbGlkYXRpb25Qcm92aWRlcnMoKTogdm9pZCB7XHJcbiAgICB0aGlzLnZhbGlkYXRpb25Qcm92aWRlcnMuc2V0KCdqb2knLCBuZXcgSm9pVmFsaWRhdGlvblByb3ZpZGVyKCkpO1xyXG4gICAgdGhpcy52YWxpZGF0aW9uUHJvdmlkZXJzLnNldCgnY2xhc3MtdmFsaWRhdG9yJywgbmV3IENsYXNzVmFsaWRhdG9yUHJvdmlkZXIoKSk7XHJcbiAgICB0aGlzLnZhbGlkYXRpb25Qcm92aWRlcnMuc2V0KCdjdXN0b20nLCBuZXcgQ3VzdG9tVmFsaWRhdGlvblByb3ZpZGVyKCkpO1xyXG5cclxuICAgIC8vIExvZyBhdmFpbGFibGUgcHJvdmlkZXJzXHJcbiAgICBjb25zdCBhdmFpbGFibGUgPSBBcnJheS5mcm9tKHRoaXMudmFsaWRhdGlvblByb3ZpZGVycy5lbnRyaWVzKCkpXHJcbiAgICAgIC5maWx0ZXIoKFtfLCBwcm92aWRlcl0pID0+IHByb3ZpZGVyLmlzQXZhaWxhYmxlKCkpXHJcbiAgICAgIC5tYXAoKFtuYW1lXSkgPT4gbmFtZSk7XHJcblxyXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYEF2YWlsYWJsZSB2YWxpZGF0aW9uIHByb3ZpZGVyczogJHthdmFpbGFibGUuam9pbignLCAnKX1gKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENyZWF0ZSBhIGRldGFpbGVkIHZhbGlkYXRpb24gZXJyb3Igd2l0aCBzb3VyY2UgaW5mb3JtYXRpb24uXHJcbiAgICogXHJcbiAgICogQHBhcmFtIG5hbWVzcGFjZSAtIE5hbWVzcGFjZSB0aGF0IGZhaWxlZCB2YWxpZGF0aW9uXHJcbiAgICogQHBhcmFtIGVycm9ycyAtIFZhbGlkYXRpb24gZXJyb3JzXHJcbiAgICogQHBhcmFtIHNvdXJjZXMgLSBDb25maWd1cmF0aW9uIHNvdXJjZXNcclxuICAgKiBAcmV0dXJucyBEZXRhaWxlZCBlcnJvclxyXG4gICAqL1xyXG4gIHByaXZhdGUgY3JlYXRlVmFsaWRhdGlvbkVycm9yKFxyXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcsXHJcbiAgICBlcnJvcnM6IHN0cmluZ1tdLFxyXG4gICAgc291cmNlcz86IENvbmZpZ3VyYXRpb25Tb3VyY2VbXVxyXG4gICk6IEVycm9yIHtcclxuICAgIGxldCBtZXNzYWdlID0gYENvbmZpZ3VyYXRpb24gdmFsaWRhdGlvbiBmYWlsZWQgZm9yIG5hbWVzcGFjZSAnJHtuYW1lc3BhY2V9JzpcXG5gO1xyXG4gICAgbWVzc2FnZSArPSBlcnJvcnMubWFwKGVycm9yID0+IGAgIC0gJHtlcnJvcn1gKS5qb2luKCdcXG4nKTtcclxuXHJcbiAgICBpZiAoc291cmNlcyAmJiBzb3VyY2VzLmxlbmd0aCA+IDApIHtcclxuICAgICAgbWVzc2FnZSArPSAnXFxuXFxuQ29uZmlndXJhdGlvbiBzb3VyY2VzOlxcbic7XHJcbiAgICAgIG1lc3NhZ2UgKz0gc291cmNlcy5tYXAoc291cmNlID0+IFxyXG4gICAgICAgIGAgIC0gJHtzb3VyY2UubmFtZX0gKCR7c291cmNlLnR5cGV9KTogJHtPYmplY3Qua2V5cyhzb3VyY2UuZGF0YSkubGVuZ3RofSBrZXlzYFxyXG4gICAgICApLmpvaW4oJ1xcbicpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgZXJyb3IubmFtZSA9ICdDb25maWd1cmF0aW9uVmFsaWRhdGlvbkVycm9yJztcclxuICAgIChlcnJvciBhcyBhbnkpLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcclxuICAgIChlcnJvciBhcyBhbnkpLnZhbGlkYXRpb25FcnJvcnMgPSBlcnJvcnM7XHJcbiAgICAoZXJyb3IgYXMgYW55KS5zb3VyY2VzID0gc291cmNlcztcclxuXHJcbiAgICByZXR1cm4gZXJyb3I7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFbmhhbmNlIGVycm9yIG1lc3NhZ2Ugd2l0aCBzb3VyY2UgaW5mb3JtYXRpb24uXHJcbiAgICogXHJcbiAgICogQHBhcmFtIGVycm9yIC0gT3JpZ2luYWwgZXJyb3IgbWVzc2FnZVxyXG4gICAqIEBwYXJhbSBzb3VyY2VzIC0gQ29uZmlndXJhdGlvbiBzb3VyY2VzXHJcbiAgICogQHJldHVybnMgRW5oYW5jZWQgZXJyb3IgbWVzc2FnZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZW5oYW5jZUVycm9yV2l0aFNvdXJjZUluZm8oZXJyb3I6IHN0cmluZywgc291cmNlcz86IENvbmZpZ3VyYXRpb25Tb3VyY2VbXSk6IHN0cmluZyB7XHJcbiAgICBpZiAoIXNvdXJjZXMgfHwgc291cmNlcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgcmV0dXJuIGVycm9yO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHNvdXJjZU5hbWVzID0gc291cmNlcy5tYXAocyA9PiBzLm5hbWUpLmpvaW4oJywgJyk7XHJcbiAgICByZXR1cm4gYCR7ZXJyb3J9IChmcm9tIHNvdXJjZXM6ICR7c291cmNlTmFtZXN9KWA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBbmFseXplIGNvbmZpZ3VyYXRpb24gc3RydWN0dXJlIGZvciB2YWxpZGF0aW9uIHJlY29tbWVuZGF0aW9ucy5cclxuICAgKiBcclxuICAgKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiB0byBhbmFseXplXHJcbiAgICogQHJldHVybnMgU3RydWN0dXJlIGFuYWx5c2lzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhbmFseXplQ29uZmlndXJhdGlvblN0cnVjdHVyZShjb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4pOiB7XHJcbiAgICBoYXNDb21wbGV4TmVzdGluZzogYm9vbGVhbjtcclxuICAgIGhhc0FycmF5czogYm9vbGVhbjtcclxuICAgIGhhc1R5cGVkVmFsdWVzOiBib29sZWFuO1xyXG4gICAgZGVwdGg6IG51bWJlcjtcclxuICB9IHtcclxuICAgIGxldCBoYXNDb21wbGV4TmVzdGluZyA9IGZhbHNlO1xyXG4gICAgbGV0IGhhc0FycmF5cyA9IGZhbHNlO1xyXG4gICAgbGV0IGhhc1R5cGVkVmFsdWVzID0gZmFsc2U7XHJcbiAgICBsZXQgbWF4RGVwdGggPSAwO1xyXG5cclxuICAgIGNvbnN0IGFuYWx5emUgPSAob2JqOiBhbnksIGRlcHRoOiBudW1iZXIgPSAwKTogdm9pZCA9PiB7XHJcbiAgICAgIG1heERlcHRoID0gTWF0aC5tYXgobWF4RGVwdGgsIGRlcHRoKTtcclxuXHJcbiAgICAgIGlmIChkZXB0aCA+IDIpIHtcclxuICAgICAgICBoYXNDb21wbGV4TmVzdGluZyA9IHRydWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgT2JqZWN0LnZhbHVlcyhvYmopKSB7XHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgICAgICBoYXNBcnJheXMgPSB0cnVlO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgYW5hbHl6ZSh2YWx1ZSwgZGVwdGggKyAxKTtcclxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgICAgIGhhc1R5cGVkVmFsdWVzID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgYW5hbHl6ZShjb25maWcpO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGhhc0NvbXBsZXhOZXN0aW5nLFxyXG4gICAgICBoYXNBcnJheXMsXHJcbiAgICAgIGhhc1R5cGVkVmFsdWVzLFxyXG4gICAgICBkZXB0aDogbWF4RGVwdGhcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZW5lcmF0ZSBKb2kgdmFsaWRhdGlvbiBleGFtcGxlLlxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIHRvIGdlbmVyYXRlIGV4YW1wbGUgZm9yXHJcbiAgICogQHJldHVybnMgSm9pIHZhbGlkYXRpb24gZXhhbXBsZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2VuZXJhdGVKb2lFeGFtcGxlKGNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55Pik6IHN0cmluZyB7XHJcbiAgICBjb25zdCBzY2hlbWEgPSB0aGlzLmdlbmVyYXRlSm9pU2NoZW1hRnJvbUNvbmZpZyhjb25maWcpO1xyXG4gICAgcmV0dXJuIGBjb25zdCBKb2kgPSByZXF1aXJlKCdqb2knKTtcclxuXHJcbmNvbnN0IHNjaGVtYSA9ICR7c2NoZW1hfTtcclxuXHJcbi8vIFVzYWdlIGluIGZhY3RvcnlcclxuY29uc3QgZmFjdG9yeSA9ICgpID0+IHtcclxuICBjb25zdCBjb25maWcgPSBsb2FkQXdzQ29uZmlnKCk7XHJcbiAgY29uc3QgeyBlcnJvciwgdmFsdWUgfSA9IHNjaGVtYS52YWxpZGF0ZShjb25maWcpO1xyXG4gIGlmIChlcnJvcikgdGhyb3cgZXJyb3I7XHJcbiAgcmV0dXJuIHZhbHVlO1xyXG59O2A7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZW5lcmF0ZSBjbGFzcy12YWxpZGF0b3IgZXhhbXBsZS5cclxuICAgKiBcclxuICAgKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiB0byBnZW5lcmF0ZSBleGFtcGxlIGZvclxyXG4gICAqIEByZXR1cm5zIGNsYXNzLXZhbGlkYXRvciBleGFtcGxlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZW5lcmF0ZUNsYXNzVmFsaWRhdG9yRXhhbXBsZShjb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBzdHJpbmcge1xyXG4gICAgY29uc3QgY2xhc3NEZWZpbml0aW9uID0gdGhpcy5nZW5lcmF0ZUNsYXNzRnJvbUNvbmZpZyhjb25maWcpO1xyXG4gICAgcmV0dXJuIGBpbXBvcnQgeyBJc1N0cmluZywgSXNOdW1iZXIsIElzT3B0aW9uYWwsIHZhbGlkYXRlU3luYyB9IGZyb20gJ2NsYXNzLXZhbGlkYXRvcic7XHJcbmltcG9ydCB7IHBsYWluVG9DbGFzcyB9IGZyb20gJ2NsYXNzLXRyYW5zZm9ybWVyJztcclxuXHJcbiR7Y2xhc3NEZWZpbml0aW9ufVxyXG5cclxuLy8gVXNhZ2UgaW4gZmFjdG9yeVxyXG5jb25zdCBmYWN0b3J5ID0gKCkgPT4ge1xyXG4gIGNvbnN0IGNvbmZpZyA9IGxvYWRBd3NDb25maWcoKTtcclxuICBjb25zdCBpbnN0YW5jZSA9IHBsYWluVG9DbGFzcyhDb25maWdDbGFzcywgY29uZmlnKTtcclxuICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZVN5bmMoaW5zdGFuY2UpO1xyXG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdWYWxpZGF0aW9uIGZhaWxlZCcpO1xyXG4gIHJldHVybiBjb25maWc7XHJcbn07YDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdlbmVyYXRlIGN1c3RvbSB2YWxpZGF0aW9uIGV4YW1wbGUuXHJcbiAgICogXHJcbiAgICogQHBhcmFtIGNvbmZpZyAtIENvbmZpZ3VyYXRpb24gdG8gZ2VuZXJhdGUgZXhhbXBsZSBmb3JcclxuICAgKiBAcmV0dXJucyBDdXN0b20gdmFsaWRhdGlvbiBleGFtcGxlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZW5lcmF0ZUN1c3RvbVZhbGlkYXRpb25FeGFtcGxlKGNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55Pik6IHN0cmluZyB7XHJcbiAgICBjb25zdCB2YWxpZGF0aW9uQ2hlY2tzID0gdGhpcy5nZW5lcmF0ZVZhbGlkYXRpb25DaGVja3MoY29uZmlnKTtcclxuICAgIHJldHVybiBgY29uc3QgdmFsaWRhdGVDb25maWcgPSAoY29uZmlnKSA9PiB7XHJcbiAgY29uc3QgZXJyb3JzID0gW107XHJcbiAgXHJcbiR7dmFsaWRhdGlvbkNoZWNrc31cclxuICBcclxuICByZXR1cm4gZXJyb3JzO1xyXG59O1xyXG5cclxuLy8gVXNhZ2UgaW4gZmFjdG9yeVxyXG5jb25zdCBmYWN0b3J5ID0gKCkgPT4ge1xyXG4gIGNvbnN0IGNvbmZpZyA9IGxvYWRBd3NDb25maWcoKTtcclxuICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZUNvbmZpZyhjb25maWcpO1xyXG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKFxcYFZhbGlkYXRpb24gZmFpbGVkOiBcXCR7ZXJyb3JzLmpvaW4oJywgJyl9XFxgKTtcclxuICByZXR1cm4gY29uZmlnO1xyXG59O2A7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZW5lcmF0ZSBKb2kgc2NoZW1hIGZyb20gY29uZmlndXJhdGlvbiBzdHJ1Y3R1cmUuXHJcbiAgICogXHJcbiAgICogQHBhcmFtIGNvbmZpZyAtIENvbmZpZ3VyYXRpb24gb2JqZWN0XHJcbiAgICogQHJldHVybnMgSm9pIHNjaGVtYSBzdHJpbmdcclxuICAgKi9cclxuICBwcml2YXRlIGdlbmVyYXRlSm9pU2NoZW1hRnJvbUNvbmZpZyhjb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBzdHJpbmcge1xyXG4gICAgY29uc3QgZ2VuZXJhdGVTY2hlbWEgPSAob2JqOiBhbnkpOiBzdHJpbmcgPT4ge1xyXG4gICAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIHJldHVybiAnSm9pLnN0cmluZygpJztcclxuICAgICAgaWYgKHR5cGVvZiBvYmogPT09ICdudW1iZXInKSByZXR1cm4gJ0pvaS5udW1iZXIoKSc7XHJcbiAgICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHJldHVybiAnSm9pLmJvb2xlYW4oKSc7XHJcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHJldHVybiAnSm9pLmFycmF5KCknO1xyXG4gICAgICBcclxuICAgICAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCkge1xyXG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBPYmplY3QuZW50cmllcyhvYmopXHJcbiAgICAgICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IGAgICR7a2V5fTogJHtnZW5lcmF0ZVNjaGVtYSh2YWx1ZSl9YClcclxuICAgICAgICAgIC5qb2luKCcsXFxuJyk7XHJcbiAgICAgICAgcmV0dXJuIGBKb2kub2JqZWN0KHtcXG4ke3Byb3BlcnRpZXN9XFxufSlgO1xyXG4gICAgICB9XHJcbiAgICAgIFxyXG4gICAgICByZXR1cm4gJ0pvaS5hbnkoKSc7XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiBnZW5lcmF0ZVNjaGVtYShjb25maWcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2VuZXJhdGUgY2xhc3MgZGVmaW5pdGlvbiBmcm9tIGNvbmZpZ3VyYXRpb24gc3RydWN0dXJlLlxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIG9iamVjdFxyXG4gICAqIEByZXR1cm5zIENsYXNzIGRlZmluaXRpb24gc3RyaW5nXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZW5lcmF0ZUNsYXNzRnJvbUNvbmZpZyhjb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBzdHJpbmcge1xyXG4gICAgY29uc3QgcHJvcGVydGllcyA9IE9iamVjdC5lbnRyaWVzKGNvbmZpZylcclxuICAgICAgLm1hcCgoW2tleSwgdmFsdWVdKSA9PiB7XHJcbiAgICAgICAgY29uc3QgZGVjb3JhdG9yID0gdGhpcy5nZXRDbGFzc1ZhbGlkYXRvckRlY29yYXRvcih2YWx1ZSk7XHJcbiAgICAgICAgcmV0dXJuIGAgICR7ZGVjb3JhdG9yfVxcbiAgJHtrZXl9OiAke3RoaXMuZ2V0VHlwZVNjcmlwdFR5cGUodmFsdWUpfTtgO1xyXG4gICAgICB9KVxyXG4gICAgICAuam9pbignXFxuXFxuJyk7XHJcblxyXG4gICAgcmV0dXJuIGBjbGFzcyBDb25maWdDbGFzcyB7XFxuJHtwcm9wZXJ0aWVzfVxcbn1gO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2VuZXJhdGUgdmFsaWRhdGlvbiBjaGVja3MgZm9yIGN1c3RvbSB2YWxpZGF0aW9uLlxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIG9iamVjdFxyXG4gICAqIEByZXR1cm5zIFZhbGlkYXRpb24gY2hlY2tzIHN0cmluZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2VuZXJhdGVWYWxpZGF0aW9uQ2hlY2tzKGNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55Pik6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoY29uZmlnKVxyXG4gICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcclxuICAgICAgICBjb25zdCBjaGVjayA9IHRoaXMuZ2V0VmFsaWRhdGlvbkNoZWNrKGtleSwgdmFsdWUpO1xyXG4gICAgICAgIHJldHVybiBgICAke2NoZWNrfWA7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5qb2luKCdcXG4nKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBjbGFzcy12YWxpZGF0b3IgZGVjb3JhdG9yIGZvciBhIHZhbHVlLlxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFZhbHVlIHRvIGdldCBkZWNvcmF0b3IgZm9yXHJcbiAgICogQHJldHVybnMgRGVjb3JhdG9yIHN0cmluZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0Q2xhc3NWYWxpZGF0b3JEZWNvcmF0b3IodmFsdWU6IGFueSk6IHN0cmluZyB7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuICdASXNTdHJpbmcoKSc7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykgcmV0dXJuICdASXNOdW1iZXIoKSc7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiAnQElzQm9vbGVhbigpJztcclxuICAgIHJldHVybiAnQElzT3B0aW9uYWwoKSc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgVHlwZVNjcmlwdCB0eXBlIGZvciBhIHZhbHVlLlxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFZhbHVlIHRvIGdldCB0eXBlIGZvclxyXG4gICAqIEByZXR1cm5zIFR5cGVTY3JpcHQgdHlwZSBzdHJpbmdcclxuICAgKi9cclxuICBwcml2YXRlIGdldFR5cGVTY3JpcHRUeXBlKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiAnc3RyaW5nJztcclxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSByZXR1cm4gJ251bWJlcic7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiAnYm9vbGVhbic7XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiAnYW55W10nO1xyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHJldHVybiAnb2JqZWN0JztcclxuICAgIHJldHVybiAnYW55JztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB2YWxpZGF0aW9uIGNoZWNrIGZvciBjdXN0b20gdmFsaWRhdGlvbi5cclxuICAgKiBcclxuICAgKiBAcGFyYW0ga2V5IC0gQ29uZmlndXJhdGlvbiBrZXlcclxuICAgKiBAcGFyYW0gdmFsdWUgLSBDb25maWd1cmF0aW9uIHZhbHVlXHJcbiAgICogQHJldHVybnMgVmFsaWRhdGlvbiBjaGVjayBzdHJpbmdcclxuICAgKi9cclxuICBwcml2YXRlIGdldFZhbGlkYXRpb25DaGVjayhrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IHN0cmluZyB7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xyXG4gICAgICByZXR1cm4gYGlmICghY29uZmlnLiR7a2V5fSB8fCB0eXBlb2YgY29uZmlnLiR7a2V5fSAhPT0gJ3N0cmluZycpIGVycm9ycy5wdXNoKCcke2tleX0gbXVzdCBiZSBhIHN0cmluZycpO2A7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xyXG4gICAgICByZXR1cm4gYGlmIChjb25maWcuJHtrZXl9ID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIGNvbmZpZy4ke2tleX0gIT09ICdudW1iZXInKSBlcnJvcnMucHVzaCgnJHtrZXl9IG11c3QgYmUgYSBudW1iZXInKTtgO1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgIHJldHVybiBgaWYgKGNvbmZpZy4ke2tleX0gPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgY29uZmlnLiR7a2V5fSAhPT0gJ2Jvb2xlYW4nKSBlcnJvcnMucHVzaCgnJHtrZXl9IG11c3QgYmUgYSBib29sZWFuJyk7YDtcclxuICAgIH1cclxuICAgIHJldHVybiBgaWYgKGNvbmZpZy4ke2tleX0gPT09IHVuZGVmaW5lZCkgZXJyb3JzLnB1c2goJyR7a2V5fSBpcyByZXF1aXJlZCcpO2A7XHJcbiAgfVxyXG59Il19