@intentius/chant-lexicon-terraform 0.124.51 → 0.124.54

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 (338) hide show
  1. package/README.md +7 -6
  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/commands.d.ts +5 -0
  27. package/dist/commands.d.ts.map +1 -1
  28. package/dist/commands.js +87 -4
  29. package/dist/components/capability-plugin.d.ts +65 -3
  30. package/dist/components/capability-plugin.d.ts.map +1 -1
  31. package/dist/components/capability-plugin.js +197 -13
  32. package/dist/components/compose-group.d.ts +145 -0
  33. package/dist/components/compose-group.d.ts.map +1 -0
  34. package/dist/components/compose-group.js +407 -0
  35. package/dist/components/placeholder-preview.d.ts +78 -0
  36. package/dist/components/placeholder-preview.d.ts.map +1 -0
  37. package/dist/components/placeholder-preview.js +254 -0
  38. package/dist/compose/apply-events.d.ts +46 -0
  39. package/dist/compose/apply-events.d.ts.map +1 -0
  40. package/dist/compose/apply-events.js +77 -0
  41. package/dist/compose/estate.d.ts +194 -0
  42. package/dist/compose/estate.d.ts.map +1 -0
  43. package/dist/compose/estate.js +363 -0
  44. package/dist/compose/hcl.d.ts +99 -0
  45. package/dist/compose/hcl.d.ts.map +1 -0
  46. package/dist/compose/hcl.js +302 -0
  47. package/dist/compose/module-address.d.ts +24 -0
  48. package/dist/compose/module-address.d.ts.map +1 -0
  49. package/dist/compose/module-address.js +43 -0
  50. package/dist/compose/root.d.ts +127 -0
  51. package/dist/compose/root.d.ts.map +1 -0
  52. package/dist/compose/root.js +586 -0
  53. package/dist/compose/run.d.ts +183 -0
  54. package/dist/compose/run.d.ts.map +1 -0
  55. package/dist/compose/run.js +447 -0
  56. package/dist/compose/slice.d.ts +102 -0
  57. package/dist/compose/slice.d.ts.map +1 -0
  58. package/dist/compose/slice.js +249 -0
  59. package/dist/compose/state-address.d.ts +28 -0
  60. package/dist/compose/state-address.d.ts.map +1 -0
  61. package/dist/compose/state-address.js +154 -0
  62. package/dist/compose/state-merge.d.ts +52 -0
  63. package/dist/compose/state-merge.d.ts.map +1 -0
  64. package/dist/compose/state-merge.js +135 -0
  65. package/dist/compose.d.ts +179 -0
  66. package/dist/compose.d.ts.map +1 -0
  67. package/dist/compose.js +482 -0
  68. package/dist/composites/terraform-apply-op.d.ts.map +1 -1
  69. package/dist/composites/terraform-apply-op.js +7 -3
  70. package/dist/config.d.ts +59 -13
  71. package/dist/config.d.ts.map +1 -1
  72. package/dist/config.js +43 -9
  73. package/dist/describe-resources.d.ts +74 -12
  74. package/dist/describe-resources.d.ts.map +1 -1
  75. package/dist/describe-resources.js +374 -66
  76. package/dist/drift-read.d.ts +33 -0
  77. package/dist/drift-read.d.ts.map +1 -0
  78. package/dist/drift-read.js +243 -0
  79. package/dist/drift-record.d.ts +147 -0
  80. package/dist/drift-record.d.ts.map +1 -0
  81. package/dist/drift-record.js +383 -0
  82. package/dist/hcl/edges.d.ts.map +1 -1
  83. package/dist/hcl/edges.js +24 -1
  84. package/dist/hcl/files.d.ts +61 -0
  85. package/dist/hcl/files.d.ts.map +1 -0
  86. package/dist/hcl/files.js +221 -0
  87. package/dist/hcl/instances.d.ts +82 -0
  88. package/dist/hcl/instances.d.ts.map +1 -0
  89. package/dist/hcl/instances.js +390 -0
  90. package/dist/hcl/parse.d.ts +81 -9
  91. package/dist/hcl/parse.d.ts.map +1 -1
  92. package/dist/hcl/parse.js +114 -16
  93. package/dist/hcl/roots.d.ts.map +1 -1
  94. package/dist/hcl/roots.js +5 -0
  95. package/dist/hcl/suppressions.d.ts.map +1 -1
  96. package/dist/hcl/suppressions.js +8 -2
  97. package/dist/index.d.ts +11 -2
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +21 -2
  100. package/dist/integrity.json +3 -3
  101. package/dist/live-plan-reasons.d.ts +21 -0
  102. package/dist/live-plan-reasons.d.ts.map +1 -0
  103. package/dist/live-plan-reasons.js +47 -0
  104. package/dist/lsp/option-keys.d.ts.map +1 -1
  105. package/dist/lsp/option-keys.js +2 -0
  106. package/dist/manifest.json +1 -1
  107. package/dist/op/activities/index.d.ts +6 -2
  108. package/dist/op/activities/index.d.ts.map +1 -1
  109. package/dist/op/activities/index.js +5 -1
  110. package/dist/op/activities/live-detect.d.ts +4 -3
  111. package/dist/op/activities/live-detect.d.ts.map +1 -1
  112. package/dist/op/activities/live-detect.js +57 -32
  113. package/dist/op/activities/pin-rollout.d.ts +2 -0
  114. package/dist/op/activities/pin-rollout.d.ts.map +1 -1
  115. package/dist/op/activities/pin-rollout.js +1 -0
  116. package/dist/op/activities/terraform.d.ts +153 -5
  117. package/dist/op/activities/terraform.d.ts.map +1 -1
  118. package/dist/op/activities/terraform.js +205 -20
  119. package/dist/op/activity-contracts.d.ts +27 -0
  120. package/dist/op/activity-contracts.d.ts.map +1 -1
  121. package/dist/op/activity-contracts.js +19 -1
  122. package/dist/op/builders.d.ts +7 -1
  123. package/dist/op/builders.d.ts.map +1 -1
  124. package/dist/op/builders.js +9 -0
  125. package/dist/pin/edit.d.ts.map +1 -1
  126. package/dist/pin/edit.js +35 -0
  127. package/dist/pin/rollout.d.ts +2 -0
  128. package/dist/pin/rollout.d.ts.map +1 -1
  129. package/dist/pin/rollout.js +14 -11
  130. package/dist/plan-shape.d.ts +30 -0
  131. package/dist/plan-shape.d.ts.map +1 -0
  132. package/dist/plan-shape.js +125 -0
  133. package/dist/plugin.d.ts.map +1 -1
  134. package/dist/plugin.js +32 -18
  135. package/dist/report.d.ts +216 -0
  136. package/dist/report.d.ts.map +1 -0
  137. package/dist/report.js +666 -0
  138. package/dist/skills/chant-terraform.md +1 -1
  139. package/dist/state/azure-blob.d.ts +68 -0
  140. package/dist/state/azure-blob.d.ts.map +1 -0
  141. package/dist/state/azure-blob.js +201 -0
  142. package/dist/state/backend.d.ts +158 -0
  143. package/dist/state/backend.d.ts.map +1 -0
  144. package/dist/state/backend.js +406 -0
  145. package/dist/state/exec.d.ts +39 -0
  146. package/dist/state/exec.d.ts.map +1 -0
  147. package/dist/state/exec.js +80 -0
  148. package/dist/state/gcs.d.ts +62 -0
  149. package/dist/state/gcs.d.ts.map +1 -0
  150. package/dist/state/gcs.js +224 -0
  151. package/dist/state/index.d.ts +15 -0
  152. package/dist/state/index.d.ts.map +1 -0
  153. package/dist/state/index.js +14 -0
  154. package/dist/state/locks.d.ts +105 -0
  155. package/dist/state/locks.d.ts.map +1 -0
  156. package/dist/state/locks.js +130 -0
  157. package/dist/state/object-store.d.ts +37 -0
  158. package/dist/state/object-store.d.ts.map +1 -0
  159. package/dist/state/object-store.js +20 -0
  160. package/dist/state/root-states.d.ts +131 -0
  161. package/dist/state/root-states.d.ts.map +1 -0
  162. package/dist/state/root-states.js +241 -0
  163. package/dist/state/s3.d.ts +68 -0
  164. package/dist/state/s3.d.ts.map +1 -0
  165. package/dist/state/s3.js +170 -0
  166. package/dist/state/store.d.ts +51 -0
  167. package/dist/state/store.d.ts.map +1 -0
  168. package/dist/state/store.js +185 -0
  169. package/dist/terragrunt/affected.d.ts.map +1 -1
  170. package/dist/terragrunt/affected.js +2 -1
  171. package/package.json +7 -3
  172. package/src/__fixtures__/ACCEPTANCE.md +69 -7
  173. package/src/__fixtures__/compose/apply-failed-in-app.jsonl +12 -0
  174. package/src/__fixtures__/compose/state-app.json +66 -0
  175. package/src/__fixtures__/compose/state-edge.json +40 -0
  176. package/src/__fixtures__/compose/state-net.json +58 -0
  177. package/src/__fixtures__/compose/three-app.plan.json +184 -0
  178. package/src/__fixtures__/compose/three-composed.plan.json +509 -0
  179. package/src/__fixtures__/compose/three-edge.plan.json +144 -0
  180. package/src/__fixtures__/compose/three-net.plan.json +174 -0
  181. package/src/__fixtures__/compose/unknown-composed.plan.json +228 -0
  182. package/src/__fixtures__/compose/working-after-apply.json +145 -0
  183. package/src/__fixtures__/config-blocks/app/main.tf +61 -0
  184. package/src/__fixtures__/config-blocks/app/modules/network/main.tf +4 -0
  185. package/src/__fixtures__/config-blocks/app-json/main.tf.json +39 -0
  186. package/src/__fixtures__/config-files/shadow/main.tf +3 -0
  187. package/src/__fixtures__/config-files/shadow/main.tofu +3 -0
  188. package/src/__fixtures__/config-files/shadow/other.tf +3 -0
  189. package/src/__fixtures__/config-files/tf/main.tf +11 -0
  190. package/src/__fixtures__/config-files/tf-json/main.tf.json +18 -0
  191. package/src/__fixtures__/config-files/tofu/main.tofu +11 -0
  192. package/src/__fixtures__/config-files/tofu-json/main.tofu.json +18 -0
  193. package/src/__fixtures__/config-files/tofu-only/main.tofu +3 -0
  194. package/src/__fixtures__/drift-record/README.md +11 -0
  195. package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
  196. package/src/__fixtures__/instance-forms/app/main.tf +110 -0
  197. package/src/__fixtures__/instance-forms/app/modules/svc/main.tf +3 -0
  198. package/src/__fixtures__/instance-vars/app/main.tf +52 -0
  199. package/src/__fixtures__/instance-vars/app/modules/app/main.tf +12 -0
  200. package/src/__fixtures__/instance-vars/app/modules/edge/main.tf +3 -0
  201. package/src/__fixtures__/instance-vars/app/terraform.tfvars +1 -0
  202. package/src/__fixtures__/live-module-keyed/live-graph.json +259 -0
  203. package/src/__fixtures__/live-module-keyed/live-plan.json +87 -0
  204. package/src/__fixtures__/live-module-keyed/root/estate.chdf.hcl +1 -0
  205. package/src/__fixtures__/live-module-keyed/root/main.tf +21 -0
  206. package/src/__fixtures__/live-module-keyed/root/modules/app/main.tf +17 -0
  207. package/src/__fixtures__/live-module-keyed/root/modules/edge/main.tf +7 -0
  208. package/src/__fixtures__/live-module-keyed/root/versions.tf +30 -0
  209. package/src/__fixtures__/live-module-keyed/show-state.json +146 -0
  210. package/src/__fixtures__/pr-loop/README.md +50 -0
  211. package/src/__fixtures__/pr-loop/chant.config.json +13 -0
  212. package/src/__fixtures__/pr-loop/estate.component.ts +10 -0
  213. package/src/__fixtures__/pr-loop/roots/a/main.tf +11 -0
  214. package/src/__fixtures__/pr-loop/roots/app/main.tf +19 -0
  215. package/src/__fixtures__/pr-loop/roots/b/main.tf +7 -0
  216. package/src/__fixtures__/pr-loop/roots/dns/main.tf +3 -0
  217. package/src/__fixtures__/pr-loop/roots/net/main.tf +7 -0
  218. package/src/__fixtures__/report/applied.show.json +51 -0
  219. package/src/__fixtures__/report/generate.ts +63 -0
  220. package/src/__fixtures__/report/plan.show.json +200 -0
  221. package/src/__fixtures__/report/tf-apply/change-set.json +170 -0
  222. package/src/__fixtures__/report/tf-apply/report.json +338 -0
  223. package/src/__fixtures__/report/tf-plan/change-set.json +170 -0
  224. package/src/__fixtures__/report/tf-plan/report.json +320 -0
  225. package/src/__fixtures__/three-cloud-azure.graph.json +290 -0
  226. package/src/applied-state.ts +52 -0
  227. package/src/backend-config.test.ts +105 -0
  228. package/src/backend-config.ts +133 -0
  229. package/src/behaviour/kinds.ts +4 -0
  230. package/src/behaviour/predict.ts +5 -2
  231. package/src/behaviour/reference-catalog.plugin.test.ts +65 -0
  232. package/src/behaviour/reference-catalog.ts +16 -5
  233. package/src/behaviour/request.ts +3 -2
  234. package/src/change-set-instances.test.ts +98 -0
  235. package/src/changed-roots.ts +14 -16
  236. package/src/commands.ts +84 -4
  237. package/src/components/capability-plugin.test.ts +172 -5
  238. package/src/components/capability-plugin.ts +212 -11
  239. package/src/components/change-set-graph.e2e.test.ts +11 -5
  240. package/src/components/compose-group.test.ts +486 -0
  241. package/src/components/compose-group.ts +489 -0
  242. package/src/components/demo-composed-roots.e2e.test.ts +440 -0
  243. package/src/components/member-outputs.test.ts +76 -0
  244. package/src/components/placeholder-preview.test.ts +147 -0
  245. package/src/components/placeholder-preview.ts +257 -0
  246. package/src/components/pr-loop-compose.tofu.e2e.test.ts +363 -0
  247. package/src/components/pr-loop.tofu.test.ts +112 -56
  248. package/src/compose/apply-events.test.ts +62 -0
  249. package/src/compose/apply-events.ts +100 -0
  250. package/src/compose/estate.choudoufu.e2e.test.ts +112 -0
  251. package/src/compose/estate.test.ts +421 -0
  252. package/src/compose/estate.ts +443 -0
  253. package/src/compose/hcl.ts +311 -0
  254. package/src/compose/module-address.ts +49 -0
  255. package/src/compose/root.test.ts +416 -0
  256. package/src/compose/root.ts +592 -0
  257. package/src/compose/run.test.ts +440 -0
  258. package/src/compose/run.tofu.test.ts +176 -0
  259. package/src/compose/run.ts +527 -0
  260. package/src/compose/slice.test.ts +184 -0
  261. package/src/compose/slice.ts +290 -0
  262. package/src/compose/state-address.ts +157 -0
  263. package/src/compose/state-merge.test.ts +131 -0
  264. package/src/compose/state-merge.ts +148 -0
  265. package/src/compose.test.ts +248 -0
  266. package/src/compose.ts +627 -0
  267. package/src/composites/terraform-apply-op.test.ts +9 -0
  268. package/src/composites/terraform-apply-op.ts +7 -3
  269. package/src/composites/terraform-pin-rollout-op.test.ts +2 -2
  270. package/src/config-file-listers.test.ts +265 -0
  271. package/src/config.ts +44 -9
  272. package/src/describe-resources.engine-facts.test.ts +412 -0
  273. package/src/describe-resources.live-module-keyed.test.ts +290 -0
  274. package/src/describe-resources.ts +416 -70
  275. package/src/drift-read.ts +284 -0
  276. package/src/drift-record.test.ts +223 -0
  277. package/src/drift-record.ts +455 -0
  278. package/src/hcl/config-blocks.test.ts +174 -0
  279. package/src/hcl/edges.ts +21 -1
  280. package/src/hcl/files.ts +234 -0
  281. package/src/hcl/instance-forms.test.ts +94 -0
  282. package/src/hcl/instances.test.ts +137 -0
  283. package/src/hcl/instances.ts +422 -0
  284. package/src/hcl/parse.test.ts +139 -1
  285. package/src/hcl/parse.ts +149 -16
  286. package/src/hcl/roots.ts +6 -0
  287. package/src/hcl/suppressions.ts +8 -2
  288. package/src/index.ts +76 -0
  289. package/src/live-plan-reasons.ts +54 -0
  290. package/src/lsp/completions.test.ts +1 -1
  291. package/src/lsp/option-keys.ts +2 -0
  292. package/src/op/activities/choudoufu-plan-set-op.test.ts +111 -0
  293. package/src/op/activities/index.ts +9 -0
  294. package/src/op/activities/live-detect.ts +55 -26
  295. package/src/op/activities/pin-rollout.ts +3 -0
  296. package/src/op/activities/registry.test.ts +2 -1
  297. package/src/op/activities/terraform.test.ts +55 -0
  298. package/src/op/activities/terraform.ts +266 -22
  299. package/src/op/activity-contracts.test.ts +1 -0
  300. package/src/op/activity-contracts.ts +24 -1
  301. package/src/op/builders.ts +14 -0
  302. package/src/pin/bundle.test.ts +2 -0
  303. package/src/pin/edit.ts +30 -0
  304. package/src/pin/rollout.ts +16 -11
  305. package/src/plan-shape.test.ts +148 -0
  306. package/src/plan-shape.ts +128 -0
  307. package/src/plugin.ts +33 -19
  308. package/src/report.test.ts +423 -0
  309. package/src/report.ts +752 -0
  310. package/src/signal-only-root.test.ts +72 -0
  311. package/src/skills/chant-terraform.md +1 -1
  312. package/src/state/azure-blob.ts +223 -0
  313. package/src/state/backend-verdict.test.ts +187 -0
  314. package/src/state/backend.test.ts +127 -0
  315. package/src/state/backend.ts +488 -0
  316. package/src/state/exec.ts +111 -0
  317. package/src/state/gcs.ts +254 -0
  318. package/src/state/index.ts +15 -0
  319. package/src/state/locks.test.ts +84 -0
  320. package/src/state/locks.ts +201 -0
  321. package/src/state/object-store.ts +35 -0
  322. package/src/state/root-states-floci.e2e.test.ts +66 -0
  323. package/src/state/root-states.test.ts +462 -0
  324. package/src/state/root-states.ts +309 -0
  325. package/src/state/s3.ts +193 -0
  326. package/src/state/store.ts +225 -0
  327. package/src/terragrunt/affected.ts +2 -1
  328. package/src/workspace-kinds.test.ts +4 -17
  329. package/workspace-kinds.json +1 -24
  330. package/dist/workspace-member.d.ts +0 -30
  331. package/dist/workspace-member.d.ts.map +0 -1
  332. package/dist/workspace-member.js +0 -91
  333. package/schemas/pulumi.schema.json +0 -34
  334. package/src/testdata/pulumi-member/Pulumi.yaml +0 -2
  335. package/src/testdata/pulumi-member/stack-export.json +0 -53
  336. package/src/testdata/pulumi-unexported/Pulumi.yaml +0 -2
  337. package/src/workspace-member.test.ts +0 -89
  338. package/src/workspace-member.ts +0 -126
@@ -0,0 +1,390 @@
1
+ /**
2
+ * Instance nodes the declared graph can count from variables, and instance
3
+ * nodes under expanded module calls (chant #4486).
4
+ *
5
+ * `./parse.ts` gives a block its `instanceKeys` when its `count` or
6
+ * `for_each` is a literal (#4454). This pass runs once a root and its child
7
+ * modules are parsed and adds two cases that need the whole root:
8
+ *
9
+ * - An expansion that reads a variable, `count = var.n`, gets its keys when
10
+ * the variable's value is known from the files a plan would read: the
11
+ * `variable` block's `default`, then `terraform.tfvars`,
12
+ * `terraform.tfvars.json`, `*.auto.tfvars(.json)` in filename order, then
13
+ * `terraform.roots.<name>.varFiles`, later over earlier. In a child module
14
+ * the value is the call's argument, when it is a literal or a `var.x`
15
+ * known in the caller, else the child variable's default when the call
16
+ * passes nothing. `TF_CLI_ARGS` is not read, so the declared graph does not
17
+ * change with the environment the build runs in.
18
+ * - A block under a module call that is itself expanded gets one instance
19
+ * per module instance (times its own instances), with the module key on
20
+ * the call's segment: `estate/module.app[0]/aws_eip.pool[1]`. The entity
21
+ * lists those as `instances` (full ids), which core's `withInstanceNodes`
22
+ * reads in place of `instanceKeys` (`@intentius/chant/instance-nodes`
23
+ * holds the id rule). A module call with a countable expansion gets
24
+ * instance nodes of its own, `estate/module.app[0]`.
25
+ *
26
+ * The forms read are `var.n`, `length(var.x)`, `var.m` (a map, or a set
27
+ * variable) for `for_each`, and `toset(var.l)`; since #4489 the same with
28
+ * `local.<x>` in place of `var.<x>`, where the local's value is a literal or
29
+ * one of the `var` forms in its scope, and `var.on ? 1 : 0` (any two whole
30
+ * numbers, and `local.on` too) over a known bool. Anything else, or any
31
+ * value that is unknown, leaves the block as one node, which is what it
32
+ * was, and the entity gets an `instanceRollup` saying why (#4489, the codes
33
+ * in `@intentius/chant/instance-nodes`). `each.value` and `merge()` stay
34
+ * rolled up by ruling. A block under an expanded call whose own expansion
35
+ * or whose call's expansion cannot be counted gets no instances at all,
36
+ * since a partial list would name ids the plan never prints.
37
+ */
38
+ import { readdirSync, readFileSync, statSync } from "node:fs";
39
+ import { join, resolve } from "node:path";
40
+ import { isResourceDeclarable } from "@intentius/chant/declarable";
41
+ import { loadHcl2json } from "@intentius/chant/terraform/hcl2json";
42
+ import { DATA_TYPE, LOCALS_TYPE, MODULE_TYPE, RESOURCE_TYPE, VARIABLE_TYPE, callersOfKey, literalInstanceKeys, scopeOfKey, } from "./parse.js";
43
+ /** The most instance nodes one block gets; past it the block draws alone. */
44
+ const MAX_INSTANCES = 256;
45
+ const NAME = "[A-Za-z_][A-Za-z0-9_-]*";
46
+ const INTERPOLATION_RE = /^\$\{\s*([\s\S]*?)\s*\}$/;
47
+ /** `var.<x>` or `local.<x>` (#4489): the kind and the name. */
48
+ const REF = `(var|local)\\.(${NAME})`;
49
+ const REF_RE = new RegExp(`^${REF}$`);
50
+ const LENGTH_RE = new RegExp(`^length\\(\\s*${REF}\\s*\\)$`);
51
+ const TOSET_RE = new RegExp(`^toset\\(\\s*${REF}\\s*\\)$`);
52
+ /** `var.on ? 1 : 0` (#4489): a bool reference choosing between two whole numbers. */
53
+ const COND_RE = new RegExp(`^${REF}\\s*\\?\\s*(\\d+)\\s*:\\s*(\\d+)$`);
54
+ const EACH_RE = /\beach\.(?:value|key)\b/;
55
+ const MERGE_RE = /\bmerge\s*\(/;
56
+ const NO_LOCALS = new Map();
57
+ /** Whether a value still holds an expression a read of the files cannot evaluate. */
58
+ function holdsExpression(value) {
59
+ if (typeof value === "string")
60
+ return value.includes("${");
61
+ if (Array.isArray(value))
62
+ return value.some(holdsExpression);
63
+ if (typeof value === "object" && value !== null) {
64
+ return Object.entries(value).some(([k, v]) => k.includes("${") || holdsExpression(v));
65
+ }
66
+ return false;
67
+ }
68
+ /** A literal value as it stands, or undefined when it holds an expression. */
69
+ function literal(value) {
70
+ return value === undefined || holdsExpression(value) ? undefined : value;
71
+ }
72
+ /**
73
+ * Evaluate an argument in a scope: a literal, a bare `var.x` or `local.x`,
74
+ * `length(...)` or `toset(...)` of one, or `var.on ? 1 : 0`. Undefined when
75
+ * unknown.
76
+ */
77
+ function evaluate(value, vars, locals = NO_LOCALS) {
78
+ if (typeof value !== "string" || !value.includes("${")) {
79
+ const v = literal(value);
80
+ return v === undefined ? undefined : { value: v, set: false };
81
+ }
82
+ const m = INTERPOLATION_RE.exec(value.trim());
83
+ if (!m)
84
+ return undefined;
85
+ const inner = m[1];
86
+ if (/^\d+$/.test(inner))
87
+ return { value: Number(inner), set: false };
88
+ const ref = (kind, name) => (kind === "var" ? vars : locals).get(name);
89
+ let r;
90
+ if ((r = REF_RE.exec(inner)))
91
+ return ref(r[1], r[2]);
92
+ if ((r = COND_RE.exec(inner))) {
93
+ const on = ref(r[1], r[2])?.value;
94
+ return typeof on === "boolean" ? { value: Number(on ? r[3] : r[4]), set: false } : undefined;
95
+ }
96
+ if ((r = LENGTH_RE.exec(inner))) {
97
+ const v = ref(r[1], r[2])?.value;
98
+ if (Array.isArray(v))
99
+ return { value: v.length, set: false };
100
+ if (typeof v === "object" && v !== null)
101
+ return { value: Object.keys(v).length, set: false };
102
+ if (typeof v === "string")
103
+ return { value: [...v].length, set: false };
104
+ return undefined;
105
+ }
106
+ if ((r = TOSET_RE.exec(inner))) {
107
+ const v = ref(r[1], r[2])?.value;
108
+ return Array.isArray(v) ? { value: v, set: true } : undefined;
109
+ }
110
+ return undefined;
111
+ }
112
+ /** The expression a `count` or `for_each` holds, as written, without the `${ }` around it. */
113
+ function expressionText(value) {
114
+ if (typeof value === "string")
115
+ return (INTERPOLATION_RE.exec(value.trim())?.[1] ?? value).trim();
116
+ return JSON.stringify(value) ?? String(value);
117
+ }
118
+ /** Why an expansion the graph could not count stays rolled up (#4489). */
119
+ function rollupCodeOf(value) {
120
+ if (typeof value !== "string" || !value.includes("${"))
121
+ return "instances-value-unknown";
122
+ const text = expressionText(value);
123
+ if (EACH_RE.test(text))
124
+ return "instances-each-value";
125
+ if (MERGE_RE.test(text))
126
+ return "instances-merge";
127
+ const m = INTERPOLATION_RE.exec(value.trim());
128
+ if (m && [/^\d+$/, REF_RE, LENGTH_RE, TOSET_RE, COND_RE].some((re) => re.test(m[1])))
129
+ return "instances-value-unknown";
130
+ return "instances-form-unread";
131
+ }
132
+ /**
133
+ * A block's expansion in a scope: its instance keys as Terraform prints them,
134
+ * `null` when the block is not expanded, or why the keys are not known.
135
+ */
136
+ export function expansionIn(body, scope) {
137
+ if (!("count" in body) && !("for_each" in body))
138
+ return null;
139
+ const argument = "count" in body ? "count" : "for_each";
140
+ const expr = body[argument];
141
+ const rolled = (code) => ({ rollup: { code, argument, expression: expressionText(expr) } });
142
+ const lit = literalInstanceKeys(body);
143
+ if (lit)
144
+ return { keys: lit };
145
+ let keys;
146
+ if (argument === "count") {
147
+ const v = evaluate(expr, scope.vars, scope.locals)?.value;
148
+ if (typeof v === "number" && Number.isInteger(v) && v >= 0)
149
+ keys = Array.from({ length: v }, (_, i) => `[${i}]`);
150
+ }
151
+ else {
152
+ const v = evaluate(expr, scope.vars, scope.locals);
153
+ if (v && Array.isArray(v.value)) {
154
+ if (v.set && v.value.every((s) => typeof s === "string")) {
155
+ keys = [...new Set(v.value)].sort().map((k) => `[${JSON.stringify(k)}]`);
156
+ }
157
+ }
158
+ else if (v && typeof v.value === "object" && v.value !== null) {
159
+ keys = Object.keys(v.value).sort().map((k) => `[${JSON.stringify(k)}]`);
160
+ }
161
+ }
162
+ if (keys === undefined)
163
+ return rolled(rollupCodeOf(expr));
164
+ if (keys.length > MAX_INSTANCES)
165
+ return rolled("instances-over-limit");
166
+ return { keys };
167
+ }
168
+ /**
169
+ * The instance keys a block's `count` or `for_each` gives in `vars`, as
170
+ * Terraform prints them. `null` when the block is not expanded, undefined
171
+ * when it is and the keys are not known.
172
+ */
173
+ export function instanceKeysIn(body, vars, locals = NO_LOCALS) {
174
+ const e = expansionIn(body, { vars, locals });
175
+ return e === null ? null : "keys" in e ? e.keys : undefined;
176
+ }
177
+ /** A root's tfvars files, in the order a plan reads them, later over earlier. */
178
+ function tfvarsFiles(dir, varFiles) {
179
+ let names = [];
180
+ try {
181
+ names = readdirSync(dir).filter((n) => statSync(join(dir, n)).isFile());
182
+ }
183
+ catch {
184
+ return [...varFiles];
185
+ }
186
+ return [
187
+ ...["terraform.tfvars", "terraform.tfvars.json"].filter((n) => names.includes(n)),
188
+ ...names.filter((n) => n.endsWith(".auto.tfvars") || n.endsWith(".auto.tfvars.json")).sort(),
189
+ ...varFiles,
190
+ ];
191
+ }
192
+ /** The values a root's tfvars files set, by variable name. A file that cannot be read or parsed sets nothing. */
193
+ async function rootTfvars(opts) {
194
+ const out = new Map();
195
+ let parser = opts.hcl2json;
196
+ for (const file of tfvarsFiles(opts.dir, opts.varFiles ?? [])) {
197
+ let text;
198
+ try {
199
+ text = readFileSync(resolve(opts.dir, file), "utf-8");
200
+ }
201
+ catch {
202
+ continue;
203
+ }
204
+ let tree;
205
+ try {
206
+ if (file.endsWith(".json"))
207
+ tree = JSON.parse(text);
208
+ else {
209
+ parser ?? (parser = await loadHcl2json());
210
+ tree = (await parser.parse(file, text));
211
+ }
212
+ }
213
+ catch {
214
+ continue;
215
+ }
216
+ for (const [k, v] of Object.entries(tree))
217
+ out.set(k, v);
218
+ }
219
+ return out;
220
+ }
221
+ function bodyOf(entity) {
222
+ const body = entity.props.body;
223
+ return (typeof body === "object" && body !== null ? body : {});
224
+ }
225
+ function isSetType(body) {
226
+ return typeof body.type === "string" && /^\$\{\s*set\(/.test(body.type);
227
+ }
228
+ /**
229
+ * Add instance nodes the declared graph can count to one root's entities, in
230
+ * place (#4486). Entities of other roots in the map are left alone.
231
+ */
232
+ export async function resolveInstanceNodes(entities, root, opts) {
233
+ const own = [...entities].filter(([key, e]) => (key === root || key.startsWith(`${root}/`)) && isResourceDeclarable(e));
234
+ if (own.length === 0)
235
+ return;
236
+ // Variable declarations per scope.
237
+ const declared = new Map();
238
+ for (const [key, e] of own) {
239
+ if (e.entityType !== VARIABLE_TYPE)
240
+ continue;
241
+ const address = e.props.address;
242
+ if (!address.startsWith("var."))
243
+ continue;
244
+ const scope = scopeOfKey(key);
245
+ (declared.get(scope) ?? declared.set(scope, new Map()).get(scope)).set(address.slice(4), e);
246
+ }
247
+ // Local values per scope (#4489): every `locals` block's names.
248
+ const localBodies = new Map();
249
+ for (const [key, e] of own) {
250
+ if (e.entityType !== LOCALS_TYPE)
251
+ continue;
252
+ const scope = scopeOfKey(key);
253
+ const into = localBodies.get(scope) ?? localBodies.set(scope, new Map()).get(scope);
254
+ for (const [name, value] of Object.entries(bodyOf(e)))
255
+ into.set(name, value);
256
+ }
257
+ const tfvars = await rootTfvars(opts);
258
+ const scopes = new Map();
259
+ const localScopes = new Map();
260
+ /**
261
+ * A scope's known local values: a literal, or a `var` form over the
262
+ * scope's variables. A local that reads another local is unknown.
263
+ */
264
+ const localsOf = (scope) => {
265
+ const cached = localScopes.get(scope);
266
+ if (cached)
267
+ return cached;
268
+ const out = new Map();
269
+ localScopes.set(scope, out);
270
+ for (const [name, value] of localBodies.get(scope) ?? []) {
271
+ const v = evaluate(value, varsOf(scope));
272
+ if (v !== undefined)
273
+ out.set(name, v);
274
+ }
275
+ return out;
276
+ };
277
+ const scopeOf = (scope) => ({ vars: varsOf(scope), locals: localsOf(scope) });
278
+ /** A scope's known variable values, computed once, outermost first. */
279
+ const varsOf = (scope) => {
280
+ const cached = scopes.get(scope);
281
+ if (cached)
282
+ return cached;
283
+ const vars = new Map();
284
+ scopes.set(scope, vars);
285
+ const decls = declared.get(scope) ?? new Map();
286
+ if (scope === root) {
287
+ for (const [name, decl] of decls) {
288
+ const body = bodyOf(decl);
289
+ const set = isSetType(body);
290
+ const v = tfvars.has(name) ? literal(tfvars.get(name)) : literal(body.default);
291
+ if (v !== undefined)
292
+ vars.set(name, { value: v, set });
293
+ }
294
+ return vars;
295
+ }
296
+ const call = entities.get(scope);
297
+ const parent = scopeOfKey(scope);
298
+ const callBody = call ? bodyOf(call) : {};
299
+ const parentVars = varsOf(parent);
300
+ for (const [name, decl] of decls) {
301
+ const body = bodyOf(decl);
302
+ const set = isSetType(body);
303
+ if (name in callBody) {
304
+ const v = evaluate(callBody[name], parentVars, localsOf(parent));
305
+ if (v !== undefined)
306
+ vars.set(name, { value: v.value, set: set || v.set });
307
+ }
308
+ else {
309
+ const v = literal(body.default);
310
+ if (v !== undefined)
311
+ vars.set(name, { value: v, set });
312
+ }
313
+ }
314
+ return vars;
315
+ };
316
+ /** A module call's expansion, by the call entity's key; a call that is not a module call is not known. */
317
+ const callExpansion = (callKey) => {
318
+ const call = entities.get(callKey);
319
+ if (!call || call.entityType !== MODULE_TYPE)
320
+ return undefined;
321
+ return expansionIn(bodyOf(call), scopeOf(scopeOfKey(callKey)));
322
+ };
323
+ const keysOf = (e) => e === undefined ? undefined : e === null ? null : "keys" in e ? e.keys : undefined;
324
+ for (const [key, entity] of own) {
325
+ if (entity.entityType !== RESOURCE_TYPE && entity.entityType !== DATA_TYPE && entity.entityType !== MODULE_TYPE)
326
+ continue;
327
+ const callers = callersOfKey(key);
328
+ const calls = callers.map((_, i) => callExpansion(`${root}/${callers.slice(0, i + 1).join("/")}`));
329
+ const chain = calls.map(keysOf);
330
+ const own = expansionIn(bodyOf(entity), scopeOf(scopeOfKey(key)));
331
+ const ownKeys = keysOf(own);
332
+ const ownRollup = own !== null && "rollup" in own ? own.rollup : undefined;
333
+ const expandedChain = chain.some((k) => k !== null);
334
+ if (!expandedChain) {
335
+ if (ownKeys && !entity.instanceKeys)
336
+ entities.set(key, { ...entity, instanceKeys: ownKeys });
337
+ else if (ownRollup)
338
+ entities.set(key, { ...entity, instanceRollup: ownRollup });
339
+ continue;
340
+ }
341
+ // Under an expanded module call the literal `instanceKeys` would name ids
342
+ // under the unexpanded call, which no plan prints: the listed instances
343
+ // replace them, or nothing does.
344
+ const { instanceKeys: _dropped, ...rest } = entity;
345
+ if (chain.some((k) => k === undefined) || ownKeys === undefined) {
346
+ // The block's own reason first, else the first call on the way that could not be counted.
347
+ const at = chain.findIndex((k) => k === undefined);
348
+ const callRollup = at === -1 ? undefined : calls[at];
349
+ const rollup = ownRollup
350
+ ?? (callRollup && "rollup" in callRollup
351
+ ? { ...callRollup.rollup, code: "instances-module-uncounted", call: callers.slice(0, at + 1).join(".") }
352
+ : undefined);
353
+ entities.set(key, (rollup ? { ...rest, instanceRollup: rollup } : rest));
354
+ continue;
355
+ }
356
+ let combos = [[]];
357
+ for (const keys of chain)
358
+ combos = combos.flatMap((c) => (keys ?? [""]).map((k) => [...c, k]));
359
+ const tails = ownKeys ?? [""];
360
+ if (combos.length * tails.length > MAX_INSTANCES) {
361
+ // Named on the block's own expansion, or on the first expanded call when the block has none.
362
+ const body = bodyOf(entity);
363
+ const at = chain.findIndex((k) => k !== null);
364
+ const on = ownKeys !== null || at === -1 ? body : bodyOf(entities.get(`${root}/${callers.slice(0, at + 1).join("/")}`));
365
+ const argument = "count" in on ? "count" : "for_each";
366
+ const rollup = {
367
+ code: "instances-over-limit",
368
+ argument,
369
+ expression: expressionText(on[argument]),
370
+ ...(on === body ? {} : { call: callers.slice(0, at + 1).join(".") }),
371
+ };
372
+ entities.set(key, { ...rest, instanceRollup: rollup });
373
+ continue;
374
+ }
375
+ const address = entity.props.address;
376
+ const instances = [];
377
+ for (const combo of combos) {
378
+ const segments = callers.map((c, i) => `${c}${combo[i]}`);
379
+ const scope = segments.join(".");
380
+ for (const tail of tails) {
381
+ instances.push({
382
+ id: `${root}/${segments.join("/")}/${address}${tail}`,
383
+ ...(tail ? { key: tail } : {}),
384
+ scope,
385
+ });
386
+ }
387
+ }
388
+ entities.set(key, { ...rest, instances });
389
+ }
390
+ }
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * The one shared HCL parse for the terraform lexicon.
3
3
  *
4
- * Two entry points, one entity shape. `parseTerraformRootDir` reads the `.tf`
5
- * files of a directory (non-recursive, matching Terraform's own module
6
- * scoping) and is what `buildRoots()` calls. `parseTerraformRootContent` takes
7
- * the joined-file string `chant audit` hands a lexicon for a discovered root
8
- * module: every `.tf` in filename order behind a `# file: <name>` line comment.
4
+ * Two entry points, one entity shape. `parseTerraformRootDir` reads the
5
+ * configuration files of a directory (non-recursive, matching Terraform's own
6
+ * module scoping; `.tf` and `.tf.json`, plus `.tofu` and `.tofu.json` for a
7
+ * tofu or choudoufu root, see `./files.ts`) and is what `buildRoots()` calls.
8
+ * `parseTerraformRootContent` takes the joined-file string `chant audit` hands
9
+ * a lexicon for a discovered root module: every configuration file in filename
10
+ * order behind a `# file: <name>` line comment, narrowed to the same set.
9
11
  * Both funnel through `blocksToEntities`, so an entity the audit path sees is
10
12
  * the entity the build path sees.
11
13
  *
@@ -22,6 +24,7 @@ import { type Declarable } from "@intentius/chant/declarable";
22
24
  import type { EntityReference } from "@intentius/chant/graph-ir";
23
25
  import type { SuppressionDirective } from "@intentius/chant/lint/suppressions";
24
26
  import type { TerraformDeleteMode } from "../config.js";
27
+ export { TERRAFORM_SUFFIXES, TOFU_SUFFIXES, isConfigFileFor, isJsonConfigFile, isTofuConfigFile, jsonConfigTree, listConfigFiles, listConfigFilesSafe, readsTofuFiles, selectConfigFiles, } from "./files.js";
25
28
  /** A parsed HCL block body, as `@cdktn/hcl2json` encodes it. */
26
29
  export type BlockBody = Record<string, unknown>;
27
30
  /**
@@ -33,6 +36,10 @@ export type BlockBody = Record<string, unknown>;
33
36
  * the instance count is a plan-time answer and often a state-time one, but it
34
37
  * is a shape a reader should be told rather than left to infer from a node
35
38
  * count that never grows.
39
+ *
40
+ * Since #4454 a literal expansion also gets its instance nodes, children of
41
+ * the block's node (`TerraformEntity.instanceKeys`). The block node stays,
42
+ * and the edges stay block to block.
36
43
  */
37
44
  export type TerraformExpansion = "count" | "for_each";
38
45
  /** Whether a root runs under choudoufu with a declared estate (#2103). */
@@ -142,6 +149,31 @@ export interface TerraformEntity extends Declarable {
142
149
  * ROOT's name, not the module's: the module is not separately applied.
143
150
  */
144
151
  readonly stack: string;
152
+ /**
153
+ * The instance keys a `resource` or `data` block's literal `count` or
154
+ * `for_each` expands to (#4454), as Terraform prints them: `[0]`, `[1]`
155
+ * for `count = 2`, `["a"]` for a `for_each` over a literal map or
156
+ * `toset([...])`. Core's `withInstanceNodes` reads this lexicon-neutral
157
+ * field, as `buildGraphIr` reads `stack`, and draws one instance node per
158
+ * key under the block's node. Absent when the block is not expanded or its
159
+ * expansion is not a literal. Since #4486 `./instances.ts` also sets it
160
+ * for an expansion it can count from the root's variables (`count = var.n`
161
+ * with `n` known), and for a `module` call.
162
+ */
163
+ readonly instanceKeys?: readonly string[];
164
+ /**
165
+ * The instance nodes of a block under an expanded module call (#4486), by
166
+ * full node id: `estate/module.app[0]/aws_eip.pool[1]`, with `key` the
167
+ * block's own key (`[1]`, absent when the block is not expanded itself)
168
+ * and `scope` the module path as Terraform prints it (`module.app[0]`).
169
+ * Core's `entityInstances` reads this in place of `instanceKeys`, which
170
+ * such a block never carries. Set by `./instances.ts`.
171
+ */
172
+ readonly instances?: ReadonlyArray<{
173
+ readonly id: string;
174
+ readonly key?: string;
175
+ readonly scope?: string;
176
+ }>;
145
177
  /**
146
178
  * Every reference in this block, resolved to the entity keys it points at
147
179
  * (chant #2265), in core's lexicon-neutral {@link EntityReference} shape.
@@ -173,6 +205,23 @@ export declare const OUTPUT_TYPE = "Terraform::Output";
173
205
  export declare const LOCALS_TYPE = "Terraform::Locals";
174
206
  /** A `live { estate = "..." }` block, or an `estate.chdf.hcl` sidecar's content (#2103). */
175
207
  export declare const LIVE_TYPE = "Terraform::Live";
208
+ /**
209
+ * The four configuration blocks that change how a plan treats addresses
210
+ * rather than declaring anything (#4458): `moved`, `import`, `removed` and
211
+ * `check`. The first three carry no label and key as `moved`, `import`,
212
+ * `removed` (numbered `~2`, `~3` when a root holds several, as `locals` is);
213
+ * a `check` keys as `check.<name>`. Their references are edges like any other
214
+ * block's: a `moved` block's `from` and `to`, an `import` block's `to`, a
215
+ * `removed` block's `from`, and everything a `check` block's assertions and
216
+ * scoped `data` blocks read. A `from` usually names an address that is no
217
+ * longer declared, which resolves to no entity and so draws no edge, and
218
+ * that is all that happens: an unresolved reference is dropped, never
219
+ * reported (`./edges.ts`).
220
+ */
221
+ export declare const MOVED_TYPE = "Terraform::Moved";
222
+ export declare const IMPORT_TYPE = "Terraform::Import";
223
+ export declare const REMOVED_TYPE = "Terraform::Removed";
224
+ export declare const CHECK_TYPE = "Terraform::Check";
176
225
  /**
177
226
  * Terragrunt config entities (#3417). A `terragrunt.hcl` or `root.hcl` is not
178
227
  * a Terraform module, so its blocks are read into these types and never into
@@ -190,6 +239,15 @@ export declare const TERRAGRUNT_FILENAMES: readonly string[];
190
239
  export declare function isTerragruntFileName(name: string): boolean;
191
240
  /** The sidecar filename choudoufu reads an estate declaration from when no in-block `live { }` is used. */
192
241
  export declare const LIVE_SIDECAR_FILENAME = "estate.chdf.hcl";
242
+ /**
243
+ * The instance keys a literal expansion gives (#4454), as Terraform prints
244
+ * them, or undefined when the expansion is not a literal a read of the
245
+ * source can count. `count` as a number (`count = 3`), `for_each` as a
246
+ * literal map (`{ a = 1 }`, keys in Terraform's lexical order) or
247
+ * `toset([...])` over string literals. Anything holding a reference is a
248
+ * plan-time answer.
249
+ */
250
+ export declare function literalInstanceKeys(body: BlockBody): string[] | undefined;
193
251
  /**
194
252
  * Build one entity. Written out rather than run through `createResource`
195
253
  * from `@intentius/chant/runtime`: that factory is for generated resource
@@ -216,8 +274,15 @@ export interface TerraformFile {
216
274
  * anonymous file, so a caller that hands over a single `.tf` still parses.
217
275
  */
218
276
  export declare function splitBundleContent(content: string, fallbackName?: string): TerraformFile[];
219
- /** Every `.tf` directly under `dir`, in filename order. Non-recursive. */
220
- export declare function listTerraformFiles(dir: string): string[];
277
+ /**
278
+ * Every configuration file directly under `dir` that a root run by `binary`
279
+ * reads, in filename order, non-recursive: `.tf` and `.tf.json`, plus `.tofu`
280
+ * and `.tofu.json` for a tofu or choudoufu root, with `x.tofu` shadowing
281
+ * `x.tf` (chant#4457). The shared lister is `./files.ts`'s `listConfigFiles`.
282
+ */
283
+ export declare function listTerraformFiles(dir: string, binary?: string): string[];
284
+ /** One file's tree in hcl2json's shape: hcl2json for HCL, {@link jsonConfigTree} for Terraform's JSON syntax. */
285
+ export declare function parseFileTree(parser: Hcl2Json, file: TerraformFile): Promise<Record<string, unknown>>;
221
286
  /** The Terragrunt config files directly under `dir` (`root.hcl`, `terragrunt.hcl`), in filename order like the audit's bundle. */
222
287
  export declare function listTerragruntFiles(dir: string): string[];
223
288
  /**
@@ -279,8 +344,9 @@ export declare const LOCK_FILENAME = ".terraform.lock.hcl";
279
344
  */
280
345
  export declare function blocksToEntities(files: readonly TerraformFile[], root: string, hcl2json?: Hcl2Json, modeOptions?: TerraformRootModeOptions, sidecar?: TerraformFile, callers?: readonly string[]): Promise<Map<string, Declarable>>;
281
346
  /**
282
- * Parse a root module directory. Reads every `.tf` directly under `dir`, plus
283
- * the `estate.chdf.hcl` sidecar beside them when present. Throws whatever the
347
+ * Parse a root module directory. Reads the configuration files directly under
348
+ * `dir` that `modeOptions.binary` reads ({@link listTerraformFiles}), plus the
349
+ * `estate.chdf.hcl` sidecar beside them when present. Throws whatever the
284
350
  * parser throws for malformed HCL; `buildRoots()` is where that becomes a
285
351
  * warning.
286
352
  */
@@ -295,6 +361,12 @@ export declare function parseTerraformRootDir(dir: string, root: string, hcl2jso
295
361
  * the same way `parseTerraformRootDir`'s callers exercise it against files.
296
362
  */
297
363
  export declare function parseTerraformRootContent(content: string, root: string, hcl2json?: Hcl2Json, modeOptions?: TerraformRootModeOptions): Promise<Map<string, Declarable>>;
364
+ /**
365
+ * The files of a joined bundle a root run by `binary` reads: the same set
366
+ * {@link listTerraformFiles} gives for a directory holding them, plus the
367
+ * Terragrunt files, in bundle order (chant#4457).
368
+ */
369
+ export declare function bundleFilesFor(files: readonly TerraformFile[], binary?: string): TerraformFile[];
298
370
  /** The root name an audit of the audited directory itself parses under. */
299
371
  export declare const AUDIT_ROOT_NAME = "audit-root";
300
372
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/hcl/parse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/hcl/parse.ts"],"names":[],"mappings":"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"}