@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,128 @@
1
+ /**
2
+ * The plan shape of a terraform-family root (#4436): what `terraform show
3
+ * -json` says a plan does, without the values, in the form core's
4
+ * `coveredRound` compares (#4419). `terraform-apply`'s `plan` returns it, and
5
+ * terragucci calls it for the plan JSON of a note (terragucci#1268).
6
+ *
7
+ * Like `./change-set`, this module imports only `@intentius/chant` subpaths,
8
+ * never the lexicon's entry point.
9
+ */
10
+
11
+ import type { PlanShape, PlanShapeEntry, ShapeReplacement } from "@intentius/chant/components/covered-round";
12
+ import { normalizePlanShape } from "@intentius/chant/components/covered-round";
13
+ import { actionFor } from "./change-set";
14
+
15
+ type Json = Record<string, unknown>;
16
+
17
+ const isObject = (v: unknown): v is Json => v !== null && typeof v === "object" && !Array.isArray(v);
18
+
19
+ /** Whether an `after_unknown` value marks anything under it unknown. */
20
+ function marks(v: unknown): boolean {
21
+ if (v === true) return true;
22
+ if (Array.isArray(v)) return v.some(marks);
23
+ if (isObject(v)) return Object.values(v).some(marks);
24
+ return false;
25
+ }
26
+
27
+ function sameJson(a: unknown, b: unknown): boolean {
28
+ if (a === b) return true;
29
+ if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((x, i) => sameJson(x, b[i]));
30
+ if (isObject(a) && isObject(b)) {
31
+ const ka = Object.keys(a);
32
+ return ka.length === Object.keys(b).length && ka.every((k) => k in b && sameJson(a[k], b[k]));
33
+ }
34
+ return false;
35
+ }
36
+
37
+ /** Whether the value at `path` in an `after_unknown` tree is unknown: `true` at the path or on a prefix of it. */
38
+ function unknownAt(tree: unknown, path: unknown[]): boolean {
39
+ let at: unknown = tree;
40
+ for (const step of path) {
41
+ if (at === true) return true;
42
+ if (Array.isArray(at) && typeof step === "number") at = at[step];
43
+ else if (isObject(at) && typeof step === "string") at = at[step];
44
+ else return false;
45
+ }
46
+ return marks(at);
47
+ }
48
+
49
+ /**
50
+ * How a change replaces its resource. A `replace_paths` entry names an
51
+ * attribute whose change forces it. When every such attribute is unknown
52
+ * after apply, the plan cannot say the value will differ, so the replacement
53
+ * is `conditional`; one with a known forcing attribute is `true`. A delete
54
+ * and create pair with no `replace_paths` (a tainted object, `-replace`) is
55
+ * `true`. An update with none replaces nothing (`false`); a create or delete
56
+ * has no replacement to state.
57
+ */
58
+ function replacementFor(change: Json, action: string): ShapeReplacement | undefined {
59
+ const paths = (Array.isArray(change.replace_paths) ? change.replace_paths : []).filter(Array.isArray) as unknown[][];
60
+ if (paths.length > 0) return paths.every((p) => unknownAt(change.after_unknown, p)) ? "conditional" : "true";
61
+ if (action === "replace") return "true";
62
+ if (action === "update") return "false";
63
+ return undefined;
64
+ }
65
+
66
+ export interface TerraformPlanShapeOptions {
67
+ /** The inputs the plan was made without, as `<component>.<output>`. */
68
+ unknownInputs?: string[];
69
+ /** The inputs the plan read with a value, by reference. */
70
+ knownInputs?: Record<string, unknown>;
71
+ }
72
+
73
+ /**
74
+ * The shape of `planJson` (`terraform show -json`, from terraform, tofu or
75
+ * choudoufu) for `member`.
76
+ *
77
+ * One entry per `resource_changes` item that is not `no-op` or `read`.
78
+ * `logicalId` is the address, with `#<deposed>` for a deposed object. `type`
79
+ * is the resource type. `properties` are the top-level attributes that differ
80
+ * between `before` and `after` (on a create, those the plan sets or leaves
81
+ * unknown), and `unknown` the ones `after_unknown` marks, so `unknown` is
82
+ * within `properties`. A delete has no properties. Values never enter it, so
83
+ * a sensitive attribute is only a name.
84
+ */
85
+ export function terraformPlanShape(planJson: unknown, member: string, options: TerraformPlanShapeOptions = {}): PlanShape {
86
+ const plan = isObject(planJson) ? planJson : {};
87
+ const raw = Array.isArray(plan.resource_changes) ? plan.resource_changes : [];
88
+ const entries: PlanShapeEntry[] = [];
89
+ for (const r of raw) {
90
+ const rc = isObject(r) ? r : {};
91
+ const change = isObject(rc.change) ? rc.change : {};
92
+ const action = actionFor(change.actions);
93
+ if (action === "no-op" || action === "read") continue;
94
+ const address = String(rc.address ?? "");
95
+ const before = isObject(change.before) ? change.before : {};
96
+ const after = isObject(change.after) ? change.after : {};
97
+ const afterUnknown = isObject(change.after_unknown) ? change.after_unknown : {};
98
+ const properties: string[] = [];
99
+ const unknown: string[] = [];
100
+ if (action !== "delete" && action !== "forget") {
101
+ for (const k of new Set([...Object.keys(before), ...Object.keys(after), ...Object.keys(afterUnknown)])) {
102
+ const isUnknown = marks(afterUnknown[k]);
103
+ const differs =
104
+ action === "create"
105
+ ? isUnknown || (after[k] !== undefined && after[k] !== null)
106
+ : isUnknown || !sameJson(before[k] ?? null, after[k] ?? null);
107
+ if (!differs) continue;
108
+ properties.push(k);
109
+ if (isUnknown) unknown.push(k);
110
+ }
111
+ }
112
+ const replacement = replacementFor(change, action);
113
+ entries.push({
114
+ logicalId: typeof rc.deposed === "string" ? `${address}#${rc.deposed}` : address,
115
+ action,
116
+ ...(replacement ? { replacement } : {}),
117
+ ...(typeof rc.type === "string" ? { type: rc.type } : {}),
118
+ properties,
119
+ unknown,
120
+ });
121
+ }
122
+ return normalizePlanShape({
123
+ member,
124
+ entries,
125
+ unknownInputs: options.unknownInputs ?? [],
126
+ ...(options.knownInputs ? { knownInputs: options.knownInputs } : {}),
127
+ });
128
+ }
package/src/plugin.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { lastMemberReport, readPulumiMember, setLastMemberReport } from "./workspace-member";
2
1
  import type { AuditEntitiesInput, LexiconPlugin } from "@intentius/chant/lexicon";
2
+ import { terraformCiSetup } from "./ci-setup";
3
3
  import { terraformBehaviourKinds } from "./behaviour/kinds";
4
4
  import type { CompletionContext, HoverContext } from "@intentius/chant/lsp/types";
5
5
  import type { Declarable } from "@intentius/chant/declarable";
@@ -11,7 +11,7 @@ import { withCallersChain } from "./lint/post-synth/scope";
11
11
  import { terraformAuditCatalog } from "./lint/audit-catalog";
12
12
  import { completions } from "./lsp/completions";
13
13
  import { hover } from "./lsp/hover";
14
- import { terraformConfigSchema, type TerraformConfig } from "./config";
14
+ import { ownRoots, terraformConfigSchema, type TerraformConfig } from "./config";
15
15
  import { renderTerraformRoots } from "./hcl/roots";
16
16
  import { existsSync } from "node:fs";
17
17
  import { join } from "node:path";
@@ -20,6 +20,7 @@ import { descendModules } from "./hcl/descend";
20
20
  import { TERRAFORM_STATE_OWNERSHIP_KEYS } from "./state-ownership";
21
21
  import { terraformCommands } from "./commands";
22
22
  import { terraformCapabilityPack } from "./capabilities/adapter";
23
+ import { TERRAFORM_REFERENCE_CATALOG } from "./behaviour/reference-catalog";
23
24
 
24
25
  const loadSkills = createSkillsLoader(import.meta.url, [
25
26
  {
@@ -79,9 +80,16 @@ export const terraformPlugin: LexiconPlugin = {
79
80
  behaviourKinds: terraformBehaviourKinds,
80
81
  name: "terraform",
81
82
  capabilityPack: terraformCapabilityPack,
83
+ // Keyed by provider type (#2360); see its module doc for which nodes it reads (#4535).
84
+ referenceCatalog: TERRAFORM_REFERENCE_CATALOG,
82
85
  serializer: terraformSerializer,
83
86
  configSchema: terraformConfigSchema,
84
87
 
88
+ // #4550: the engine install lines for the pull request pipeline's default image.
89
+ ciSetup(ctx: { dir: string }): string[] {
90
+ return terraformCiSetup(ctx);
91
+ },
92
+
85
93
  // ── Required lifecycle methods ────────────────────────────────
86
94
 
87
95
  async generate(options?: { verbose?: boolean }): Promise<void> {
@@ -141,6 +149,18 @@ export const terraformPlugin: LexiconPlugin = {
141
149
  return describeResources(options);
142
150
  },
143
151
 
152
+ /**
153
+ * Each root's drift, as drift-record stream lines (behold#995): a stock
154
+ * root through its state or a plan, a live root through `live-plan` (and a
155
+ * plan), one resource through `live-plan -resource`. `chant workspace
156
+ * drift` reaches it through `chant lifecycle drift` in a member's reader
157
+ * project. See `./drift-read.ts`.
158
+ */
159
+ async readDrift(options) {
160
+ const { readTerraformDrift } = await import("./drift-read");
161
+ return readTerraformDrift(options);
162
+ },
163
+
144
164
  /**
145
165
  * The prediction, for whichever estate `options.from` names (#2495). The
146
166
  * producer is `predictTerraformBehaviour` and this is its second caller, not
@@ -181,15 +201,9 @@ export const terraformPlugin: LexiconPlugin = {
181
201
  * project root, which is what relative `dir` paths resolve against.
182
202
  */
183
203
  async buildRoots(ctx): Promise<{ entities: Map<string, Declarable>; warnings: string[] }> {
184
- setLastMemberReport(undefined);
185
204
  const namespace = (ctx.config as { terraform?: TerraformConfig }).terraform;
186
- // A pulumi workspace member (#3179): its checked-in stack export, never the program.
187
- if (namespace?.pulumiMember) {
188
- const read = readPulumiMember({ member: namespace.pulumiMember });
189
- setLastMemberReport(read.report);
190
- return { entities: read.entities, warnings: read.warnings };
191
- }
192
- const roots = namespace?.roots ?? {};
205
+ // A `signalOnly` root (#4484) feeds change detection only, so it builds no entities here.
206
+ const roots = ownRoots(namespace?.roots);
193
207
  if (Object.keys(roots).length === 0) return { entities: new Map(), warnings: [] };
194
208
  return renderTerraformRoots({
195
209
  projectRoot: ctx.projectRoot,
@@ -200,11 +214,6 @@ export const terraformPlugin: LexiconPlugin = {
200
214
  });
201
215
  },
202
216
 
203
- graphMeta() {
204
- const report = lastMemberReport();
205
- return report ? { pulumiMember: report } : undefined;
206
- },
207
-
208
217
  /** `chant terraform pin-rollout` (#3189). */
209
218
  commands() {
210
219
  return terraformCommands;
@@ -213,13 +222,15 @@ export const terraformPlugin: LexiconPlugin = {
213
222
  /**
214
223
  * The `terraform.roots` a change touched (#3183): a changed file in the
215
224
  * root's directory, in a local module it calls, or one of its var files.
216
- * See `./changed-roots.ts`.
225
+ * See `./changed-roots.ts`. Every root counts, a `signalOnly` one too
226
+ * (#4484): that is what it is declared for.
217
227
  */
218
228
  async changedUnits(ctx) {
219
- const roots = (ctx.config as { terraform?: TerraformConfig }).terraform?.roots ?? {};
229
+ const tf = (ctx.config as { terraform?: TerraformConfig }).terraform;
230
+ const roots = tf?.roots ?? {};
220
231
  if (Object.keys(roots).length === 0) return [];
221
232
  const { changedRoots } = await import("./changed-roots");
222
- return changedRoots(ctx.projectRoot, roots, ctx.changedFiles);
233
+ return changedRoots(ctx.projectRoot, roots, ctx.changedFiles, tf?.binary);
223
234
  },
224
235
 
225
236
  lintRules() {
@@ -294,12 +305,21 @@ export const terraformPlugin: LexiconPlugin = {
294
305
  // A local audit knows the root's directory, so it can say whether the
295
306
  // lock file is beside the `.tf` files (TF040); a fetched one cannot.
296
307
  const lockFile = input?.dir !== undefined ? existsSync(join(input.dir, LOCK_FILENAME)) : undefined;
297
- const entities = await parseTerraformRootContent(content, root, undefined, lockFile === undefined ? undefined : { lockFile });
308
+ // An audit has no `terraform.binary` to follow (chant#4457). A root
309
+ // that carries a `.tofu` file is written for OpenTofu, so it is read
310
+ // as a tofu root; any other is read as terraform, the config default.
311
+ const binary = /^# file: .*\.tofu(\.json)?\s*$/m.test(content) ? "tofu" : undefined;
312
+ const modeOptions = {
313
+ ...(binary !== undefined ? { binary } : {}),
314
+ ...(lockFile !== undefined ? { lockFile } : {}),
315
+ };
316
+ const entities = await parseTerraformRootContent(content, root, undefined, Object.keys(modeOptions).length > 0 ? modeOptions : undefined);
298
317
  if (input?.dir === undefined) return entities;
299
318
  const { entities: children } = await descendModules(entities, {
300
319
  dir: input.dir,
301
320
  root,
302
321
  projectRoot: input.baseDir ?? input.dir,
322
+ ...(binary !== undefined ? { modeOptions: { binary } } : {}),
303
323
  });
304
324
  for (const [key, entity] of children) entities.set(key, entity);
305
325
  return entities;
@@ -0,0 +1,3 @@
1
+ formatter: markdown table
2
+ output:
3
+ mode: inject
@@ -0,0 +1 @@
1
+ # documented
@@ -0,0 +1,8 @@
1
+ variable "name" {
2
+ type = string
3
+ description = "The bucket's name."
4
+ }
5
+
6
+ output "bucket" {
7
+ value = var.name
8
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "terraform": {
3
+ "required_providers": {
4
+ "google": { "source": "hashicorp/google", "version": "~> 6.0" }
5
+ }
6
+ },
7
+ "variable": {
8
+ "project": { "type": "string", "description": "The project id." },
9
+ "region": { "type": "string", "default": "us-central1" }
10
+ },
11
+ "output": {
12
+ "name": { "value": "${var.project}", "description": "The project id, echoed." }
13
+ }
14
+ }
@@ -0,0 +1,3 @@
1
+ # vpc
2
+
3
+ A VPC with flow logs.
@@ -0,0 +1,5 @@
1
+ module "vpc" {
2
+ source = "../.."
3
+ cidr = "10.1.0.0/16"
4
+ tags = { team = "net" }
5
+ }
@@ -0,0 +1,4 @@
1
+ module "vpc" {
2
+ source = "../.."
3
+ cidr = "10.0.0.0/16"
4
+ }
@@ -0,0 +1,14 @@
1
+ terraform {
2
+ required_version = ">= 1.5"
3
+ required_providers {
4
+ aws = {
5
+ source = "hashicorp/aws"
6
+ version = ">= 5.0"
7
+ }
8
+ }
9
+ }
10
+
11
+ resource "aws_vpc" "this" {
12
+ cidr_block = var.cidr
13
+ tags = var.tags
14
+ }
@@ -0,0 +1,9 @@
1
+ output "vpc_id" {
2
+ value = aws_vpc.this.id
3
+ description = "The VPC's id."
4
+ }
5
+
6
+ output "arn" {
7
+ value = aws_vpc.this.arn
8
+ sensitive = true
9
+ }
@@ -0,0 +1,16 @@
1
+ variable "cidr" {
2
+ type = string
3
+ description = "The VPC's IPv4 CIDR block."
4
+ }
5
+
6
+ variable "tags" {
7
+ type = map(string)
8
+ default = {}
9
+ description = "Tags for every resource."
10
+ }
11
+
12
+ variable "flow_log_key" {
13
+ type = string
14
+ default = "not-a-real-key"
15
+ sensitive = true
16
+ }
@@ -0,0 +1,12 @@
1
+ terraform {
2
+ required_providers {
3
+ aws = {
4
+ source = "acme.jfrog.io/tf-remote__hashicorp/aws"
5
+ }
6
+ }
7
+ }
8
+
9
+ module "vpc" {
10
+ source = "acme.jfrog.io/tf-remote__terraform-aws-modules/vpc/aws"
11
+ version = "5.1.0"
12
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Where a module sits in a Terraform module registry, and how a registry
3
+ * source (`<host>/<namespace>/<name>/<system>`) is split into those parts.
4
+ * Lifted from terragucci's `publish/registry.ts` (18f6431595) for chant#4565.
5
+ * No Node imports, so an edge function can carry it.
6
+ */
7
+
8
+ export const DISCOVERY = ".well-known/terraform.json";
9
+ export const MODULES_V1 = "/v1/modules/";
10
+ export const DEFAULT_SYSTEM = "generic";
11
+
12
+ /** A registry namespace or module name: letters, digits, `-` and `_`, starting and ending on a letter or digit. */
13
+ export const REGISTRY_NAME = /^[0-9A-Za-z](?:[0-9A-Za-z_-]{0,62}[0-9A-Za-z])?$/;
14
+ /** A registry module's system (its target provider): lower-case letters and digits. */
15
+ export const REGISTRY_SYSTEM = /^[0-9a-z]{1,64}$/;
16
+
17
+ /** Where a module is in the registry. */
18
+ export interface RegistryAddress {
19
+ namespace: string;
20
+ name: string;
21
+ system: string;
22
+ /** `<host>/<namespace>/<name>/<system>`, the source a root writes. */
23
+ source: string;
24
+ /** The module's directory under the registry root: `v1/modules/<namespace>/<name>/<system>`. */
25
+ path: string;
26
+ }
27
+
28
+ /** What placing a module needs from a registry's settings. */
29
+ export interface RegistryPlacement {
30
+ /** The registry's base URL; its host is what sources name. */
31
+ url: string;
32
+ namespace: string;
33
+ /** A namespace per path prefix, the longest prefix winning. */
34
+ namespaces?: Record<string, string>;
35
+ system?: string;
36
+ }
37
+
38
+ /** A module name the protocol cannot carry. */
39
+ export class RegistryNameError extends Error {
40
+ constructor(message: string) {
41
+ super(message);
42
+ this.name = "RegistryNameError";
43
+ }
44
+ }
45
+
46
+ /** The host a registry's sources name: its URL without the scheme, lower-cased. */
47
+ export const registryHost = (reg: Pick<RegistryPlacement, "url">): string => new URL(reg.url).host.toLowerCase();
48
+
49
+ /** The namespace a module's path goes under: the longest `namespaces` prefix it starts with, else `namespace`. */
50
+ export function namespaceFor(reg: Pick<RegistryPlacement, "namespace" | "namespaces">, rel: string): string {
51
+ let best: { prefix: string; ns: string } | undefined;
52
+ for (const [prefix, ns] of Object.entries(reg.namespaces ?? {})) {
53
+ const p = prefix.replace(/^\.\//, "");
54
+ const dir = p.endsWith("/") ? p : `${p}/`;
55
+ if ((rel.startsWith(dir) || rel === p.replace(/\/+$/, "")) && (!best || p.length > best.prefix.length)) best = { prefix: p, ns };
56
+ }
57
+ return best?.ns ?? reg.namespace;
58
+ }
59
+
60
+ /** A module's place in the registry: its namespace, its name (the last segment of its path) and its system. */
61
+ export function registryAddress(reg: RegistryPlacement, rel: string): RegistryAddress {
62
+ const namespace = namespaceFor(reg, rel);
63
+ const name = rel.replace(/\/+$/, "").split("/").pop() ?? "";
64
+ const system = reg.system ?? DEFAULT_SYSTEM;
65
+ if (!REGISTRY_NAME.test(name)) throw new RegistryNameError(`${rel}: a registry module's name is letters, digits, - and _, and ${JSON.stringify(name)} is not; rename the directory`);
66
+ return { namespace, name, system, source: `${registryHost(reg)}/${namespace}/${name}/${system}`, path: `v1/modules/${namespace}/${name}/${system}` };
67
+ }
68
+
69
+ /** A registry source split into its parts. */
70
+ export interface RegistrySource {
71
+ host: string;
72
+ namespace: string;
73
+ name: string;
74
+ system: string;
75
+ }
76
+
77
+ /**
78
+ * A registry source split into its host and module, or undefined when the
79
+ * source is not one: `host/ns/name/system`, with an optional `//subdir` and
80
+ * query. The host must look like one (a dot, a port, or `localhost`), so a
81
+ * three-part public registry source with no host is not taken for one.
82
+ * `hosts` names bare hosts a CLI `host` block declares (a Nexus repository's
83
+ * name, chant#4605), which are taken as hosts too.
84
+ */
85
+ export function parseRegistrySource(source: string, hosts: readonly string[] = []): RegistrySource | undefined {
86
+ const base = source.split("?")[0]!.split("//")[0]!;
87
+ const m = /^([a-z0-9.-]+(?::\d+)?)\/([^/]+)\/([^/]+)\/([^/]+)$/i.exec(base);
88
+ const known = (h: string) => hosts.some((k) => k.toLowerCase() === h.toLowerCase());
89
+ if (!m || (!m[1]!.includes(".") && !m[1]!.includes(":") && m[1] !== "localhost" && !known(m[1]!))) return undefined;
90
+ return { host: m[1]!.toLowerCase(), namespace: m[2]!, name: m[3]!, system: m[4]! };
91
+ }
92
+
93
+ /** A key under a registry's prefix in its bucket or directory. */
94
+ export const keyFor = (prefix: string | undefined, path: string): string => {
95
+ const p = (prefix ?? "").replace(/^\/+|\/+$/g, "");
96
+ return p ? `${p}/${path}` : path;
97
+ };
98
+
99
+ /** The tarball's name beside its version. */
100
+ export const tarballName = (addr: Pick<RegistryAddress, "name">, version: string): string => `${addr.name}-${version}.tar.gz`;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Reading a registry's release catalog (chant#4599, terragucci#1289 bundle
3
+ * B): `catalog/index.json` beside the registry's files, the document
4
+ * `renderCatalogSite` writes (`@intentius/chant/lifecycle/release-catalog-site`).
5
+ *
6
+ * The request carries the token the CLIs would send the host (chant#4563,
7
+ * `readToken` in ./reader.ts), so a registry behind the edge function's
8
+ * `auth: token` check answers it. Per ruling B (2026-10-27) this reader is
9
+ * how a token-protected catalog is read; the edge function gains no cookie
10
+ * and no open path, and a browser reaches the catalog over the
11
+ * network-private path.
12
+ */
13
+ import { credentialsHost, tokenVariable } from "@intentius/chant/terraform/credentials";
14
+ import { parseReleaseCatalog, ReleaseCatalogError, type ReleaseCatalog } from "@intentius/chant/lifecycle/release-catalog";
15
+ import { readToken, RegistryError, type RegistryFetch, type RegistryReadOptions } from "./reader";
16
+
17
+ /** Where the catalog sits under a registry's root. */
18
+ export const CATALOG_PATH = "catalog/index.json";
19
+
20
+ /** The catalog URL for a registry: a host (`modules.acme.dev`) or a base URL (`https://modules.acme.dev/` or `https://cdn.acme.dev/registry/`). */
21
+ export function catalogUrl(registry: string, scheme: "https" | "http" = "https"): string {
22
+ const base = registry.includes("://") ? registry : `${scheme}://${registry}`;
23
+ return new URL(CATALOG_PATH, base.endsWith("/") ? base : `${base}/`).toString();
24
+ }
25
+
26
+ /**
27
+ * Fetch and validate a registry's catalog. Throws `RegistryError` when the
28
+ * request fails or is refused (naming where a token goes, never a value),
29
+ * and when the answer is not a valid catalog. A registry with no catalog
30
+ * (404) gives null.
31
+ */
32
+ export async function readRegistryCatalog(registry: string, options: RegistryReadOptions = {}): Promise<ReleaseCatalog | null> {
33
+ const url = catalogUrl(registry, options.scheme);
34
+ const host = new URL(url).host.toLowerCase();
35
+ const token = readToken(host, options);
36
+ const fetchFn: RegistryFetch = options.fetch ?? ((u, init) => fetch(u, init));
37
+ let res: Response;
38
+ try {
39
+ res = await fetchFn(url, { method: "GET", redirect: "follow", headers: { Accept: "application/json", ...(token ? { Authorization: `Bearer ${token}` } : {}) } });
40
+ } catch (e) {
41
+ throw new RegistryError(`${url}: ${(e as Error).message}`);
42
+ }
43
+ if (res.status === 404) return null;
44
+ if (res.status === 401 || res.status === 403) {
45
+ const variable = tokenVariable(host);
46
+ const where = variable ? `${variable} or a credentials "${credentialsHost(host)}" block` : `a credentials "${credentialsHost(host) ?? host}" block in credentials.tfrc.json`;
47
+ throw new RegistryError(token ? `${url} answered ${res.status}: the registry refused the token for ${host}` : `${url} answered ${res.status}: the catalog wants a token; set ${where}`);
48
+ }
49
+ if (!res.ok) throw new RegistryError(`${url} answered ${res.status}`);
50
+ try {
51
+ return parseReleaseCatalog(await res.text());
52
+ } catch (e) {
53
+ if (e instanceof ReleaseCatalogError) throw new RegistryError(`${url} is not a release catalog: ${e.problems.slice(0, 3).join("; ")}`);
54
+ throw e;
55
+ }
56
+ }