@intentius/chant-lexicon-terraform 0.124.52 → 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.
- package/README.md +7 -6
- package/dist/__fixtures__/pr-loop/estate.component.d.ts +7 -0
- package/dist/__fixtures__/pr-loop/estate.component.d.ts.map +1 -0
- package/dist/__fixtures__/pr-loop/estate.component.js +7 -0
- package/dist/__fixtures__/report/generate.d.ts +26 -0
- package/dist/__fixtures__/report/generate.d.ts.map +1 -0
- package/dist/__fixtures__/report/generate.js +58 -0
- package/dist/applied-state.d.ts +27 -0
- package/dist/applied-state.d.ts.map +1 -0
- package/dist/applied-state.js +44 -0
- package/dist/backend-config.d.ts +53 -0
- package/dist/backend-config.d.ts.map +1 -0
- package/dist/backend-config.js +136 -0
- package/dist/behaviour/kinds.d.ts.map +1 -1
- package/dist/behaviour/kinds.js +4 -0
- package/dist/behaviour/predict.d.ts.map +1 -1
- package/dist/behaviour/predict.js +6 -2
- package/dist/behaviour/reference-catalog.d.ts +16 -5
- package/dist/behaviour/reference-catalog.d.ts.map +1 -1
- package/dist/behaviour/reference-catalog.js +16 -5
- package/dist/behaviour/request.d.ts.map +1 -1
- package/dist/behaviour/request.js +3 -2
- package/dist/changed-roots.d.ts +6 -4
- package/dist/changed-roots.d.ts.map +1 -1
- package/dist/changed-roots.js +14 -18
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +4 -3
- package/dist/components/capability-plugin.d.ts +65 -3
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability-plugin.js +197 -13
- package/dist/components/compose-group.d.ts +145 -0
- package/dist/components/compose-group.d.ts.map +1 -0
- package/dist/components/compose-group.js +407 -0
- package/dist/components/placeholder-preview.d.ts +78 -0
- package/dist/components/placeholder-preview.d.ts.map +1 -0
- package/dist/components/placeholder-preview.js +254 -0
- package/dist/compose/apply-events.d.ts +46 -0
- package/dist/compose/apply-events.d.ts.map +1 -0
- package/dist/compose/apply-events.js +77 -0
- package/dist/compose/estate.d.ts +194 -0
- package/dist/compose/estate.d.ts.map +1 -0
- package/dist/compose/estate.js +363 -0
- package/dist/compose/hcl.d.ts +99 -0
- package/dist/compose/hcl.d.ts.map +1 -0
- package/dist/compose/hcl.js +302 -0
- package/dist/compose/module-address.d.ts +24 -0
- package/dist/compose/module-address.d.ts.map +1 -0
- package/dist/compose/module-address.js +43 -0
- package/dist/compose/root.d.ts +127 -0
- package/dist/compose/root.d.ts.map +1 -0
- package/dist/compose/root.js +586 -0
- package/dist/compose/run.d.ts +183 -0
- package/dist/compose/run.d.ts.map +1 -0
- package/dist/compose/run.js +447 -0
- package/dist/compose/slice.d.ts +102 -0
- package/dist/compose/slice.d.ts.map +1 -0
- package/dist/compose/slice.js +249 -0
- package/dist/compose/state-address.d.ts +28 -0
- package/dist/compose/state-address.d.ts.map +1 -0
- package/dist/compose/state-address.js +154 -0
- package/dist/compose/state-merge.d.ts +52 -0
- package/dist/compose/state-merge.d.ts.map +1 -0
- package/dist/compose/state-merge.js +135 -0
- package/dist/compose.d.ts +179 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +482 -0
- package/dist/composites/terraform-apply-op.d.ts.map +1 -1
- package/dist/composites/terraform-apply-op.js +7 -3
- package/dist/config.d.ts +59 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -9
- package/dist/describe-resources.d.ts +74 -12
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/describe-resources.js +374 -66
- package/dist/drift-read.d.ts +33 -0
- package/dist/drift-read.d.ts.map +1 -0
- package/dist/drift-read.js +243 -0
- package/dist/drift-record.d.ts +147 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +383 -0
- package/dist/hcl/edges.d.ts.map +1 -1
- package/dist/hcl/edges.js +24 -1
- package/dist/hcl/files.d.ts +61 -0
- package/dist/hcl/files.d.ts.map +1 -0
- package/dist/hcl/files.js +221 -0
- package/dist/hcl/instances.d.ts +82 -0
- package/dist/hcl/instances.d.ts.map +1 -0
- package/dist/hcl/instances.js +390 -0
- package/dist/hcl/parse.d.ts +81 -9
- package/dist/hcl/parse.d.ts.map +1 -1
- package/dist/hcl/parse.js +114 -16
- package/dist/hcl/roots.d.ts.map +1 -1
- package/dist/hcl/roots.js +5 -0
- package/dist/hcl/suppressions.d.ts.map +1 -1
- package/dist/hcl/suppressions.js +8 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/integrity.json +3 -3
- package/dist/live-plan-reasons.d.ts +21 -0
- package/dist/live-plan-reasons.d.ts.map +1 -0
- package/dist/live-plan-reasons.js +47 -0
- package/dist/lsp/option-keys.d.ts.map +1 -1
- package/dist/lsp/option-keys.js +2 -0
- package/dist/manifest.json +1 -1
- package/dist/op/activities/index.d.ts +6 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +5 -1
- package/dist/op/activities/live-detect.d.ts +4 -3
- package/dist/op/activities/live-detect.d.ts.map +1 -1
- package/dist/op/activities/live-detect.js +57 -32
- package/dist/op/activities/pin-rollout.d.ts +2 -0
- package/dist/op/activities/pin-rollout.d.ts.map +1 -1
- package/dist/op/activities/pin-rollout.js +1 -0
- package/dist/op/activities/terraform.d.ts +153 -5
- package/dist/op/activities/terraform.d.ts.map +1 -1
- package/dist/op/activities/terraform.js +205 -20
- package/dist/op/activity-contracts.d.ts +27 -0
- package/dist/op/activity-contracts.d.ts.map +1 -1
- package/dist/op/activity-contracts.js +19 -1
- package/dist/op/builders.d.ts +7 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +9 -0
- package/dist/pin/edit.d.ts.map +1 -1
- package/dist/pin/edit.js +35 -0
- package/dist/pin/rollout.d.ts +2 -0
- package/dist/pin/rollout.d.ts.map +1 -1
- package/dist/pin/rollout.js +14 -11
- package/dist/plan-shape.d.ts +30 -0
- package/dist/plan-shape.d.ts.map +1 -0
- package/dist/plan-shape.js +125 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +32 -18
- package/dist/report.d.ts +15 -6
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +28 -55
- package/dist/skills/chant-terraform.md +1 -1
- package/dist/state/azure-blob.d.ts +68 -0
- package/dist/state/azure-blob.d.ts.map +1 -0
- package/dist/state/azure-blob.js +201 -0
- package/dist/state/backend.d.ts +158 -0
- package/dist/state/backend.d.ts.map +1 -0
- package/dist/state/backend.js +406 -0
- package/dist/state/exec.d.ts +39 -0
- package/dist/state/exec.d.ts.map +1 -0
- package/dist/state/exec.js +80 -0
- package/dist/state/gcs.d.ts +62 -0
- package/dist/state/gcs.d.ts.map +1 -0
- package/dist/state/gcs.js +224 -0
- package/dist/state/index.d.ts +15 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +14 -0
- package/dist/state/locks.d.ts +105 -0
- package/dist/state/locks.d.ts.map +1 -0
- package/dist/state/locks.js +130 -0
- package/dist/state/object-store.d.ts +37 -0
- package/dist/state/object-store.d.ts.map +1 -0
- package/dist/state/object-store.js +20 -0
- package/dist/state/root-states.d.ts +131 -0
- package/dist/state/root-states.d.ts.map +1 -0
- package/dist/state/root-states.js +241 -0
- package/dist/state/s3.d.ts +68 -0
- package/dist/state/s3.d.ts.map +1 -0
- package/dist/state/s3.js +170 -0
- package/dist/state/store.d.ts +51 -0
- package/dist/state/store.d.ts.map +1 -0
- package/dist/state/store.js +185 -0
- package/dist/terragrunt/affected.d.ts.map +1 -1
- package/dist/terragrunt/affected.js +2 -1
- package/package.json +7 -3
- package/src/__fixtures__/ACCEPTANCE.md +69 -7
- package/src/__fixtures__/compose/apply-failed-in-app.jsonl +12 -0
- package/src/__fixtures__/compose/state-app.json +66 -0
- package/src/__fixtures__/compose/state-edge.json +40 -0
- package/src/__fixtures__/compose/state-net.json +58 -0
- package/src/__fixtures__/compose/three-app.plan.json +184 -0
- package/src/__fixtures__/compose/three-composed.plan.json +509 -0
- package/src/__fixtures__/compose/three-edge.plan.json +144 -0
- package/src/__fixtures__/compose/three-net.plan.json +174 -0
- package/src/__fixtures__/compose/unknown-composed.plan.json +228 -0
- package/src/__fixtures__/compose/working-after-apply.json +145 -0
- package/src/__fixtures__/config-blocks/app/main.tf +61 -0
- package/src/__fixtures__/config-blocks/app/modules/network/main.tf +4 -0
- package/src/__fixtures__/config-blocks/app-json/main.tf.json +39 -0
- package/src/__fixtures__/config-files/shadow/main.tf +3 -0
- package/src/__fixtures__/config-files/shadow/main.tofu +3 -0
- package/src/__fixtures__/config-files/shadow/other.tf +3 -0
- package/src/__fixtures__/config-files/tf/main.tf +11 -0
- package/src/__fixtures__/config-files/tf-json/main.tf.json +18 -0
- package/src/__fixtures__/config-files/tofu/main.tofu +11 -0
- package/src/__fixtures__/config-files/tofu-json/main.tofu.json +18 -0
- package/src/__fixtures__/config-files/tofu-only/main.tofu +3 -0
- package/src/__fixtures__/drift-record/README.md +11 -0
- package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
- package/src/__fixtures__/instance-forms/app/main.tf +110 -0
- package/src/__fixtures__/instance-forms/app/modules/svc/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/main.tf +52 -0
- package/src/__fixtures__/instance-vars/app/modules/app/main.tf +12 -0
- package/src/__fixtures__/instance-vars/app/modules/edge/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/terraform.tfvars +1 -0
- package/src/__fixtures__/live-module-keyed/live-graph.json +259 -0
- package/src/__fixtures__/live-module-keyed/live-plan.json +87 -0
- package/src/__fixtures__/live-module-keyed/root/estate.chdf.hcl +1 -0
- package/src/__fixtures__/live-module-keyed/root/main.tf +21 -0
- package/src/__fixtures__/live-module-keyed/root/modules/app/main.tf +17 -0
- package/src/__fixtures__/live-module-keyed/root/modules/edge/main.tf +7 -0
- package/src/__fixtures__/live-module-keyed/root/versions.tf +30 -0
- package/src/__fixtures__/live-module-keyed/show-state.json +146 -0
- package/src/__fixtures__/pr-loop/README.md +50 -0
- package/src/__fixtures__/pr-loop/chant.config.json +13 -0
- package/src/__fixtures__/pr-loop/estate.component.ts +10 -0
- package/src/__fixtures__/pr-loop/roots/a/main.tf +11 -0
- package/src/__fixtures__/pr-loop/roots/app/main.tf +19 -0
- package/src/__fixtures__/pr-loop/roots/b/main.tf +7 -0
- package/src/__fixtures__/pr-loop/roots/dns/main.tf +3 -0
- package/src/__fixtures__/pr-loop/roots/net/main.tf +7 -0
- package/src/__fixtures__/report/applied.show.json +51 -0
- package/src/__fixtures__/report/generate.ts +63 -0
- package/src/__fixtures__/report/plan.show.json +200 -0
- package/src/__fixtures__/report/tf-apply/change-set.json +170 -0
- package/src/__fixtures__/report/tf-apply/report.json +338 -0
- package/src/__fixtures__/report/tf-plan/change-set.json +170 -0
- package/src/__fixtures__/report/tf-plan/report.json +320 -0
- package/src/__fixtures__/three-cloud-azure.graph.json +290 -0
- package/src/applied-state.ts +52 -0
- package/src/backend-config.test.ts +105 -0
- package/src/backend-config.ts +133 -0
- package/src/behaviour/kinds.ts +4 -0
- package/src/behaviour/predict.ts +5 -2
- package/src/behaviour/reference-catalog.plugin.test.ts +65 -0
- package/src/behaviour/reference-catalog.ts +16 -5
- package/src/behaviour/request.ts +3 -2
- package/src/change-set-instances.test.ts +98 -0
- package/src/changed-roots.ts +14 -16
- package/src/commands.ts +4 -3
- package/src/components/capability-plugin.test.ts +172 -5
- package/src/components/capability-plugin.ts +212 -11
- package/src/components/change-set-graph.e2e.test.ts +11 -5
- package/src/components/compose-group.test.ts +486 -0
- package/src/components/compose-group.ts +489 -0
- package/src/components/demo-composed-roots.e2e.test.ts +440 -0
- package/src/components/member-outputs.test.ts +76 -0
- package/src/components/placeholder-preview.test.ts +147 -0
- package/src/components/placeholder-preview.ts +257 -0
- package/src/components/pr-loop-compose.tofu.e2e.test.ts +363 -0
- package/src/components/pr-loop.tofu.test.ts +112 -56
- package/src/compose/apply-events.test.ts +62 -0
- package/src/compose/apply-events.ts +100 -0
- package/src/compose/estate.choudoufu.e2e.test.ts +112 -0
- package/src/compose/estate.test.ts +421 -0
- package/src/compose/estate.ts +443 -0
- package/src/compose/hcl.ts +311 -0
- package/src/compose/module-address.ts +49 -0
- package/src/compose/root.test.ts +416 -0
- package/src/compose/root.ts +592 -0
- package/src/compose/run.test.ts +440 -0
- package/src/compose/run.tofu.test.ts +176 -0
- package/src/compose/run.ts +527 -0
- package/src/compose/slice.test.ts +184 -0
- package/src/compose/slice.ts +290 -0
- package/src/compose/state-address.ts +157 -0
- package/src/compose/state-merge.test.ts +131 -0
- package/src/compose/state-merge.ts +148 -0
- package/src/compose.test.ts +248 -0
- package/src/compose.ts +627 -0
- package/src/composites/terraform-apply-op.test.ts +9 -0
- package/src/composites/terraform-apply-op.ts +7 -3
- package/src/config-file-listers.test.ts +265 -0
- package/src/config.ts +44 -9
- package/src/describe-resources.engine-facts.test.ts +412 -0
- package/src/describe-resources.live-module-keyed.test.ts +290 -0
- package/src/describe-resources.ts +416 -70
- package/src/drift-read.ts +284 -0
- package/src/drift-record.test.ts +223 -0
- package/src/drift-record.ts +455 -0
- package/src/hcl/config-blocks.test.ts +174 -0
- package/src/hcl/edges.ts +21 -1
- package/src/hcl/files.ts +234 -0
- package/src/hcl/instance-forms.test.ts +94 -0
- package/src/hcl/instances.test.ts +137 -0
- package/src/hcl/instances.ts +422 -0
- package/src/hcl/parse.test.ts +139 -1
- package/src/hcl/parse.ts +149 -16
- package/src/hcl/roots.ts +6 -0
- package/src/hcl/suppressions.ts +8 -2
- package/src/index.ts +76 -0
- package/src/live-plan-reasons.ts +54 -0
- package/src/lsp/completions.test.ts +1 -1
- package/src/lsp/option-keys.ts +2 -0
- package/src/op/activities/choudoufu-plan-set-op.test.ts +111 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/live-detect.ts +55 -26
- package/src/op/activities/pin-rollout.ts +3 -0
- package/src/op/activities/registry.test.ts +2 -1
- package/src/op/activities/terraform.test.ts +55 -0
- package/src/op/activities/terraform.ts +266 -22
- package/src/op/activity-contracts.test.ts +1 -0
- package/src/op/activity-contracts.ts +24 -1
- package/src/op/builders.ts +14 -0
- package/src/pin/bundle.test.ts +2 -0
- package/src/pin/edit.ts +30 -0
- package/src/pin/rollout.ts +16 -11
- package/src/plan-shape.test.ts +148 -0
- package/src/plan-shape.ts +128 -0
- package/src/plugin.ts +33 -19
- package/src/report.test.ts +82 -1
- package/src/report.ts +31 -54
- package/src/signal-only-root.test.ts +72 -0
- package/src/skills/chant-terraform.md +1 -1
- package/src/state/azure-blob.ts +223 -0
- package/src/state/backend-verdict.test.ts +187 -0
- package/src/state/backend.test.ts +127 -0
- package/src/state/backend.ts +488 -0
- package/src/state/exec.ts +111 -0
- package/src/state/gcs.ts +254 -0
- package/src/state/index.ts +15 -0
- package/src/state/locks.test.ts +84 -0
- package/src/state/locks.ts +201 -0
- package/src/state/object-store.ts +35 -0
- package/src/state/root-states-floci.e2e.test.ts +66 -0
- package/src/state/root-states.test.ts +462 -0
- package/src/state/root-states.ts +309 -0
- package/src/state/s3.ts +193 -0
- package/src/state/store.ts +225 -0
- package/src/terragrunt/affected.ts +2 -1
- package/src/workspace-kinds.test.ts +4 -17
- package/workspace-kinds.json +1 -24
- package/dist/workspace-member.d.ts +0 -30
- package/dist/workspace-member.d.ts.map +0 -1
- package/dist/workspace-member.js +0 -91
- package/schemas/pulumi.schema.json +0 -34
- package/src/testdata/pulumi-member/Pulumi.yaml +0 -2
- package/src/testdata/pulumi-member/stack-export.json +0 -53
- package/src/testdata/pulumi-unexported/Pulumi.yaml +0 -2
- package/src/workspace-member.test.ts +0 -89
- 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
|
+
}
|
package/dist/hcl/parse.d.ts
CHANGED
|
@@ -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
|
|
5
|
-
* files of a directory (non-recursive, matching Terraform's own
|
|
6
|
-
* scoping
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
-
/**
|
|
220
|
-
|
|
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
|
|
283
|
-
*
|
|
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
|
/**
|
package/dist/hcl/parse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/hcl/parse.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/hcl/parse.ts"],"names":[],"mappings":"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"}
|