@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,254 @@
1
+ /**
2
+ * Previewing a root whose `vars` read outputs not known yet (#4463).
3
+ *
4
+ * terraform takes no unknown variable, so such a root used to get no plan at
5
+ * pull-request time, only a hole. Now it is planned with a stand-in for each
6
+ * variable that holds no value yet, typed from the root's own `variable`
7
+ * block ({@link terraformPlaceholder}). Every attribute and output the
8
+ * stand-ins drive is then marked unknown after apply in the plan JSON
9
+ * ({@link markPlaceholderDriven}) before the change set, the shape and the
10
+ * planned outputs are read from it, so no stand-in value reaches the note or
11
+ * the digest. The member's change-set part lists the variables under
12
+ * `placeholders`.
13
+ *
14
+ * What a stand-in drives is read from the plan's own `configuration`: an
15
+ * attribute whose expression references `var.<name>`, through module inputs
16
+ * too, plus any string attribute or output whose planned value carries
17
+ * {@link TERRAFORM_UNKNOWN_MARK}. A value that reaches an attribute another
18
+ * way (a number through a `local`) is not marked; the fresh plan at apply
19
+ * then differs from the preview and asks for an approval of its own, which
20
+ * costs a round and never applies a change nobody approved.
21
+ *
22
+ * A preview is not possible when a variable that holds the unknown read is
23
+ * not declared, when the unknown sits inside a larger value, when a `count`
24
+ * or `for_each` reads a stand-in (the preview would show a count the real
25
+ * value does not have), or when the placeholder plan fails, say on a
26
+ * `validation` block. The member then stays a hole, as before, and the
27
+ * hole's reason says why (the 2026-10-25 ruling on #4463).
28
+ */
29
+ /** The marker every string stand-in carries, so a reader can tell it from a real value. */
30
+ export const TERRAFORM_UNKNOWN_MARK = "known-after-apply";
31
+ const isObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
32
+ /** Split `text` on `sep` where no bracket is open. */
33
+ function splitTop(text, sep) {
34
+ const out = [];
35
+ let depth = 0;
36
+ let quoted = false;
37
+ let start = 0;
38
+ for (let i = 0; i < text.length; i++) {
39
+ const c = text[i];
40
+ if (c === '"' && text[i - 1] !== "\\")
41
+ quoted = !quoted;
42
+ if (quoted)
43
+ continue;
44
+ if (c === "(" || c === "[" || c === "{")
45
+ depth++;
46
+ else if (c === ")" || c === "]" || c === "}")
47
+ depth--;
48
+ else if (depth === 0 && (typeof sep === "string" ? c === sep : sep.test(c))) {
49
+ out.push(text.slice(start, i));
50
+ start = i + 1;
51
+ }
52
+ }
53
+ out.push(text.slice(start));
54
+ return out.map((s) => s.trim()).filter((s) => s !== "");
55
+ }
56
+ /** `name(inner)` read off a type expression, or `undefined` when it is not one. */
57
+ function call(type, name) {
58
+ const m = type.match(new RegExp(`^${name}\\s*\\(([\\s\\S]*)\\)$`));
59
+ return m ? m[1].trim() : undefined;
60
+ }
61
+ /**
62
+ * A stand-in for a variable of `type`, a Terraform type expression as the
63
+ * `variable` block writes it (`string`, `list(string)`, `object({ id = string })`).
64
+ *
65
+ * - `string`, `any` or no type: {@link TERRAFORM_UNKNOWN_MARK}.
66
+ * - `number`: 0. `bool`: false.
67
+ * - `list(...)`, `set(...)`: an empty list. `map(...)`: an empty map.
68
+ * - `tuple([a, b])`: one stand-in per element type.
69
+ * - `object({ a = t })`: one stand-in per attribute, `optional(t)` read as `t`.
70
+ *
71
+ * An empty collection plans no element, so a resource that iterates one
72
+ * plans none; the fresh plan at apply then asks for its own approval.
73
+ */
74
+ export function terraformPlaceholder(type) {
75
+ const t = (type ?? "").trim().replace(/^\$\{([\s\S]*)\}$/, "$1").trim();
76
+ if (t === "" || t === "any" || t === "string")
77
+ return TERRAFORM_UNKNOWN_MARK;
78
+ if (t === "number")
79
+ return 0;
80
+ if (t === "bool")
81
+ return false;
82
+ const optional = call(t, "optional");
83
+ if (optional !== undefined)
84
+ return terraformPlaceholder(splitTop(optional, ",")[0]);
85
+ if (call(t, "list") !== undefined || call(t, "set") !== undefined)
86
+ return [];
87
+ if (call(t, "map") !== undefined)
88
+ return {};
89
+ const tuple = call(t, "tuple");
90
+ if (tuple !== undefined) {
91
+ const inner = tuple.replace(/^\[([\s\S]*)\]$/, "$1");
92
+ return splitTop(inner, ",").map((e) => terraformPlaceholder(e));
93
+ }
94
+ const object = call(t, "object");
95
+ if (object !== undefined) {
96
+ const inner = object.replace(/^\{([\s\S]*)\}$/, "$1");
97
+ const out = {};
98
+ for (const attr of splitTop(inner, /[,\n]/)) {
99
+ const at = attr.indexOf("=");
100
+ if (at < 0)
101
+ continue;
102
+ const name = attr.slice(0, at).trim().replace(/^"(.*)"$/, "$1");
103
+ out[name] = terraformPlaceholder(attr.slice(at + 1));
104
+ }
105
+ return out;
106
+ }
107
+ return TERRAFORM_UNKNOWN_MARK;
108
+ }
109
+ const containsUndefined = (v) => v === undefined || (Array.isArray(v) ? v.some(containsUndefined) : isObject(v) ? Object.values(v).some(containsUndefined) : false);
110
+ /**
111
+ * The stand-ins for a step's `vars` (#4463): each variable whose value is
112
+ * `undefined` (a `stackOutput()` read with nothing to read yet) gets
113
+ * {@link terraformPlaceholder} of its declared type. Returns why instead when
114
+ * no preview can be made: no variable holds the unknown read, one that does
115
+ * is not declared in the root, or the unknown sits inside a larger value.
116
+ */
117
+ export function placeholderVars(vars, declared) {
118
+ const given = vars ?? {};
119
+ const placeholders = [];
120
+ const out = {};
121
+ for (const [name, value] of Object.entries(given)) {
122
+ if (value === undefined) {
123
+ const decl = declared.get(name);
124
+ if (!decl)
125
+ return `var.${name} holds the unknown read and the root declares no variable "${name}" to type a stand-in from`;
126
+ placeholders.push(name);
127
+ out[name] = terraformPlaceholder(decl.type);
128
+ }
129
+ else if (containsUndefined(value)) {
130
+ return `the unknown read sits inside var.${name}, which a stand-in cannot fill in part`;
131
+ }
132
+ else
133
+ out[name] = value;
134
+ }
135
+ if (placeholders.length === 0)
136
+ return "no variable of the step holds the unknown read";
137
+ return { placeholders: placeholders.sort(), vars: out };
138
+ }
139
+ /** Every `references` entry under an expression, at any depth (nested blocks are arrays of expression objects). */
140
+ function referencesIn(expr, out = []) {
141
+ if (Array.isArray(expr))
142
+ for (const e of expr)
143
+ referencesIn(e, out);
144
+ else if (isObject(expr)) {
145
+ if (Array.isArray(expr.references))
146
+ for (const r of expr.references)
147
+ if (typeof r === "string")
148
+ out.push(r);
149
+ for (const [k, v] of Object.entries(expr))
150
+ if (k !== "references" && k !== "constant_value")
151
+ referencesIn(v, out);
152
+ }
153
+ return out;
154
+ }
155
+ const readsVar = (expr, vars) => referencesIn(expr).some((r) => {
156
+ const m = r.match(/^var\.([^.[]+)/);
157
+ return m !== null && vars.has(m[1]);
158
+ });
159
+ const resourceKey = (modulePath, mode, type, name) => `${modulePath}|${mode === "data" ? "data." : ""}${type}.${name}`;
160
+ function walkModule(mod, path, vars, driven) {
161
+ if (!isObject(mod) || vars.size === 0)
162
+ return;
163
+ const at = (address) => (path ? `${path}.${address}` : address);
164
+ for (const r of Array.isArray(mod.resources) ? mod.resources : []) {
165
+ if (!isObject(r))
166
+ continue;
167
+ const mode = String(r.mode ?? "managed");
168
+ const address = String(r.address ?? `${r.type}.${r.name}`);
169
+ if (readsVar(r.count_expression, vars) || readsVar(r.for_each_expression, vars))
170
+ driven.expansions.push(at(address));
171
+ const exprs = isObject(r.expressions) ? r.expressions : {};
172
+ const attrs = new Set(Object.entries(exprs).filter(([, e]) => readsVar(e, vars)).map(([k]) => k));
173
+ if (attrs.size > 0)
174
+ driven.attributes.set(resourceKey(path, mode, String(r.type), String(r.name)), attrs);
175
+ }
176
+ for (const [name, c] of Object.entries(isObject(mod.module_calls) ? mod.module_calls : {})) {
177
+ if (!isObject(c))
178
+ continue;
179
+ if (readsVar(c.count_expression, vars) || readsVar(c.for_each_expression, vars))
180
+ driven.expansions.push(at(`module.${name}`));
181
+ const exprs = isObject(c.expressions) ? c.expressions : {};
182
+ const inputs = new Set(Object.entries(exprs).filter(([, e]) => readsVar(e, vars)).map(([k]) => k));
183
+ walkModule(c.module, at(`module.${name}`), inputs, driven);
184
+ }
185
+ if (path === "") {
186
+ for (const [name, o] of Object.entries(isObject(mod.outputs) ? mod.outputs : {})) {
187
+ if (isObject(o) && readsVar(o.expression, vars))
188
+ driven.outputs.add(name);
189
+ }
190
+ }
191
+ }
192
+ const carriesMark = (v) => typeof v === "string" ? v.includes(TERRAFORM_UNKNOWN_MARK) : Array.isArray(v) ? v.some(carriesMark) : isObject(v) ? Object.values(v).some(carriesMark) : false;
193
+ /** A `resource_changes` item's key in {@link Driven.attributes}: its module path without instance keys. */
194
+ function changeKey(rc) {
195
+ const modulePath = typeof rc.module_address === "string" ? rc.module_address.replace(/\[[^\]]*\]/g, "") : "";
196
+ return resourceKey(modulePath, String(rc.mode ?? "managed"), String(rc.type), String(rc.name));
197
+ }
198
+ /**
199
+ * `planJson` (`show -json` of the placeholder plan) with every attribute and
200
+ * root output the stand-ins for `placeholders` drive marked unknown after
201
+ * apply, their planned values dropped. Returns why instead when a `count` or
202
+ * `for_each` reads a stand-in. The input is not changed.
203
+ */
204
+ export function markPlaceholderDriven(planJson, placeholders) {
205
+ const plan = structuredClone(isObject(planJson) ? planJson : {});
206
+ const driven = { attributes: new Map(), outputs: new Set(), expansions: [] };
207
+ const config = isObject(plan.configuration) ? plan.configuration : {};
208
+ walkModule(config.root_module, "", new Set(placeholders), driven);
209
+ if (driven.expansions.length > 0) {
210
+ return { refused: `the count or for_each of ${[...new Set(driven.expansions)].sort().join(", ")} reads a stand-in, so the preview cannot say how many instances there are` };
211
+ }
212
+ for (const r of Array.isArray(plan.resource_changes) ? plan.resource_changes : []) {
213
+ if (!isObject(r) || !isObject(r.change))
214
+ continue;
215
+ const change = r.change;
216
+ const after = isObject(change.after) ? change.after : undefined;
217
+ const attrs = new Set(driven.attributes.get(changeKey(r)) ?? []);
218
+ for (const [k, v] of Object.entries(after ?? {}))
219
+ if (carriesMark(v))
220
+ attrs.add(k);
221
+ if (attrs.size === 0)
222
+ continue;
223
+ const afterUnknown = isObject(change.after_unknown) ? change.after_unknown : {};
224
+ for (const k of attrs) {
225
+ afterUnknown[k] = true;
226
+ if (after)
227
+ delete after[k];
228
+ }
229
+ change.after_unknown = afterUnknown;
230
+ }
231
+ const outputChanges = isObject(plan.output_changes) ? plan.output_changes : {};
232
+ const plannedOutputs = isObject(plan.planned_values) && isObject(plan.planned_values.outputs) ? plan.planned_values.outputs : {};
233
+ for (const [name, o] of Object.entries(outputChanges))
234
+ if (isObject(o) && carriesMark(o.after))
235
+ driven.outputs.add(name);
236
+ for (const [name, o] of Object.entries(plannedOutputs))
237
+ if (isObject(o) && carriesMark(o.value))
238
+ driven.outputs.add(name);
239
+ for (const name of driven.outputs) {
240
+ const o = isObject(outputChanges[name]) ? outputChanges[name] : (outputChanges[name] = {});
241
+ delete o.after;
242
+ o.after_unknown = true;
243
+ delete plannedOutputs[name];
244
+ }
245
+ return { plan };
246
+ }
247
+ /** The hole a root keeps when its preview is not possible: the old reason, and why there is no preview. */
248
+ export function waitingHole(root, unresolved, why) {
249
+ return {
250
+ address: root,
251
+ type: "terraform_root",
252
+ reason: `inputs from ${unresolved.join(", ")}; planned again once they apply${why ? `; no preview: ${why}` : ""}`,
253
+ };
254
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * How each member's part of a composed apply ended (chant#4442, epic #4419),
3
+ * read from the binary's `apply -json` lines: `applied`, `partial`,
4
+ * `failed`, `not-started` or `no-changes`, core's `GroupMemberStatus`
5
+ * (ws-107).
6
+ *
7
+ * Lifted from terragucci's `packages/terragucci/src/compose.ts` at c493e0e
8
+ * (`readApplyEvents`, `memberApply`).
9
+ */
10
+ import type { GroupMemberStatus } from "@intentius/chant/components/capability";
11
+ import type { Composition } from "../compose.js";
12
+ /** How one member's part of the apply ended. */
13
+ export type MemberApply = GroupMemberStatus;
14
+ /** What `apply -json` said of each module: the changes that completed, started, or errored, and the first error. */
15
+ export interface ApplyEvents {
16
+ done: Map<string, number>;
17
+ started: Map<string, number>;
18
+ errored: Map<string, string>;
19
+ /** Errors no module's resource names. */
20
+ other: string[];
21
+ }
22
+ /** Read `apply -json` lines into each module's progress. A line that is not JSON is skipped. */
23
+ export declare function readApplyEvents(out: string, modules: readonly string[]): ApplyEvents;
24
+ /** How a member's part of the apply ended, from its planned changes and the events. */
25
+ export declare function memberApply(m: string, planned: number, ev: ApplyEvents): {
26
+ apply: MemberApply;
27
+ done: number;
28
+ };
29
+ /** One member's outcome of a composed apply. */
30
+ export interface MemberApplyOutcome {
31
+ status: MemberApply;
32
+ /** Its planned changes that completed. */
33
+ done: number;
34
+ /** The first error its part named. */
35
+ error?: string;
36
+ }
37
+ /**
38
+ * Every member's outcome of a composed apply, by component, from the
39
+ * `apply -json` output and each member's planned changes
40
+ * (`PlanCounts.changes` of its slice).
41
+ */
42
+ export declare function composedApplyOutcomes(c: Pick<Composition, "order" | "modules">, planned: ReadonlyMap<string, number>, out: string): {
43
+ members: Record<string, MemberApplyOutcome>;
44
+ other: string[];
45
+ };
46
+ //# sourceMappingURL=apply-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-events.d.ts","sourceRoot":"","sources":["../../src/compose/apply-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE5C,oHAAoH;AACpH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,yCAAyC;IACzC,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AASD,gGAAgG;AAChG,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,CA6BpF;AAED,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAO7G;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAUpM"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * How each member's part of a composed apply ended (chant#4442, epic #4419),
3
+ * read from the binary's `apply -json` lines: `applied`, `partial`,
4
+ * `failed`, `not-started` or `no-changes`, core's `GroupMemberStatus`
5
+ * (ws-107).
6
+ *
7
+ * Lifted from terragucci's `packages/terragucci/src/compose.ts` at c493e0e
8
+ * (`readApplyEvents`, `memberApply`).
9
+ */
10
+ import { stripModule, topModule } from "./module-address.js";
11
+ /** Read `apply -json` lines into each module's progress. A line that is not JSON is skipped. */
12
+ export function readApplyEvents(out, modules) {
13
+ const ev = { done: new Map(), started: new Map(), errored: new Map(), other: [] };
14
+ const known = new Set(modules);
15
+ const moduleOf = (addr) => {
16
+ const m = addr !== undefined ? topModule(addr) : undefined;
17
+ return m !== undefined && known.has(m) && addr !== `module.${m}` ? m : undefined;
18
+ };
19
+ const bump = (map, m) => map.set(m, (map.get(m) ?? 0) + 1);
20
+ for (const line of out.split("\n")) {
21
+ if (!line.startsWith("{"))
22
+ continue;
23
+ let e;
24
+ try {
25
+ e = JSON.parse(line);
26
+ }
27
+ catch {
28
+ continue;
29
+ }
30
+ const addr = e.hook?.resource?.addr;
31
+ const m = moduleOf(addr);
32
+ if (e.type === "apply_start" && m)
33
+ bump(ev.started, m);
34
+ else if (e.type === "apply_complete" && m)
35
+ bump(ev.done, m);
36
+ else if (e.type === "apply_errored" && m && !ev.errored.has(m))
37
+ ev.errored.set(m, `${stripModule(addr)}: ${e.hook?.error ?? e["@message"] ?? "errored"}`);
38
+ else if (e.type === "diagnostic" && e.diagnostic?.severity === "error") {
39
+ const dm = moduleOf(e.diagnostic.address);
40
+ const text = `${e.diagnostic.summary ?? "Error"}${e.diagnostic.detail ? `: ${e.diagnostic.detail.split("\n")[0]}` : ""}`;
41
+ if (dm && !ev.errored.has(dm))
42
+ ev.errored.set(dm, `${stripModule(e.diagnostic.address)}: Error: ${text}`);
43
+ else if (!dm)
44
+ ev.other.push(text);
45
+ }
46
+ }
47
+ return ev;
48
+ }
49
+ /** How a member's part of the apply ended, from its planned changes and the events. */
50
+ export function memberApply(m, planned, ev) {
51
+ const done = Math.min(ev.done.get(m) ?? 0, planned);
52
+ if (planned === 0)
53
+ return { apply: "no-changes", done: 0 };
54
+ if (done >= planned)
55
+ return { apply: "applied", done };
56
+ if (done > 0)
57
+ return { apply: "partial", done };
58
+ if (ev.errored.has(m) || (ev.started.get(m) ?? 0) > 0)
59
+ return { apply: "failed", done };
60
+ return { apply: "not-started", done };
61
+ }
62
+ /**
63
+ * Every member's outcome of a composed apply, by component, from the
64
+ * `apply -json` output and each member's planned changes
65
+ * (`PlanCounts.changes` of its slice).
66
+ */
67
+ export function composedApplyOutcomes(c, planned, out) {
68
+ const ev = readApplyEvents(out, c.order.map((member) => c.modules.get(member)));
69
+ const members = {};
70
+ for (const member of c.order) {
71
+ const m = c.modules.get(member);
72
+ const { apply, done } = memberApply(m, planned.get(member) ?? 0, ev);
73
+ const error = ev.errored.get(m);
74
+ members[member] = { status: apply, done, ...(error && apply !== "applied" ? { error } : {}) };
75
+ }
76
+ return { members, other: ev.other };
77
+ }
@@ -0,0 +1,194 @@
1
+ /**
2
+ * The composed run of choudoufu estates (chant#4445, epic #4419): when every
3
+ * member runs choudoufu against a `live` estate (`Composition.estate`), one
4
+ * `choudoufu plan` and one `choudoufu apply` from a composed root of `module`
5
+ * calls (choudoufu#2059).
6
+ *
7
+ * An estate has no state file, so nothing is pulled, locked, split or
8
+ * written back: each resource's record goes to its own estate as it applies,
9
+ * and a `terraform_estate_outputs` read of another estate in the run is
10
+ * answered inside the run. The composed root is `writeEstateRoot`'s
11
+ * (./root.ts, #4441). The run takes the job's environment and assumes no
12
+ * role of its own: each estate's provider blocks name its role.
13
+ *
14
+ * choudoufu refuses a bare `show` under a `live` block, so the values the
15
+ * plan left unknown are read after the apply from a second plan of the
16
+ * composed root: its `prior_state`, sliced per module (./slice.ts, #4442) and
17
+ * read through `../applied-state`, the reader `chant terraform report` uses.
18
+ * The same plan says how far a failed apply got: a member whose part plans
19
+ * no change any more applied.
20
+ *
21
+ * Lifted from terragucci's `packages/terragucci/src/compose.ts` at c493e0e
22
+ * (`ComposedRun` with `estate` set: `plan`, `apply`, `finishEstate`,
23
+ * `showEstateMembers`, `composedEnv`). The state-backed run is #4444; this one
24
+ * has the same `plan()`, `apply()` and `release()` and returns the same
25
+ * shapes, and #4447 picks one by `Composition.estate`.
26
+ */
27
+ import type { CapabilityGroupOutcome, CapabilityGroupPlan, GroupMemberOutcome } from "@intentius/chant/components/capability";
28
+ import type { ComposeFallback, Composition } from "../compose.js";
29
+ import type { TerraformConfig } from "../config.js";
30
+ import { type StateResourceValues } from "../applied-state.js";
31
+ import { type BinaryExec } from "../state/exec.js";
32
+ import { type ApplyEvents, type MemberApply } from "./apply-events.js";
33
+ import { type ComposedMemberPlan, type PlanCounts } from "./slice.js";
34
+ /** What a composed run's `plan()` answers. Assignable to core's `CapabilityGroupPlan` (ws-107). */
35
+ export interface ComposedRunPlan extends CapabilityGroupPlan {
36
+ /** Each member's part of the plan, by component. Empty when the run fell back or the plan failed. */
37
+ members: Record<string, ComposedMemberPlan>;
38
+ /** What the approval binds beside the members' own plans: the composed plan and the generated files. Empty when nothing planned. */
39
+ digest: string;
40
+ /** Why the run did not plan as one: the members plan wave by wave instead. Decided before anything planned. */
41
+ fallback?: ComposeFallback;
42
+ /** Why the composed plan failed: every member is plan-failed. */
43
+ error?: string;
44
+ /** The member {@link error} is about, when it is about one (a hook, an init, a lock). */
45
+ member?: string;
46
+ /** The composed plan's `show -json`. */
47
+ plan?: unknown;
48
+ /** The saved plan file `apply()` applies. */
49
+ planFile: string;
50
+ /** The composed plan's `show` text. */
51
+ text: string;
52
+ /** Each member's part of the `show` text, by component. */
53
+ texts: Record<string, string>;
54
+ /** sha256 of each generated file of the composed root, as `ComposedRoot.generated`. */
55
+ generated: [string, string][];
56
+ /** The whole run's counts. */
57
+ counts: PlanCounts;
58
+ /** The binary's `Plan:` line for the whole run. */
59
+ summary: string;
60
+ }
61
+ /** One member's outcome of a composed apply. Assignable to core's `GroupMemberOutcome` (ws-107). */
62
+ export interface ComposedMemberOutcome extends GroupMemberOutcome {
63
+ status: MemberApply;
64
+ /** Its planned changes. */
65
+ planned: number;
66
+ /** Its planned changes that completed. */
67
+ done: number;
68
+ /** Each resource of its part of the state after the apply, by address with its module taken off. */
69
+ resources?: Map<string, StateResourceValues>;
70
+ }
71
+ /** What a composed run's `apply()` answers. Assignable to core's `CapabilityGroupOutcome` (ws-107). */
72
+ export interface ComposedRunApply extends CapabilityGroupOutcome {
73
+ /** Every member applied or had no changes, and the binary exited 0. */
74
+ ok: boolean;
75
+ members: Record<string, ComposedMemberOutcome>;
76
+ /** `show -json` of the plan made after the apply. Absent when it could not be made. */
77
+ after?: unknown;
78
+ }
79
+ /** The surface #4447 drives, whichever run `Composition.estate` picks. */
80
+ export interface ComposedRunner {
81
+ plan(): Promise<ComposedRunPlan>;
82
+ apply(): Promise<ComposedRunApply>;
83
+ release(): Promise<void>;
84
+ }
85
+ export interface EstateRunOptions {
86
+ /** The checkout's root: where `chant.config.*` was loaded from. `.chant-compose/` is written here. */
87
+ projectRoot: string;
88
+ /** What `compositionFor` answered, with `estate` set and two or more members. */
89
+ composition: Composition;
90
+ /** The config's `terraform` namespace: a root's `estate`. */
91
+ terraform: TerraformConfig;
92
+ /** The job's environment. The run adds no role to it. */
93
+ env: NodeJS.ProcessEnv;
94
+ /** The choudoufu binary, by name or path. Default `terraform.binary`, else `choudoufu`. */
95
+ binary?: string;
96
+ /** Where the plan files go. Default: a new directory under the system's temp directory. */
97
+ work?: string;
98
+ /** How the binary runs. Default {@link runBinary}; a test injects a fake. */
99
+ exec?: BinaryExec;
100
+ log?: (line: string) => void;
101
+ }
102
+ /**
103
+ * Why a choudoufu's `version` output cannot run a composed run of estates, or
104
+ * undefined when it can. A release older than
105
+ * {@link MIN_CHOUDOUFU_ESTATES_VERSION} falls back; a dev build names no
106
+ * release and passes.
107
+ */
108
+ export declare function estateVersionFallback(versionOutput: string): ComposeFallback | undefined;
109
+ /**
110
+ * What choudoufu's human `apply` output says of each module: the changes
111
+ * that completed (`<addr>: Creation complete`, `Modifications complete`,
112
+ * `Destruction complete`), started (`Creating...` and the rest) or errored
113
+ * (an `Error:` box naming `with <addr>,`). An estate's apply runs under live
114
+ * resource markers and prints no `-json` lines, so this reads the text.
115
+ */
116
+ export declare function readEstateApplyText(out: string, modules: readonly string[]): ApplyEvents;
117
+ /**
118
+ * Each member's outcome from its planned changes, what the apply printed, its
119
+ * exit code and, when the post-apply plan was made, the changes each member's
120
+ * part still plans. A clean exit means every planned change applied. After a
121
+ * failure, a member's changes left in the post-apply plan say how many of its
122
+ * planned changes applied; without that plan the printed completions do.
123
+ */
124
+ export declare function estateOutcomes(c: Pick<Composition, "order" | "modules">, planned: ReadonlyMap<string, number>, out: string, code: number, remaining?: ReadonlyMap<string, number>): {
125
+ members: Record<string, {
126
+ status: MemberApply;
127
+ done: number;
128
+ planned: number;
129
+ error?: string;
130
+ }>;
131
+ other: string[];
132
+ };
133
+ /**
134
+ * One composed run of estates: `plan()`, then `apply()` once the approval is
135
+ * given, then `release()` whatever happened. No call reads, locks or writes
136
+ * a state.
137
+ */
138
+ export declare class EstateRun implements ComposedRunner {
139
+ private readonly o;
140
+ private readonly exec;
141
+ private readonly binary;
142
+ private readonly composeDir;
143
+ private readonly work;
144
+ private readonly madeWork;
145
+ private planned?;
146
+ private root?;
147
+ constructor(o: EstateRunOptions);
148
+ private get c();
149
+ private log;
150
+ /**
151
+ * The composed root's environment: the job's, with no role added (each
152
+ * estate's provider blocks name its role) and its `-var-file` flags taken
153
+ * out. With a shared provider cache and no lock file to check a cached
154
+ * provider against, the cache may fill the lock file.
155
+ */
156
+ private env;
157
+ /** The estate each member's records go to: its root's `estate`, else its `live` block's. */
158
+ private estateOf;
159
+ private notPlanned;
160
+ /**
161
+ * Why this choudoufu cannot run the composition, or undefined. Runs
162
+ * `choudoufu version`; what #4447's `groupFallback` asks before planning.
163
+ */
164
+ fallback(): Promise<ComposeFallback | undefined>;
165
+ private writeRoot;
166
+ private restoreRoot;
167
+ /**
168
+ * Check the binary's version, write the composed root, init it and plan
169
+ * once, then cut the plan into each member's part. The composed root is
170
+ * taken away again before this returns.
171
+ */
172
+ plan(): Promise<ComposedRunPlan>;
173
+ /**
174
+ * Apply the saved plan from the composed root, then plan again and read
175
+ * each member's values from that plan's `prior_state`. A failed apply
176
+ * leaves what applied applied, and each member's outcome says how far its
177
+ * part got.
178
+ */
179
+ apply(): Promise<ComposedRunApply>;
180
+ /**
181
+ * `show -json` of a plan of the composed root made after the apply, whose
182
+ * `prior_state` choudoufu builds from the records and the live system.
183
+ * Undefined when it cannot be made: the values unknown at plan then stay
184
+ * unknown. Never fails the run.
185
+ */
186
+ private planAfter;
187
+ /**
188
+ * Take the composed root away if a call left it, with the binary's working
189
+ * files under `.chant-compose/`, and the plan files. There is no lock to
190
+ * let go of. Safe to call more than once.
191
+ */
192
+ release(): Promise<void>;
193
+ }
194
+ //# sourceMappingURL=estate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estate.d.ts","sourceRoot":"","sources":["../../src/compose/estate.ts"],"names":[],"mappings":"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"}