@l-v-yonsama/multi-platform-database-drivers 1.2.0 → 2.0.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 (315) hide show
  1. package/README.md +40 -0
  2. package/built/src/drivers/Auth0Driver.js +9 -9
  3. package/built/src/drivers/Auth0Driver.js.map +1 -1
  4. package/built/src/drivers/AwsDriver.d.ts +6 -0
  5. package/built/src/drivers/AwsDriver.js +87 -7
  6. package/built/src/drivers/AwsDriver.js.map +1 -1
  7. package/built/src/drivers/BaseDriver.d.ts +1 -1
  8. package/built/src/drivers/BaseDriver.js +4 -6
  9. package/built/src/drivers/BaseDriver.js.map +1 -1
  10. package/built/src/drivers/DBDriverResolver.js.map +1 -1
  11. package/built/src/drivers/DBError.js.map +1 -1
  12. package/built/src/drivers/KeycloakDriver.d.ts +2 -3
  13. package/built/src/drivers/KeycloakDriver.js +27 -262
  14. package/built/src/drivers/KeycloakDriver.js.map +1 -1
  15. package/built/src/drivers/MemcacheDriver.d.ts +0 -1
  16. package/built/src/drivers/MemcacheDriver.js +5 -5
  17. package/built/src/drivers/MemcacheDriver.js.map +1 -1
  18. package/built/src/drivers/MqttDriver.d.ts +0 -1
  19. package/built/src/drivers/MqttDriver.js +4 -4
  20. package/built/src/drivers/MqttDriver.js.map +1 -1
  21. package/built/src/drivers/MySQLDriver.js +12 -12
  22. package/built/src/drivers/MySQLDriver.js.map +1 -1
  23. package/built/src/drivers/OracleDriver.js +13 -13
  24. package/built/src/drivers/OracleDriver.js.map +1 -1
  25. package/built/src/drivers/PostgresDriver.js +22 -2
  26. package/built/src/drivers/PostgresDriver.js.map +1 -1
  27. package/built/src/drivers/RDSBaseDriver.d.ts +1 -1
  28. package/built/src/drivers/RDSBaseDriver.js +6 -6
  29. package/built/src/drivers/RDSBaseDriver.js.map +1 -1
  30. package/built/src/drivers/RedisDriver.js +2 -2
  31. package/built/src/drivers/RedisDriver.js.map +1 -1
  32. package/built/src/drivers/SQLServerDriver.js +7 -7
  33. package/built/src/drivers/SQLServerDriver.js.map +1 -1
  34. package/built/src/drivers/SQLiteDriver.d.ts +1 -1
  35. package/built/src/drivers/SQLiteDriver.js +7 -7
  36. package/built/src/drivers/SQLiteDriver.js.map +1 -1
  37. package/built/src/drivers/aws/AwsCloudFormationServiceClient.d.ts +35 -0
  38. package/built/src/drivers/aws/AwsCloudFormationServiceClient.js +197 -0
  39. package/built/src/drivers/aws/AwsCloudFormationServiceClient.js.map +1 -0
  40. package/built/src/drivers/aws/AwsCloudwatchServiceClient.js +4 -7
  41. package/built/src/drivers/aws/AwsCloudwatchServiceClient.js.map +1 -1
  42. package/built/src/drivers/aws/AwsDynamoServiceClient.js +8 -11
  43. package/built/src/drivers/aws/AwsDynamoServiceClient.js.map +1 -1
  44. package/built/src/drivers/aws/AwsS3ServiceClient.js +28 -30
  45. package/built/src/drivers/aws/AwsS3ServiceClient.js.map +1 -1
  46. package/built/src/drivers/aws/AwsSESServiceClient.js +23 -0
  47. package/built/src/drivers/aws/AwsSESServiceClient.js.map +1 -1
  48. package/built/src/drivers/aws/AwsSQSServiceClient.d.ts +1 -0
  49. package/built/src/drivers/aws/AwsSQSServiceClient.js +40 -8
  50. package/built/src/drivers/aws/AwsSQSServiceClient.js.map +1 -1
  51. package/built/src/drivers/aws/AwsSecretsManagerServiceClient.d.ts +19 -0
  52. package/built/src/drivers/aws/AwsSecretsManagerServiceClient.js +118 -0
  53. package/built/src/drivers/aws/AwsSecretsManagerServiceClient.js.map +1 -0
  54. package/built/src/drivers/aws/AwsServiceClient.d.ts +1 -0
  55. package/built/src/drivers/aws/AwsServiceClient.js +13 -2
  56. package/built/src/drivers/aws/AwsServiceClient.js.map +1 -1
  57. package/built/src/drivers/aws/AwsSsmServiceClient.d.ts +19 -0
  58. package/built/src/drivers/aws/AwsSsmServiceClient.js +116 -0
  59. package/built/src/drivers/aws/AwsSsmServiceClient.js.map +1 -0
  60. package/built/src/drivers/aws/index.d.ts +3 -0
  61. package/built/src/drivers/aws/index.js +3 -0
  62. package/built/src/drivers/aws/index.js.map +1 -1
  63. package/built/src/drivers/keycloak/resourceTreeBuilder.d.ts +5 -0
  64. package/built/src/drivers/keycloak/resourceTreeBuilder.js +37 -0
  65. package/built/src/drivers/keycloak/resourceTreeBuilder.js.map +1 -0
  66. package/built/src/drivers/keycloak/scanResultBuilder.d.ts +8 -0
  67. package/built/src/drivers/keycloak/scanResultBuilder.js +212 -0
  68. package/built/src/drivers/keycloak/scanResultBuilder.js.map +1 -0
  69. package/built/src/drivers/memcache/helper.d.ts +0 -1
  70. package/built/src/drivers/memcache/helper.js +13 -14
  71. package/built/src/drivers/memcache/helper.js.map +1 -1
  72. package/built/src/helpers/ProposalHelper.js +3 -3
  73. package/built/src/helpers/ProposalHelper.js.map +1 -1
  74. package/built/src/helpers/RdhRecordRuleHelper.js.map +1 -1
  75. package/built/src/helpers/RuleEngine.d.ts +5 -5
  76. package/built/src/helpers/RuleEngine.js +14 -14
  77. package/built/src/helpers/RuleEngine.js.map +1 -1
  78. package/built/src/helpers/SQLHelper.d.ts +8 -115
  79. package/built/src/helpers/SQLHelper.js +35 -1084
  80. package/built/src/helpers/SQLHelper.js.map +1 -1
  81. package/built/src/helpers/prompts/Auth0PromptHelper.js.map +1 -1
  82. package/built/src/helpers/prompts/AwsPromptHelper.js +93 -2
  83. package/built/src/helpers/prompts/AwsPromptHelper.js.map +1 -1
  84. package/built/src/helpers/prompts/KeycloakPromptHelper.js.map +1 -1
  85. package/built/src/helpers/prompts/MemcachePromptHelper.js.map +1 -1
  86. package/built/src/helpers/prompts/MqttPromptHelper.js.map +1 -1
  87. package/built/src/helpers/prompts/RdsPromptHelper.js +1 -1
  88. package/built/src/helpers/prompts/RdsPromptHelper.js.map +1 -1
  89. package/built/src/helpers/prompts/RedisPromptHelper.js.map +1 -1
  90. package/built/src/helpers/prompts/SchemaPromptHelper.js.map +1 -1
  91. package/built/src/helpers/sql/dynamoConversion.d.ts +2 -0
  92. package/built/src/helpers/sql/dynamoConversion.js +27 -0
  93. package/built/src/helpers/sql/dynamoConversion.js.map +1 -0
  94. package/built/src/helpers/sql/formatQuery.d.ts +6 -0
  95. package/built/src/helpers/sql/formatQuery.js +45 -0
  96. package/built/src/helpers/sql/formatQuery.js.map +1 -0
  97. package/built/src/helpers/sql/mutationQuery.d.ts +54 -0
  98. package/built/src/helpers/sql/mutationQuery.js +250 -0
  99. package/built/src/helpers/sql/mutationQuery.js.map +1 -0
  100. package/built/src/helpers/sql/parameterNormalizer.d.ts +16 -0
  101. package/built/src/helpers/sql/parameterNormalizer.js +166 -0
  102. package/built/src/helpers/sql/parameterNormalizer.js.map +1 -0
  103. package/built/src/helpers/sql/queryParser.d.ts +6 -0
  104. package/built/src/helpers/sql/queryParser.js +239 -0
  105. package/built/src/helpers/sql/queryParser.js.map +1 -0
  106. package/built/src/helpers/sql/quote.d.ts +17 -0
  107. package/built/src/helpers/sql/quote.js +140 -0
  108. package/built/src/helpers/sql/quote.js.map +1 -0
  109. package/built/src/helpers/sql/selectQuery.d.ts +24 -0
  110. package/built/src/helpers/sql/selectQuery.js +262 -0
  111. package/built/src/helpers/sql/selectQuery.js.map +1 -0
  112. package/built/src/resource/aws.d.ts +106 -0
  113. package/built/src/resource/aws.js +219 -0
  114. package/built/src/resource/aws.js.map +1 -0
  115. package/built/src/resource/base.d.ts +28 -0
  116. package/built/src/resource/base.js +76 -0
  117. package/built/src/resource/base.js.map +1 -0
  118. package/built/src/resource/connection.d.ts +35 -0
  119. package/built/src/resource/connection.js +52 -0
  120. package/built/src/resource/connection.js.map +1 -0
  121. package/built/src/resource/fromJson.d.ts +2 -0
  122. package/built/src/resource/fromJson.js +125 -0
  123. package/built/src/resource/fromJson.js.map +1 -0
  124. package/built/src/resource/iam.d.ts +70 -0
  125. package/built/src/resource/iam.js +175 -0
  126. package/built/src/resource/iam.js.map +1 -0
  127. package/built/src/resource/index.d.ts +8 -1
  128. package/built/src/resource/index.js +8 -1
  129. package/built/src/resource/index.js.map +1 -1
  130. package/built/src/resource/keyValue.d.ts +85 -0
  131. package/built/src/resource/keyValue.js +74 -0
  132. package/built/src/resource/keyValue.js.map +1 -0
  133. package/built/src/resource/rdb.d.ts +49 -0
  134. package/built/src/resource/rdb.js +155 -0
  135. package/built/src/resource/rdb.js.map +1 -0
  136. package/built/src/resource/types.d.ts +18 -0
  137. package/built/src/resource/types.js +3 -0
  138. package/built/src/resource/types.js.map +1 -0
  139. package/built/src/types/drivers/Keycloak.js +1 -1
  140. package/built/src/types/drivers/Keycloak.js.map +1 -1
  141. package/built/src/types/drivers/MemcachedParams.d.ts +0 -1
  142. package/built/src/types/drivers/ScanParams.d.ts +15 -1
  143. package/built/src/types/helpers/index.js +1 -1
  144. package/built/src/types/helpers/index.js.map +1 -1
  145. package/built/src/types/resource/AwsCfnStackAttributes.d.ts +164 -0
  146. package/built/src/types/resource/AwsCfnStackAttributes.js +56 -0
  147. package/built/src/types/resource/AwsCfnStackAttributes.js.map +1 -0
  148. package/built/src/types/resource/AwsSESIdentityAttributes.d.ts +17 -0
  149. package/built/src/types/resource/AwsSESIdentityAttributes.js +3 -0
  150. package/built/src/types/resource/AwsSESIdentityAttributes.js.map +1 -0
  151. package/built/src/types/resource/AwsSQSAttributes.d.ts +1 -0
  152. package/built/src/types/resource/AwsSecretAttributes.d.ts +6 -0
  153. package/built/src/types/resource/AwsSecretAttributes.js +3 -0
  154. package/built/src/types/resource/AwsSecretAttributes.js.map +1 -0
  155. package/built/src/types/resource/AwsServiceType.d.ts +4 -1
  156. package/built/src/types/resource/AwsServiceType.js +3 -0
  157. package/built/src/types/resource/AwsServiceType.js.map +1 -1
  158. package/built/src/types/resource/AwsSsmParameterAttributes.d.ts +12 -0
  159. package/built/src/types/resource/AwsSsmParameterAttributes.js +3 -0
  160. package/built/src/types/resource/AwsSsmParameterAttributes.js.map +1 -0
  161. package/built/src/types/resource/ConnectionSetting.d.ts +2 -2
  162. package/built/src/types/resource/ConnectionSetting.js.map +1 -1
  163. package/built/src/types/resource/MySQLColumnType.js +2 -2
  164. package/built/src/types/resource/MySQLColumnType.js.map +1 -1
  165. package/built/src/types/resource/OracleColumnType.js +2 -2
  166. package/built/src/types/resource/OracleColumnType.js.map +1 -1
  167. package/built/src/types/resource/PartiQLAttrType.js.map +1 -1
  168. package/built/src/types/resource/PostgresColumnType.js +2 -2
  169. package/built/src/types/resource/PostgresColumnType.js.map +1 -1
  170. package/built/src/types/resource/ResourceType.d.ts +5 -0
  171. package/built/src/types/resource/ResourceType.js +5 -0
  172. package/built/src/types/resource/ResourceType.js.map +1 -1
  173. package/built/src/types/resource/SQLServerColumnType.js +2 -2
  174. package/built/src/types/resource/SQLServerColumnType.js.map +1 -1
  175. package/built/src/types/resource/index.d.ts +4 -0
  176. package/built/src/types/resource/index.js +4 -0
  177. package/built/src/types/resource/index.js.map +1 -1
  178. package/built/src/types/utils/index.js +2 -2
  179. package/built/src/types/utils/index.js.map +1 -1
  180. package/built/src/utils/base.js +1 -1
  181. package/built/src/utils/base.js.map +1 -1
  182. package/built/src/utils/cfn/applicationDiagram.d.ts +2 -0
  183. package/built/src/utils/cfn/applicationDiagram.js +174 -0
  184. package/built/src/utils/cfn/applicationDiagram.js.map +1 -0
  185. package/built/src/utils/cfn/applicationRelations.d.ts +28 -0
  186. package/built/src/utils/cfn/applicationRelations.js +430 -0
  187. package/built/src/utils/cfn/applicationRelations.js.map +1 -0
  188. package/built/src/utils/cfn/cfnDependencyGraphDiagram.d.ts +2 -0
  189. package/built/src/utils/cfn/cfnDependencyGraphDiagram.js +198 -0
  190. package/built/src/utils/cfn/cfnDependencyGraphDiagram.js.map +1 -0
  191. package/built/src/utils/cfn/deploymentTopology.d.ts +132 -0
  192. package/built/src/utils/cfn/deploymentTopology.js +637 -0
  193. package/built/src/utils/cfn/deploymentTopology.js.map +1 -0
  194. package/built/src/utils/cfn/diagramFileModel.d.ts +2 -0
  195. package/built/src/utils/cfn/diagramFileModel.js +178 -0
  196. package/built/src/utils/cfn/diagramFileModel.js.map +1 -0
  197. package/built/src/utils/cfn/drawio/cfnDependencyGraphDiagram.d.ts +3 -0
  198. package/built/src/utils/cfn/drawio/cfnDependencyGraphDiagram.js +174 -0
  199. package/built/src/utils/cfn/drawio/cfnDependencyGraphDiagram.js.map +1 -0
  200. package/built/src/utils/cfn/drawio/commonCells.d.ts +22 -0
  201. package/built/src/utils/cfn/drawio/commonCells.js +83 -0
  202. package/built/src/utils/cfn/drawio/commonCells.js.map +1 -0
  203. package/built/src/utils/cfn/drawio/edgeRouting.d.ts +34 -0
  204. package/built/src/utils/cfn/drawio/edgeRouting.js +77 -0
  205. package/built/src/utils/cfn/drawio/edgeRouting.js.map +1 -0
  206. package/built/src/utils/cfn/drawio/multiAzInfrastructureDiagram.d.ts +3 -0
  207. package/built/src/utils/cfn/drawio/multiAzInfrastructureDiagram.js +812 -0
  208. package/built/src/utils/cfn/drawio/multiAzInfrastructureDiagram.js.map +1 -0
  209. package/built/src/utils/cfn/drawioApplicationDiagram.d.ts +3 -0
  210. package/built/src/utils/cfn/drawioApplicationDiagram.js +455 -0
  211. package/built/src/utils/cfn/drawioApplicationDiagram.js.map +1 -0
  212. package/built/src/utils/cfn/drawioInfrastructureDiagrams.d.ts +2 -0
  213. package/built/src/utils/cfn/drawioInfrastructureDiagrams.js +10 -0
  214. package/built/src/utils/cfn/drawioInfrastructureDiagrams.js.map +1 -0
  215. package/built/src/utils/cfn/drawioXml.d.ts +1 -0
  216. package/built/src/utils/cfn/drawioXml.js +11 -0
  217. package/built/src/utils/cfn/drawioXml.js.map +1 -0
  218. package/built/src/utils/cfn/generateDiagram.d.ts +2 -0
  219. package/built/src/utils/cfn/generateDiagram.js +22 -0
  220. package/built/src/utils/cfn/generateDiagram.js.map +1 -0
  221. package/built/src/utils/cfn/icons.d.ts +1 -0
  222. package/built/src/utils/cfn/icons.js +60 -0
  223. package/built/src/utils/cfn/icons.js.map +1 -0
  224. package/built/src/utils/cfn/index.d.ts +11 -0
  225. package/built/src/utils/cfn/index.js +34 -0
  226. package/built/src/utils/cfn/index.js.map +1 -0
  227. package/built/src/utils/cfn/intrinsics.d.ts +12 -0
  228. package/built/src/utils/cfn/intrinsics.js +158 -0
  229. package/built/src/utils/cfn/intrinsics.js.map +1 -0
  230. package/built/src/utils/cfn/mermaidFlowchart.d.ts +3 -0
  231. package/built/src/utils/cfn/mermaidFlowchart.js +14 -0
  232. package/built/src/utils/cfn/mermaidFlowchart.js.map +1 -0
  233. package/built/src/utils/cfn/multiAzDeploymentTrafficPathsAndProtection.d.ts +27 -0
  234. package/built/src/utils/cfn/multiAzDeploymentTrafficPathsAndProtection.js +409 -0
  235. package/built/src/utils/cfn/multiAzDeploymentTrafficPathsAndProtection.js.map +1 -0
  236. package/built/src/utils/cfn/multiAzDeploymentTrafficPathsAndProtectionDiagram.d.ts +2 -0
  237. package/built/src/utils/cfn/multiAzDeploymentTrafficPathsAndProtectionDiagram.js +286 -0
  238. package/built/src/utils/cfn/multiAzDeploymentTrafficPathsAndProtectionDiagram.js.map +1 -0
  239. package/built/src/utils/cfn/naming.d.ts +7 -0
  240. package/built/src/utils/cfn/naming.js +33 -0
  241. package/built/src/utils/cfn/naming.js.map +1 -0
  242. package/built/src/utils/cfn/resourceDependencies.d.ts +2 -0
  243. package/built/src/utils/cfn/resourceDependencies.js +33 -0
  244. package/built/src/utils/cfn/resourceDependencies.js.map +1 -0
  245. package/built/src/utils/cfn/templateParsing.d.ts +3 -0
  246. package/built/src/utils/cfn/templateParsing.js +58 -0
  247. package/built/src/utils/cfn/templateParsing.js.map +1 -0
  248. package/built/src/utils/cfn/viewpoints.d.ts +3 -0
  249. package/built/src/utils/cfn/viewpoints.js +122 -0
  250. package/built/src/utils/cfn/viewpoints.js.map +1 -0
  251. package/built/src/utils/csv.js.map +1 -1
  252. package/built/src/utils/dbType.js.map +1 -1
  253. package/built/src/utils/diagramLayout/elkLayoutEngine.d.ts +3 -0
  254. package/built/src/utils/diagramLayout/elkLayoutEngine.js +199 -0
  255. package/built/src/utils/diagramLayout/elkLayoutEngine.js.map +1 -0
  256. package/built/src/utils/diagramLayout/index.d.ts +4 -0
  257. package/built/src/utils/diagramLayout/index.js +13 -0
  258. package/built/src/utils/diagramLayout/index.js.map +1 -0
  259. package/built/src/utils/diagramLayout/normalizeLayout.d.ts +33 -0
  260. package/built/src/utils/diagramLayout/normalizeLayout.js +116 -0
  261. package/built/src/utils/diagramLayout/normalizeLayout.js.map +1 -0
  262. package/built/src/utils/diagramLayout/types.d.ts +64 -0
  263. package/built/src/utils/diagramLayout/types.js +3 -0
  264. package/built/src/utils/diagramLayout/types.js.map +1 -0
  265. package/built/src/utils/drawio/drawioXml.d.ts +24 -0
  266. package/built/src/utils/drawio/drawioXml.js +47 -0
  267. package/built/src/utils/drawio/drawioXml.js.map +1 -0
  268. package/built/src/utils/drawio/index.d.ts +2 -0
  269. package/built/src/utils/drawio/index.js +10 -0
  270. package/built/src/utils/drawio/index.js.map +1 -0
  271. package/built/src/utils/driverUtil.d.ts +1 -1
  272. package/built/src/utils/driverUtil.js.map +1 -1
  273. package/built/src/utils/er/erDiagramDrawioGenerator.d.ts +26 -0
  274. package/built/src/utils/er/erDiagramDrawioGenerator.js +99 -0
  275. package/built/src/utils/er/erDiagramDrawioGenerator.js.map +1 -0
  276. package/built/src/utils/er/erDiagramDrawioGeneratorAuto.d.ts +2 -0
  277. package/built/src/utils/er/erDiagramDrawioGeneratorAuto.js +103 -0
  278. package/built/src/utils/er/erDiagramDrawioGeneratorAuto.js.map +1 -0
  279. package/built/src/utils/er/erDiagramGenerator.d.ts +7 -0
  280. package/built/src/utils/er/erDiagramGenerator.js +321 -0
  281. package/built/src/utils/er/erDiagramGenerator.js.map +1 -0
  282. package/built/src/utils/er/index.d.ts +4 -0
  283. package/built/src/utils/er/index.js +13 -0
  284. package/built/src/utils/er/index.js.map +1 -0
  285. package/built/src/utils/er/types.d.ts +31 -0
  286. package/built/src/utils/er/types.js +3 -0
  287. package/built/src/utils/er/types.js.map +1 -0
  288. package/built/src/utils/index.d.ts +2 -0
  289. package/built/src/utils/index.js +2 -0
  290. package/built/src/utils/index.js.map +1 -1
  291. package/built/src/utils/log/LogParser.js.map +1 -1
  292. package/built/src/utils/log/buildSqlExecutions.js +3 -4
  293. package/built/src/utils/log/buildSqlExecutions.js.map +1 -1
  294. package/built/src/utils/log/classify/classifyEvent.js +2 -3
  295. package/built/src/utils/log/classify/classifyEvent.js.map +1 -1
  296. package/built/src/utils/log/detect/presetDetector.js +4 -5
  297. package/built/src/utils/log/detect/presetDetector.js.map +1 -1
  298. package/built/src/utils/log/extract/runExtractors.js +1 -2
  299. package/built/src/utils/log/extract/runExtractors.js.map +1 -1
  300. package/built/src/utils/log/logSummary.js +5 -5
  301. package/built/src/utils/log/logSummary.js.map +1 -1
  302. package/built/src/utils/log/pattern/logEventPattern.js +2 -3
  303. package/built/src/utils/log/pattern/logEventPattern.js.map +1 -1
  304. package/built/src/utils/log/rdh/convertExtractedSqlRdhResult.js +2 -3
  305. package/built/src/utils/log/rdh/convertExtractedSqlRdhResult.js.map +1 -1
  306. package/built/src/utils/log/split/splitLogEvents.js +1 -2
  307. package/built/src/utils/log/split/splitLogEvents.js.map +1 -1
  308. package/built/src/utils/log/sql/removeSqlComments.js +2 -3
  309. package/built/src/utils/log/sql/removeSqlComments.js.map +1 -1
  310. package/built/src/utils/log/validator.js +8 -5
  311. package/built/src/utils/log/validator.js.map +1 -1
  312. package/package.json +21 -9
  313. package/built/src/resource/DbResource.d.ts +0 -355
  314. package/built/src/resource/DbResource.js +0 -755
  315. package/built/src/resource/DbResource.js.map +0 -1
@@ -0,0 +1,637 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CfnDeploymentTopologyStructure = void 0;
4
+ const intrinsics_1 = require("./intrinsics");
5
+ const naming_1 = require("./naming");
6
+ const sortSubnets = (a, b) => {
7
+ const priority = {
8
+ public: 0,
9
+ private: 1,
10
+ isolated: 2,
11
+ };
12
+ return priority[a.connectivity] - priority[b.connectivity] ||
13
+ a.cidrBlock.localeCompare(b.cidrBlock);
14
+ };
15
+ const uniqueByIdentity = (values) => Array.from(new Map(values.map((value) => [
16
+ `${value.fileIndex}:${value.logicalId}`,
17
+ value,
18
+ ])).values());
19
+ const displayProperty = (value) => {
20
+ const resolved = (0, intrinsics_1.resolveCfnString)(value);
21
+ if (resolved !== undefined)
22
+ return resolved;
23
+ if (value === undefined || value === null)
24
+ return undefined;
25
+ const serialized = JSON.stringify(value);
26
+ return serialized.length > 80 ? `${serialized.slice(0, 77)}...` : serialized;
27
+ };
28
+ const resolveInteger = (value) => {
29
+ if (typeof value === 'number' && Number.isFinite(value))
30
+ return value;
31
+ const resolved = typeof value === 'string' ? value : (0, intrinsics_1.resolveCfnString)(value);
32
+ if (resolved === undefined || !/^\d+$/.test(resolved))
33
+ return undefined;
34
+ return Number(resolved);
35
+ };
36
+ const pluralize = (count, noun) => `${count} ${noun}${count === 1 ? '' : 's'}`;
37
+ const buildElastiCacheReplicationGroupTraits = (properties) => {
38
+ const traits = [];
39
+ if ((properties === null || properties === void 0 ? void 0 : properties.MultiAZEnabled) === true)
40
+ traits.push('Multi-AZ');
41
+ if ((properties === null || properties === void 0 ? void 0 : properties.AutomaticFailoverEnabled) === true)
42
+ traits.push('automatic failover');
43
+ const numNodeGroups = resolveInteger(properties === null || properties === void 0 ? void 0 : properties.NumNodeGroups);
44
+ const replicasPerNodeGroup = resolveInteger(properties === null || properties === void 0 ? void 0 : properties.ReplicasPerNodeGroup);
45
+ if (numNodeGroups !== undefined) {
46
+ traits.push(replicasPerNodeGroup !== undefined
47
+ ? `${pluralize(numNodeGroups, 'shard')} · ${pluralize(replicasPerNodeGroup, 'replica')} per shard`
48
+ : pluralize(numNodeGroups, 'shard'));
49
+ }
50
+ else {
51
+ const numCacheClusters = resolveInteger(properties === null || properties === void 0 ? void 0 : properties.NumCacheClusters);
52
+ if (numCacheClusters !== undefined)
53
+ traits.push(pluralize(numCacheClusters, 'cache node'));
54
+ }
55
+ return traits;
56
+ };
57
+ const listenerRuleConditions = (conditions) => {
58
+ if (!Array.isArray(conditions))
59
+ return [];
60
+ return conditions.flatMap((condition) => {
61
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
62
+ const field = (_a = displayProperty(condition === null || condition === void 0 ? void 0 : condition.Field)) !== null && _a !== void 0 ? _a : 'condition';
63
+ const values = (_k = (_h = (_f = (_d = (_b = condition === null || condition === void 0 ? void 0 : condition.Values) !== null && _b !== void 0 ? _b : (_c = condition === null || condition === void 0 ? void 0 : condition.PathPatternConfig) === null || _c === void 0 ? void 0 : _c.Values) !== null && _d !== void 0 ? _d : (_e = condition === null || condition === void 0 ? void 0 : condition.HostHeaderConfig) === null || _e === void 0 ? void 0 : _e.Values) !== null && _f !== void 0 ? _f : (_g = condition === null || condition === void 0 ? void 0 : condition.HttpHeaderConfig) === null || _g === void 0 ? void 0 : _g.Values) !== null && _h !== void 0 ? _h : (_j = condition === null || condition === void 0 ? void 0 : condition.QueryStringConfig) === null || _j === void 0 ? void 0 : _j.Values) !== null && _k !== void 0 ? _k : (_l = condition === null || condition === void 0 ? void 0 : condition.SourceIpConfig) === null || _l === void 0 ? void 0 : _l.Values;
64
+ if (!Array.isArray(values) || values.length === 0)
65
+ return [field];
66
+ return [`${field}: ${values.map((value) => { var _a; return (_a = displayProperty(value)) !== null && _a !== void 0 ? _a : '?'; }).join(', ')}`];
67
+ });
68
+ };
69
+ const resolutionContextFor = (file) => ({
70
+ parameters: file.cfnTemplate.Parameters,
71
+ parameterValues: file.parameterValues,
72
+ pseudoParameters: Object.assign({ 'AWS::StackName': file.groupName }, file.pseudoParameterValues),
73
+ });
74
+ const availabilityZoneName = (value, file) => {
75
+ var _a, _b, _c, _d, _e;
76
+ if (typeof value === 'string')
77
+ return value;
78
+ const resolutionContext = resolutionContextFor(file);
79
+ const resolved = (0, intrinsics_1.resolveCfnString)(value, resolutionContext);
80
+ if (resolved)
81
+ return resolved;
82
+ const select = (_a = value === null || value === void 0 ? void 0 : value['Fn::Select']) !== null && _a !== void 0 ? _a : value === null || value === void 0 ? void 0 : value['!Select'];
83
+ if (Array.isArray(select) && select.length >= 2) {
84
+ const index = (0, intrinsics_1.resolveCfnString)(select[0], resolutionContext);
85
+ const getAzs = (_c = (_b = select[1]) === null || _b === void 0 ? void 0 : _b['Fn::GetAZs']) !== null && _c !== void 0 ? _c : (_d = select[1]) === null || _d === void 0 ? void 0 : _d['!GetAZs'];
86
+ if (index !== undefined && getAzs !== undefined) {
87
+ const selectedRegion = (0, intrinsics_1.resolveCfnString)(getAzs, resolutionContext);
88
+ const region = selectedRegion || ((_e = file.pseudoParameterValues) === null || _e === void 0 ? void 0 : _e['AWS::Region']);
89
+ return region
90
+ ? `${region} AZ index ${index}`
91
+ : `Availability Zone index ${index}`;
92
+ }
93
+ }
94
+ return value ? JSON.stringify(value) : 'unspecified';
95
+ };
96
+ class CfnDeploymentTopologyStructure {
97
+ constructor(diagramFiles) {
98
+ this.diagramFiles = diagramFiles;
99
+ this.vpcs = [];
100
+ this.standaloneResources = [];
101
+ diagramFiles.forEach((file) => this.collectVpcs(file));
102
+ diagramFiles.forEach((file) => this.collectSubnets(file));
103
+ diagramFiles.forEach((file) => this.classifySubnetConnectivity(file));
104
+ diagramFiles.forEach((file) => this.attachSubnetAndVpcResources(file));
105
+ diagramFiles.forEach((file) => this.attachInternetGateway(file));
106
+ diagramFiles.forEach((file) => this.collectLoadBalancers(file));
107
+ }
108
+ getResourceFrom(reference) {
109
+ const normalized = this.normalizeRef(reference.logicalId.rawValue, reference.sourceFileIndex);
110
+ for (const vpc of this.vpcs) {
111
+ for (const resource of vpc.resources) {
112
+ if (this.resourceMatches(resource, normalized, reference.sourceFileIndex)) {
113
+ return { vpc, resource };
114
+ }
115
+ }
116
+ for (const az of vpc.availabilityZones) {
117
+ for (const subnet of az.subnets) {
118
+ const resource = subnet.resources.find((candidate) => this.resourceMatches(candidate, normalized, reference.sourceFileIndex));
119
+ if (resource)
120
+ return { vpc, subnet, resource };
121
+ }
122
+ }
123
+ }
124
+ return undefined;
125
+ }
126
+ collectVpcs(file) {
127
+ Object.entries(file.cfnTemplate.Resources)
128
+ .filter(([, resource]) => resource.Type === 'AWS::EC2::VPC')
129
+ .forEach(([logicalId, resource]) => {
130
+ this.vpcs.push({
131
+ fileIndex: file.fileIndex,
132
+ logicalId,
133
+ cidrBlock: (0, naming_1.getCidrBlock)(resource.Properties, resolutionContextFor(file)),
134
+ availabilityZones: [],
135
+ resources: [],
136
+ loadBalancers: [],
137
+ natGateways: [],
138
+ });
139
+ });
140
+ file.outputs.forEach((output) => {
141
+ const vpc = this.vpcs.find((candidate) => candidate.fileIndex === file.fileIndex &&
142
+ candidate.logicalId === output.value.logicalId);
143
+ if (vpc && output.export.rawName)
144
+ vpc.exportedName = output.export.rawName;
145
+ });
146
+ }
147
+ collectSubnets(file) {
148
+ Object.entries(file.cfnTemplate.Resources)
149
+ .filter(([, resource]) => resource.Type === 'AWS::EC2::Subnet')
150
+ .forEach(([logicalId, resource]) => {
151
+ var _a;
152
+ const vpc = this.getVpc(this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.VpcId, file.fileIndex), file.fileIndex);
153
+ if (!vpc) {
154
+ console.warn(`VPC not found for subnet ${file.fileName}:${logicalId}.`);
155
+ return;
156
+ }
157
+ const az = this.getOrCreateAvailabilityZone(vpc, resource, file);
158
+ az.subnets.push({
159
+ fileIndex: file.fileIndex,
160
+ logicalId,
161
+ connectivity: 'isolated',
162
+ cidrBlock: (0, naming_1.getCidrBlock)(resource.Properties, resolutionContextFor(file)),
163
+ resources: [],
164
+ });
165
+ });
166
+ file.outputs.forEach((output) => {
167
+ const subnet = this.allSubnets().find((candidate) => candidate.fileIndex === file.fileIndex &&
168
+ candidate.logicalId === output.value.logicalId);
169
+ if (subnet && output.export.rawName)
170
+ subnet.exportedName = output.export.rawName;
171
+ });
172
+ }
173
+ getOrCreateAvailabilityZone(vpc, subnetResource, file) {
174
+ var _a;
175
+ const availabilityZone = (_a = subnetResource.Properties) === null || _a === void 0 ? void 0 : _a.AvailabilityZone;
176
+ const azName = availabilityZoneName(availabilityZone, file);
177
+ const azId = (0, naming_1.sanitizeLogicalId)(azName);
178
+ let az = vpc.availabilityZones.find((candidate) => candidate.id === azId);
179
+ if (!az) {
180
+ az = { id: azId, name: azName, subnets: [] };
181
+ vpc.availabilityZones.push(az);
182
+ }
183
+ return az;
184
+ }
185
+ classifySubnetConnectivity(file) {
186
+ const resources = file.cfnTemplate.Resources;
187
+ Object.values(resources)
188
+ .filter((resource) => resource.Type === 'AWS::EC2::SubnetRouteTableAssociation')
189
+ .forEach((association) => {
190
+ var _a, _b, _c, _d, _e;
191
+ const subnet = this.getSubnet(this.normalizeRef((_a = association.Properties) === null || _a === void 0 ? void 0 : _a.SubnetId, file.fileIndex), file.fileIndex);
192
+ const routeTableRef = this.normalizeRef((_b = association.Properties) === null || _b === void 0 ? void 0 : _b.RouteTableId, file.fileIndex);
193
+ if (!subnet || routeTableRef.type === 'ImportValue')
194
+ return;
195
+ const routes = Object.values(resources).filter((resource) => {
196
+ var _a, _b, _c;
197
+ return resource.Type === 'AWS::EC2::Route' &&
198
+ this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.RouteTableId, file.fileIndex).value === routeTableRef.value &&
199
+ (((_b = resource.Properties) === null || _b === void 0 ? void 0 : _b.DestinationCidrBlock) === '0.0.0.0/0' ||
200
+ ((_c = resource.Properties) === null || _c === void 0 ? void 0 : _c.DestinationIpv6CidrBlock) === '::/0');
201
+ });
202
+ const internetRoute = routes.find((route) => {
203
+ var _a;
204
+ const gatewayValue = (_a = route.Properties) === null || _a === void 0 ? void 0 : _a.GatewayId;
205
+ if (typeof gatewayValue === 'string')
206
+ return gatewayValue.startsWith('igw-');
207
+ const gateway = this.findTemplateResource(this.normalizeRef(gatewayValue, file.fileIndex), file.fileIndex);
208
+ return (gateway === null || gateway === void 0 ? void 0 : gateway.detail.Type) === 'AWS::EC2::InternetGateway';
209
+ });
210
+ const natRoute = routes.find((route) => { var _a; return ((_a = route.Properties) === null || _a === void 0 ? void 0 : _a.NatGatewayId) !== undefined; });
211
+ const egressOnlyRoute = routes.find((route) => { var _a; return ((_a = route.Properties) === null || _a === void 0 ? void 0 : _a.EgressOnlyInternetGatewayId) !== undefined; });
212
+ if (internetRoute) {
213
+ subnet.connectivity = 'public';
214
+ const gatewayRef = this.normalizeRef((_c = internetRoute.Properties) === null || _c === void 0 ? void 0 : _c.GatewayId, file.fileIndex);
215
+ subnet.defaultRoute = {
216
+ kind: 'internet-gateway',
217
+ fileIndex: file.fileIndex,
218
+ logicalId: gatewayRef.value || undefined,
219
+ };
220
+ }
221
+ else if (natRoute) {
222
+ subnet.connectivity = 'private';
223
+ const natRef = this.normalizeRef((_d = natRoute.Properties) === null || _d === void 0 ? void 0 : _d.NatGatewayId, file.fileIndex);
224
+ subnet.defaultRoute = {
225
+ kind: 'nat-gateway',
226
+ fileIndex: file.fileIndex,
227
+ logicalId: natRef.value || undefined,
228
+ };
229
+ }
230
+ else if (egressOnlyRoute) {
231
+ subnet.connectivity = 'private';
232
+ const gatewayRef = this.normalizeRef((_e = egressOnlyRoute.Properties) === null || _e === void 0 ? void 0 : _e.EgressOnlyInternetGatewayId, file.fileIndex);
233
+ subnet.defaultRoute = {
234
+ kind: 'egress-only-internet-gateway',
235
+ fileIndex: file.fileIndex,
236
+ logicalId: gatewayRef.value || undefined,
237
+ };
238
+ }
239
+ else {
240
+ subnet.connectivity = 'isolated';
241
+ subnet.defaultRoute = undefined;
242
+ }
243
+ });
244
+ this.vpcs.forEach((vpc) => vpc.availabilityZones.forEach((az) => az.subnets.sort(sortSubnets)));
245
+ }
246
+ attachSubnetAndVpcResources(file) {
247
+ Object.entries(file.cfnTemplate.Resources).forEach(([logicalId, resource]) => {
248
+ switch (resource.Type) {
249
+ case 'AWS::EC2::Instance':
250
+ this.attachEc2Instance(file, logicalId, resource);
251
+ break;
252
+ case 'AWS::EC2::NatGateway':
253
+ this.attachNatGateway(file, logicalId, resource);
254
+ break;
255
+ case 'AWS::RDS::DBInstance':
256
+ case 'AWS::RDS::DBCluster':
257
+ this.attachDatabase(file, logicalId, resource);
258
+ break;
259
+ case 'AWS::ECS::Service':
260
+ this.attachEcsService(file, logicalId, resource);
261
+ break;
262
+ case 'AWS::ElastiCache::ReplicationGroup':
263
+ this.attachElastiCacheReplicationGroup(file, logicalId, resource);
264
+ break;
265
+ case 'AWS::AutoScaling::AutoScalingGroup':
266
+ this.attachAutoScalingGroup(file, logicalId, resource);
267
+ break;
268
+ }
269
+ });
270
+ }
271
+ attachEc2Instance(file, logicalId, resource) {
272
+ var _a, _b, _c, _d, _e;
273
+ const subnetValue = (_b = (_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.SubnetId) !== null && _b !== void 0 ? _b : (_e = (_d = (_c = resource.Properties) === null || _c === void 0 ? void 0 : _c.NetworkInterfaces) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.SubnetId;
274
+ const subnet = this.getSubnet(this.normalizeRef(subnetValue, file.fileIndex), file.fileIndex);
275
+ if (!subnet) {
276
+ this.addStandalone(file, logicalId, resource, 'EC2 Instance has no resolvable subnet');
277
+ return;
278
+ }
279
+ subnet.resources.push(this.topologyResource(file, logicalId, resource));
280
+ }
281
+ attachNatGateway(file, logicalId, resource) {
282
+ var _a;
283
+ const subnet = this.getSubnet(this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.SubnetId, file.fileIndex), file.fileIndex);
284
+ if (!subnet)
285
+ return;
286
+ const vpc = this.vpcForSubnet(subnet);
287
+ if (!vpc)
288
+ return;
289
+ const topologyResource = this.topologyResource(file, logicalId, resource);
290
+ subnet.resources.push(topologyResource);
291
+ vpc.natGateways.push({ fileIndex: file.fileIndex, logicalId, subnet });
292
+ }
293
+ attachDatabase(file, logicalId, resource) {
294
+ var _a, _b, _c;
295
+ const subnetGroupRef = this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.DBSubnetGroupName, file.fileIndex);
296
+ const subnetGroup = this.findTemplateResource(subnetGroupRef, file.fileIndex);
297
+ const subnetIds = (_b = subnetGroup === null || subnetGroup === void 0 ? void 0 : subnetGroup.detail.Properties) === null || _b === void 0 ? void 0 : _b.SubnetIds;
298
+ if (!subnetGroup || !Array.isArray(subnetIds)) {
299
+ this.addStandalone(file, logicalId, resource, 'database has no resolvable DB subnet group');
300
+ return;
301
+ }
302
+ const subnets = subnetIds
303
+ .map((value) => this.getSubnet(this.normalizeRef(value, subnetGroup.file.fileIndex), subnetGroup.file.fileIndex))
304
+ .filter((subnet) => Boolean(subnet));
305
+ const vpcs = uniqueByIdentity(subnets.flatMap((subnet) => {
306
+ const vpc = this.vpcForSubnet(subnet);
307
+ return vpc ? [vpc] : [];
308
+ }));
309
+ if (subnets.length === 0 || vpcs.length !== 1) {
310
+ this.addStandalone(file, logicalId, resource, 'database subnet group does not resolve to one VPC');
311
+ return;
312
+ }
313
+ vpcs[0].resources.push(Object.assign(Object.assign({}, this.topologyResource(file, logicalId, resource)), { placement: `DB subnet group ${subnetGroup.logicalId}: ${subnets.length} candidate subnets`, candidateSubnets: subnets, multiAz: ((_c = resource.Properties) === null || _c === void 0 ? void 0 : _c.MultiAZ) === true || resource.Type === 'AWS::RDS::DBCluster', traits: resource.Type === 'AWS::RDS::DBCluster'
314
+ ? this.databaseClusterTraits(file, logicalId, resource)
315
+ : undefined }));
316
+ }
317
+ databaseClusterTraits(file, logicalId, resource) {
318
+ var _a, _b;
319
+ const memberCount = Object.values(file.cfnTemplate.Resources).filter((candidate) => {
320
+ var _a;
321
+ return candidate.Type === 'AWS::RDS::DBInstance' &&
322
+ this.normalizeRef((_a = candidate.Properties) === null || _a === void 0 ? void 0 : _a.DBClusterIdentifier, file.fileIndex).value === logicalId;
323
+ }).length;
324
+ const traits = memberCount > 0 ? [pluralize(memberCount, 'DB instance')] : [];
325
+ const engine = (_b = displayProperty((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.Engine)) === null || _b === void 0 ? void 0 : _b.toLowerCase();
326
+ if (engine === null || engine === void 0 ? void 0 : engine.startsWith('aurora'))
327
+ traits.push('writer/reader roles dynamic');
328
+ return traits;
329
+ }
330
+ attachEcsService(file, logicalId, resource) {
331
+ var _a, _b, _c;
332
+ const subnetValues = (_c = (_b = (_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.NetworkConfiguration) === null || _b === void 0 ? void 0 : _b.AwsvpcConfiguration) === null || _c === void 0 ? void 0 : _c.Subnets;
333
+ if (!Array.isArray(subnetValues))
334
+ return;
335
+ const subnets = subnetValues
336
+ .map((value) => this.getSubnet(this.normalizeRef(value, file.fileIndex), file.fileIndex))
337
+ .filter((subnet) => Boolean(subnet));
338
+ const vpcs = uniqueByIdentity(subnets.flatMap((subnet) => {
339
+ const vpc = this.vpcForSubnet(subnet);
340
+ return vpc ? [vpc] : [];
341
+ }));
342
+ if (vpcs.length !== 1)
343
+ return;
344
+ vpcs[0].resources.push(Object.assign(Object.assign({}, this.topologyResource(file, logicalId, resource)), { placement: `ECS service: ${subnets.length} configured subnets`, candidateSubnets: subnets }));
345
+ }
346
+ attachElastiCacheReplicationGroup(file, logicalId, resource) {
347
+ var _a, _b;
348
+ const subnetGroupRef = this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.CacheSubnetGroupName, file.fileIndex);
349
+ const subnetGroup = this.findTemplateResource(subnetGroupRef, file.fileIndex);
350
+ const subnetIds = (_b = subnetGroup === null || subnetGroup === void 0 ? void 0 : subnetGroup.detail.Properties) === null || _b === void 0 ? void 0 : _b.SubnetIds;
351
+ if (!subnetGroup ||
352
+ subnetGroup.detail.Type !== 'AWS::ElastiCache::SubnetGroup' ||
353
+ !Array.isArray(subnetIds)) {
354
+ this.addStandalone(file, logicalId, resource, 'ElastiCache replication group has no resolvable cache subnet group');
355
+ return;
356
+ }
357
+ const subnets = subnetIds
358
+ .map((value) => this.getSubnet(this.normalizeRef(value, subnetGroup.file.fileIndex), subnetGroup.file.fileIndex))
359
+ .filter((subnet) => Boolean(subnet));
360
+ const vpcs = uniqueByIdentity(subnets.flatMap((subnet) => {
361
+ const vpc = this.vpcForSubnet(subnet);
362
+ return vpc ? [vpc] : [];
363
+ }));
364
+ if (subnets.length === 0 || vpcs.length !== 1) {
365
+ this.addStandalone(file, logicalId, resource, 'ElastiCache cache subnet group does not resolve to one VPC');
366
+ return;
367
+ }
368
+ vpcs[0].resources.push(Object.assign(Object.assign({}, this.topologyResource(file, logicalId, resource)), { placement: `Cache subnet group ${subnetGroup.logicalId}: ${subnets.length} candidate subnets`, candidateSubnets: subnets, traits: buildElastiCacheReplicationGroupTraits(resource.Properties) }));
369
+ }
370
+ attachAutoScalingGroup(file, logicalId, resource) {
371
+ var _a, _b, _c, _d;
372
+ const subnetValues = (_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.VPCZoneIdentifier;
373
+ if (!Array.isArray(subnetValues)) {
374
+ this.addStandalone(file, logicalId, resource, 'Auto Scaling Group has no resolvable VPCZoneIdentifier');
375
+ return;
376
+ }
377
+ const subnets = subnetValues
378
+ .map((value) => this.getSubnet(this.normalizeRef(value, file.fileIndex), file.fileIndex))
379
+ .filter((subnet) => Boolean(subnet));
380
+ const vpcs = uniqueByIdentity(subnets.flatMap((subnet) => {
381
+ const vpc = this.vpcForSubnet(subnet);
382
+ return vpc ? [vpc] : [];
383
+ }));
384
+ if (subnets.length === 0 || vpcs.length !== 1) {
385
+ this.addStandalone(file, logicalId, resource, 'Auto Scaling Group VPCZoneIdentifier does not resolve to one VPC');
386
+ return;
387
+ }
388
+ vpcs[0].resources.push(Object.assign(Object.assign({}, this.topologyResource(file, logicalId, resource)), { placement: `Auto Scaling group: ${subnets.length} configured subnets`, candidateSubnets: subnets, traits: [
389
+ ['desired', resolveInteger((_b = resource.Properties) === null || _b === void 0 ? void 0 : _b.DesiredCapacity)],
390
+ ['min', resolveInteger((_c = resource.Properties) === null || _c === void 0 ? void 0 : _c.MinSize)],
391
+ ['max', resolveInteger((_d = resource.Properties) === null || _d === void 0 ? void 0 : _d.MaxSize)],
392
+ ].flatMap(([label, value]) => value === undefined ? [] : [`${label} ${value}`]) }));
393
+ }
394
+ attachInternetGateway(file) {
395
+ Object.values(file.cfnTemplate.Resources)
396
+ .filter((resource) => resource.Type === 'AWS::EC2::VPCGatewayAttachment')
397
+ .forEach((attachment) => {
398
+ var _a, _b;
399
+ const vpc = this.getVpc(this.normalizeRef((_a = attachment.Properties) === null || _a === void 0 ? void 0 : _a.VpcId, file.fileIndex), file.fileIndex);
400
+ const gateway = this.findTemplateResource(this.normalizeRef((_b = attachment.Properties) === null || _b === void 0 ? void 0 : _b.InternetGatewayId, file.fileIndex), file.fileIndex);
401
+ if (vpc && (gateway === null || gateway === void 0 ? void 0 : gateway.detail.Type) === 'AWS::EC2::InternetGateway') {
402
+ vpc.igw = {
403
+ fileIndex: gateway.file.fileIndex,
404
+ logicalId: gateway.logicalId,
405
+ };
406
+ }
407
+ });
408
+ }
409
+ collectLoadBalancers(file) {
410
+ Object.entries(file.cfnTemplate.Resources)
411
+ .filter(([, resource]) => resource.Type === 'AWS::ElasticLoadBalancingV2::LoadBalancer')
412
+ .forEach(([logicalId, resource]) => {
413
+ var _a, _b, _c, _d, _e;
414
+ const subnetValues = (_b = (_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.Subnets) !== null && _b !== void 0 ? _b : (_d = (_c = resource.Properties) === null || _c === void 0 ? void 0 : _c.SubnetMappings) === null || _d === void 0 ? void 0 : _d.map((mapping) => mapping.SubnetId);
415
+ if (!Array.isArray(subnetValues))
416
+ return;
417
+ const subnets = subnetValues
418
+ .map((value) => this.getSubnet(this.normalizeRef(value, file.fileIndex), file.fileIndex))
419
+ .filter((subnet) => Boolean(subnet));
420
+ const vpcs = uniqueByIdentity(subnets.flatMap((subnet) => {
421
+ const vpc = this.vpcForSubnet(subnet);
422
+ return vpc ? [vpc] : [];
423
+ }));
424
+ if (vpcs.length !== 1)
425
+ return;
426
+ const targetGroups = this.targetGroupsForLoadBalancer(file, logicalId);
427
+ vpcs[0].loadBalancers.push({
428
+ fileIndex: file.fileIndex,
429
+ logicalId,
430
+ internetFacing: ((_e = resource.Properties) === null || _e === void 0 ? void 0 : _e.Scheme) !== 'internal',
431
+ subnets,
432
+ targetGroups,
433
+ listeners: this.listenersForLoadBalancer(file, logicalId),
434
+ });
435
+ });
436
+ }
437
+ listenersForLoadBalancer(file, loadBalancerLogicalId) {
438
+ return Object.entries(file.cfnTemplate.Resources)
439
+ .filter(([, resource]) => {
440
+ var _a;
441
+ return resource.Type === 'AWS::ElasticLoadBalancingV2::Listener' &&
442
+ this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.LoadBalancerArn, file.fileIndex).value === loadBalancerLogicalId;
443
+ })
444
+ .map(([logicalId, listener]) => {
445
+ var _a, _b, _c;
446
+ const targetGroups = this.targetGroupsFromActions(file, Array.isArray((_a = listener.Properties) === null || _a === void 0 ? void 0 : _a.DefaultActions)
447
+ ? listener.Properties.DefaultActions
448
+ : []);
449
+ const rules = Object.entries(file.cfnTemplate.Resources)
450
+ .filter(([, resource]) => {
451
+ var _a;
452
+ return resource.Type === 'AWS::ElasticLoadBalancingV2::ListenerRule' &&
453
+ this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.ListenerArn, file.fileIndex).value === logicalId;
454
+ })
455
+ .map(([ruleLogicalId, rule]) => {
456
+ var _a, _b, _c;
457
+ return ({
458
+ fileIndex: file.fileIndex,
459
+ logicalId: ruleLogicalId,
460
+ conditions: listenerRuleConditions((_a = rule.Properties) === null || _a === void 0 ? void 0 : _a.Conditions),
461
+ priority: displayProperty((_b = rule.Properties) === null || _b === void 0 ? void 0 : _b.Priority),
462
+ targetGroups: this.targetGroupsFromActions(file, Array.isArray((_c = rule.Properties) === null || _c === void 0 ? void 0 : _c.Actions) ? rule.Properties.Actions : []),
463
+ });
464
+ });
465
+ return {
466
+ fileIndex: file.fileIndex,
467
+ logicalId,
468
+ protocol: displayProperty((_b = listener.Properties) === null || _b === void 0 ? void 0 : _b.Protocol),
469
+ port: displayProperty((_c = listener.Properties) === null || _c === void 0 ? void 0 : _c.Port),
470
+ targetGroups,
471
+ rules,
472
+ };
473
+ });
474
+ }
475
+ targetGroupsFromActions(file, actions) {
476
+ const targets = actions
477
+ .flatMap((action) => {
478
+ var _a;
479
+ return [
480
+ ...(action.TargetGroupArn ? [action.TargetGroupArn] : []),
481
+ ...(Array.isArray((_a = action.ForwardConfig) === null || _a === void 0 ? void 0 : _a.TargetGroups)
482
+ ? action.ForwardConfig.TargetGroups.flatMap((target) => target.TargetGroupArn ? [target.TargetGroupArn] : [])
483
+ : []),
484
+ ];
485
+ })
486
+ .map((value) => this.findTemplateResource(this.normalizeRef(value, file.fileIndex), file.fileIndex))
487
+ .filter((target) => Boolean(target && target.detail.Type === 'AWS::ElasticLoadBalancingV2::TargetGroup'));
488
+ return uniqueByIdentity(targets.map((target) => this.toTopologyTargetGroup(target)));
489
+ }
490
+ targetGroupsForLoadBalancer(file, loadBalancerLogicalId) {
491
+ const listeners = Object.entries(file.cfnTemplate.Resources)
492
+ .filter(([, resource]) => {
493
+ var _a;
494
+ return resource.Type === 'AWS::ElasticLoadBalancingV2::Listener' &&
495
+ this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.LoadBalancerArn, file.fileIndex).value === loadBalancerLogicalId;
496
+ });
497
+ const listenerIds = new Set(listeners.map(([logicalId]) => logicalId));
498
+ const listenerActions = listeners.flatMap(([, listener]) => {
499
+ var _a;
500
+ return Array.isArray((_a = listener.Properties) === null || _a === void 0 ? void 0 : _a.DefaultActions)
501
+ ? listener.Properties.DefaultActions
502
+ : [];
503
+ });
504
+ const listenerRuleActions = Object.values(file.cfnTemplate.Resources)
505
+ .filter((resource) => {
506
+ var _a;
507
+ return resource.Type === 'AWS::ElasticLoadBalancingV2::ListenerRule' &&
508
+ listenerIds.has(this.normalizeRef((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.ListenerArn, file.fileIndex).value);
509
+ })
510
+ .flatMap((rule) => { var _a; return Array.isArray((_a = rule.Properties) === null || _a === void 0 ? void 0 : _a.Actions) ? rule.Properties.Actions : []; });
511
+ const targetGroupResources = [...listenerActions, ...listenerRuleActions]
512
+ .flatMap((action) => {
513
+ var _a;
514
+ return [
515
+ ...(action.TargetGroupArn ? [action.TargetGroupArn] : []),
516
+ ...(Array.isArray((_a = action.ForwardConfig) === null || _a === void 0 ? void 0 : _a.TargetGroups)
517
+ ? action.ForwardConfig.TargetGroups.flatMap((target) => target.TargetGroupArn ? [target.TargetGroupArn] : [])
518
+ : []),
519
+ ];
520
+ })
521
+ .map((value) => this.findTemplateResource(this.normalizeRef(value, file.fileIndex), file.fileIndex))
522
+ .filter((target) => Boolean(target && target.detail.Type === 'AWS::ElasticLoadBalancingV2::TargetGroup'));
523
+ return uniqueByIdentity(targetGroupResources.map((targetGroup) => this.toTopologyTargetGroup(targetGroup)));
524
+ }
525
+ toTopologyTargetGroup(targetGroup) {
526
+ var _a, _b, _c, _d;
527
+ const staticTargets = Array.isArray((_a = targetGroup.detail.Properties) === null || _a === void 0 ? void 0 : _a.Targets)
528
+ ? targetGroup.detail.Properties.Targets.map((target) => ({
529
+ sourceFileIndex: targetGroup.file.fileIndex,
530
+ logicalId: this.normalizeRef(target.Id, targetGroup.file.fileIndex),
531
+ }))
532
+ : [];
533
+ const ecsTargets = this.diagramFiles.flatMap((candidateFile) => Object.entries(candidateFile.cfnTemplate.Resources).flatMap(([logicalId, resource]) => {
534
+ var _a;
535
+ if (resource.Type !== 'AWS::ECS::Service' || !Array.isArray((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.LoadBalancers)) {
536
+ return [];
537
+ }
538
+ const matches = resource.Properties.LoadBalancers.some((binding) => {
539
+ const resolved = this.findTemplateResource(this.normalizeRef(binding.TargetGroupArn, candidateFile.fileIndex), candidateFile.fileIndex);
540
+ return (resolved === null || resolved === void 0 ? void 0 : resolved.file.fileIndex) === targetGroup.file.fileIndex &&
541
+ resolved.logicalId === targetGroup.logicalId;
542
+ });
543
+ return matches ? [{
544
+ sourceFileIndex: candidateFile.fileIndex,
545
+ logicalId: this.normalizeRef({ Ref: logicalId }, candidateFile.fileIndex),
546
+ }] : [];
547
+ }));
548
+ const autoScalingTargets = this.diagramFiles.flatMap((candidateFile) => Object.entries(candidateFile.cfnTemplate.Resources).flatMap(([logicalId, resource]) => {
549
+ var _a;
550
+ if (resource.Type !== 'AWS::AutoScaling::AutoScalingGroup' ||
551
+ !Array.isArray((_a = resource.Properties) === null || _a === void 0 ? void 0 : _a.TargetGroupARNs))
552
+ return [];
553
+ const matches = resource.Properties.TargetGroupARNs.some((targetGroupArn) => {
554
+ const resolved = this.findTemplateResource(this.normalizeRef(targetGroupArn, candidateFile.fileIndex), candidateFile.fileIndex);
555
+ return (resolved === null || resolved === void 0 ? void 0 : resolved.file.fileIndex) === targetGroup.file.fileIndex &&
556
+ resolved.logicalId === targetGroup.logicalId;
557
+ });
558
+ return matches ? [{
559
+ sourceFileIndex: candidateFile.fileIndex,
560
+ logicalId: this.normalizeRef({ Ref: logicalId }, candidateFile.fileIndex),
561
+ }] : [];
562
+ }));
563
+ return {
564
+ fileIndex: targetGroup.file.fileIndex,
565
+ logicalId: targetGroup.logicalId,
566
+ protocol: displayProperty((_b = targetGroup.detail.Properties) === null || _b === void 0 ? void 0 : _b.Protocol),
567
+ port: displayProperty((_c = targetGroup.detail.Properties) === null || _c === void 0 ? void 0 : _c.Port),
568
+ targetType: displayProperty((_d = targetGroup.detail.Properties) === null || _d === void 0 ? void 0 : _d.TargetType),
569
+ targets: [...staticTargets, ...ecsTargets, ...autoScalingTargets],
570
+ };
571
+ }
572
+ topologyResource(file, logicalId, detail) {
573
+ var _a;
574
+ return {
575
+ fileIndex: file.fileIndex,
576
+ logicalId,
577
+ exportedName: (_a = file.outputs.find((output) => output.value.logicalId === logicalId)) === null || _a === void 0 ? void 0 : _a.export.rawName,
578
+ detail,
579
+ };
580
+ }
581
+ addStandalone(file, logicalId, detail, reason) {
582
+ console.warn(`${file.fileName}:${logicalId} ${reason} - rendering it standalone.`);
583
+ this.standaloneResources.push({ fileIndex: file.fileIndex, logicalId, detail });
584
+ }
585
+ normalizeRef(value, sourceFileIndex) {
586
+ var _a, _b;
587
+ const parsed = (0, intrinsics_1.parseRefValue)(value);
588
+ if (parsed.type !== 'ImportValue')
589
+ return parsed;
590
+ const importExpression = (_a = value === null || value === void 0 ? void 0 : value['Fn::ImportValue']) !== null && _a !== void 0 ? _a : value === null || value === void 0 ? void 0 : value['!ImportValue'];
591
+ const sourceFile = this.diagramFiles[sourceFileIndex];
592
+ return Object.assign(Object.assign({}, parsed), { value: (_b = (0, intrinsics_1.resolveCfnString)(importExpression, {
593
+ parameters: sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.cfnTemplate.Parameters,
594
+ parameterValues: sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.parameterValues,
595
+ pseudoParameters: sourceFile ? Object.assign({ 'AWS::StackName': sourceFile.groupName }, sourceFile.pseudoParameterValues) : undefined,
596
+ })) !== null && _b !== void 0 ? _b : parsed.value });
597
+ }
598
+ findTemplateResource(reference, sourceFileIndex) {
599
+ if (reference.type === 'ImportValue') {
600
+ for (const file of this.diagramFiles) {
601
+ const output = file.outputs.find((candidate) => candidate.export.rawName === reference.value);
602
+ if (output) {
603
+ const detail = file.cfnTemplate.Resources[output.value.logicalId];
604
+ if (detail)
605
+ return { file, logicalId: output.value.logicalId, detail };
606
+ }
607
+ }
608
+ return undefined;
609
+ }
610
+ const file = this.diagramFiles[sourceFileIndex];
611
+ const detail = file === null || file === void 0 ? void 0 : file.cfnTemplate.Resources[reference.value];
612
+ return detail ? { file, logicalId: reference.value, detail } : undefined;
613
+ }
614
+ getVpc(reference, sourceFileIndex) {
615
+ return this.vpcs.find((vpc) => reference.type === 'ImportValue'
616
+ ? vpc.exportedName === reference.value
617
+ : vpc.fileIndex === sourceFileIndex && vpc.logicalId === reference.value);
618
+ }
619
+ getSubnet(reference, sourceFileIndex) {
620
+ return this.allSubnets().find((subnet) => reference.type === 'ImportValue'
621
+ ? subnet.exportedName === reference.value
622
+ : subnet.fileIndex === sourceFileIndex && subnet.logicalId === reference.value);
623
+ }
624
+ resourceMatches(resource, reference, sourceFileIndex) {
625
+ return reference.type === 'ImportValue'
626
+ ? resource.exportedName === reference.value
627
+ : resource.fileIndex === sourceFileIndex && resource.logicalId === reference.value;
628
+ }
629
+ vpcForSubnet(target) {
630
+ return this.vpcs.find((vpc) => vpc.availabilityZones.some((az) => az.subnets.includes(target)));
631
+ }
632
+ allSubnets() {
633
+ return this.vpcs.flatMap((vpc) => vpc.availabilityZones.flatMap((az) => az.subnets));
634
+ }
635
+ }
636
+ exports.CfnDeploymentTopologyStructure = CfnDeploymentTopologyStructure;
637
+ //# sourceMappingURL=deploymentTopology.js.map