@intentius/chant-lexicon-terraform 0.124.52 → 0.124.55

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 (641) hide show
  1. package/README.md +14 -10
  2. package/dist/__fixtures__/pr-loop/estate.component.d.ts +7 -0
  3. package/dist/__fixtures__/pr-loop/estate.component.d.ts.map +1 -0
  4. package/dist/__fixtures__/pr-loop/estate.component.js +7 -0
  5. package/dist/__fixtures__/report/generate.d.ts +26 -0
  6. package/dist/__fixtures__/report/generate.d.ts.map +1 -0
  7. package/dist/__fixtures__/report/generate.js +58 -0
  8. package/dist/applied-state.d.ts +27 -0
  9. package/dist/applied-state.d.ts.map +1 -0
  10. package/dist/applied-state.js +44 -0
  11. package/dist/backend-config.d.ts +53 -0
  12. package/dist/backend-config.d.ts.map +1 -0
  13. package/dist/backend-config.js +136 -0
  14. package/dist/behaviour/kinds.d.ts.map +1 -1
  15. package/dist/behaviour/kinds.js +4 -0
  16. package/dist/behaviour/predict.d.ts.map +1 -1
  17. package/dist/behaviour/predict.js +6 -2
  18. package/dist/behaviour/reference-catalog.d.ts +16 -5
  19. package/dist/behaviour/reference-catalog.d.ts.map +1 -1
  20. package/dist/behaviour/reference-catalog.js +16 -5
  21. package/dist/behaviour/request.d.ts.map +1 -1
  22. package/dist/behaviour/request.js +3 -2
  23. package/dist/changed-roots.d.ts +6 -4
  24. package/dist/changed-roots.d.ts.map +1 -1
  25. package/dist/changed-roots.js +14 -18
  26. package/dist/ci-setup.d.ts +11 -0
  27. package/dist/ci-setup.d.ts.map +1 -0
  28. package/dist/ci-setup.js +41 -0
  29. package/dist/commands.d.ts.map +1 -1
  30. package/dist/commands.js +4 -3
  31. package/dist/components/capability-plugin.d.ts +105 -9
  32. package/dist/components/capability-plugin.d.ts.map +1 -1
  33. package/dist/components/capability-plugin.js +357 -36
  34. package/dist/components/compose-group.d.ts +145 -0
  35. package/dist/components/compose-group.d.ts.map +1 -0
  36. package/dist/components/compose-group.js +407 -0
  37. package/dist/components/placeholder-preview.d.ts +78 -0
  38. package/dist/components/placeholder-preview.d.ts.map +1 -0
  39. package/dist/components/placeholder-preview.js +254 -0
  40. package/dist/components/release-inputs.d.ts +29 -0
  41. package/dist/components/release-inputs.d.ts.map +1 -0
  42. package/dist/components/release-inputs.js +57 -0
  43. package/dist/components/trace-facts.d.ts +16 -0
  44. package/dist/components/trace-facts.d.ts.map +1 -0
  45. package/dist/components/trace-facts.js +19 -0
  46. package/dist/compose/apply-events.d.ts +46 -0
  47. package/dist/compose/apply-events.d.ts.map +1 -0
  48. package/dist/compose/apply-events.js +77 -0
  49. package/dist/compose/estate.d.ts +194 -0
  50. package/dist/compose/estate.d.ts.map +1 -0
  51. package/dist/compose/estate.js +363 -0
  52. package/dist/compose/hcl.d.ts +99 -0
  53. package/dist/compose/hcl.d.ts.map +1 -0
  54. package/dist/compose/hcl.js +302 -0
  55. package/dist/compose/module-address.d.ts +24 -0
  56. package/dist/compose/module-address.d.ts.map +1 -0
  57. package/dist/compose/module-address.js +43 -0
  58. package/dist/compose/root.d.ts +127 -0
  59. package/dist/compose/root.d.ts.map +1 -0
  60. package/dist/compose/root.js +586 -0
  61. package/dist/compose/run.d.ts +183 -0
  62. package/dist/compose/run.d.ts.map +1 -0
  63. package/dist/compose/run.js +447 -0
  64. package/dist/compose/slice.d.ts +102 -0
  65. package/dist/compose/slice.d.ts.map +1 -0
  66. package/dist/compose/slice.js +249 -0
  67. package/dist/compose/state-address.d.ts +28 -0
  68. package/dist/compose/state-address.d.ts.map +1 -0
  69. package/dist/compose/state-address.js +154 -0
  70. package/dist/compose/state-merge.d.ts +52 -0
  71. package/dist/compose/state-merge.d.ts.map +1 -0
  72. package/dist/compose/state-merge.js +135 -0
  73. package/dist/compose.d.ts +179 -0
  74. package/dist/compose.d.ts.map +1 -0
  75. package/dist/compose.js +482 -0
  76. package/dist/composites/terraform-apply-op.d.ts.map +1 -1
  77. package/dist/composites/terraform-apply-op.js +7 -3
  78. package/dist/cone.d.ts +53 -0
  79. package/dist/cone.d.ts.map +1 -0
  80. package/dist/cone.js +119 -0
  81. package/dist/config.d.ts +59 -13
  82. package/dist/config.d.ts.map +1 -1
  83. package/dist/config.js +43 -9
  84. package/dist/cost-hold.d.ts +27 -0
  85. package/dist/cost-hold.d.ts.map +1 -0
  86. package/dist/cost-hold.js +21 -0
  87. package/dist/describe-resources.d.ts +74 -12
  88. package/dist/describe-resources.d.ts.map +1 -1
  89. package/dist/describe-resources.js +374 -66
  90. package/dist/drift-read.d.ts +33 -0
  91. package/dist/drift-read.d.ts.map +1 -0
  92. package/dist/drift-read.js +243 -0
  93. package/dist/drift-record.d.ts +147 -0
  94. package/dist/drift-record.d.ts.map +1 -0
  95. package/dist/drift-record.js +383 -0
  96. package/dist/drift-rows.d.ts +61 -0
  97. package/dist/drift-rows.d.ts.map +1 -0
  98. package/dist/drift-rows.js +108 -0
  99. package/dist/exit-codes.d.ts +55 -0
  100. package/dist/exit-codes.d.ts.map +1 -0
  101. package/dist/exit-codes.js +48 -0
  102. package/dist/hcl/edges.d.ts.map +1 -1
  103. package/dist/hcl/edges.js +24 -1
  104. package/dist/hcl/files.d.ts +61 -0
  105. package/dist/hcl/files.d.ts.map +1 -0
  106. package/dist/hcl/files.js +221 -0
  107. package/dist/hcl/instances.d.ts +82 -0
  108. package/dist/hcl/instances.d.ts.map +1 -0
  109. package/dist/hcl/instances.js +390 -0
  110. package/dist/hcl/parse.d.ts +81 -9
  111. package/dist/hcl/parse.d.ts.map +1 -1
  112. package/dist/hcl/parse.js +114 -16
  113. package/dist/hcl/roots.d.ts.map +1 -1
  114. package/dist/hcl/roots.js +5 -0
  115. package/dist/hcl/suppressions.d.ts.map +1 -1
  116. package/dist/hcl/suppressions.js +8 -2
  117. package/dist/index.d.ts +13 -2
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +24 -2
  120. package/dist/integrity.json +8 -5
  121. package/dist/lint/audit-catalog.d.ts.map +1 -1
  122. package/dist/lint/audit-catalog.js +27 -3
  123. package/dist/lint/audit-lineage.d.ts +14 -2
  124. package/dist/lint/audit-lineage.d.ts.map +1 -1
  125. package/dist/lint/post-synth/index.d.ts.map +1 -1
  126. package/dist/lint/post-synth/index.js +4 -0
  127. package/dist/lint/post-synth/record-store.d.ts +54 -0
  128. package/dist/lint/post-synth/record-store.d.ts.map +1 -0
  129. package/dist/lint/post-synth/record-store.js +104 -0
  130. package/dist/lint/post-synth/tf001.d.ts +2 -2
  131. package/dist/lint/post-synth/tf001.js +2 -2
  132. package/dist/lint/post-synth/tf024.d.ts +35 -11
  133. package/dist/lint/post-synth/tf024.d.ts.map +1 -1
  134. package/dist/lint/post-synth/tf024.js +92 -20
  135. package/dist/lint/post-synth/tf046.d.ts +64 -0
  136. package/dist/lint/post-synth/tf046.d.ts.map +1 -0
  137. package/dist/lint/post-synth/tf046.js +175 -0
  138. package/dist/lint/post-synth/tf047.d.ts +36 -0
  139. package/dist/lint/post-synth/tf047.d.ts.map +1 -0
  140. package/dist/lint/post-synth/tf047.js +94 -0
  141. package/dist/live-plan-reasons.d.ts +21 -0
  142. package/dist/live-plan-reasons.d.ts.map +1 -0
  143. package/dist/live-plan-reasons.js +47 -0
  144. package/dist/lock-rows.d.ts +36 -0
  145. package/dist/lock-rows.d.ts.map +1 -0
  146. package/dist/lock-rows.js +60 -0
  147. package/dist/lock-timeout.d.ts +22 -0
  148. package/dist/lock-timeout.d.ts.map +1 -0
  149. package/dist/lock-timeout.js +32 -0
  150. package/dist/lsp/option-keys.d.ts.map +1 -1
  151. package/dist/lsp/option-keys.js +2 -0
  152. package/dist/manifest.json +1 -1
  153. package/dist/module-catalog/index.d.ts +69 -0
  154. package/dist/module-catalog/index.d.ts.map +1 -0
  155. package/dist/module-catalog/index.js +110 -0
  156. package/dist/module-catalog/refresh-cli.d.ts +4 -0
  157. package/dist/module-catalog/refresh-cli.d.ts.map +1 -0
  158. package/dist/module-catalog/refresh-cli.js +64 -0
  159. package/dist/module-catalog/static-tier.d.ts +6 -0
  160. package/dist/module-catalog/static-tier.d.ts.map +1 -0
  161. package/dist/module-catalog/static-tier.js +1650 -0
  162. package/dist/module-catalog/types.d.ts +65 -0
  163. package/dist/module-catalog/types.d.ts.map +1 -0
  164. package/dist/module-catalog/types.js +33 -0
  165. package/dist/okf/index.md +3 -1
  166. package/dist/okf/rules/TF024.md +2 -2
  167. package/dist/okf/rules/TF046.md +11 -0
  168. package/dist/okf/rules/TF047.md +11 -0
  169. package/dist/op/activities/index.d.ts +6 -2
  170. package/dist/op/activities/index.d.ts.map +1 -1
  171. package/dist/op/activities/index.js +5 -1
  172. package/dist/op/activities/live-detect.d.ts +4 -3
  173. package/dist/op/activities/live-detect.d.ts.map +1 -1
  174. package/dist/op/activities/live-detect.js +57 -32
  175. package/dist/op/activities/pin-rollout.d.ts +2 -0
  176. package/dist/op/activities/pin-rollout.d.ts.map +1 -1
  177. package/dist/op/activities/pin-rollout.js +1 -0
  178. package/dist/op/activities/terraform.d.ts +182 -5
  179. package/dist/op/activities/terraform.d.ts.map +1 -1
  180. package/dist/op/activities/terraform.js +224 -24
  181. package/dist/op/activity-contracts.d.ts +27 -0
  182. package/dist/op/activity-contracts.d.ts.map +1 -1
  183. package/dist/op/activity-contracts.js +19 -1
  184. package/dist/op/builders.d.ts +7 -1
  185. package/dist/op/builders.d.ts.map +1 -1
  186. package/dist/op/builders.js +9 -0
  187. package/dist/pin/consumers.d.ts +35 -0
  188. package/dist/pin/consumers.d.ts.map +1 -0
  189. package/dist/pin/consumers.js +70 -0
  190. package/dist/pin/edit.d.ts.map +1 -1
  191. package/dist/pin/edit.js +35 -0
  192. package/dist/pin/rollout.d.ts +2 -0
  193. package/dist/pin/rollout.d.ts.map +1 -1
  194. package/dist/pin/rollout.js +14 -11
  195. package/dist/plan-shape.d.ts +30 -0
  196. package/dist/plan-shape.d.ts.map +1 -0
  197. package/dist/plan-shape.js +125 -0
  198. package/dist/plugin.d.ts.map +1 -1
  199. package/dist/plugin.js +37 -18
  200. package/dist/registry/address.d.ts +63 -0
  201. package/dist/registry/address.d.ts.map +1 -0
  202. package/dist/registry/address.js +65 -0
  203. package/dist/registry/catalog-read.d.ts +14 -0
  204. package/dist/registry/catalog-read.d.ts.map +1 -0
  205. package/dist/registry/catalog-read.js +58 -0
  206. package/dist/registry/deprecated.d.ts +37 -0
  207. package/dist/registry/deprecated.d.ts.map +1 -0
  208. package/dist/registry/deprecated.js +43 -0
  209. package/dist/registry/docs.d.ts +96 -0
  210. package/dist/registry/docs.d.ts.map +1 -0
  211. package/dist/registry/docs.js +210 -0
  212. package/dist/registry/edge/edge.d.ts +46 -0
  213. package/dist/registry/edge/edge.d.ts.map +1 -0
  214. package/dist/registry/edge/edge.js +194 -0
  215. package/dist/registry/edge/index.d.ts +11 -0
  216. package/dist/registry/edge/index.d.ts.map +1 -0
  217. package/dist/registry/edge/index.js +10 -0
  218. package/dist/registry/edge/lambda-edge.d.ts +76 -0
  219. package/dist/registry/edge/lambda-edge.d.ts.map +1 -0
  220. package/dist/registry/edge/lambda-edge.js +95 -0
  221. package/dist/registry/edge/sigv4-web.d.ts +33 -0
  222. package/dist/registry/edge/sigv4-web.d.ts.map +1 -0
  223. package/dist/registry/edge/sigv4-web.js +56 -0
  224. package/dist/registry/edge/token-source.d.ts +73 -0
  225. package/dist/registry/edge/token-source.d.ts.map +1 -0
  226. package/dist/registry/edge/token-source.js +115 -0
  227. package/dist/registry/edge/worker.d.ts +45 -0
  228. package/dist/registry/edge/worker.d.ts.map +1 -0
  229. package/dist/registry/edge/worker.js +26 -0
  230. package/dist/registry/handler.d.ts +25 -0
  231. package/dist/registry/handler.d.ts.map +1 -0
  232. package/dist/registry/handler.js +75 -0
  233. package/dist/registry/headers-file.d.ts +21 -0
  234. package/dist/registry/headers-file.d.ts.map +1 -0
  235. package/dist/registry/headers-file.js +57 -0
  236. package/dist/registry/index.d.ts +31 -0
  237. package/dist/registry/index.d.ts.map +1 -0
  238. package/dist/registry/index.js +30 -0
  239. package/dist/registry/mirror-paths.d.ts +9 -0
  240. package/dist/registry/mirror-paths.d.ts.map +1 -0
  241. package/dist/registry/mirror-paths.js +8 -0
  242. package/dist/registry/mirror.d.ts +130 -0
  243. package/dist/registry/mirror.d.ts.map +1 -0
  244. package/dist/registry/mirror.js +319 -0
  245. package/dist/registry/proxies.d.ts +73 -0
  246. package/dist/registry/proxies.d.ts.map +1 -0
  247. package/dist/registry/proxies.js +111 -0
  248. package/dist/registry/reader.d.ts +57 -0
  249. package/dist/registry/reader.d.ts.map +1 -0
  250. package/dist/registry/reader.js +198 -0
  251. package/dist/registry/semver.d.ts +16 -0
  252. package/dist/registry/semver.d.ts.map +1 -0
  253. package/dist/registry/semver.js +24 -0
  254. package/dist/registry/serve.d.ts +24 -0
  255. package/dist/registry/serve.d.ts.map +1 -0
  256. package/dist/registry/serve.js +64 -0
  257. package/dist/registry/source-forms.d.ts +79 -0
  258. package/dist/registry/source-forms.d.ts.map +1 -0
  259. package/dist/registry/source-forms.js +202 -0
  260. package/dist/registry/targets/artifactory.d.ts +28 -0
  261. package/dist/registry/targets/artifactory.d.ts.map +1 -0
  262. package/dist/registry/targets/artifactory.js +206 -0
  263. package/dist/registry/targets/fake-artifactory.d.ts +30 -0
  264. package/dist/registry/targets/fake-artifactory.d.ts.map +1 -0
  265. package/dist/registry/targets/fake-artifactory.js +142 -0
  266. package/dist/registry/targets/fake-gitlab.d.ts +39 -0
  267. package/dist/registry/targets/fake-gitlab.d.ts.map +1 -0
  268. package/dist/registry/targets/fake-gitlab.js +136 -0
  269. package/dist/registry/targets/fake-hcp.d.ts +50 -0
  270. package/dist/registry/targets/fake-hcp.d.ts.map +1 -0
  271. package/dist/registry/targets/fake-hcp.js +202 -0
  272. package/dist/registry/targets/fake-http.d.ts +31 -0
  273. package/dist/registry/targets/fake-http.d.ts.map +1 -0
  274. package/dist/registry/targets/fake-http.js +87 -0
  275. package/dist/registry/targets/fake-nexus.d.ts +27 -0
  276. package/dist/registry/targets/fake-nexus.d.ts.map +1 -0
  277. package/dist/registry/targets/fake-nexus.js +137 -0
  278. package/dist/registry/targets/gitlab.d.ts +53 -0
  279. package/dist/registry/targets/gitlab.d.ts.map +1 -0
  280. package/dist/registry/targets/gitlab.js +187 -0
  281. package/dist/registry/targets/hcp.d.ts +29 -0
  282. package/dist/registry/targets/hcp.d.ts.map +1 -0
  283. package/dist/registry/targets/hcp.js +310 -0
  284. package/dist/registry/targets/hosted.d.ts +62 -0
  285. package/dist/registry/targets/hosted.d.ts.map +1 -0
  286. package/dist/registry/targets/hosted.js +74 -0
  287. package/dist/registry/targets/index.d.ts +18 -0
  288. package/dist/registry/targets/index.d.ts.map +1 -0
  289. package/dist/registry/targets/index.js +17 -0
  290. package/dist/registry/targets/module-target.d.ts +68 -0
  291. package/dist/registry/targets/module-target.d.ts.map +1 -0
  292. package/dist/registry/targets/module-target.js +63 -0
  293. package/dist/registry/targets/nexus.d.ts +43 -0
  294. package/dist/registry/targets/nexus.d.ts.map +1 -0
  295. package/dist/registry/targets/nexus.js +250 -0
  296. package/dist/registry/targets/zip.d.ts +55 -0
  297. package/dist/registry/targets/zip.d.ts.map +1 -0
  298. package/dist/registry/targets/zip.js +278 -0
  299. package/dist/registry/writer.d.ts +101 -0
  300. package/dist/registry/writer.d.ts.map +1 -0
  301. package/dist/registry/writer.js +109 -0
  302. package/dist/report.d.ts +15 -6
  303. package/dist/report.d.ts.map +1 -1
  304. package/dist/report.js +28 -55
  305. package/dist/rules/record-store.ts +122 -0
  306. package/dist/rules/tf001.ts +2 -2
  307. package/dist/rules/tf024.ts +105 -22
  308. package/dist/rules/tf046.ts +204 -0
  309. package/dist/rules/tf047.ts +114 -0
  310. package/dist/skills/chant-terraform.md +1 -1
  311. package/dist/state/azure-blob.d.ts +9 -0
  312. package/dist/state/azure-blob.d.ts.map +1 -0
  313. package/dist/state/azure-blob.js +8 -0
  314. package/dist/state/backend.d.ts +158 -0
  315. package/dist/state/backend.d.ts.map +1 -0
  316. package/dist/state/backend.js +406 -0
  317. package/dist/state/exec.d.ts +39 -0
  318. package/dist/state/exec.d.ts.map +1 -0
  319. package/dist/state/exec.js +80 -0
  320. package/dist/state/gcs.d.ts +8 -0
  321. package/dist/state/gcs.d.ts.map +1 -0
  322. package/dist/state/gcs.js +7 -0
  323. package/dist/state/index.d.ts +15 -0
  324. package/dist/state/index.d.ts.map +1 -0
  325. package/dist/state/index.js +14 -0
  326. package/dist/state/locks.d.ts +105 -0
  327. package/dist/state/locks.d.ts.map +1 -0
  328. package/dist/state/locks.js +130 -0
  329. package/dist/state/object-store.d.ts +8 -0
  330. package/dist/state/object-store.d.ts.map +1 -0
  331. package/dist/state/object-store.js +7 -0
  332. package/dist/state/root-states.d.ts +131 -0
  333. package/dist/state/root-states.d.ts.map +1 -0
  334. package/dist/state/root-states.js +241 -0
  335. package/dist/state/s3.d.ts +21 -0
  336. package/dist/state/s3.d.ts.map +1 -0
  337. package/dist/state/s3.js +19 -0
  338. package/dist/state/store.d.ts +51 -0
  339. package/dist/state/store.d.ts.map +1 -0
  340. package/dist/state/store.js +185 -0
  341. package/dist/state-ops.d.ts +255 -0
  342. package/dist/state-ops.d.ts.map +1 -0
  343. package/dist/state-ops.js +305 -0
  344. package/dist/state-reads.d.ts +57 -0
  345. package/dist/state-reads.d.ts.map +1 -0
  346. package/dist/state-reads.js +104 -0
  347. package/dist/terragrunt/affected.d.ts.map +1 -1
  348. package/dist/terragrunt/affected.js +2 -1
  349. package/dist/used-sources.d.ts +54 -0
  350. package/dist/used-sources.d.ts.map +1 -0
  351. package/dist/used-sources.js +157 -0
  352. package/package.json +24 -4
  353. package/src/__fixtures__/ACCEPTANCE.md +69 -7
  354. package/src/__fixtures__/compose/apply-failed-in-app.jsonl +12 -0
  355. package/src/__fixtures__/compose/state-app.json +66 -0
  356. package/src/__fixtures__/compose/state-edge.json +40 -0
  357. package/src/__fixtures__/compose/state-net.json +58 -0
  358. package/src/__fixtures__/compose/three-app.plan.json +184 -0
  359. package/src/__fixtures__/compose/three-composed.plan.json +509 -0
  360. package/src/__fixtures__/compose/three-edge.plan.json +144 -0
  361. package/src/__fixtures__/compose/three-net.plan.json +174 -0
  362. package/src/__fixtures__/compose/unknown-composed.plan.json +228 -0
  363. package/src/__fixtures__/compose/working-after-apply.json +145 -0
  364. package/src/__fixtures__/config-blocks/app/main.tf +61 -0
  365. package/src/__fixtures__/config-blocks/app/modules/network/main.tf +4 -0
  366. package/src/__fixtures__/config-blocks/app-json/main.tf.json +39 -0
  367. package/src/__fixtures__/config-files/shadow/main.tf +3 -0
  368. package/src/__fixtures__/config-files/shadow/main.tofu +3 -0
  369. package/src/__fixtures__/config-files/shadow/other.tf +3 -0
  370. package/src/__fixtures__/config-files/tf/main.tf +11 -0
  371. package/src/__fixtures__/config-files/tf-json/main.tf.json +18 -0
  372. package/src/__fixtures__/config-files/tofu/main.tofu +11 -0
  373. package/src/__fixtures__/config-files/tofu-json/main.tofu.json +18 -0
  374. package/src/__fixtures__/config-files/tofu-only/main.tofu +3 -0
  375. package/src/__fixtures__/drift-record/README.md +16 -0
  376. package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
  377. package/src/__fixtures__/drift-rows/live-root-plan.json +70 -0
  378. package/src/__fixtures__/drift-rows/refresh-plan.json +61 -0
  379. package/src/__fixtures__/instance-forms/app/main.tf +110 -0
  380. package/src/__fixtures__/instance-forms/app/modules/svc/main.tf +3 -0
  381. package/src/__fixtures__/instance-vars/app/main.tf +52 -0
  382. package/src/__fixtures__/instance-vars/app/modules/app/main.tf +12 -0
  383. package/src/__fixtures__/instance-vars/app/modules/edge/main.tf +3 -0
  384. package/src/__fixtures__/instance-vars/app/terraform.tfvars +1 -0
  385. package/src/__fixtures__/live-module-keyed/live-graph.json +259 -0
  386. package/src/__fixtures__/live-module-keyed/live-plan.json +87 -0
  387. package/src/__fixtures__/live-module-keyed/root/estate.chdf.hcl +1 -0
  388. package/src/__fixtures__/live-module-keyed/root/main.tf +21 -0
  389. package/src/__fixtures__/live-module-keyed/root/modules/app/main.tf +17 -0
  390. package/src/__fixtures__/live-module-keyed/root/modules/edge/main.tf +7 -0
  391. package/src/__fixtures__/live-module-keyed/root/versions.tf +30 -0
  392. package/src/__fixtures__/live-module-keyed/show-state.json +146 -0
  393. package/src/__fixtures__/pr-loop/README.md +50 -0
  394. package/src/__fixtures__/pr-loop/chant.config.json +13 -0
  395. package/src/__fixtures__/pr-loop/estate.component.ts +10 -0
  396. package/src/__fixtures__/pr-loop/roots/a/main.tf +11 -0
  397. package/src/__fixtures__/pr-loop/roots/app/main.tf +19 -0
  398. package/src/__fixtures__/pr-loop/roots/b/main.tf +7 -0
  399. package/src/__fixtures__/pr-loop/roots/dns/main.tf +3 -0
  400. package/src/__fixtures__/pr-loop/roots/net/main.tf +7 -0
  401. package/src/__fixtures__/report/applied.show.json +51 -0
  402. package/src/__fixtures__/report/generate.ts +63 -0
  403. package/src/__fixtures__/report/plan.show.json +200 -0
  404. package/src/__fixtures__/report/tf-apply/change-set.json +170 -0
  405. package/src/__fixtures__/report/tf-apply/report.json +338 -0
  406. package/src/__fixtures__/report/tf-plan/change-set.json +170 -0
  407. package/src/__fixtures__/report/tf-plan/report.json +320 -0
  408. package/src/__fixtures__/three-cloud-azure.graph.json +290 -0
  409. package/src/__fixtures__/used-sources/root/extra.tofu +1 -0
  410. package/src/__fixtures__/used-sources/root/main.tf +31 -0
  411. package/src/__fixtures__/used-sources/root/modules/net/main.tf +14 -0
  412. package/src/__fixtures__/used-sources/root/modules/net/versions.tf.json +7 -0
  413. package/src/__fixtures__/used-sources/unit/terragrunt.hcl +3 -0
  414. package/src/applied-state.ts +52 -0
  415. package/src/backend-config.test.ts +105 -0
  416. package/src/backend-config.ts +133 -0
  417. package/src/behaviour/kinds.ts +4 -0
  418. package/src/behaviour/predict.ts +5 -2
  419. package/src/behaviour/reference-catalog.plugin.test.ts +65 -0
  420. package/src/behaviour/reference-catalog.ts +16 -5
  421. package/src/behaviour/request.ts +3 -2
  422. package/src/change-set-instances.test.ts +98 -0
  423. package/src/changed-roots.ts +14 -16
  424. package/src/ci-setup.ts +42 -0
  425. package/src/commands.ts +4 -3
  426. package/src/components/capability-plugin.test.ts +198 -19
  427. package/src/components/capability-plugin.ts +383 -35
  428. package/src/components/change-set-graph.e2e.test.ts +11 -5
  429. package/src/components/compose-group.test.ts +486 -0
  430. package/src/components/compose-group.ts +489 -0
  431. package/src/components/demo-composed-roots.e2e.test.ts +440 -0
  432. package/src/components/member-outputs.test.ts +76 -0
  433. package/src/components/placeholder-preview.test.ts +147 -0
  434. package/src/components/placeholder-preview.ts +257 -0
  435. package/src/components/pr-loop-compose.tofu.e2e.test.ts +363 -0
  436. package/src/components/pr-loop.tofu.test.ts +113 -57
  437. package/src/components/release-inputs.ts +69 -0
  438. package/src/components/trace-facts.test.ts +21 -0
  439. package/src/components/trace-facts.ts +27 -0
  440. package/src/compose/apply-events.test.ts +62 -0
  441. package/src/compose/apply-events.ts +100 -0
  442. package/src/compose/estate.choudoufu.e2e.test.ts +112 -0
  443. package/src/compose/estate.test.ts +421 -0
  444. package/src/compose/estate.ts +443 -0
  445. package/src/compose/hcl.ts +311 -0
  446. package/src/compose/module-address.ts +49 -0
  447. package/src/compose/root.test.ts +416 -0
  448. package/src/compose/root.ts +592 -0
  449. package/src/compose/run.test.ts +440 -0
  450. package/src/compose/run.tofu.test.ts +176 -0
  451. package/src/compose/run.ts +527 -0
  452. package/src/compose/slice.test.ts +184 -0
  453. package/src/compose/slice.ts +290 -0
  454. package/src/compose/state-address.ts +157 -0
  455. package/src/compose/state-merge.test.ts +131 -0
  456. package/src/compose/state-merge.ts +148 -0
  457. package/src/compose.test.ts +248 -0
  458. package/src/compose.ts +627 -0
  459. package/src/composites/terraform-apply-op.test.ts +9 -0
  460. package/src/composites/terraform-apply-op.ts +7 -3
  461. package/src/cone.ts +138 -0
  462. package/src/config-file-listers.test.ts +265 -0
  463. package/src/config.ts +44 -9
  464. package/src/cost-hold.ts +29 -0
  465. package/src/describe-resources.engine-facts.test.ts +411 -0
  466. package/src/describe-resources.live-module-keyed.test.ts +290 -0
  467. package/src/describe-resources.ts +416 -70
  468. package/src/drift-read.ts +284 -0
  469. package/src/drift-record.test.ts +223 -0
  470. package/src/drift-record.ts +455 -0
  471. package/src/drift-rows.test.ts +135 -0
  472. package/src/drift-rows.ts +137 -0
  473. package/src/exit-codes.test.ts +23 -0
  474. package/src/exit-codes.ts +59 -0
  475. package/src/hcl/config-blocks.test.ts +174 -0
  476. package/src/hcl/edges.ts +21 -1
  477. package/src/hcl/files.ts +234 -0
  478. package/src/hcl/instance-forms.test.ts +94 -0
  479. package/src/hcl/instances.test.ts +137 -0
  480. package/src/hcl/instances.ts +422 -0
  481. package/src/hcl/parse.test.ts +139 -1
  482. package/src/hcl/parse.ts +149 -16
  483. package/src/hcl/roots.ts +6 -0
  484. package/src/hcl/suppressions.ts +8 -2
  485. package/src/index.ts +79 -0
  486. package/src/lint/audit-catalog.ts +29 -3
  487. package/src/lint/audit-lineage.ts +14 -2
  488. package/src/lint/post-synth/fixtures/TF024/live-with-record-store/main.tf +18 -0
  489. package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/estate.chdf.hcl +1 -0
  490. package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/main.tf +10 -0
  491. package/src/lint/post-synth/fixtures/TF046/azurerm-no-resource-group/main.tf +15 -0
  492. package/src/lint/post-synth/fixtures/TF046/backend-config-only/main.tf +14 -0
  493. package/src/lint/post-synth/fixtures/TF046/derived-s3/backend.tf +7 -0
  494. package/src/lint/post-synth/fixtures/TF046/derived-s3/main.tf +9 -0
  495. package/src/lint/post-synth/fixtures/TF046/explicit-local/main.tf +16 -0
  496. package/src/lint/post-synth/fixtures/TF046/explicit-s3-beside-local-backend/main.tf +15 -0
  497. package/src/lint/post-synth/fixtures/TF046/implied-local/main.tf +9 -0
  498. package/src/lint/post-synth/fixtures/TF046/sidecar-implied/estate.chdf.hcl +1 -0
  499. package/src/lint/post-synth/fixtures/TF046/sidecar-implied/main.tf +5 -0
  500. package/src/lint/post-synth/fixtures/TF047/clear/main.tf +12 -0
  501. package/src/lint/post-synth/fixtures/TF047/refused/main.tf +12 -0
  502. package/src/lint/post-synth/fixtures/TF047/unknown-module/main.tf +12 -0
  503. package/src/lint/post-synth/fixtures/TF047/unknown-version/main.tf +12 -0
  504. package/src/lint/post-synth/index.ts +4 -0
  505. package/src/lint/post-synth/record-store.ts +122 -0
  506. package/src/lint/post-synth/tf001.ts +2 -2
  507. package/src/lint/post-synth/tf024.test.ts +26 -5
  508. package/src/lint/post-synth/tf024.ts +105 -22
  509. package/src/lint/post-synth/tf046.test.ts +137 -0
  510. package/src/lint/post-synth/tf046.ts +204 -0
  511. package/src/lint/post-synth/tf047.test.ts +56 -0
  512. package/src/lint/post-synth/tf047.ts +114 -0
  513. package/src/live-plan-reasons.ts +54 -0
  514. package/src/lock-rows.test.ts +70 -0
  515. package/src/lock-rows.ts +82 -0
  516. package/src/lock-timeout.ts +34 -0
  517. package/src/lsp/completions.test.ts +1 -1
  518. package/src/lsp/option-keys.ts +2 -0
  519. package/src/module-catalog/index.test.ts +93 -0
  520. package/src/module-catalog/index.ts +159 -0
  521. package/src/module-catalog/refresh-cli.ts +68 -0
  522. package/src/module-catalog/static-tier.ts +1659 -0
  523. package/src/module-catalog/types.ts +88 -0
  524. package/src/op/activities/choudoufu-plan-set-op.test.ts +111 -0
  525. package/src/op/activities/index.ts +9 -0
  526. package/src/op/activities/live-detect.ts +55 -26
  527. package/src/op/activities/pin-rollout.ts +3 -0
  528. package/src/op/activities/registry.test.ts +2 -1
  529. package/src/op/activities/terraform.test.ts +55 -0
  530. package/src/op/activities/terraform.ts +312 -27
  531. package/src/op/activity-contracts.test.ts +1 -0
  532. package/src/op/activity-contracts.ts +24 -1
  533. package/src/op/builders.ts +14 -0
  534. package/src/op-wave-step.test.ts +109 -0
  535. package/src/pin/__fixtures__/consumers/live/dev/main.tf +4 -0
  536. package/src/pin/__fixtures__/consumers/live/prod/main.tf +21 -0
  537. package/src/pin/__fixtures__/consumers/units/vpc/terragrunt.hcl +7 -0
  538. package/src/pin/bundle.test.ts +2 -0
  539. package/src/pin/consumers.test.ts +57 -0
  540. package/src/pin/consumers.ts +95 -0
  541. package/src/pin/edit.ts +30 -0
  542. package/src/pin/rollout.ts +16 -11
  543. package/src/plan-shape.test.ts +148 -0
  544. package/src/plan-shape.ts +128 -0
  545. package/src/plugin.ts +39 -19
  546. package/src/registry/__fixtures__/docs/documented/.terraform-docs.yml +3 -0
  547. package/src/registry/__fixtures__/docs/documented/README.md +1 -0
  548. package/src/registry/__fixtures__/docs/documented/main.tf +8 -0
  549. package/src/registry/__fixtures__/docs/json/main.tf.json +14 -0
  550. package/src/registry/__fixtures__/docs/vpc/README.md +3 -0
  551. package/src/registry/__fixtures__/docs/vpc/examples/complete/main.tf +5 -0
  552. package/src/registry/__fixtures__/docs/vpc/examples/simple/README.md +1 -0
  553. package/src/registry/__fixtures__/docs/vpc/examples/simple/main.tf +4 -0
  554. package/src/registry/__fixtures__/docs/vpc/main.tf +14 -0
  555. package/src/registry/__fixtures__/docs/vpc/outputs.tf +9 -0
  556. package/src/registry/__fixtures__/docs/vpc/variables.tf +16 -0
  557. package/src/registry/__fixtures__/proxied-root/main.tf +12 -0
  558. package/src/registry/address.ts +100 -0
  559. package/src/registry/catalog-read.ts +56 -0
  560. package/src/registry/deprecated.test.ts +139 -0
  561. package/src/registry/deprecated.ts +76 -0
  562. package/src/registry/docs.test.ts +140 -0
  563. package/src/registry/docs.ts +299 -0
  564. package/src/registry/edge/bundle.test.ts +50 -0
  565. package/src/registry/edge/edge.test.ts +176 -0
  566. package/src/registry/edge/edge.ts +211 -0
  567. package/src/registry/edge/index.ts +10 -0
  568. package/src/registry/edge/lambda-edge.ts +127 -0
  569. package/src/registry/edge/sigv4-web.ts +79 -0
  570. package/src/registry/edge/token-source.test.ts +258 -0
  571. package/src/registry/edge/token-source.ts +169 -0
  572. package/src/registry/edge/worker.ts +61 -0
  573. package/src/registry/handler.ts +89 -0
  574. package/src/registry/headers-file.ts +61 -0
  575. package/src/registry/index.ts +31 -0
  576. package/src/registry/mirror-paths.ts +10 -0
  577. package/src/registry/mirror.test.ts +198 -0
  578. package/src/registry/mirror.ts +395 -0
  579. package/src/registry/proxies.test.ts +153 -0
  580. package/src/registry/proxies.ts +132 -0
  581. package/src/registry/reader.ts +225 -0
  582. package/src/registry/registry.test.ts +262 -0
  583. package/src/registry/semver.ts +34 -0
  584. package/src/registry/serve.ts +82 -0
  585. package/src/registry/source-forms.test.ts +87 -0
  586. package/src/registry/source-forms.ts +216 -0
  587. package/src/registry/targets/artifactory.test.ts +248 -0
  588. package/src/registry/targets/artifactory.ts +257 -0
  589. package/src/registry/targets/fake-artifactory.ts +158 -0
  590. package/src/registry/targets/fake-gitlab.ts +161 -0
  591. package/src/registry/targets/fake-hcp.ts +233 -0
  592. package/src/registry/targets/fake-http.ts +97 -0
  593. package/src/registry/targets/fake-nexus.ts +152 -0
  594. package/src/registry/targets/gitlab.test.ts +208 -0
  595. package/src/registry/targets/gitlab.ts +223 -0
  596. package/src/registry/targets/hcp.test.ts +230 -0
  597. package/src/registry/targets/hcp.ts +360 -0
  598. package/src/registry/targets/hosted.ts +117 -0
  599. package/src/registry/targets/index.ts +17 -0
  600. package/src/registry/targets/module-target.ts +131 -0
  601. package/src/registry/targets/nexus.test.ts +220 -0
  602. package/src/registry/targets/nexus.ts +314 -0
  603. package/src/registry/targets/zip.test.ts +65 -0
  604. package/src/registry/targets/zip.ts +287 -0
  605. package/src/registry/writer.ts +155 -0
  606. package/src/report.test.ts +82 -1
  607. package/src/report.ts +31 -54
  608. package/src/signal-only-root.test.ts +72 -0
  609. package/src/skills/chant-terraform.md +1 -1
  610. package/src/state/azure-blob.ts +8 -0
  611. package/src/state/backend-verdict.test.ts +187 -0
  612. package/src/state/backend.test.ts +127 -0
  613. package/src/state/backend.ts +488 -0
  614. package/src/state/exec.ts +111 -0
  615. package/src/state/gcs.ts +7 -0
  616. package/src/state/index.ts +15 -0
  617. package/src/state/locks.test.ts +84 -0
  618. package/src/state/locks.ts +201 -0
  619. package/src/state/object-store.ts +7 -0
  620. package/src/state/root-states-floci.e2e.test.ts +66 -0
  621. package/src/state/root-states.test.ts +462 -0
  622. package/src/state/root-states.ts +309 -0
  623. package/src/state/s3.ts +21 -0
  624. package/src/state/store.ts +225 -0
  625. package/src/state-ops.test.ts +182 -0
  626. package/src/state-ops.ts +462 -0
  627. package/src/state-reads.ts +116 -0
  628. package/src/terragrunt/affected.ts +2 -1
  629. package/src/used-sources.test.ts +75 -0
  630. package/src/used-sources.ts +204 -0
  631. package/src/workspace-kinds.test.ts +4 -17
  632. package/workspace-kinds.json +1 -24
  633. package/dist/workspace-member.d.ts +0 -30
  634. package/dist/workspace-member.d.ts.map +0 -1
  635. package/dist/workspace-member.js +0 -91
  636. package/schemas/pulumi.schema.json +0 -34
  637. package/src/testdata/pulumi-member/Pulumi.yaml +0 -2
  638. package/src/testdata/pulumi-member/stack-export.json +0 -53
  639. package/src/testdata/pulumi-unexported/Pulumi.yaml +0 -2
  640. package/src/workspace-member.test.ts +0 -89
  641. package/src/workspace-member.ts +0 -126
@@ -0,0 +1,383 @@
1
+ /**
2
+ * Drift-record adapters for the terraform family (#4451): a stock root's
3
+ * state read and plan, and a choudoufu live root's `live-plan -json`,
4
+ * `live-ls -json` and plan, each into `@intentius/chant/drift-record`
5
+ * records.
6
+ *
7
+ * | source | read | status |
8
+ * |---|---|---|
9
+ * | `show -json` over state | `state` | in state: recorded. Declared and not in state: pending |
10
+ * | `show -json` of a saved plan | `plan` | no `resource_drift` row: in-sync. Drift update: drifted with paths. Drift delete: missing. Create with no prior row: pending. Delete with no drift: undeclared |
11
+ * | `live-plan -json` | `ownership` | `bound[]`: in-sync, owned by its `source`. `unowned[]` and `adoptable[]`: unclaimed. `ABSENT`: pending. Any other omission: not-observed. `foreign[]`: undeclared, foreign. `controller_held[]`: runtime |
12
+ * | `live-ls -json` | `ownership` | `declared: false`: undeclared. A gap no live-plan row answers: not-observed |
13
+ * | live-plan and a plan together | `plan` | bound with a planned update or replace: drifted with paths, the live-plan ownership kept |
14
+ *
15
+ * A state read never says in-sync or drifted: `driftRecord` refuses it.
16
+ *
17
+ * An omission keeps its token in `evidence.engineCode`, and so does the
18
+ * `UNOWNED` omission that has no `unowned[]` row: chant reads it as
19
+ * not-observed (`read-failed`), not as unclaimed, since nothing in the
20
+ * document says what holds the identity.
21
+ *
22
+ * ## Values
23
+ *
24
+ * Attribute values come from `./plan-observation.ts`, which already replaced
25
+ * every value the planner flagged, or that equals a flagged string, with
26
+ * `(sensitive)`. Here a `(sensitive)` side makes the attribute `sensitive:
27
+ * true` with neither value, and the record constructor's key-name pass runs
28
+ * after. `before` is what was expected and `after` what the read found, so
29
+ * a stock root's drift row reads state then refreshed object, and a live
30
+ * root's planned update reads declared then live (the plan's after, then
31
+ * its before).
32
+ *
33
+ * ## The import graph
34
+ *
35
+ * Like `./change-set.ts`, this imports chant's `drift-record` subpath, the
36
+ * plan projection and the omission table, never the lexicon's entry point
37
+ * or `./describe-resources.ts`, so it bundles without TypeScript, node's
38
+ * process modules or the lint rules (#3421).
39
+ */
40
+ import { driftRecord, placeDriftRecord, } from "@intentius/chant/drift-record";
41
+ import { LIVE_PLAN_OMISSION_REASONS, readsAsCredentials } from "./live-plan-reasons.js";
42
+ import { blockAddressOf, indexPlan, KNOWN_AFTER_APPLY, SENSITIVE_VALUE } from "./plan-observation.js";
43
+ const isObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
44
+ const asArray = (v) => (Array.isArray(v) ? v : []);
45
+ const asString = (v) => (typeof v === "string" && v.length > 0 ? v : undefined);
46
+ const byString = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
47
+ const byAddress = (a, b) => byString(a.address, b.address);
48
+ /** True for an address inside a `data` block, which has no drift. */
49
+ function isDataAddress(address) {
50
+ return /(^|\.)data\./.test(blockAddressOf(address));
51
+ }
52
+ function common(input, engine, read, address) {
53
+ return {
54
+ member: input.member,
55
+ engine,
56
+ address,
57
+ ...placeDriftRecord(input, engine, address),
58
+ observedAt: input.observedAt,
59
+ read,
60
+ ...(input.fellBackFrom !== undefined ? { fellBackFrom: input.fellBackFrom } : {}),
61
+ };
62
+ }
63
+ /** One projected plan change as a drift attribute. `swap` reads the change's after as expected. */
64
+ function attributeOf(change, swap) {
65
+ const path = change.path;
66
+ if (change.before === SENSITIVE_VALUE || change.after === SENSITIVE_VALUE)
67
+ return { path, sensitive: true };
68
+ const expected = swap ? change.after : change.before;
69
+ const found = swap ? change.before : change.after;
70
+ return {
71
+ path,
72
+ ...(expected !== null && expected !== undefined && expected !== KNOWN_AFTER_APPLY ? { before: expected } : {}),
73
+ ...(found !== null && found !== undefined && found !== KNOWN_AFTER_APPLY ? { after: found } : {}),
74
+ };
75
+ }
76
+ // ── state ──────────────────────────────────────────────────────────────────────
77
+ /** Every managed resource row of a `show -json` state document: address and type. */
78
+ function stateRows(showJson) {
79
+ const rows = new Map();
80
+ const walk = (module, prefix) => {
81
+ const node = isObject(module) ? module : {};
82
+ for (const entry of asArray(node.resources)) {
83
+ if (!isObject(entry))
84
+ continue;
85
+ const raw = asString(entry.address);
86
+ if (!raw || entry.mode === "data")
87
+ continue;
88
+ const address = prefix && !raw.startsWith(`${prefix}.`) ? `${prefix}.${raw}` : raw;
89
+ rows.set(address, asString(entry.type) ? { type: asString(entry.type) } : {});
90
+ }
91
+ for (const child of asArray(node.child_modules)) {
92
+ if (isObject(child))
93
+ walk(child, asString(child.address) ?? prefix);
94
+ }
95
+ };
96
+ const doc = isObject(showJson) ? showJson : {};
97
+ walk(isObject(doc.values) ? doc.values.root_module : undefined, "");
98
+ return rows;
99
+ }
100
+ /**
101
+ * A stock root's records from its state: every managed instance in state is
102
+ * recorded, every declared block with no instance there is pending, and a
103
+ * failed read makes every declared block not-observed. Never in-sync or
104
+ * drifted: state says what the last apply recorded, not what the account
105
+ * holds.
106
+ */
107
+ export function terraformStateDriftRecords(input) {
108
+ const engine = input.engine ?? "terraform";
109
+ const evidence = { tool: engine, ...(input.version ? { version: input.version } : {}), command: `${engine} show -json` };
110
+ if (input.failed) {
111
+ return (input.declared ?? [])
112
+ .map((address) => driftRecord({
113
+ ...common(input, engine, "state", address),
114
+ status: "not-observed",
115
+ unobserved: { reason: input.failed.reason, ...(input.failed.detail ? { detail: input.failed.detail } : {}) },
116
+ evidence,
117
+ }))
118
+ .sort(byAddress);
119
+ }
120
+ const rows = stateRows(input.state);
121
+ const out = [];
122
+ for (const [address, row] of rows) {
123
+ out.push(driftRecord({ ...common(input, engine, "state", address), ...(row.type ? { resourceType: row.type } : {}), status: "recorded", ownership: { verdict: "owned", by: "state" }, evidence }));
124
+ }
125
+ const blocks = new Set([...rows.keys()].map(blockAddressOf));
126
+ for (const address of input.declared ?? []) {
127
+ if (blocks.has(address) || rows.has(address))
128
+ continue;
129
+ out.push(driftRecord({ ...common(input, engine, "state", address), status: "pending", evidence }));
130
+ }
131
+ return out.sort(byAddress);
132
+ }
133
+ /**
134
+ * A stock root's records from a saved plan's `show -json`, one per managed
135
+ * instance the plan names. A `resource_drift[]` row decides: update is
136
+ * drifted with its paths (before is state, after the refreshed object),
137
+ * delete is missing. With no drift row, a create with no prior-state row is
138
+ * pending, a delete or forget the configuration no longer declares is
139
+ * undeclared, and anything else is in-sync, since a planned change from
140
+ * configuration is the change set's to show and not drift.
141
+ */
142
+ export function terraformPlanDriftRecords(input) {
143
+ const engine = input.engine ?? "terraform";
144
+ const doc = isObject(input.plan) ? input.plan : {};
145
+ const version = input.version ?? asString(doc.terraform_version);
146
+ const evidence = { tool: engine, ...(version ? { version } : {}), command: `${engine} show -json` };
147
+ const index = indexPlan(input.plan);
148
+ const prior = stateRows({ values: isObject(index.priorState) ? index.priorState.values : undefined });
149
+ const types = new Map();
150
+ for (const entry of asArray(doc.resource_changes)) {
151
+ if (isObject(entry) && asString(entry.address) && asString(entry.type))
152
+ types.set(entry.address, entry.type);
153
+ }
154
+ const addresses = [...new Set([...index.changes.keys(), ...index.drift.keys()])].filter((a) => !isDataAddress(a)).sort(byString);
155
+ return addresses.map((address) => {
156
+ const type = types.get(address) ?? prior.get(address)?.type;
157
+ const at = { ...common(input, engine, "plan", address), ...(type ? { resourceType: type } : {}), evidence };
158
+ const drift = index.drift.get(address);
159
+ if (drift?.actions.includes("delete"))
160
+ return driftRecord({ ...at, status: "missing" });
161
+ if (drift && drift.actions.includes("update")) {
162
+ const attributes = drift.changes.map((c) => attributeOf(c, false));
163
+ return driftRecord({ ...at, status: "drifted", ...(attributes.length > 0 ? { attributes } : {}) });
164
+ }
165
+ const actions = index.changes.get(address)?.actions ?? [];
166
+ if (actions.length === 1 && actions[0] === "create" && !prior.has(address))
167
+ return driftRecord({ ...at, status: "pending" });
168
+ if (actions.length === 1 && (actions[0] === "delete" || actions[0] === "forget"))
169
+ return driftRecord({ ...at, status: "undeclared" });
170
+ return driftRecord({ ...at, status: "in-sync" });
171
+ });
172
+ }
173
+ // ── choudoufu live-plan ────────────────────────────────────────────────────────
174
+ const BOUND_SOURCES = ["marker", "record", "derived", "cache"];
175
+ /**
176
+ * A live root's records from `live-plan -json`, read `ownership`, one per
177
+ * address the document names.
178
+ *
179
+ * - `bound[]`: in-sync, `owned` by the row's `source`, the marker on the
180
+ * object exactly when the source is `marker`.
181
+ * - `unowned[]`: unclaimed, `adoptable` when the row carries the adopting
182
+ * tag values and `foreign` otherwise, with the estate it does carry. It
183
+ * answers before the paired `UNOWNED` omission.
184
+ * - `adoptable[]`: unclaimed, `adoptable`, the paired omission's token kept.
185
+ * - an `ABSENT` omission: pending.
186
+ * - any other omission, `UNOWNED` with no row included: not-observed with
187
+ * the reason `LIVE_PLAN_OMISSION_REASONS` gives (`VERIFIED_NOT_IMPORTABLE`
188
+ * read-failed, `OUT_OF_SCOPE` filtered), a credentials failure named as
189
+ * such.
190
+ * - `foreign[]`: undeclared, `foreign`, addressed by its identity.
191
+ * - `controller_held[]`: runtime, `foreign`, held by its controller,
192
+ * addressed by the marker's address when it has one and its identity
193
+ * otherwise.
194
+ */
195
+ export function choudoufuLivePlanDriftRecords(input) {
196
+ const doc = isObject(input.livePlan) ? input.livePlan : {};
197
+ const version = input.version ?? asString(doc.choudoufu_version);
198
+ const evidence = (engineCode) => ({
199
+ tool: "choudoufu",
200
+ ...(version ? { version } : {}),
201
+ command: "choudoufu live-plan -json",
202
+ ...(engineCode ? { engineCode } : {}),
203
+ });
204
+ const out = new Map();
205
+ const put = (address, record) => {
206
+ if (!out.has(address))
207
+ out.set(address, driftRecord({ ...common(input, "choudoufu", "ownership", address), ...record }));
208
+ };
209
+ const typed = (row) => (asString(row.type) ? { resourceType: asString(row.type) } : {});
210
+ const omissions = new Map();
211
+ for (const row of asArray(doc.omissions).filter(isObject)) {
212
+ const addr = asString(row.addr);
213
+ if (addr)
214
+ omissions.set(addr, { reason: asString(row.reason) ?? "", detail: asString(row.detail) ?? "" });
215
+ }
216
+ for (const row of asArray(doc.unowned).filter(isObject)) {
217
+ const addr = asString(row.addr);
218
+ if (!addr)
219
+ continue;
220
+ const heldBy = asString(row.tofu_estate);
221
+ const adopt = asString(row.adopt_tofu_address);
222
+ const ownership = adopt || asString(row.adopt_tofu_estate)
223
+ ? { verdict: "adoptable", markerOnObject: heldBy !== undefined, ...(heldBy ? { by: "marker", ownedBy: heldBy } : {}), ...(adopt ? { adopt } : {}) }
224
+ : { verdict: "foreign", markerOnObject: heldBy !== undefined, ...(heldBy ? { by: "marker", ownedBy: heldBy } : {}) };
225
+ put(addr, { ...typed(row), status: "unclaimed", ownership, evidence: evidence(omissions.get(addr)?.reason || "UNOWNED") });
226
+ }
227
+ for (const row of asArray(doc.bound).filter(isObject)) {
228
+ const addr = asString(row.addr);
229
+ if (!addr)
230
+ continue;
231
+ const source = asString(row.source);
232
+ const by = BOUND_SOURCES.find((s) => s === source);
233
+ put(addr, { ...typed(row), status: "in-sync", ownership: { verdict: "owned", ...(by ? { by } : {}), markerOnObject: source === "marker" }, evidence: evidence() });
234
+ }
235
+ for (const row of asArray(doc.adoptable).filter(isObject)) {
236
+ const addr = asString(row.addr);
237
+ if (!addr)
238
+ continue;
239
+ const adopt = asString(row.adopt_tofu_address);
240
+ put(addr, {
241
+ ...typed(row),
242
+ status: "unclaimed",
243
+ ownership: { verdict: "adoptable", markerOnObject: false, ...(adopt ? { adopt } : {}) },
244
+ evidence: evidence(omissions.get(addr)?.reason),
245
+ });
246
+ }
247
+ for (const [addr, row] of omissions) {
248
+ const mapped = LIVE_PLAN_OMISSION_REASONS[row.reason] ?? "read-failed";
249
+ if (mapped === "absent") {
250
+ put(addr, { status: "pending", evidence: evidence(row.reason) });
251
+ continue;
252
+ }
253
+ const reason = mapped === "read-failed" && readsAsCredentials(row.detail) ? "no-credentials" : mapped;
254
+ put(addr, {
255
+ status: "not-observed",
256
+ unobserved: { reason, ...(row.detail ? { detail: row.detail } : {}) },
257
+ evidence: evidence(row.reason || undefined),
258
+ });
259
+ }
260
+ for (const row of asArray(doc.foreign).filter(isObject)) {
261
+ const identity = asString(row.identity);
262
+ if (!identity)
263
+ continue;
264
+ const heldBy = asString(row.tofu_estate);
265
+ put(identity, {
266
+ ...typed(row),
267
+ status: "undeclared",
268
+ ownership: { verdict: "foreign", markerOnObject: heldBy !== undefined, ...(heldBy ? { by: "marker", ownedBy: heldBy } : {}) },
269
+ evidence: evidence(),
270
+ });
271
+ }
272
+ for (const row of asArray(doc.controller_held).filter(isObject)) {
273
+ const address = asString(row.addr) ?? asString(row.identity);
274
+ if (!address)
275
+ continue;
276
+ const heldBy = asString(row.held_by) ?? asString(row.controller);
277
+ put(address, {
278
+ ...typed(row),
279
+ status: "runtime",
280
+ ownership: { verdict: "foreign", by: "label", ...(heldBy ? { ownedBy: heldBy } : {}) },
281
+ evidence: evidence(asString(row.controller)),
282
+ });
283
+ }
284
+ return [...out.values()].sort(byAddress);
285
+ }
286
+ /**
287
+ * A live root's records from `live-ls -json`, read `ownership`. An item with
288
+ * `declared: false` is undeclared, addressed by its marker's address or else
289
+ * its identity: `owned` when its marker names this estate, held by the
290
+ * controller (runtime) when it has `held_by`, `foreign` when it names
291
+ * another estate. A declared item is live-plan's to answer and is left out.
292
+ * A gap is not-observed `unsupported-kind` with its rung as the token,
293
+ * unless `answered` holds its address.
294
+ */
295
+ export function choudoufuLiveLsDriftRecords(input) {
296
+ const doc = isObject(input.liveLs) ? input.liveLs : {};
297
+ const estate = asString(doc.estate);
298
+ const answered = new Set(input.answered ?? []);
299
+ const evidence = (engineCode) => ({
300
+ tool: "choudoufu",
301
+ ...(input.version ? { version: input.version } : {}),
302
+ command: "choudoufu live-ls -json",
303
+ ...(engineCode ? { engineCode } : {}),
304
+ });
305
+ const out = new Map();
306
+ for (const row of asArray(doc.items).filter(isObject)) {
307
+ if (row.declared !== false)
308
+ continue;
309
+ const address = asString(row.address) ?? asString(row.id);
310
+ if (!address || out.has(address))
311
+ continue;
312
+ const tags = isObject(row.tags) ? row.tags : {};
313
+ const marker = asString(tags["tofu-estate"]);
314
+ const heldBy = asString(row.held_by);
315
+ const ownership = heldBy
316
+ ? { verdict: "foreign", by: "label", ownedBy: heldBy }
317
+ : marker === undefined
318
+ ? { verdict: "unknown" }
319
+ : marker === estate
320
+ ? { verdict: "owned", by: "marker", markerOnObject: true }
321
+ : { verdict: "foreign", by: "marker", markerOnObject: true, ownedBy: marker };
322
+ out.set(address, driftRecord({
323
+ ...common(input, "choudoufu", "ownership", address),
324
+ ...(asString(row.type) ? { resourceType: asString(row.type) } : {}),
325
+ status: heldBy ? "runtime" : "undeclared",
326
+ ownership,
327
+ evidence: evidence(),
328
+ }));
329
+ }
330
+ for (const row of asArray(doc.gaps).filter(isObject)) {
331
+ const address = asString(row.address);
332
+ if (!address || answered.has(address) || out.has(address))
333
+ continue;
334
+ out.set(address, driftRecord({
335
+ ...common(input, "choudoufu", "ownership", address),
336
+ ...(asString(row.type) ? { resourceType: asString(row.type) } : {}),
337
+ status: "not-observed",
338
+ unobserved: { reason: "unsupported-kind", ...(asString(row.detail) ? { detail: asString(row.detail) } : {}) },
339
+ evidence: evidence(asString(row.rung)),
340
+ }));
341
+ }
342
+ return [...out.values()].sort(byAddress);
343
+ }
344
+ /** live-plan's records, then live-ls's undeclared items and the gaps live-plan did not answer. */
345
+ export function choudoufuLiveDriftRecords(input) {
346
+ const plan = choudoufuLivePlanDriftRecords(input);
347
+ if (input.liveLs === undefined)
348
+ return plan;
349
+ const answered = new Set(plan.map((r) => r.address));
350
+ const ls = choudoufuLiveLsDriftRecords({ ...input, liveLs: input.liveLs, answered }).filter((r) => !answered.has(r.address));
351
+ return [...plan, ...ls].sort(byAddress);
352
+ }
353
+ /**
354
+ * A live root at the plan depth. Every bound instance is read `plan`: a
355
+ * planned update or replace is drifted with the plan's paths, since a live
356
+ * root's prior state is the account itself, and anything else is in-sync.
357
+ * Its ownership facet is live-plan's. Every other address keeps its
358
+ * live-plan or live-ls record, read `ownership`, because the plan does not
359
+ * say who holds it.
360
+ */
361
+ export function choudoufuLivePlusPlanDriftRecords(input) {
362
+ const live = choudoufuLiveDriftRecords(input);
363
+ const index = indexPlan(input.plan);
364
+ const doc = isObject(input.plan) ? input.plan : {};
365
+ const version = input.version ?? asString(doc.terraform_version);
366
+ return live
367
+ .map((r) => {
368
+ if (r.read !== "ownership" || r.status !== "in-sync" || r.ownership?.verdict !== "owned")
369
+ return r;
370
+ const change = index.changes.get(r.address);
371
+ const actions = change?.actions ?? [];
372
+ const moves = actions.includes("update") || (actions.includes("create") && actions.includes("delete"));
373
+ const attributes = moves ? change.changes.map((c) => attributeOf(c, true)) : [];
374
+ return driftRecord({
375
+ ...r,
376
+ read: "plan",
377
+ status: moves ? "drifted" : "in-sync",
378
+ ...(attributes.length > 0 ? { attributes } : {}),
379
+ evidence: { tool: "choudoufu", ...(version ? { version } : {}), command: "choudoufu live-plan -json, choudoufu show -json" },
380
+ });
381
+ })
382
+ .sort(byAddress);
383
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Drift rows (#4580): one row per object a plan found drifted, by address,
3
+ * with its action and the object's real name, counted the way a product's
4
+ * drift report counts. `./drift-record.ts` answers a different question (the
5
+ * status of each instance the plan names), so it skips create rows, carries
6
+ * no names and stays as it is.
7
+ *
8
+ * A stock root's refresh-only plan reports drift as `resource_drift`, and
9
+ * every entry there is one row, data blocks and creates included. A full
10
+ * plan of a root under live resource markers (`live: true`) reads drift from
11
+ * `resource_changes` instead, seen from the other side: a create there is an
12
+ * object that no longer exists (delete), a delete one that exists outside
13
+ * the code (create), a replacement or any other pair of actions an update.
14
+ * Data blocks, no-op and read entries are not drift.
15
+ *
16
+ * These are terragucci's rules (packages/terragucci/src/report/drift.ts:
17
+ * `liveDrift`, `driftCount`, `driftNames`), so a row count here equals the
18
+ * count its report gives for the same plan.
19
+ *
20
+ * A row carries no attribute values. Its `name` is the first non-empty
21
+ * string among `name`, `id`, `bucket`, `function_name` and `arn`, read from
22
+ * the object as found and then as the code has it; a deleted object has no
23
+ * other place its name survives.
24
+ *
25
+ * The module imports nothing, so a product can load it behind a
26
+ * feature-detect without pulling the lexicon's entry point.
27
+ */
28
+ /** One drifted object. */
29
+ export interface TerraformDriftRow {
30
+ /** The resource address, `""` when the plan's entry has none. */
31
+ address: string;
32
+ /**
33
+ * What happened outside the code: `update`, `delete` (the object is gone),
34
+ * `create` (an object exists that state or code does not hold), or on a
35
+ * stock root whatever single action the plan's entry names. On a stock
36
+ * root a delete-and-create pair is `replace`, and any other pair `update`.
37
+ */
38
+ action: string;
39
+ /** The resource type, when the entry names one. */
40
+ type?: string;
41
+ /** The object's real name, by the rule in this module's header. */
42
+ name?: string;
43
+ }
44
+ export interface TerraformPlanDriftRowsOptions {
45
+ /**
46
+ * The plan is a full plan of a root under live resource markers, whose
47
+ * changes are its drift. Default false: a refresh-only plan's
48
+ * `resource_drift`.
49
+ */
50
+ live?: boolean;
51
+ }
52
+ /**
53
+ * The drift a plan (`show -json`, parsed) found, one row per drifted object
54
+ * in the plan's order. Its length is the drift count.
55
+ */
56
+ export declare function terraformPlanDriftRows(plan: unknown, options?: TerraformPlanDriftRowsOptions): TerraformDriftRow[];
57
+ /** How many objects a plan found drifted: `terraformPlanDriftRows(plan, options).length`. */
58
+ export declare function terraformPlanDriftCount(plan: unknown, options?: TerraformPlanDriftRowsOptions): number;
59
+ /** Each drifted object's real name by address, for the rows that have one. */
60
+ export declare function terraformPlanDriftNames(plan: unknown, options?: TerraformPlanDriftRowsOptions): Map<string, string>;
61
+ //# sourceMappingURL=drift-rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-rows.d.ts","sourceRoot":"","sources":["../src/drift-rows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,0BAA0B;AAC1B,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6DD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,6BAAkC,GAAG,iBAAiB,EAAE,CAGtH;AAED,6FAA6F;AAC7F,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,6BAAkC,GAAG,MAAM,CAE1G;AAED,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,6BAAkC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvH"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Drift rows (#4580): one row per object a plan found drifted, by address,
3
+ * with its action and the object's real name, counted the way a product's
4
+ * drift report counts. `./drift-record.ts` answers a different question (the
5
+ * status of each instance the plan names), so it skips create rows, carries
6
+ * no names and stays as it is.
7
+ *
8
+ * A stock root's refresh-only plan reports drift as `resource_drift`, and
9
+ * every entry there is one row, data blocks and creates included. A full
10
+ * plan of a root under live resource markers (`live: true`) reads drift from
11
+ * `resource_changes` instead, seen from the other side: a create there is an
12
+ * object that no longer exists (delete), a delete one that exists outside
13
+ * the code (create), a replacement or any other pair of actions an update.
14
+ * Data blocks, no-op and read entries are not drift.
15
+ *
16
+ * These are terragucci's rules (packages/terragucci/src/report/drift.ts:
17
+ * `liveDrift`, `driftCount`, `driftNames`), so a row count here equals the
18
+ * count its report gives for the same plan.
19
+ *
20
+ * A row carries no attribute values. Its `name` is the first non-empty
21
+ * string among `name`, `id`, `bucket`, `function_name` and `arn`, read from
22
+ * the object as found and then as the code has it; a deleted object has no
23
+ * other place its name survives.
24
+ *
25
+ * The module imports nothing, so a product can load it behind a
26
+ * feature-detect without pulling the lexicon's entry point.
27
+ */
28
+ const isObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
29
+ const FLIP = { create: "delete", delete: "create" };
30
+ const NAME_KEYS = ["name", "id", "bucket", "function_name", "arn"];
31
+ function nameOf(values) {
32
+ const objects = values.filter(isObject);
33
+ for (const key of NAME_KEYS) {
34
+ const v = objects.map((x) => x[key]).find((x) => typeof x === "string" && x !== "");
35
+ if (typeof v === "string")
36
+ return v;
37
+ }
38
+ return undefined;
39
+ }
40
+ function rowOf(entry, action, values) {
41
+ const r = isObject(entry) ? entry : {};
42
+ const name = nameOf(values);
43
+ return {
44
+ address: typeof r.address === "string" ? r.address : "",
45
+ action,
46
+ ...(typeof r.type === "string" && r.type !== "" ? { type: r.type } : {}),
47
+ ...(name !== undefined ? { name } : {}),
48
+ };
49
+ }
50
+ function stockAction(actions) {
51
+ if (actions.length === 1)
52
+ return actions[0];
53
+ if (actions.length === 2 && actions.includes("delete") && actions.includes("create"))
54
+ return "replace";
55
+ return "update";
56
+ }
57
+ /** A refresh-only plan's `resource_drift`, one row per entry. */
58
+ function stockRows(doc) {
59
+ const list = Array.isArray(doc.resource_drift) ? doc.resource_drift : [];
60
+ return list.map((entry) => {
61
+ const ch = isObject(entry) && isObject(entry.change) ? entry.change : {};
62
+ const actions = Array.isArray(ch.actions) ? ch.actions.map(String) : [];
63
+ return rowOf(entry, stockAction(actions), [ch.after, ch.before]);
64
+ });
65
+ }
66
+ /** A live root's full plan, its changes read as drift. */
67
+ function liveRows(doc) {
68
+ const list = Array.isArray(doc.resource_changes) ? doc.resource_changes : [];
69
+ const out = [];
70
+ for (const entry of list) {
71
+ if (!isObject(entry) || entry.mode === "data")
72
+ continue;
73
+ const ch = isObject(entry.change) ? entry.change : {};
74
+ const actions = Array.isArray(ch.actions) ? ch.actions.map(String) : [];
75
+ if (actions.length === 0 || actions.every((a) => a === "no-op" || a === "read"))
76
+ continue;
77
+ const action = actions.length === 1 ? (FLIP[actions[0]] ?? actions[0]) : "update";
78
+ const live = isObject(ch.before) ? ch.before : null;
79
+ let code = isObject(ch.after) ? ch.after : null;
80
+ // A value the plan knows only after the apply is not a difference: the live one stands for it.
81
+ const unknown = isObject(ch.after_unknown) ? ch.after_unknown : {};
82
+ if (code && live)
83
+ code = { ...code, ...Object.fromEntries(Object.keys(unknown).filter((k) => unknown[k] === true && k in live).map((k) => [k, live[k]])) };
84
+ out.push(rowOf(entry, action, [live, code]));
85
+ }
86
+ return out;
87
+ }
88
+ /**
89
+ * The drift a plan (`show -json`, parsed) found, one row per drifted object
90
+ * in the plan's order. Its length is the drift count.
91
+ */
92
+ export function terraformPlanDriftRows(plan, options = {}) {
93
+ if (!isObject(plan))
94
+ return [];
95
+ return options.live ? liveRows(plan) : stockRows(plan);
96
+ }
97
+ /** How many objects a plan found drifted: `terraformPlanDriftRows(plan, options).length`. */
98
+ export function terraformPlanDriftCount(plan, options = {}) {
99
+ return terraformPlanDriftRows(plan, options).length;
100
+ }
101
+ /** Each drifted object's real name by address, for the rows that have one. */
102
+ export function terraformPlanDriftNames(plan, options = {}) {
103
+ const out = new Map();
104
+ for (const row of terraformPlanDriftRows(plan, options))
105
+ if (row.name !== undefined)
106
+ out.set(row.address, row.name);
107
+ return out;
108
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * OpenTofu, Terraform and choudoufu outcomes mapped onto chant's exit-code
3
+ * table (#4553, `CHANT_EXIT` in `@intentius/chant/exit-codes`).
4
+ *
5
+ * The lexicon never picks the process's exit code itself: for a moved plan it
6
+ * throws an error core marks as moved (`planMoved: true`, read by
7
+ * `isPlanMovedError`), and core exits `CHANT_EXIT.moved`. This mapping says
8
+ * which engine outcome is which row of the table, so the throw sites and the
9
+ * reference page agree.
10
+ *
11
+ * | Engine outcome | Table |
12
+ * |---|---|
13
+ * | `plan -detailed-exitcode` 0 or 2 | not an exit: the plan's answer. 2 under a drift check is `drift` |
14
+ * | any 1 | `failed` |
15
+ * | choudoufu `apply <planfile>` 3, approval mismatch | `moved` |
16
+ * | choudoufu `apply <planfile>` 3, plan made against another estate | `failed`: the pipeline handed the wrong file, and no approval fixes that |
17
+ * | choudoufu `live-wave-apply` 3, set moved | `moved` |
18
+ * | choudoufu `live-wave-apply` 4 or `live-plan-set` 4, a root failed | `failed` |
19
+ * | a composed plan that moved | `moved` |
20
+ * | `live-affected` 2, `live-cone` 2 | planner answers, never a job's exit |
21
+ */
22
+ import { type ChantExitCode } from "@intentius/chant/exit-codes";
23
+ import { type TerraformApprovalRefusal } from "./op/activities/terraform.js";
24
+ /** The command whose exit status is mapped. */
25
+ export type TerraformExitSource =
26
+ /** `terraform|tofu|choudoufu plan -detailed-exitcode`; `drift` says a drift check asked for it. */
27
+ {
28
+ command: "plan";
29
+ code: number;
30
+ drift?: boolean;
31
+ }
32
+ /** `choudoufu apply <planfile>` on a live root; `refusal` is `classifyApprovalRefusal`'s answer for its output. */
33
+ | {
34
+ command: "apply";
35
+ code: number;
36
+ refusal?: TerraformApprovalRefusal;
37
+ }
38
+ /** `choudoufu live-wave-apply`. */
39
+ | {
40
+ command: "live-wave-apply";
41
+ code: number;
42
+ }
43
+ /** `choudoufu live-plan-set`. */
44
+ | {
45
+ command: "live-plan-set";
46
+ code: number;
47
+ };
48
+ /**
49
+ * The table's code for a terraform, tofu or choudoufu exit status. A plan's
50
+ * 0 and 2 are both `done` unless a drift check asked, when 2 is `drift`.
51
+ */
52
+ export declare function terraformExitOf(source: TerraformExitSource): ChantExitCode;
53
+ /** Whether `source` is a plan that moved since its approval: the outcomes the lexicon throws a `planMoved` error for. */
54
+ export declare function terraformPlanMoved(source: TerraformExitSource): boolean;
55
+ //# sourceMappingURL=exit-codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAqD,KAAK,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE7H,+CAA+C;AAC/C,MAAM,MAAM,mBAAmB;AAC7B,mGAAmG;AACjG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE;AACpD,mHAAmH;GACjH;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,wBAAwB,CAAA;CAAE;AACxE,mCAAmC;GACjC;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC9C,iCAAiC;GAC/B;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAc1E;AAED,yHAAyH;AACzH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAEvE"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * OpenTofu, Terraform and choudoufu outcomes mapped onto chant's exit-code
3
+ * table (#4553, `CHANT_EXIT` in `@intentius/chant/exit-codes`).
4
+ *
5
+ * The lexicon never picks the process's exit code itself: for a moved plan it
6
+ * throws an error core marks as moved (`planMoved: true`, read by
7
+ * `isPlanMovedError`), and core exits `CHANT_EXIT.moved`. This mapping says
8
+ * which engine outcome is which row of the table, so the throw sites and the
9
+ * reference page agree.
10
+ *
11
+ * | Engine outcome | Table |
12
+ * |---|---|
13
+ * | `plan -detailed-exitcode` 0 or 2 | not an exit: the plan's answer. 2 under a drift check is `drift` |
14
+ * | any 1 | `failed` |
15
+ * | choudoufu `apply <planfile>` 3, approval mismatch | `moved` |
16
+ * | choudoufu `apply <planfile>` 3, plan made against another estate | `failed`: the pipeline handed the wrong file, and no approval fixes that |
17
+ * | choudoufu `live-wave-apply` 3, set moved | `moved` |
18
+ * | choudoufu `live-wave-apply` 4 or `live-plan-set` 4, a root failed | `failed` |
19
+ * | a composed plan that moved | `moved` |
20
+ * | `live-affected` 2, `live-cone` 2 | planner answers, never a job's exit |
21
+ */
22
+ import { CHANT_EXIT } from "@intentius/chant/exit-codes";
23
+ import { CHOUDOUFU_APPROVAL_EXIT_CODE, CHOUDOUFU_WAVE_EXIT } from "./op/activities/terraform.js";
24
+ /**
25
+ * The table's code for a terraform, tofu or choudoufu exit status. A plan's
26
+ * 0 and 2 are both `done` unless a drift check asked, when 2 is `drift`.
27
+ */
28
+ export function terraformExitOf(source) {
29
+ const { code } = source;
30
+ if (code === 0)
31
+ return CHANT_EXIT.done;
32
+ switch (source.command) {
33
+ case "plan":
34
+ if (code === 2)
35
+ return source.drift ? CHANT_EXIT.drift : CHANT_EXIT.done;
36
+ return CHANT_EXIT.failed;
37
+ case "apply":
38
+ return code === CHOUDOUFU_APPROVAL_EXIT_CODE && source.refusal === "approval-mismatch" ? CHANT_EXIT.moved : CHANT_EXIT.failed;
39
+ case "live-wave-apply":
40
+ return code === CHOUDOUFU_WAVE_EXIT.setMoved ? CHANT_EXIT.moved : CHANT_EXIT.failed;
41
+ case "live-plan-set":
42
+ return code === 2 ? CHANT_EXIT.done : CHANT_EXIT.failed;
43
+ }
44
+ }
45
+ /** Whether `source` is a plan that moved since its approval: the outcomes the lexicon throws a `planMoved` error for. */
46
+ export function terraformPlanMoved(source) {
47
+ return terraformExitOf(source) === CHANT_EXIT.moved;
48
+ }