@quadnix/octo 0.0.30 → 0.1.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 (362) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +25 -3
  3. package/dist/app.type.d.ts +143 -4
  4. package/dist/app.type.js +80 -9
  5. package/dist/app.type.js.map +1 -1
  6. package/dist/decorators/action.decorator.d.ts +10 -6
  7. package/dist/decorators/action.decorator.js +19 -6
  8. package/dist/decorators/action.decorator.js.map +1 -1
  9. package/dist/decorators/anchor.decorator.d.ts +12 -5
  10. package/dist/decorators/anchor.decorator.js +12 -5
  11. package/dist/decorators/anchor.decorator.js.map +1 -1
  12. package/dist/decorators/enable-hook.decorator.d.ts +1 -1
  13. package/dist/decorators/enable-hook.decorator.js +1 -1
  14. package/dist/decorators/factory.decorator.d.ts +18 -34
  15. package/dist/decorators/factory.decorator.js +18 -34
  16. package/dist/decorators/factory.decorator.js.map +1 -1
  17. package/dist/decorators/model.decorator.d.ts +1 -1
  18. package/dist/decorators/model.decorator.js +1 -1
  19. package/dist/decorators/module.decorator.d.ts +16 -10
  20. package/dist/decorators/module.decorator.js +16 -10
  21. package/dist/decorators/module.decorator.js.map +1 -1
  22. package/dist/decorators/on-event.decorator.d.ts +5 -0
  23. package/dist/decorators/on-event.decorator.js +5 -0
  24. package/dist/decorators/on-event.decorator.js.map +1 -1
  25. package/dist/decorators/validate.decorator.d.ts +15 -1
  26. package/dist/decorators/validate.decorator.js +15 -1
  27. package/dist/decorators/validate.decorator.js.map +1 -1
  28. package/dist/errors/container.error.d.ts +18 -0
  29. package/dist/errors/container.error.js +18 -0
  30. package/dist/errors/container.error.js.map +1 -1
  31. package/dist/errors/index.d.ts +1 -0
  32. package/dist/errors/index.js +1 -0
  33. package/dist/errors/index.js.map +1 -1
  34. package/dist/errors/module.error.d.ts +6 -0
  35. package/dist/errors/module.error.js +6 -0
  36. package/dist/errors/module.error.js.map +1 -1
  37. package/dist/errors/node.error.d.ts +56 -0
  38. package/dist/errors/node.error.js +56 -0
  39. package/dist/errors/node.error.js.map +1 -1
  40. package/dist/errors/schema.error.d.ts +6 -0
  41. package/dist/errors/schema.error.js +6 -0
  42. package/dist/errors/schema.error.js.map +1 -1
  43. package/dist/errors/terraform.error.d.ts +19 -0
  44. package/dist/errors/terraform.error.js +23 -0
  45. package/dist/errors/terraform.error.js.map +1 -0
  46. package/dist/errors/transaction.error.d.ts +61 -0
  47. package/dist/errors/transaction.error.js +61 -0
  48. package/dist/errors/transaction.error.js.map +1 -1
  49. package/dist/events/action.event.d.ts +0 -2
  50. package/dist/events/action.event.js +0 -2
  51. package/dist/events/action.event.js.map +1 -1
  52. package/dist/events/event.model.d.ts +21 -5
  53. package/dist/events/event.model.js +11 -5
  54. package/dist/events/event.model.js.map +1 -1
  55. package/dist/events/hook/commit.hook.event.d.ts +0 -6
  56. package/dist/events/hook/commit.hook.event.js +0 -6
  57. package/dist/events/hook/commit.hook.event.js.map +1 -1
  58. package/dist/events/hook/hook.event.d.ts +0 -2
  59. package/dist/events/hook/hook.event.js +0 -2
  60. package/dist/events/hook/hook.event.js.map +1 -1
  61. package/dist/events/hook/model.hook.event.d.ts +0 -6
  62. package/dist/events/hook/model.hook.event.js +0 -6
  63. package/dist/events/hook/model.hook.event.js.map +1 -1
  64. package/dist/events/hook/resource.hook.event.d.ts +0 -6
  65. package/dist/events/hook/resource.hook.event.js +0 -6
  66. package/dist/events/hook/resource.hook.event.js.map +1 -1
  67. package/dist/events/index.d.ts +3 -0
  68. package/dist/events/index.js +3 -0
  69. package/dist/events/index.js.map +1 -1
  70. package/dist/events/mode-result.event.d.ts +57 -0
  71. package/dist/events/mode-result.event.js +24 -0
  72. package/dist/events/mode-result.event.js.map +1 -0
  73. package/dist/events/mode.event.d.ts +57 -0
  74. package/dist/events/mode.event.js +32 -0
  75. package/dist/events/mode.event.js.map +1 -0
  76. package/dist/events/module.event.d.ts +0 -2
  77. package/dist/events/module.event.js +0 -2
  78. package/dist/events/module.event.js.map +1 -1
  79. package/dist/events/registration.event.d.ts +18 -14
  80. package/dist/events/registration.event.js +18 -14
  81. package/dist/events/registration.event.js.map +1 -1
  82. package/dist/events/serialization.event.d.ts +15 -12
  83. package/dist/events/serialization.event.js +15 -12
  84. package/dist/events/serialization.event.js.map +1 -1
  85. package/dist/events/terraform.event.d.ts +42 -0
  86. package/dist/events/terraform.event.js +31 -0
  87. package/dist/events/terraform.event.js.map +1 -0
  88. package/dist/events/transaction.event.d.ts +0 -37
  89. package/dist/events/transaction.event.js +0 -28
  90. package/dist/events/transaction.event.js.map +1 -1
  91. package/dist/functions/container/container.d.ts +54 -13
  92. package/dist/functions/container/container.js +63 -18
  93. package/dist/functions/container/container.js.map +1 -1
  94. package/dist/functions/container/test-container.d.ts +43 -29
  95. package/dist/functions/container/test-container.js +71 -43
  96. package/dist/functions/container/test-container.js.map +1 -1
  97. package/dist/functions/dependency/dependency.d.ts +82 -8
  98. package/dist/functions/dependency/dependency.js +80 -14
  99. package/dist/functions/dependency/dependency.js.map +1 -1
  100. package/dist/functions/diff/aggregate-resource-actions.d.ts +19 -0
  101. package/dist/functions/diff/aggregate-resource-actions.js +41 -0
  102. package/dist/functions/diff/aggregate-resource-actions.js.map +1 -0
  103. package/dist/functions/diff/diff-metadata.d.ts +21 -3
  104. package/dist/functions/diff/diff-metadata.js +18 -0
  105. package/dist/functions/diff/diff-metadata.js.map +1 -1
  106. package/dist/functions/diff/diff.d.ts +55 -1
  107. package/dist/functions/diff/diff.js +44 -3
  108. package/dist/functions/diff/diff.js.map +1 -1
  109. package/dist/functions/diff/diff.utility.d.ts +17 -2
  110. package/dist/functions/diff/diff.utility.js +53 -38
  111. package/dist/functions/diff/diff.utility.js.map +1 -1
  112. package/dist/functions/hook/commit.hook.d.ts +16 -1
  113. package/dist/functions/hook/commit.hook.js +21 -6
  114. package/dist/functions/hook/commit.hook.js.map +1 -1
  115. package/dist/functions/hook/model-action.hook.d.ts +16 -1
  116. package/dist/functions/hook/model-action.hook.js +21 -6
  117. package/dist/functions/hook/model-action.hook.js.map +1 -1
  118. package/dist/functions/hook/resource-action.hook.d.ts +16 -1
  119. package/dist/functions/hook/resource-action.hook.js +21 -6
  120. package/dist/functions/hook/resource-action.hook.js.map +1 -1
  121. package/dist/functions/node/node-action.abstract.d.ts +23 -0
  122. package/dist/functions/node/node-action.abstract.js +20 -0
  123. package/dist/functions/node/node-action.abstract.js.map +1 -1
  124. package/dist/functions/node/node.abstract.d.ts +56 -5
  125. package/dist/functions/node/node.abstract.js +85 -12
  126. package/dist/functions/node/node.abstract.js.map +1 -1
  127. package/dist/functions/node/node.interface.d.ts +1 -0
  128. package/dist/functions/schema/schema.d.ts +7 -0
  129. package/dist/functions/schema/schema.js +9 -0
  130. package/dist/functions/schema/schema.js.map +1 -1
  131. package/dist/index.d.ts +5 -1
  132. package/dist/index.js +4 -1
  133. package/dist/index.js.map +1 -1
  134. package/dist/main.d.ts +244 -14
  135. package/dist/main.js +361 -72
  136. package/dist/main.js.map +1 -1
  137. package/dist/models/account/account.model.d.ts +37 -7
  138. package/dist/models/account/account.model.js +40 -8
  139. package/dist/models/account/account.model.js.map +1 -1
  140. package/dist/models/account/account.schema.d.ts +13 -1
  141. package/dist/models/account/account.schema.js +12 -0
  142. package/dist/models/account/account.schema.js.map +1 -1
  143. package/dist/models/app/app.model.d.ts +16 -1
  144. package/dist/models/app/app.model.js +19 -4
  145. package/dist/models/app/app.model.js.map +1 -1
  146. package/dist/models/app/app.schema.d.ts +6 -0
  147. package/dist/models/app/app.schema.js +6 -0
  148. package/dist/models/app/app.schema.js.map +1 -1
  149. package/dist/models/deployment/deployment.model.d.ts +13 -1
  150. package/dist/models/deployment/deployment.model.js +16 -4
  151. package/dist/models/deployment/deployment.model.js.map +1 -1
  152. package/dist/models/deployment/deployment.schema.d.ts +2 -0
  153. package/dist/models/deployment/deployment.schema.js +2 -0
  154. package/dist/models/deployment/deployment.schema.js.map +1 -1
  155. package/dist/models/environment/environment.model.d.ts +13 -1
  156. package/dist/models/environment/environment.model.js +20 -8
  157. package/dist/models/environment/environment.model.js.map +1 -1
  158. package/dist/models/environment/environment.schema.d.ts +2 -0
  159. package/dist/models/environment/environment.schema.js +2 -0
  160. package/dist/models/environment/environment.schema.js.map +1 -1
  161. package/dist/models/execution/execution.model.d.ts +20 -2
  162. package/dist/models/execution/execution.model.js +46 -28
  163. package/dist/models/execution/execution.model.js.map +1 -1
  164. package/dist/models/execution/execution.schema.d.ts +11 -0
  165. package/dist/models/execution/execution.schema.js +11 -0
  166. package/dist/models/execution/execution.schema.js.map +1 -1
  167. package/dist/models/filesystem/filesystem.model.d.ts +27 -1
  168. package/dist/models/filesystem/filesystem.model.js +30 -4
  169. package/dist/models/filesystem/filesystem.model.js.map +1 -1
  170. package/dist/models/filesystem/filesystem.schema.d.ts +5 -0
  171. package/dist/models/filesystem/filesystem.schema.js +5 -0
  172. package/dist/models/filesystem/filesystem.schema.js.map +1 -1
  173. package/dist/models/image/image.model.d.ts +17 -4
  174. package/dist/models/image/image.model.js +20 -7
  175. package/dist/models/image/image.model.js.map +1 -1
  176. package/dist/models/image/image.schema.d.ts +8 -0
  177. package/dist/models/image/image.schema.js +8 -0
  178. package/dist/models/image/image.schema.js.map +1 -1
  179. package/dist/models/model-action.interface.d.ts +17 -4
  180. package/dist/models/model.abstract.d.ts +96 -1
  181. package/dist/models/model.abstract.js +106 -7
  182. package/dist/models/model.abstract.js.map +1 -1
  183. package/dist/models/model.interface.d.ts +3 -0
  184. package/dist/models/pipeline/pipeline.model.d.ts +13 -1
  185. package/dist/models/pipeline/pipeline.model.js +18 -6
  186. package/dist/models/pipeline/pipeline.model.js.map +1 -1
  187. package/dist/models/pipeline/pipeline.schema.d.ts +8 -0
  188. package/dist/models/pipeline/pipeline.schema.js +8 -0
  189. package/dist/models/pipeline/pipeline.schema.js.map +1 -1
  190. package/dist/models/region/region.model.d.ts +16 -1
  191. package/dist/models/region/region.model.js +19 -4
  192. package/dist/models/region/region.model.js.map +1 -1
  193. package/dist/models/region/region.schema.d.ts +6 -0
  194. package/dist/models/region/region.schema.js +6 -0
  195. package/dist/models/region/region.schema.js.map +1 -1
  196. package/dist/models/server/server.model.d.ts +13 -1
  197. package/dist/models/server/server.model.js +16 -4
  198. package/dist/models/server/server.model.js.map +1 -1
  199. package/dist/models/server/server.schema.d.ts +3 -1
  200. package/dist/models/server/server.schema.js +3 -1
  201. package/dist/models/server/server.schema.js.map +1 -1
  202. package/dist/models/service/service.model.d.ts +15 -1
  203. package/dist/models/service/service.model.js +15 -1
  204. package/dist/models/service/service.model.js.map +1 -1
  205. package/dist/models/service/service.schema.d.ts +4 -1
  206. package/dist/models/service/service.schema.js +4 -1
  207. package/dist/models/service/service.schema.js.map +1 -1
  208. package/dist/models/subnet/subnet.model.d.ts +27 -3
  209. package/dist/models/subnet/subnet.model.js +40 -16
  210. package/dist/models/subnet/subnet.model.js.map +1 -1
  211. package/dist/models/subnet/subnet.schema.d.ts +9 -0
  212. package/dist/models/subnet/subnet.schema.js +9 -0
  213. package/dist/models/subnet/subnet.schema.js.map +1 -1
  214. package/dist/modes/apply-transaction.d.ts +23 -0
  215. package/dist/modes/apply-transaction.js +25 -0
  216. package/dist/modes/apply-transaction.js.map +1 -0
  217. package/dist/modes/commit.mode.d.ts +54 -0
  218. package/dist/modes/commit.mode.js +235 -0
  219. package/dist/modes/commit.mode.js.map +1 -0
  220. package/dist/modes/generate.mode.d.ts +29 -0
  221. package/dist/modes/generate.mode.js +49 -0
  222. package/dist/modes/generate.mode.js.map +1 -0
  223. package/dist/modes/run-action.mode.d.ts +30 -0
  224. package/dist/modes/run-action.mode.js +140 -0
  225. package/dist/modes/run-action.mode.js.map +1 -0
  226. package/dist/modes/validate.mode.d.ts +162 -0
  227. package/dist/modes/validate.mode.js +480 -0
  228. package/dist/modes/validate.mode.js.map +1 -0
  229. package/dist/modules/module.abstract.d.ts +51 -0
  230. package/dist/modules/module.abstract.js +36 -0
  231. package/dist/modules/module.abstract.js.map +1 -1
  232. package/dist/modules/module.container.d.ts +36 -0
  233. package/dist/modules/module.container.js +36 -0
  234. package/dist/modules/module.container.js.map +1 -1
  235. package/dist/modules/test-module.container.d.ts +139 -25
  236. package/dist/modules/test-module.container.js +410 -178
  237. package/dist/modules/test-module.container.js.map +1 -1
  238. package/dist/overlays/anchor.abstract.d.ts +32 -1
  239. package/dist/overlays/anchor.abstract.js +42 -11
  240. package/dist/overlays/anchor.abstract.js.map +1 -1
  241. package/dist/overlays/anchor.schema.d.ts +21 -0
  242. package/dist/overlays/anchor.schema.js +21 -0
  243. package/dist/overlays/anchor.schema.js.map +1 -1
  244. package/dist/overlays/overlay-data.repository.d.ts +18 -0
  245. package/dist/overlays/overlay-data.repository.js +18 -0
  246. package/dist/overlays/overlay-data.repository.js.map +1 -1
  247. package/dist/overlays/overlay.abstract.d.ts +56 -1
  248. package/dist/overlays/overlay.abstract.js +79 -20
  249. package/dist/overlays/overlay.abstract.js.map +1 -1
  250. package/dist/overlays/overlay.schema.d.ts +20 -0
  251. package/dist/overlays/overlay.schema.js +20 -0
  252. package/dist/overlays/overlay.schema.js.map +1 -1
  253. package/dist/resources/resource-action.interface.d.ts +26 -2
  254. package/dist/resources/resource-data.repository.d.ts +63 -1
  255. package/dist/resources/resource-data.repository.js +94 -4
  256. package/dist/resources/resource-data.repository.js.map +1 -1
  257. package/dist/resources/resource.abstract.d.ts +118 -3
  258. package/dist/resources/resource.abstract.js +166 -33
  259. package/dist/resources/resource.abstract.js.map +1 -1
  260. package/dist/resources/resource.schema.d.ts +29 -1
  261. package/dist/resources/resource.schema.js +28 -0
  262. package/dist/resources/resource.schema.js.map +1 -1
  263. package/dist/resources/terraform-resource.abstract.d.ts +44 -0
  264. package/dist/resources/terraform-resource.abstract.js +45 -0
  265. package/dist/resources/terraform-resource.abstract.js.map +1 -0
  266. package/dist/services/event/event.service.d.ts +30 -3
  267. package/dist/services/event/event.service.js +58 -16
  268. package/dist/services/event/event.service.js.map +1 -1
  269. package/dist/services/input/input.service.d.ts +52 -3
  270. package/dist/services/input/input.service.js +72 -8
  271. package/dist/services/input/input.service.js.map +1 -1
  272. package/dist/services/schema-translation/schema-translation.service.d.ts +9 -0
  273. package/dist/services/schema-translation/schema-translation.service.js +9 -0
  274. package/dist/services/schema-translation/schema-translation.service.js.map +1 -1
  275. package/dist/services/serialization/model/model-serialization.service.d.ts +26 -2
  276. package/dist/services/serialization/model/model-serialization.service.js +110 -62
  277. package/dist/services/serialization/model/model-serialization.service.js.map +1 -1
  278. package/dist/services/serialization/resource/resource-serialization.service.d.ts +33 -4
  279. package/dist/services/serialization/resource/resource-serialization.service.js +64 -28
  280. package/dist/services/serialization/resource/resource-serialization.service.js.map +1 -1
  281. package/dist/services/state-management/file-app-lock.utility.d.ts +43 -0
  282. package/dist/services/state-management/file-app-lock.utility.js +124 -0
  283. package/dist/services/state-management/file-app-lock.utility.js.map +1 -0
  284. package/dist/services/state-management/local-encryption.state-provider.d.ts +53 -2
  285. package/dist/services/state-management/local-encryption.state-provider.js +75 -49
  286. package/dist/services/state-management/local-encryption.state-provider.js.map +1 -1
  287. package/dist/services/state-management/local.state-provider.d.ts +49 -2
  288. package/dist/services/state-management/local.state-provider.js +70 -49
  289. package/dist/services/state-management/local.state-provider.js.map +1 -1
  290. package/dist/services/state-management/state-management.service.d.ts +141 -6
  291. package/dist/services/state-management/state-management.service.js +149 -4
  292. package/dist/services/state-management/state-management.service.js.map +1 -1
  293. package/dist/services/state-management/state-provider.interface.d.ts +55 -1
  294. package/dist/services/state-management/terraform-state.service.d.ts +76 -0
  295. package/dist/services/state-management/terraform-state.service.js +154 -0
  296. package/dist/services/state-management/terraform-state.service.js.map +1 -0
  297. package/dist/services/state-management/test.state-provider.d.ts +38 -1
  298. package/dist/services/state-management/test.state-provider.js +52 -21
  299. package/dist/services/state-management/test.state-provider.js.map +1 -1
  300. package/dist/services/terraform/terraform.service.d.ts +426 -0
  301. package/dist/services/terraform/terraform.service.js +995 -0
  302. package/dist/services/terraform/terraform.service.js.map +1 -0
  303. package/dist/services/terraform/terraform.type.d.ts +387 -0
  304. package/dist/services/terraform/terraform.type.js +579 -0
  305. package/dist/services/terraform/terraform.type.js.map +1 -0
  306. package/dist/services/transaction/transaction.service.d.ts +86 -10
  307. package/dist/services/transaction/transaction.service.js +387 -232
  308. package/dist/services/transaction/transaction.service.js.map +1 -1
  309. package/dist/services/validation/validation.service.d.ts +13 -1
  310. package/dist/services/validation/validation.service.js +12 -0
  311. package/dist/services/validation/validation.service.js.map +1 -1
  312. package/dist/utilities/array/array.utility.d.ts +3 -0
  313. package/dist/utilities/array/array.utility.js +3 -0
  314. package/dist/utilities/array/array.utility.js.map +1 -1
  315. package/dist/utilities/file/file.utility.d.ts +15 -0
  316. package/dist/utilities/file/file.utility.js +18 -1
  317. package/dist/utilities/file/file.utility.js.map +1 -1
  318. package/dist/utilities/hcl/hcl.utility.d.ts +61 -0
  319. package/dist/utilities/hcl/hcl.utility.js +229 -0
  320. package/dist/utilities/hcl/hcl.utility.js.map +1 -0
  321. package/dist/utilities/node/node.utility.d.ts +3 -0
  322. package/dist/utilities/node/node.utility.js +3 -0
  323. package/dist/utilities/node/node.utility.js.map +1 -1
  324. package/dist/utilities/object/object.utility.d.ts +12 -0
  325. package/dist/utilities/object/object.utility.js +12 -0
  326. package/dist/utilities/object/object.utility.js.map +1 -1
  327. package/dist/utilities/project/project.utility.d.ts +28 -0
  328. package/dist/utilities/project/project.utility.js +35 -0
  329. package/dist/utilities/project/project.utility.js.map +1 -0
  330. package/dist/utilities/string/string.utility.d.ts +21 -0
  331. package/dist/utilities/string/string.utility.js +39 -0
  332. package/dist/utilities/string/string.utility.js.map +1 -0
  333. package/dist/utilities/terraform/terraform.utility.d.ts +227 -0
  334. package/dist/utilities/terraform/terraform.utility.js +434 -0
  335. package/dist/utilities/terraform/terraform.utility.js.map +1 -0
  336. package/dist/utilities/test-helpers/test-classes.d.ts +18 -31
  337. package/dist/utilities/test-helpers/test-classes.js +18 -41
  338. package/dist/utilities/test-helpers/test-classes.js.map +1 -1
  339. package/dist/utilities/test-helpers/test-models.js +12 -0
  340. package/dist/utilities/test-helpers/test-models.js.map +1 -1
  341. package/dist/utilities/test-helpers/test-modes.d.ts +315 -0
  342. package/dist/utilities/test-helpers/test-modes.js +463 -0
  343. package/dist/utilities/test-helpers/test-modes.js.map +1 -0
  344. package/dist/utilities/test-helpers/test-modules.d.ts +41 -0
  345. package/dist/utilities/test-helpers/test-modules.js +79 -0
  346. package/dist/utilities/test-helpers/test-modules.js.map +1 -0
  347. package/dist/utilities/test-helpers/test-overlays.d.ts +17 -1
  348. package/dist/utilities/test-helpers/test-overlays.js +49 -5
  349. package/dist/utilities/test-helpers/test-overlays.js.map +1 -1
  350. package/dist/utilities/test-helpers/test-resources.d.ts +19 -1
  351. package/dist/utilities/test-helpers/test-resources.js +61 -3
  352. package/dist/utilities/test-helpers/test-resources.js.map +1 -1
  353. package/dist/utilities/validation/validation.utility.d.ts +24 -0
  354. package/dist/utilities/validation/validation.utility.js +24 -0
  355. package/dist/utilities/validation/validation.utility.js.map +1 -1
  356. package/package.json +6 -5
  357. package/dist/services/capture/capture.service.d.ts +0 -19
  358. package/dist/services/capture/capture.service.js +0 -43
  359. package/dist/services/capture/capture.service.js.map +0 -1
  360. package/dist/utilities/cidr/cidr.utility.d.ts +0 -10
  361. package/dist/utilities/cidr/cidr.utility.js +0 -51
  362. package/dist/utilities/cidr/cidr.utility.js.map +0 -1
@@ -0,0 +1,162 @@
1
+ import type { TerraformFolderOutput, TerraformResourceOutput } from '../app.type.js';
2
+ import { type AggregatedResourceAction } from '../functions/diff/aggregate-resource-actions.js';
3
+ import type { ModelTransactionResult } from './apply-transaction.js';
4
+ /**
5
+ * One argument terraform plans to change on a resource, with the values on either side.
6
+ *
7
+ * Values are rendered, truncated strings rather than the raw payload: a report is read, not
8
+ * replayed, and the raw payload of a real resource is both enormous and a place secrets live.
9
+ */
10
+ export interface ValidateFieldChange {
11
+ field: string;
12
+ /**
13
+ * The current value. Absent on a create. `(sensitive)` when terraform marked it so.
14
+ */
15
+ from?: string;
16
+ /**
17
+ * The planned value. `(known after apply)` when terraform cannot say yet.
18
+ */
19
+ to?: string;
20
+ }
21
+ /**
22
+ * One terraform address and the actions terraform plans on it (`create`, `update`, `delete`, …).
23
+ */
24
+ export interface ValidateTerraformChange {
25
+ address: string;
26
+ /**
27
+ * Which arguments moved, for the changes where that is the whole question: an in-place `update`,
28
+ * and a `create`+`delete` where the point is *which* argument forced the replacement.
29
+ *
30
+ * Left empty on a plain create or delete, where the address and the action already say everything.
31
+ */
32
+ changedFields: ValidateFieldChange[];
33
+ tfActions: string[];
34
+ }
35
+ /**
36
+ * What `validate` saw, as a report rather than a verdict.
37
+ *
38
+ * Octo's diff and terraform's plan measure different things from different baselines: octo's diff is
39
+ * `desired graph − last committed graph`, terraform's plan is `desired HCL − real cloud state`. The
40
+ * report correlates the two and explains what it can. Only being unable to read a plan makes it
41
+ * unsuccessful — see {@link ValidateReport.failures}.
42
+ */
43
+ export interface ValidateReport {
44
+ /**
45
+ * Terraform changes with no octo diff of their own that octo can explain: the resource references
46
+ * something whose identity moved, or the resource no longer renders that address.
47
+ */
48
+ attributedChanges: {
49
+ address: string;
50
+ causeKind: 'address-no-longer-rendered' | 'identity-changed';
51
+ causeResourceId: string;
52
+ moduleId: string;
53
+ tfActions: string[];
54
+ }[];
55
+ /**
56
+ * How far this report can be trusted, decided by whether intent changed.
57
+ *
58
+ * - `exact` — octo's diff is empty. Nothing is mocked and no dependency output moves, so every
59
+ * folder's plan reflects reality and drift detection is reliable.
60
+ * - `approximate` — octo's diff is non-empty. Each folder is planned alone against the *last
61
+ * applied* outputs of its dependencies, so a cross-folder consequence of this change is invisible
62
+ * until apply, and a renamed producer's outputs come from `mock_outputs`. The report may both
63
+ * understate what apply will do and overstate drift.
64
+ */
65
+ confidence: 'approximate' | 'exact';
66
+ /**
67
+ * Terraform changes nothing in octo explains: the infrastructure moved out from under intent.
68
+ */
69
+ drift: {
70
+ address: string;
71
+ moduleId: string;
72
+ tfActions: string[];
73
+ }[];
74
+ /**
75
+ * Folders terraform could not plan. The only unsuccessful outcome, because validate cannot report
76
+ * on a folder it was unable to read.
77
+ */
78
+ failures: {
79
+ message: string;
80
+ moduleId?: string;
81
+ }[];
82
+ /**
83
+ * Octo resources that changed, each with the terraform changes correlated to it. An empty
84
+ * `terraformChanges` means the intent change carries no infrastructure cost.
85
+ */
86
+ intentChanges: {
87
+ moduleId?: string;
88
+ octoAction: AggregatedResourceAction['action'];
89
+ reason?: string;
90
+ resourceContext: string;
91
+ resourceId: string;
92
+ terraformChanges: ValidateTerraformChange[];
93
+ }[];
94
+ /**
95
+ * Observations that judge nothing: a folder octo does not track, a delete it cannot correlate.
96
+ */
97
+ notes: {
98
+ message: string;
99
+ moduleId?: string;
100
+ }[];
101
+ /**
102
+ * Terraform changes planned against a value that may be a `mock_outputs` placeholder. Reported
103
+ * apart from {@link ValidateReport.drift}, and never as drift.
104
+ */
105
+ uncertain: {
106
+ address: string;
107
+ moduleId: string;
108
+ reason: string;
109
+ tfActions: string[];
110
+ }[];
111
+ }
112
+ /**
113
+ * One module's parsed terraform plan, i.e. the JSON produced by `terraform show -json <plan-file>`
114
+ * (run via terragrunt by the caller, so it is backend-agnostic). Only `resource_changes` is read.
115
+ */
116
+ export interface TerraformPlan {
117
+ resource_changes?: {
118
+ address: string;
119
+ change?: {
120
+ actions?: string[];
121
+ after?: Record<string, unknown> | null;
122
+ after_sensitive?: Record<string, unknown> | boolean | null;
123
+ after_unknown?: Record<string, unknown> | boolean | null;
124
+ before?: Record<string, unknown> | null;
125
+ before_sensitive?: Record<string, unknown> | boolean | null;
126
+ };
127
+ mode?: string;
128
+ }[];
129
+ }
130
+ /**
131
+ * Read-only correlation of `terraform plan` against intent. Never writes state or folders.
132
+ *
133
+ * `plans` maps each module folder's id to its parsed terraform plan, and `planErrors` maps a folder
134
+ * terraform *failed* to plan to the reason why. The two are disjoint, and a folder in neither was
135
+ * never inspected.
136
+ *
137
+ * `persistedMappings` is the octo→terraform mapping captured by the last commit. It supplies the
138
+ * addresses of resources deleted since (absent from this boot's generated files), and identifies
139
+ * producers that have never been applied, whose outputs terragrunt can only supply as a mock.
140
+ *
141
+ * Plans are partitioned by the tracked set (intent ∪ the committed folder record,
142
+ * `previousFolders`): a plan for a module the sweep filled is demanded and correlated; a plan for a
143
+ * committed-then-deleted (emptied) folder is read when supplied; a plan for a folder octo does
144
+ * **not** track is noted and excluded from all correlation, and re-declaring its module in intent
145
+ * re-adopts it.
146
+ *
147
+ * `externalResourceStateIds` names every external resource a `run-action` published and no commit
148
+ * has recorded yet, from `StateManagementService.listExternalResourceStateIds()`. Each one is
149
+ * reported as a note.
150
+ *
151
+ * By-design limit: correlation is resource-level, not field-level.
152
+ *
153
+ * @internal
154
+ */
155
+ export declare function validate({ externalResourceStateIds, persistedMappings, planErrors, plans, previousFolders, transaction, }: {
156
+ externalResourceStateIds?: string[];
157
+ persistedMappings: Map<string, TerraformResourceOutput>;
158
+ planErrors?: Map<string, string>;
159
+ plans: Map<string, TerraformPlan>;
160
+ previousFolders?: TerraformFolderOutput[];
161
+ transaction: ModelTransactionResult;
162
+ }): Promise<ValidateReport>;
@@ -0,0 +1,480 @@
1
+ import { Container } from '../functions/container/container.js';
2
+ import { aggregateResourceActions, } from '../functions/diff/aggregate-resource-actions.js';
3
+ import { DiffAction } from '../functions/diff/diff.js';
4
+ import { ResourceDataRepository } from '../resources/resource-data.repository.js';
5
+ import { TerraformService } from '../services/terraform/terraform.service.js';
6
+ const MAX_RENDERED_VALUE_LENGTH = 80;
7
+ const MAX_REPORTED_FIELDS = 12;
8
+ /**
9
+ * Renders one terraform value as a short, readable string.
10
+ */
11
+ function renderPlanValue(value) {
12
+ if (value === null || value === undefined) {
13
+ return '(none)';
14
+ }
15
+ const truncate = (rendered) => rendered.length > MAX_RENDERED_VALUE_LENGTH ? `${rendered.slice(0, MAX_RENDERED_VALUE_LENGTH)}…` : rendered;
16
+ if (Array.isArray(value)) {
17
+ if (value.length === 0) {
18
+ return 'none';
19
+ }
20
+ // Terraform's list-typed blocks (indexes, rules, listeners) are the ones worth naming: "2 items
21
+ // -> 1 item" does not answer *which* index went away, which is the whole question.
22
+ const names = value
23
+ .map((element) => typeof element === 'object' && element !== null
24
+ ? (element.name ?? element.index_name)
25
+ : element)
26
+ .filter((name) => typeof name === 'string' && name.length > 0);
27
+ return names.length === value.length ? truncate(names.join(', ')) : `${value.length} item(s)`;
28
+ }
29
+ return truncate(typeof value === 'string' ? value : JSON.stringify(value));
30
+ }
31
+ /**
32
+ * True when any leaf of a terraform sensitive/unknown mark is `true`.
33
+ *
34
+ * These maps mirror the *shape* of the value they describe, so a list of five blocks with nothing
35
+ * sensitive in it is `[{}, {}, {}, {}, {}]` — structure, not a signal. Only a literal `true`
36
+ * anywhere in that structure marks something, which is why "non-empty object" is the wrong test: it
37
+ * reported every list-typed argument on a DynamoDB table as sensitive.
38
+ */
39
+ function hasMark(mark) {
40
+ if (mark === true) {
41
+ return true;
42
+ }
43
+ if (typeof mark !== 'object' || mark === null) {
44
+ return false;
45
+ }
46
+ return Object.values(mark).some(hasMark);
47
+ }
48
+ /**
49
+ * True when terraform's sensitive/unknown map marks `key`.
50
+ */
51
+ function isMarked(marks, key) {
52
+ if (marks === true) {
53
+ return true;
54
+ }
55
+ if (!marks || typeof marks !== 'object') {
56
+ return false;
57
+ }
58
+ return hasMark(marks[key]);
59
+ }
60
+ /**
61
+ * The arguments that differ between `before` and `after`.
62
+ *
63
+ * Terraform already hands us both sides — `readPlan` parses the whole `show -json` payload — so this
64
+ * costs nothing but the comparison. Without it an added index and a removed index render as the
65
+ * same sentence: "1 update".
66
+ */
67
+ function describeFieldChanges(change) {
68
+ const actions = new Set(change.actions ?? []);
69
+ // A plain create or delete needs no field list: the address and the action are the whole story.
70
+ const isUpdate = actions.has('update');
71
+ const isReplace = actions.has('create') && actions.has('delete');
72
+ if (!isUpdate && !isReplace) {
73
+ return [];
74
+ }
75
+ const before = (change.before ?? {});
76
+ const after = (change.after ?? {});
77
+ const fields = [];
78
+ for (const key of [...new Set([...Object.keys(before), ...Object.keys(after)])].sort()) {
79
+ const unknownAfter = isMarked(change.after_unknown, key);
80
+ if (!unknownAfter && JSON.stringify(before[key]) === JSON.stringify(after[key])) {
81
+ continue;
82
+ }
83
+ fields.push({
84
+ field: key,
85
+ from: isMarked(change.before_sensitive, key) ? '(sensitive)' : renderPlanValue(before[key]),
86
+ to: unknownAfter
87
+ ? '(known after apply)'
88
+ : isMarked(change.after_sensitive, key)
89
+ ? '(sensitive)'
90
+ : renderPlanValue(after[key]),
91
+ });
92
+ if (fields.length === MAX_REPORTED_FIELDS) {
93
+ break;
94
+ }
95
+ }
96
+ return fields;
97
+ }
98
+ /**
99
+ * Read-only correlation of `terraform plan` against intent. Never writes state or folders.
100
+ *
101
+ * `plans` maps each module folder's id to its parsed terraform plan, and `planErrors` maps a folder
102
+ * terraform *failed* to plan to the reason why. The two are disjoint, and a folder in neither was
103
+ * never inspected.
104
+ *
105
+ * `persistedMappings` is the octo→terraform mapping captured by the last commit. It supplies the
106
+ * addresses of resources deleted since (absent from this boot's generated files), and identifies
107
+ * producers that have never been applied, whose outputs terragrunt can only supply as a mock.
108
+ *
109
+ * Plans are partitioned by the tracked set (intent ∪ the committed folder record,
110
+ * `previousFolders`): a plan for a module the sweep filled is demanded and correlated; a plan for a
111
+ * committed-then-deleted (emptied) folder is read when supplied; a plan for a folder octo does
112
+ * **not** track is noted and excluded from all correlation, and re-declaring its module in intent
113
+ * re-adopts it.
114
+ *
115
+ * `externalResourceStateIds` names every external resource a `run-action` published and no commit
116
+ * has recorded yet, from `StateManagementService.listExternalResourceStateIds()`. Each one is
117
+ * reported as a note.
118
+ *
119
+ * By-design limit: correlation is resource-level, not field-level.
120
+ *
121
+ * @internal
122
+ */
123
+ export async function validate({ externalResourceStateIds = [], persistedMappings, planErrors = new Map(), plans, previousFolders = [], transaction, }) {
124
+ const container = Container.getInstance();
125
+ const [resourceDataRepository, terraformService] = await Promise.all([
126
+ container.get(ResourceDataRepository),
127
+ container.get(TerraformService),
128
+ ]);
129
+ const allDiffs = transaction.resourceDiffs.flat();
130
+ const mappings = terraformService.getOctoTerraformResourceMappings();
131
+ const report = {
132
+ attributedChanges: [],
133
+ confidence: allDiffs.length === 0 ? 'exact' : 'approximate',
134
+ drift: [],
135
+ failures: [],
136
+ intentChanges: [],
137
+ notes: [],
138
+ uncertain: [],
139
+ };
140
+ // Report what an external resource published and no commit has recorded. Octo reaches that record
141
+ // only by the resource id terraform asks for, so one whose resource has left both graphs is
142
+ // published infrastructure nothing will ever ask about again - the only place a user can be told
143
+ // is here.
144
+ if (externalResourceStateIds.length > 0) {
145
+ const heldResourceIds = new Set([
146
+ ...resourceDataRepository.getNewResourcesByProperties(),
147
+ ...resourceDataRepository.getActualResourcesByProperties(),
148
+ ].map((resource) => resource.resourceId));
149
+ for (const resourceId of [...externalResourceStateIds].sort()) {
150
+ report.notes.push({
151
+ message: heldResourceIds.has(resourceId)
152
+ ? `External resource "${resourceId}" is published but not recorded in octo state; the next successful ` +
153
+ 'commit records it.'
154
+ : `External resource "${resourceId}" is published but not recorded in octo state, and neither intent nor ` +
155
+ 'the committed graph declares it any more, so octo will never delete it.',
156
+ });
157
+ }
158
+ }
159
+ // Aggregate octo diffs to one action per resource.
160
+ const octoActions = aggregateResourceActions(allDiffs);
161
+ const parsePlanChanges = (plan) => {
162
+ const changes = new Map();
163
+ for (const resourceChange of plan.resource_changes ?? []) {
164
+ if (resourceChange.mode === 'data') {
165
+ continue;
166
+ }
167
+ changes.set(resourceChange.address, {
168
+ changedFields: resourceChange.change ? describeFieldChanges(resourceChange.change) : [],
169
+ tfActions: resourceChange.change?.actions ?? [],
170
+ });
171
+ }
172
+ return changes;
173
+ };
174
+ const sweptModuleIds = new Set(terraformService.getModuleIds());
175
+ const trackedModuleIds = new Set([...sweptModuleIds, ...previousFolders.map((folder) => folder.moduleId)]);
176
+ const planChangesByModule = new Map();
177
+ const NO_PLAN_CHANGE = { changedFields: [], tfActions: [] };
178
+ // Every module the sweep filled must have a plan. `getModuleIds()` only lists modules that
179
+ // contributed a resource, so a missing plan means terraform ran on a real folder and failed.
180
+ for (const moduleId of sweptModuleIds) {
181
+ const plan = plans.get(moduleId);
182
+ if (!plan) {
183
+ const cause = planErrors.get(moduleId);
184
+ report.failures.push({
185
+ message: cause
186
+ ? `Terraform failed to plan module "${moduleId}":\n${cause}`
187
+ : `No terraform plan was supplied for module "${moduleId}", so octo cannot report on it.`,
188
+ moduleId,
189
+ });
190
+ continue;
191
+ }
192
+ planChangesByModule.set(moduleId, parsePlanChanges(plan));
193
+ }
194
+ // Remaining plans belong either to an emptied folder octo still tracks, or to a folder it does not
195
+ // own at all.
196
+ for (const [moduleId, plan] of plans.entries()) {
197
+ if (sweptModuleIds.has(moduleId)) {
198
+ continue;
199
+ }
200
+ if (trackedModuleIds.has(moduleId)) {
201
+ planChangesByModule.set(moduleId, parsePlanChanges(plan));
202
+ }
203
+ else {
204
+ report.notes.push({
205
+ message: `Terraform plan supplied for folder "${moduleId}", which octo does not track (not in intent or committed ` +
206
+ 'state); excluding it from this report. Re-declare its module in intent to re-adopt it.',
207
+ moduleId,
208
+ });
209
+ }
210
+ }
211
+ const isNoop = (actions) => actions.length === 0 || (actions.length === 1 && (actions[0] === 'no-op' || actions[0] === 'read'));
212
+ const claimedAddresses = new Map();
213
+ const claim = (moduleId, address) => {
214
+ if (!claimedAddresses.has(moduleId)) {
215
+ claimedAddresses.set(moduleId, new Set());
216
+ }
217
+ claimedAddresses.get(moduleId).add(address);
218
+ };
219
+ const referrers = terraformService.getResourceReferrers();
220
+ const mappingByResourceId = new Map(mappings.map((mapping) => [mapping.resourceId, mapping]));
221
+ // Terraform changes everything that transitively references a resource whose identity moved, while
222
+ // octo's diff carries only the moved resource itself. Walking the same reference graph terraform
223
+ // cascades along recovers the rest.
224
+ //
225
+ // An identity moves on REPLACE (force-new recreates the referrer too), and on ADD or DELETE of a
226
+ // resourceId — a referrer that kept its own id then renders a different terraform address. Renaming
227
+ // an execution, for instance, replaces `alb-target-group-<old>` with `alb-target-group-<new>`, and
228
+ // the untouched alb-listener's `default_action.forward.target_group.arn` moves with it.
229
+ const identityChangedResourceIds = new Set([...octoActions.values()]
230
+ .filter((a) => a.action === DiffAction.REPLACE || a.action === DiffAction.ADD || a.action === DiffAction.DELETE)
231
+ .map((a) => a.resourceId));
232
+ // Each affected referrer maps to the moved resource it references, so the report can name the cause.
233
+ const cascadeCauseByResourceId = new Map();
234
+ const cascadeQueue = [...identityChangedResourceIds];
235
+ while (cascadeQueue.length > 0) {
236
+ const referentId = cascadeQueue.shift();
237
+ for (const referrerId of referrers.get(referentId) ?? []) {
238
+ if (!cascadeCauseByResourceId.has(referrerId) && !identityChangedResourceIds.has(referrerId)) {
239
+ cascadeCauseByResourceId.set(referrerId, referentId);
240
+ cascadeQueue.push(referrerId);
241
+ }
242
+ }
243
+ }
244
+ // Resources that may have been planned against a `mock_outputs` placeholder rather than a real
245
+ // value. Terragrunt substitutes a mock for any output name the producer folder's state lacks, and
246
+ // that happens two ways: the producer has never been applied, so it has no outputs at all; or it
247
+ // has been applied and now declares an output it did not declare then, because its response gained
248
+ // a key. Same-module references use no dependency block and cannot be mocked.
249
+ //
250
+ // The second case is read off the committed graph rather than the persisted mapping, which records
251
+ // addresses and not output names. A commit demands every declared output resolve before it records
252
+ // a resource, so a key the committed response does not hold is an output that was not there.
253
+ const mockFedCauseByResourceId = new Map();
254
+ const mockQueue = [];
255
+ const markMockFed = (resourceId, cause) => {
256
+ if (!mockFedCauseByResourceId.has(resourceId)) {
257
+ mockFedCauseByResourceId.set(resourceId, cause);
258
+ mockQueue.push(resourceId);
259
+ }
260
+ };
261
+ /**
262
+ * Why a producer's outputs would be mocked, or `undefined` when every one of them is in state.
263
+ */
264
+ const describeProducerMocking = (referent) => {
265
+ if (!persistedMappings.has(referent.resourceContext)) {
266
+ return 'never-applied';
267
+ }
268
+ // An external resource publishes its whole response under one output name, so a response that
269
+ // gained a key adds no output name for terragrunt to miss.
270
+ if (referent.entireResponseOutput !== undefined) {
271
+ return undefined;
272
+ }
273
+ const committed = resourceDataRepository.getActualResourceByContext(referent.resourceContext);
274
+ if (!committed) {
275
+ return 'never-applied';
276
+ }
277
+ return referent.outputMappings.some(({ key }) => !(key in committed.response)) ? 'new-output' : undefined;
278
+ };
279
+ for (const [referentId, referrerIds] of referrers.entries()) {
280
+ const referent = mappingByResourceId.get(referentId);
281
+ if (!referent) {
282
+ continue;
283
+ }
284
+ const kind = describeProducerMocking(referent);
285
+ if (!kind) {
286
+ continue;
287
+ }
288
+ for (const referrerId of referrerIds) {
289
+ const referrer = mappingByResourceId.get(referrerId);
290
+ if (referrer && referrer.moduleId !== referent.moduleId) {
291
+ markMockFed(referrerId, { kind, resourceId: referentId });
292
+ }
293
+ }
294
+ }
295
+ // A mocked value propagates: anything reading it is planned on it too.
296
+ while (mockQueue.length > 0) {
297
+ const resourceId = mockQueue.shift();
298
+ const cause = mockFedCauseByResourceId.get(resourceId);
299
+ for (const referrerId of referrers.get(resourceId) ?? []) {
300
+ markMockFed(referrerId, cause);
301
+ }
302
+ }
303
+ const mockFedModuleIds = new Set([...mockFedCauseByResourceId.keys()]
304
+ .map((resourceId) => mappingByResourceId.get(resourceId)?.moduleId)
305
+ .filter((moduleId) => moduleId !== undefined));
306
+ const describeMockCause = (cause) => `planned against a "mock_outputs" placeholder: it consumes an output of "${cause.resourceId}", which has ` +
307
+ (cause.kind === 'never-applied' ? 'never been applied' : 'gained an output since it was last applied') +
308
+ ', so the value terraform compared against is not the value it will get';
309
+ /**
310
+ * Classifies a terraform change on a resource octo did not flag: attributed if octo explains it,
311
+ * uncertain if the plan itself may be wrong, drift otherwise.
312
+ */
313
+ const classifyChangeWithNoOctoDiff = (moduleId, resourceId, change) => {
314
+ const cascadeCause = cascadeCauseByResourceId.get(resourceId);
315
+ if (cascadeCause) {
316
+ report.attributedChanges.push({
317
+ address: change.address,
318
+ causeKind: 'identity-changed',
319
+ causeResourceId: cascadeCause,
320
+ moduleId,
321
+ tfActions: change.tfActions,
322
+ });
323
+ return;
324
+ }
325
+ const mockCause = mockFedCauseByResourceId.get(resourceId);
326
+ if (mockCause) {
327
+ report.uncertain.push({
328
+ address: change.address,
329
+ moduleId,
330
+ reason: describeMockCause(mockCause),
331
+ tfActions: change.tfActions,
332
+ });
333
+ return;
334
+ }
335
+ report.drift.push({ address: change.address, moduleId, tfActions: change.tfActions });
336
+ };
337
+ // Forward: correlate every address this sweep rendered with the plan.
338
+ for (const mapping of mappings) {
339
+ const octoAction = octoActions.get(mapping.resourceContext);
340
+ // The folder failed to plan and is already a `failure`. Reporting an empty terraform side here
341
+ // would read as "no infrastructure change" for a folder nobody could read.
342
+ const planChanges = planChangesByModule.get(mapping.moduleId);
343
+ if (!planChanges) {
344
+ continue;
345
+ }
346
+ const addressActions = mapping.terraformAddresses.map((address) => {
347
+ claim(mapping.moduleId, address);
348
+ const planChange = planChanges.get(address) ?? NO_PLAN_CHANGE;
349
+ return { address, changedFields: planChange.changedFields, tfActions: planChange.tfActions };
350
+ });
351
+ // A resource can render a variable number of addresses — one rule resource per security group
352
+ // rule, one object per s3 website file. When it survives but renders fewer, the dropped address
353
+ // is in no current mapping, so its destroy belongs to the resource that stopped rendering it.
354
+ const persisted = persistedMappings.get(mapping.resourceContext);
355
+ const currentAddresses = new Set(mapping.terraformAddresses);
356
+ for (const address of persisted?.terraformAddresses ?? []) {
357
+ if (currentAddresses.has(address)) {
358
+ continue;
359
+ }
360
+ claim(mapping.moduleId, address);
361
+ const { tfActions } = planChanges.get(address) ?? NO_PLAN_CHANGE;
362
+ if (!isNoop(tfActions)) {
363
+ report.attributedChanges.push({
364
+ address,
365
+ causeKind: 'address-no-longer-rendered',
366
+ causeResourceId: mapping.resourceId,
367
+ moduleId: mapping.moduleId,
368
+ tfActions,
369
+ });
370
+ }
371
+ }
372
+ const changed = addressActions.filter((a) => !isNoop(a.tfActions));
373
+ // Record what octo said and what terraform said, without requiring the two to agree.
374
+ if (octoAction) {
375
+ report.intentChanges.push({
376
+ moduleId: mapping.moduleId,
377
+ octoAction: octoAction.action,
378
+ reason: octoAction.reason,
379
+ resourceContext: mapping.resourceContext,
380
+ resourceId: mapping.resourceId,
381
+ terraformChanges: changed,
382
+ });
383
+ continue;
384
+ }
385
+ for (const change of changed) {
386
+ classifyChangeWithNoOctoDiff(mapping.moduleId, mapping.resourceId, change);
387
+ }
388
+ }
389
+ // Deleted octo resources are absent from this boot's generated files, so their addresses come from
390
+ // the mapping persisted at the last commit.
391
+ let hasUnverifiableDelete = false;
392
+ for (const [context, octoAction] of octoActions.entries()) {
393
+ if (octoAction.action !== DiffAction.DELETE) {
394
+ continue;
395
+ }
396
+ // Never committed through the terraform flow, so its addresses were never recorded.
397
+ const persisted = persistedMappings.get(context);
398
+ if (!persisted) {
399
+ report.notes.push({
400
+ message: `Deleted resource "${octoAction.resourceId}" is not in the persisted terraform mapping ` +
401
+ '(deleted before it was ever committed?); its terraform addresses are unknown.',
402
+ });
403
+ report.intentChanges.push({
404
+ octoAction: DiffAction.DELETE,
405
+ reason: octoAction.reason,
406
+ resourceContext: context,
407
+ resourceId: octoAction.resourceId,
408
+ terraformChanges: [],
409
+ });
410
+ hasUnverifiableDelete = true;
411
+ continue;
412
+ }
413
+ // The owning folder is emptied and no plan was supplied for it, so its destroys cannot be
414
+ // correlated.
415
+ const planChanges = planChangesByModule.get(persisted.moduleId);
416
+ if (!planChanges) {
417
+ report.notes.push({
418
+ message: `Deleted resource "${octoAction.resourceId}" lived in module "${persisted.moduleId}", whose ` +
419
+ 'plan was not supplied; its terraform deletes are not in this report.',
420
+ moduleId: persisted.moduleId,
421
+ });
422
+ report.intentChanges.push({
423
+ moduleId: persisted.moduleId,
424
+ octoAction: DiffAction.DELETE,
425
+ reason: octoAction.reason,
426
+ resourceContext: context,
427
+ resourceId: octoAction.resourceId,
428
+ terraformChanges: [],
429
+ });
430
+ continue;
431
+ }
432
+ const terraformChanges = [];
433
+ for (const address of persisted.terraformAddresses) {
434
+ const { changedFields, tfActions } = planChanges.get(address) ?? NO_PLAN_CHANGE;
435
+ claim(persisted.moduleId, address);
436
+ if (!isNoop(tfActions)) {
437
+ terraformChanges.push({ address, changedFields, tfActions });
438
+ }
439
+ }
440
+ // No terraform change means the resource is already gone from the cloud and intent has caught up.
441
+ report.intentChanges.push({
442
+ moduleId: persisted.moduleId,
443
+ octoAction: DiffAction.DELETE,
444
+ reason: octoAction.reason,
445
+ resourceContext: context,
446
+ resourceId: octoAction.resourceId,
447
+ terraformChanges,
448
+ });
449
+ }
450
+ // Reverse: whatever terraform plans that no octo resource has claimed.
451
+ for (const [moduleId, planChanges] of planChangesByModule.entries()) {
452
+ for (const [address, { tfActions }] of planChanges.entries()) {
453
+ if (claimedAddresses.get(moduleId)?.has(address) || isNoop(tfActions)) {
454
+ continue;
455
+ }
456
+ const joined = [...tfActions].sort().join(',');
457
+ if (joined === 'delete' && hasUnverifiableDelete) {
458
+ report.notes.push({
459
+ message: `Terraform plans a delete on "${address}", which is unclaimed — an octo delete with no persisted ` +
460
+ 'mapping may own it.',
461
+ moduleId,
462
+ });
463
+ }
464
+ else if (mockFedModuleIds.has(moduleId)) {
465
+ report.uncertain.push({
466
+ address,
467
+ moduleId,
468
+ reason: 'no octo resource renders this address, and this folder was planned with at least one ' +
469
+ '"mock_outputs" placeholder substituted',
470
+ tfActions,
471
+ });
472
+ }
473
+ else {
474
+ report.drift.push({ address, moduleId, tfActions });
475
+ }
476
+ }
477
+ }
478
+ return report;
479
+ }
480
+ //# sourceMappingURL=validate.mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.mode.js","sourceRoot":"","sources":["../../src/modes/validate.mode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,OAAO,EAEL,wBAAwB,GACzB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAkJ9E,MAAM,yBAAyB,GAAG,EAAE,CAAC;AACrC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B;;GAEG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC5C,QAAQ,CAAC,MAAM,GAAG,yBAAyB,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,yBAAyB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE9G,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,gGAAgG;QAChG,mFAAmF;QACnF,MAAM,KAAK,GAAG,KAAK;aAChB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACf,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;YAC7C,CAAC,CAAC,CAAE,OAAmC,CAAC,IAAI,IAAK,OAAmC,CAAC,UAAU,CAAC;YAChG,CAAC,CAAC,OAAO,CACZ;aACA,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEjF,OAAO,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,UAAU,CAAC;IAChG,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,OAAO,CAAC,IAAa;IAC5B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,IAA+B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,KAA2D,EAAE,GAAW;IACxF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAC3B,MAAqF;IAErF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC9C,gGAAgG;IAChG,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjE,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAA4B,CAAC;IAChE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;IAC9D,MAAM,MAAM,GAA0B,EAAE,CAAC;IAEzC,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACvF,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAChF,SAAS;QACX,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,GAAG;YACV,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3F,EAAE,EAAE,YAAY;gBACd,CAAC,CAAC,qBAAqB;gBACvB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,CAAC;oBACrC,CAAC,CAAC,aAAa;oBACf,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;YAC1C,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,EAC7B,wBAAwB,GAAG,EAAE,EAC7B,iBAAiB,EACjB,UAAU,GAAG,IAAI,GAAG,EAAE,EACtB,KAAK,EACL,eAAe,GAAG,EAAE,EACpB,WAAW,GAQZ;IACC,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACnE,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC;QACrC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC;KAChC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,WAAW,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,gCAAgC,EAAE,CAAC;IAErE,MAAM,MAAM,GAAmB;QAC7B,iBAAiB,EAAE,EAAE;QACrB,UAAU,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa;QAC3D,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,EAAE;QACZ,aAAa,EAAE,EAAE;QACjB,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;KACd,CAAC;IAEF,kGAAkG;IAClG,4FAA4F;IAC5F,iGAAiG;IACjG,WAAW;IACX,IAAI,wBAAwB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B;YACE,GAAG,sBAAsB,CAAC,2BAA2B,EAAE;YACvD,GAAG,sBAAsB,CAAC,8BAA8B,EAAE;SAC3D,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CACzC,CAAC;QAEF,KAAK,MAAM,UAAU,IAAI,CAAC,GAAG,wBAAwB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAChB,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;oBACtC,CAAC,CAAC,sBAAsB,UAAU,qEAAqE;wBACrG,oBAAoB;oBACtB,CAAC,CAAC,sBAAsB,UAAU,wEAAwE;wBACxG,yEAAyE;aAC9E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,MAAM,WAAW,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAEvD,MAAM,gBAAgB,GAAG,CAAC,IAAmB,EAA2B,EAAE;QACxE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;QAE9C,KAAK,MAAM,cAAc,IAAI,IAAI,CAAC,gBAAgB,IAAI,EAAE,EAAE,CAAC;YACzD,IAAI,cAAc,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACnC,SAAS;YACX,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE;gBAClC,aAAa,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;gBACvF,SAAS,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;aAChD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC,CAAC;IAChE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,cAAc,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3G,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAmC,CAAC;IACvE,MAAM,cAAc,GAAe,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAExE,2FAA2F;IAC3F,6FAA6F;IAC7F,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;oBACZ,CAAC,CAAC,oCAAoC,QAAQ,OAAO,KAAK,EAAE;oBAC5D,CAAC,CAAC,8CAA8C,QAAQ,iCAAiC;gBAC3F,QAAQ;aACT,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,mBAAmB,CAAC,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,mGAAmG;IACnG,cAAc;IACd,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,IAAI,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,SAAS;QACX,CAAC;QAED,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,mBAAmB,CAAC,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAChB,OAAO,EACL,uCAAuC,QAAQ,2DAA2D;oBAC1G,wFAAwF;gBAC1F,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,OAAiB,EAAW,EAAE,CAC5C,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;IAEtG,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;IACxD,MAAM,KAAK,GAAG,CAAC,QAAgB,EAAE,OAAe,EAAQ,EAAE;QACxD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,gBAAgB,CAAC,oBAAoB,EAAE,CAAC;IAC1D,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAE9F,mGAAmG;IACnG,iGAAiG;IACjG,oCAAoC;IACpC,EAAE;IACF,iGAAiG;IACjG,oGAAoG;IACpG,mGAAmG;IACnG,wFAAwF;IACxF,MAAM,0BAA0B,GAAG,IAAI,GAAG,CACxC,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;SACtB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,CAAC;SAC/G,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAC5B,CAAC;IAEF,qGAAqG;IACrG,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3D,MAAM,YAAY,GAAG,CAAC,GAAG,0BAA0B,CAAC,CAAC;IAErD,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAG,CAAC;QAEzC,KAAK,MAAM,UAAU,IAAI,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACzD,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7F,wBAAwB,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;gBACrD,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAED,+FAA+F;IAC/F,kGAAkG;IAClG,iGAAiG;IACjG,mGAAmG;IACnG,8EAA8E;IAC9E,EAAE;IACF,mGAAmG;IACnG,mGAAmG;IACnG,6FAA6F;IAC7F,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC9D,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,WAAW,GAAG,CAAC,UAAkB,EAAE,KAAgB,EAAQ,EAAE;QACjE,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9C,wBAAwB,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAChD,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,uBAAuB,GAAG,CAAC,QAAyB,EAAiC,EAAE;QAC3F,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACrD,OAAO,eAAe,CAAC;QACzB,CAAC;QAED,8FAA8F;QAC9F,2DAA2D;QAC3D,IAAI,QAAQ,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;YAChD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,SAAS,GAAG,sBAAsB,CAAC,0BAA0B,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC9F,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,eAAe,CAAC;QACzB,CAAC;QAED,OAAO,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,CAAC,CAAC;IAEF,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACxD,WAAW,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,EAAG,CAAC;QACtC,MAAM,KAAK,GAAG,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC;QAExD,KAAK,MAAM,UAAU,IAAI,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACzD,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B,CAAC,GAAG,wBAAwB,CAAC,IAAI,EAAE,CAAC;SACjC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC;SAClE,MAAM,CAAC,CAAC,QAAQ,EAAsB,EAAE,CAAC,QAAQ,KAAK,SAAS,CAAC,CACpE,CAAC;IAEF,MAAM,iBAAiB,GAAG,CAAC,KAAgB,EAAU,EAAE,CACrD,2EAA2E,KAAK,CAAC,UAAU,eAAe;QAC1G,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,4CAA4C,CAAC;QACtG,wEAAwE,CAAC;IAE3E;;;OAGG;IACH,MAAM,4BAA4B,GAAG,CACnC,QAAgB,EAChB,UAAkB,EAClB,MAA+B,EACzB,EAAE;QACR,MAAM,YAAY,GAAG,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9D,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC;gBAC5B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,SAAS,EAAE,kBAAkB;gBAC7B,eAAe,EAAE,YAAY;gBAC7B,QAAQ;gBACR,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3D,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;gBACpB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,QAAQ;gBACR,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC;gBACpC,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACxF,CAAC,CAAC;IAEF,sEAAsE;IACtE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAE5D,+FAA+F;QAC/F,2EAA2E;QAC3E,MAAM,WAAW,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QAED,MAAM,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YAChE,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjC,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC;YAC9D,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,aAAa,EAAE,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,CAAC;QAC/F,CAAC,CAAC,CAAC;QAEH,8FAA8F;QAC9F,gGAAgG;QAChG,8FAA8F;QAC9F,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACjE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAE7D,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,kBAAkB,IAAI,EAAE,EAAE,CAAC;YAC1D,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClC,SAAS;YACX,CAAC;YAED,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEjC,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC;YACjE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC;oBAC5B,OAAO;oBACP,SAAS,EAAE,4BAA4B;oBACvC,eAAe,EAAE,OAAO,CAAC,UAAU;oBACnC,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,SAAS;iBACV,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAEnE,qFAAqF;QACrF,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;gBACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,eAAe,EAAE,OAAO,CAAC,eAAe;gBACxC,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,gBAAgB,EAAE,OAAO;aAC1B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,4BAA4B,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IAED,mGAAmG;IACnG,4CAA4C;IAC5C,IAAI,qBAAqB,GAAG,KAAK,CAAC;IAElC,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1D,IAAI,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;YAC5C,SAAS;QACX,CAAC;QAED,oFAAoF;QACpF,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAChB,OAAO,EACL,qBAAqB,UAAU,CAAC,UAAU,8CAA8C;oBACxF,+EAA+E;aAClF,CAAC,CAAC;YACH,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;gBACxB,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,eAAe,EAAE,OAAO;gBACxB,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,gBAAgB,EAAE,EAAE;aACrB,CAAC,CAAC;YAEH,qBAAqB,GAAG,IAAI,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,0FAA0F;QAC1F,cAAc;QACd,MAAM,WAAW,GAAG,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAChE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAChB,OAAO,EACL,qBAAqB,UAAU,CAAC,UAAU,sBAAsB,SAAS,CAAC,QAAQ,WAAW;oBAC7F,sEAAsE;gBACxE,QAAQ,EAAE,SAAS,CAAC,QAAQ;aAC7B,CAAC,CAAC;YACH,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;gBACxB,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,eAAe,EAAE,OAAO;gBACxB,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,gBAAgB,EAAE,EAAE;aACrB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,gBAAgB,GAA8B,EAAE,CAAC;QAEvD,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,kBAAkB,EAAE,CAAC;YACnD,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC;YAChF,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEnC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvB,gBAAgB,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QAED,kGAAkG;QAClG,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YACxB,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,UAAU,EAAE,UAAU,CAAC,MAAM;YAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,eAAe,EAAE,OAAO;YACxB,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,gBAAgB;SACjB,CAAC,CAAC;IACL,CAAC;IAED,uEAAuE;IACvE,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC;QACpE,KAAK,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7D,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtE,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAE/C,IAAI,MAAM,KAAK,QAAQ,IAAI,qBAAqB,EAAE,CAAC;gBACjD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;oBAChB,OAAO,EACL,gCAAgC,OAAO,2DAA2D;wBAClG,qBAAqB;oBACvB,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1C,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;oBACpB,OAAO;oBACP,QAAQ;oBACR,MAAM,EACJ,uFAAuF;wBACvF,wCAAwC;oBAC1C,SAAS;iBACV,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}