@intentius/chant-lexicon-terraform 0.57.0 → 0.58.0

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 (381) hide show
  1. package/dist/composites/terraform-adopt-op.d.ts +126 -0
  2. package/dist/composites/terraform-adopt-op.d.ts.map +1 -0
  3. package/dist/composites/terraform-apply-op.d.ts +63 -16
  4. package/dist/composites/terraform-apply-op.d.ts.map +1 -1
  5. package/dist/composites/terraform-watch-op.d.ts +80 -36
  6. package/dist/composites/terraform-watch-op.d.ts.map +1 -1
  7. package/dist/config.d.ts +49 -2
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/describe-resources.d.ts +256 -16
  10. package/dist/describe-resources.d.ts.map +1 -1
  11. package/dist/hcl/descend.d.ts +98 -0
  12. package/dist/hcl/descend.d.ts.map +1 -0
  13. package/dist/hcl/marker.d.ts +130 -0
  14. package/dist/hcl/marker.d.ts.map +1 -0
  15. package/dist/hcl/parse.d.ts +142 -9
  16. package/dist/hcl/parse.d.ts.map +1 -1
  17. package/dist/hcl/references.d.ts +76 -0
  18. package/dist/hcl/references.d.ts.map +1 -0
  19. package/dist/hcl/roots.d.ts +22 -3
  20. package/dist/hcl/roots.d.ts.map +1 -1
  21. package/dist/hcl/suppressions.d.ts +54 -0
  22. package/dist/hcl/suppressions.d.ts.map +1 -0
  23. package/dist/hcl/value.d.ts +77 -0
  24. package/dist/hcl/value.d.ts.map +1 -0
  25. package/dist/index.d.ts +5 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/integrity.json +32 -5
  28. package/dist/lint/audit-catalog.d.ts +3 -2
  29. package/dist/lint/audit-catalog.d.ts.map +1 -1
  30. package/dist/lint/audit-lineage.d.ts +68 -0
  31. package/dist/lint/audit-lineage.d.ts.map +1 -1
  32. package/dist/lint/post-synth/blocks.d.ts +53 -0
  33. package/dist/lint/post-synth/blocks.d.ts.map +1 -0
  34. package/dist/lint/post-synth/fixtures/load.d.ts +37 -0
  35. package/dist/lint/post-synth/fixtures/load.d.ts.map +1 -0
  36. package/dist/lint/post-synth/index.d.ts.map +1 -1
  37. package/dist/lint/post-synth/module-source.d.ts +38 -0
  38. package/dist/lint/post-synth/module-source.d.ts.map +1 -0
  39. package/dist/lint/post-synth/scope.d.ts +65 -0
  40. package/dist/lint/post-synth/scope.d.ts.map +1 -0
  41. package/dist/lint/post-synth/tf001.d.ts +18 -0
  42. package/dist/lint/post-synth/tf001.d.ts.map +1 -1
  43. package/dist/lint/post-synth/tf002.d.ts +32 -0
  44. package/dist/lint/post-synth/tf002.d.ts.map +1 -0
  45. package/dist/lint/post-synth/tf003.d.ts +22 -0
  46. package/dist/lint/post-synth/tf003.d.ts.map +1 -0
  47. package/dist/lint/post-synth/tf004.d.ts +22 -0
  48. package/dist/lint/post-synth/tf004.d.ts.map +1 -0
  49. package/dist/lint/post-synth/tf005.d.ts +28 -0
  50. package/dist/lint/post-synth/tf005.d.ts.map +1 -0
  51. package/dist/lint/post-synth/tf006.d.ts +21 -0
  52. package/dist/lint/post-synth/tf006.d.ts.map +1 -0
  53. package/dist/lint/post-synth/tf007.d.ts +21 -0
  54. package/dist/lint/post-synth/tf007.d.ts.map +1 -0
  55. package/dist/lint/post-synth/tf008.d.ts +22 -0
  56. package/dist/lint/post-synth/tf008.d.ts.map +1 -0
  57. package/dist/lint/post-synth/tf009.d.ts +24 -0
  58. package/dist/lint/post-synth/tf009.d.ts.map +1 -0
  59. package/dist/lint/post-synth/tf010.d.ts +19 -0
  60. package/dist/lint/post-synth/tf010.d.ts.map +1 -0
  61. package/dist/lint/post-synth/tf011.d.ts +18 -0
  62. package/dist/lint/post-synth/tf011.d.ts.map +1 -0
  63. package/dist/lint/post-synth/tf012.d.ts +17 -0
  64. package/dist/lint/post-synth/tf012.d.ts.map +1 -0
  65. package/dist/lint/post-synth/tf013.d.ts +21 -0
  66. package/dist/lint/post-synth/tf013.d.ts.map +1 -0
  67. package/dist/lint/post-synth/tf014.d.ts +25 -0
  68. package/dist/lint/post-synth/tf014.d.ts.map +1 -0
  69. package/dist/lint/post-synth/tf015.d.ts +21 -0
  70. package/dist/lint/post-synth/tf015.d.ts.map +1 -0
  71. package/dist/lint/post-synth/tf016.d.ts +30 -0
  72. package/dist/lint/post-synth/tf016.d.ts.map +1 -0
  73. package/dist/lint/post-synth/tf017.d.ts +19 -0
  74. package/dist/lint/post-synth/tf017.d.ts.map +1 -0
  75. package/dist/lint/post-synth/tf018.d.ts +20 -0
  76. package/dist/lint/post-synth/tf018.d.ts.map +1 -0
  77. package/dist/lint/post-synth/tf019.d.ts +25 -0
  78. package/dist/lint/post-synth/tf019.d.ts.map +1 -0
  79. package/dist/lint/post-synth/tf020.d.ts +38 -0
  80. package/dist/lint/post-synth/tf020.d.ts.map +1 -0
  81. package/dist/lint/post-synth/tf021.d.ts +41 -0
  82. package/dist/lint/post-synth/tf021.d.ts.map +1 -0
  83. package/dist/lint/post-synth/tf022.d.ts +24 -0
  84. package/dist/lint/post-synth/tf022.d.ts.map +1 -0
  85. package/dist/lint/post-synth/tf024.d.ts +24 -0
  86. package/dist/lint/post-synth/tf024.d.ts.map +1 -0
  87. package/dist/lint/post-synth/tf025.d.ts +29 -0
  88. package/dist/lint/post-synth/tf025.d.ts.map +1 -0
  89. package/dist/lint/post-synth/tf026.d.ts +21 -0
  90. package/dist/lint/post-synth/tf026.d.ts.map +1 -0
  91. package/dist/lint/rules/fixtures/load.d.ts +13 -0
  92. package/dist/lint/rules/fixtures/load.d.ts.map +1 -0
  93. package/dist/lint/rules/plan-before-apply.d.ts +11 -0
  94. package/dist/lint/rules/plan-before-apply.d.ts.map +1 -1
  95. package/dist/lint/secret-shape.d.ts +68 -0
  96. package/dist/lint/secret-shape.d.ts.map +1 -0
  97. package/dist/live-ownership.d.ts +55 -0
  98. package/dist/live-ownership.d.ts.map +1 -0
  99. package/dist/lsp/option-keys.d.ts.map +1 -1
  100. package/dist/manifest.json +1 -1
  101. package/dist/okf/index.md +24 -0
  102. package/dist/okf/rules/TF002.md +11 -0
  103. package/dist/okf/rules/TF003.md +11 -0
  104. package/dist/okf/rules/TF004.md +11 -0
  105. package/dist/okf/rules/TF005.md +11 -0
  106. package/dist/okf/rules/TF006.md +11 -0
  107. package/dist/okf/rules/TF007.md +11 -0
  108. package/dist/okf/rules/TF008.md +11 -0
  109. package/dist/okf/rules/TF009.md +11 -0
  110. package/dist/okf/rules/TF010.md +11 -0
  111. package/dist/okf/rules/TF011.md +11 -0
  112. package/dist/okf/rules/TF012.md +11 -0
  113. package/dist/okf/rules/TF013.md +11 -0
  114. package/dist/okf/rules/TF014.md +11 -0
  115. package/dist/okf/rules/TF015.md +11 -0
  116. package/dist/okf/rules/TF016.md +11 -0
  117. package/dist/okf/rules/TF017.md +11 -0
  118. package/dist/okf/rules/TF018.md +11 -0
  119. package/dist/okf/rules/TF019.md +11 -0
  120. package/dist/okf/rules/TF020.md +11 -0
  121. package/dist/okf/rules/TF021.md +11 -0
  122. package/dist/okf/rules/TF022.md +11 -0
  123. package/dist/okf/rules/TF024.md +11 -0
  124. package/dist/okf/rules/TF025.md +11 -0
  125. package/dist/okf/rules/TF026.md +11 -0
  126. package/dist/op/activities/index.d.ts +13 -6
  127. package/dist/op/activities/index.d.ts.map +1 -1
  128. package/dist/op/activities/live-detect.d.ts +51 -0
  129. package/dist/op/activities/live-detect.d.ts.map +1 -0
  130. package/dist/op/activities/terraform.d.ts +445 -17
  131. package/dist/op/activities/terraform.d.ts.map +1 -1
  132. package/dist/op/activity-contracts.d.ts +148 -0
  133. package/dist/op/activity-contracts.d.ts.map +1 -0
  134. package/dist/op/adoption.d.ts +118 -0
  135. package/dist/op/adoption.d.ts.map +1 -0
  136. package/dist/op/builders.d.ts +46 -6
  137. package/dist/op/builders.d.ts.map +1 -1
  138. package/dist/op/resolve-root-mode.d.ts +45 -0
  139. package/dist/op/resolve-root-mode.d.ts.map +1 -0
  140. package/dist/plugin.d.ts.map +1 -1
  141. package/dist/rules/blocks.ts +109 -0
  142. package/dist/rules/module-source.ts +121 -0
  143. package/dist/rules/plan-before-apply.ts +11 -0
  144. package/dist/rules/scope.ts +107 -0
  145. package/dist/rules/tf001.ts +32 -8
  146. package/dist/rules/tf002.ts +151 -0
  147. package/dist/rules/tf003.ts +71 -0
  148. package/dist/rules/tf004.ts +63 -0
  149. package/dist/rules/tf005.ts +76 -0
  150. package/dist/rules/tf006.ts +53 -0
  151. package/dist/rules/tf007.ts +78 -0
  152. package/dist/rules/tf008.ts +75 -0
  153. package/dist/rules/tf009.ts +59 -0
  154. package/dist/rules/tf010.ts +51 -0
  155. package/dist/rules/tf011.ts +49 -0
  156. package/dist/rules/tf012.ts +47 -0
  157. package/dist/rules/tf013.ts +63 -0
  158. package/dist/rules/tf014.ts +72 -0
  159. package/dist/rules/tf015.ts +63 -0
  160. package/dist/rules/tf016.ts +75 -0
  161. package/dist/rules/tf017.ts +50 -0
  162. package/dist/rules/tf018.ts +72 -0
  163. package/dist/rules/tf019.ts +72 -0
  164. package/dist/rules/tf020.ts +123 -0
  165. package/dist/rules/tf021.ts +126 -0
  166. package/dist/rules/tf022.ts +61 -0
  167. package/dist/rules/tf024.ts +70 -0
  168. package/dist/rules/tf025.ts +101 -0
  169. package/dist/rules/tf026.ts +80 -0
  170. package/dist/skills/chant-terraform.md +1 -1
  171. package/package.json +7 -2
  172. package/src/__fixtures__/live/main.tf +28 -0
  173. package/src/__fixtures__/live-adopt/estate.chdf.hcl +6 -0
  174. package/src/__fixtures__/live-adopt/main.tf +21 -0
  175. package/src/__fixtures__/live-estate/README.md +58 -0
  176. package/src/__fixtures__/live-estate/compute.tf +10 -0
  177. package/src/__fixtures__/live-estate/estate.chdf.hcl +1 -0
  178. package/src/__fixtures__/live-estate/logs.tf +8 -0
  179. package/src/__fixtures__/live-estate/network.tf +24 -0
  180. package/src/__fixtures__/live-estate/rule.tf +11 -0
  181. package/src/__fixtures__/live-estate/unowned.tf +21 -0
  182. package/src/__fixtures__/live-estate/versions.tf +31 -0
  183. package/src/__fixtures__/live-ls.json +98 -0
  184. package/src/__fixtures__/live-plan.json +285 -0
  185. package/src/__fixtures__/live-sidecar/estate.chdf.hcl +3 -0
  186. package/src/__fixtures__/live-sidecar/main.tf +24 -0
  187. package/src/__fixtures__/module-tree/README.md +16 -0
  188. package/src/__fixtures__/module-tree/cycle/main.tf +3 -0
  189. package/src/__fixtures__/module-tree/cycle/modules/a/main.tf +9 -0
  190. package/src/__fixtures__/module-tree/cycle/modules/b/main.tf +9 -0
  191. package/src/__fixtures__/module-tree/missing/main.tf +9 -0
  192. package/src/__fixtures__/module-tree/outside/root/main.tf +9 -0
  193. package/src/__fixtures__/module-tree/root/main.tf +28 -0
  194. package/src/__fixtures__/module-tree/root/modules/cdn/main.tf +15 -0
  195. package/src/__fixtures__/module-tree/root/modules/cdn/modules/bucket/main.tf +11 -0
  196. package/src/__fixtures__/module-tree/shared/main.tf +5 -0
  197. package/src/__fixtures__/references/main.tf +56 -0
  198. package/src/codegen/lint-rules-page.test.ts +28 -0
  199. package/src/composites/terraform-adopt-op.acceptance.test.ts +166 -0
  200. package/src/composites/terraform-adopt-op.test.ts +170 -0
  201. package/src/composites/terraform-adopt-op.ts +197 -0
  202. package/src/composites/terraform-apply-op.acceptance.test.ts +183 -5
  203. package/src/composites/terraform-apply-op.test.ts +167 -15
  204. package/src/composites/terraform-apply-op.ts +105 -28
  205. package/src/composites/terraform-watch-op.test.ts +85 -26
  206. package/src/composites/terraform-watch-op.ts +130 -73
  207. package/src/config.ts +32 -3
  208. package/src/describe-resources.live.test.ts +598 -0
  209. package/src/describe-resources.test.ts +53 -0
  210. package/src/describe-resources.ts +811 -28
  211. package/src/hcl/descend.test.ts +162 -0
  212. package/src/hcl/descend.ts +273 -0
  213. package/src/hcl/marker.test.ts +147 -0
  214. package/src/hcl/marker.ts +235 -0
  215. package/src/hcl/parse.test.ts +69 -0
  216. package/src/hcl/parse.ts +249 -27
  217. package/src/hcl/references.test.ts +116 -0
  218. package/src/hcl/references.ts +172 -0
  219. package/src/hcl/roots.ts +59 -5
  220. package/src/hcl/suppressions.test.ts +147 -0
  221. package/src/hcl/suppressions.ts +204 -0
  222. package/src/hcl/value.test.ts +73 -0
  223. package/src/hcl/value.ts +106 -0
  224. package/src/index.ts +31 -1
  225. package/src/lint/audit-catalog.ts +264 -3
  226. package/src/lint/audit-lineage.ts +319 -1
  227. package/src/lint/audit.test.ts +40 -1
  228. package/src/lint/post-synth/blocks.ts +109 -0
  229. package/src/lint/post-synth/fixtures/TF001/negative.tf +28 -0
  230. package/src/lint/post-synth/fixtures/TF001/positive.tf +24 -0
  231. package/src/lint/post-synth/fixtures/TF002/negative.tf +17 -0
  232. package/src/lint/post-synth/fixtures/TF002/positive-legacy.tf +10 -0
  233. package/src/lint/post-synth/fixtures/TF002/positive-no-version.tf +12 -0
  234. package/src/lint/post-synth/fixtures/TF002/positive.tf +7 -0
  235. package/src/lint/post-synth/fixtures/TF003/negative.tf +10 -0
  236. package/src/lint/post-synth/fixtures/TF003/positive.tf +8 -0
  237. package/src/lint/post-synth/fixtures/TF004/negative-git.tf +3 -0
  238. package/src/lint/post-synth/fixtures/TF004/negative-local.tf +3 -0
  239. package/src/lint/post-synth/fixtures/TF004/negative.tf +4 -0
  240. package/src/lint/post-synth/fixtures/TF004/positive.tf +3 -0
  241. package/src/lint/post-synth/fixtures/TF005/negative-local.tf +3 -0
  242. package/src/lint/post-synth/fixtures/TF005/negative-registry.tf +3 -0
  243. package/src/lint/post-synth/fixtures/TF005/negative-sha.tf +3 -0
  244. package/src/lint/post-synth/fixtures/TF005/negative.tf +3 -0
  245. package/src/lint/post-synth/fixtures/TF005/positive-branch.tf +3 -0
  246. package/src/lint/post-synth/fixtures/TF005/positive-non-semver.tf +3 -0
  247. package/src/lint/post-synth/fixtures/TF005/positive.tf +3 -0
  248. package/src/lint/post-synth/fixtures/TF006/negative.tf +5 -0
  249. package/src/lint/post-synth/fixtures/TF006/positive-empty-default.tf +11 -0
  250. package/src/lint/post-synth/fixtures/TF006/positive.tf +6 -0
  251. package/src/lint/post-synth/fixtures/TF007/negative.tf +10 -0
  252. package/src/lint/post-synth/fixtures/TF007/positive.tf +9 -0
  253. package/src/lint/post-synth/fixtures/TF008/negative-variable.tf +10 -0
  254. package/src/lint/post-synth/fixtures/TF008/negative.tf +8 -0
  255. package/src/lint/post-synth/fixtures/TF008/positive-other-provider.tf +10 -0
  256. package/src/lint/post-synth/fixtures/TF008/positive.tf +5 -0
  257. package/src/lint/post-synth/fixtures/TF009/negative.tf +10 -0
  258. package/src/lint/post-synth/fixtures/TF009/positive.tf +4 -0
  259. package/src/lint/post-synth/fixtures/TF010/negative.tf +5 -0
  260. package/src/lint/post-synth/fixtures/TF010/positive.tf +4 -0
  261. package/src/lint/post-synth/fixtures/TF011/negative.tf +5 -0
  262. package/src/lint/post-synth/fixtures/TF011/positive-blank.tf +5 -0
  263. package/src/lint/post-synth/fixtures/TF011/positive.tf +4 -0
  264. package/src/lint/post-synth/fixtures/TF012/negative.tf +4 -0
  265. package/src/lint/post-synth/fixtures/TF012/positive.tf +3 -0
  266. package/src/lint/post-synth/fixtures/TF013/negative.tf +8 -0
  267. package/src/lint/post-synth/fixtures/TF013/positive-data.tf +8 -0
  268. package/src/lint/post-synth/fixtures/TF013/positive.tf +8 -0
  269. package/src/lint/post-synth/fixtures/TF014/negative/main.tf +26 -0
  270. package/src/lint/post-synth/fixtures/TF014/negative/modules/cdn/main.tf +19 -0
  271. package/src/lint/post-synth/fixtures/TF014/positive/main.tf +16 -0
  272. package/src/lint/post-synth/fixtures/TF014/positive/modules/cdn/main.tf +15 -0
  273. package/src/lint/post-synth/fixtures/TF015/negative/main.tf +13 -0
  274. package/src/lint/post-synth/fixtures/TF015/negative/modules/cdn/main.tf +16 -0
  275. package/src/lint/post-synth/fixtures/TF015/positive/main.tf +13 -0
  276. package/src/lint/post-synth/fixtures/TF015/positive/modules/cdn/main.tf +14 -0
  277. package/src/lint/post-synth/fixtures/TF016/negative-template.tf +7 -0
  278. package/src/lint/post-synth/fixtures/TF016/negative.tf +16 -0
  279. package/src/lint/post-synth/fixtures/TF016/positive-shared-file.tf +12 -0
  280. package/src/lint/post-synth/fixtures/TF016/positive.tf +13 -0
  281. package/src/lint/post-synth/fixtures/TF017/negative.tf +4 -0
  282. package/src/lint/post-synth/fixtures/TF017/positive.tf +5 -0
  283. package/src/lint/post-synth/fixtures/TF018/negative.tf +9 -0
  284. package/src/lint/post-synth/fixtures/TF018/positive-data.tf +9 -0
  285. package/src/lint/post-synth/fixtures/TF018/positive.tf +4 -0
  286. package/src/lint/post-synth/fixtures/TF019/negative.tf +14 -0
  287. package/src/lint/post-synth/fixtures/TF019/positive-output.tf +5 -0
  288. package/src/lint/post-synth/fixtures/TF019/positive.tf +16 -0
  289. package/src/lint/post-synth/fixtures/TF020/negative.tf +43 -0
  290. package/src/lint/post-synth/fixtures/TF020/positive.tf +32 -0
  291. package/src/lint/post-synth/fixtures/TF020/scoped/main.tf +21 -0
  292. package/src/lint/post-synth/fixtures/TF020/scoped/modules/cdn/main.tf +13 -0
  293. package/src/lint/post-synth/fixtures/TF021/negative.tf +31 -0
  294. package/src/lint/post-synth/fixtures/TF021/positive-length.tf +8 -0
  295. package/src/lint/post-synth/fixtures/TF021/positive.tf +8 -0
  296. package/src/lint/post-synth/fixtures/TF022/negative-locator.tf +7 -0
  297. package/src/lint/post-synth/fixtures/TF022/negative.tf +10 -0
  298. package/src/lint/post-synth/fixtures/TF022/positive-nested.tf +10 -0
  299. package/src/lint/post-synth/fixtures/TF022/positive.tf +6 -0
  300. package/src/lint/post-synth/fixtures/TF023/negative/main.tf +15 -0
  301. package/src/lint/post-synth/fixtures/TF023/positive/main.tf +9 -0
  302. package/src/lint/post-synth/fixtures/TF023/positive/state.json +24 -0
  303. package/src/lint/post-synth/fixtures/TF024/live-clean/main.tf +9 -0
  304. package/src/lint/post-synth/fixtures/TF024/live-with-backend/main.tf +14 -0
  305. package/src/lint/post-synth/fixtures/TF024/live-with-cloud/main.tf +16 -0
  306. package/src/lint/post-synth/fixtures/TF025/live-clean/main.tf +13 -0
  307. package/src/lint/post-synth/fixtures/TF025/live-with-workspace-ref/main.tf +13 -0
  308. package/src/lint/post-synth/fixtures/TF026/live-default/main.tf +9 -0
  309. package/src/lint/post-synth/fixtures/TF026/live-explicit-delete/main.tf +13 -0
  310. package/src/lint/post-synth/fixtures/TF026/live-keep/main.tf +13 -0
  311. package/src/lint/post-synth/fixtures/load.ts +108 -0
  312. package/src/lint/post-synth/index.ts +48 -0
  313. package/src/lint/post-synth/module-rules.test.ts +153 -0
  314. package/src/lint/post-synth/module-source.test.ts +75 -0
  315. package/src/lint/post-synth/module-source.ts +121 -0
  316. package/src/lint/post-synth/post-synth.test.ts +14 -15
  317. package/src/lint/post-synth/scope.ts +107 -0
  318. package/src/lint/post-synth/single-block.test.ts +263 -0
  319. package/src/lint/post-synth/suppression.test.ts +110 -0
  320. package/src/lint/post-synth/tf001.ts +32 -8
  321. package/src/lint/post-synth/tf002.test.ts +93 -0
  322. package/src/lint/post-synth/tf002.ts +151 -0
  323. package/src/lint/post-synth/tf003.test.ts +75 -0
  324. package/src/lint/post-synth/tf003.ts +71 -0
  325. package/src/lint/post-synth/tf004.test.ts +47 -0
  326. package/src/lint/post-synth/tf004.ts +63 -0
  327. package/src/lint/post-synth/tf005.test.ts +57 -0
  328. package/src/lint/post-synth/tf005.ts +76 -0
  329. package/src/lint/post-synth/tf006.ts +53 -0
  330. package/src/lint/post-synth/tf007.ts +78 -0
  331. package/src/lint/post-synth/tf008.ts +75 -0
  332. package/src/lint/post-synth/tf009.ts +59 -0
  333. package/src/lint/post-synth/tf010.ts +51 -0
  334. package/src/lint/post-synth/tf011.ts +49 -0
  335. package/src/lint/post-synth/tf012.ts +47 -0
  336. package/src/lint/post-synth/tf013.ts +63 -0
  337. package/src/lint/post-synth/tf014.ts +72 -0
  338. package/src/lint/post-synth/tf015.ts +63 -0
  339. package/src/lint/post-synth/tf016.ts +75 -0
  340. package/src/lint/post-synth/tf017.ts +50 -0
  341. package/src/lint/post-synth/tf018.ts +72 -0
  342. package/src/lint/post-synth/tf019.ts +72 -0
  343. package/src/lint/post-synth/tf020.ts +123 -0
  344. package/src/lint/post-synth/tf021.ts +126 -0
  345. package/src/lint/post-synth/tf022.ts +61 -0
  346. package/src/lint/post-synth/tf024.test.ts +42 -0
  347. package/src/lint/post-synth/tf024.ts +70 -0
  348. package/src/lint/post-synth/tf025.test.ts +46 -0
  349. package/src/lint/post-synth/tf025.ts +101 -0
  350. package/src/lint/post-synth/tf026.test.ts +56 -0
  351. package/src/lint/post-synth/tf026.ts +80 -0
  352. package/src/lint/presets.test.ts +72 -0
  353. package/src/lint/rules/fixtures/TF101/negative-op.ts +2 -0
  354. package/src/lint/rules/fixtures/TF101/positive-op.ts +2 -0
  355. package/src/lint/rules/fixtures/load.ts +53 -0
  356. package/src/lint/rules/plan-before-apply.test.ts +112 -7
  357. package/src/lint/rules/plan-before-apply.ts +11 -0
  358. package/src/lint/secret-shape.test.ts +150 -0
  359. package/src/lint/secret-shape.ts +159 -0
  360. package/src/live-ownership.ts +60 -0
  361. package/src/lsp/completions.test.ts +3 -2
  362. package/src/lsp/option-keys.ts +10 -5
  363. package/src/op/activities/choudoufu.acceptance.test.ts +143 -0
  364. package/src/op/activities/choudoufu.test.ts +693 -0
  365. package/src/op/activities/index.ts +40 -4
  366. package/src/op/activities/live-detect.test.ts +143 -0
  367. package/src/op/activities/live-detect.ts +162 -0
  368. package/src/op/activities/registry.test.ts +11 -3
  369. package/src/op/activities/terraform.test.ts +7 -3
  370. package/src/op/activities/terraform.ts +823 -69
  371. package/src/op/activity-contracts.test.ts +147 -0
  372. package/src/op/activity-contracts.ts +178 -0
  373. package/src/op/adoption.test.ts +170 -0
  374. package/src/op/adoption.ts +241 -0
  375. package/src/op/builders.test.ts +60 -5
  376. package/src/op/builders.ts +93 -5
  377. package/src/op/resolve-root-mode.test.ts +85 -0
  378. package/src/op/resolve-root-mode.ts +72 -0
  379. package/src/plugin.test.ts +68 -0
  380. package/src/plugin.ts +75 -9
  381. package/src/skills/chant-terraform.md +1 -1
@@ -1,12 +1,19 @@
1
1
  /**
2
- * Live observation for declared terraform entities (#2087).
2
+ * Live observation for declared terraform entities (#2087, #2104).
3
3
  *
4
4
  * `buildRoots()` turns each configured root module into one entity per HCL
5
5
  * block, keyed `<root>/<address>` (`./hcl/parse.ts`). This reader answers the
6
- * lifecycle question for those entities by running `terraform show -json` over
7
- * the root's current state and matching addresses.
6
+ * lifecycle question for those entities, and how it answers depends on one
7
+ * fact the parse already recorded on every entity: the root's `mode`.
8
8
  *
9
- * ## The state file is the ownership answer
9
+ * A **stock** root is read with `terraform show -json` over its state, and
10
+ * state membership is the ownership answer. A **live** root, meaning
11
+ * `terraform.binary` is `"choudoufu"` and the root declares an estate
12
+ * (#2103), has no state to show: it is read with `choudoufu live-plan -json`,
13
+ * and the marker on the resource is the ownership answer. The two halves are
14
+ * two adapters over the same `observeEntities` harness, picked per root.
15
+ *
16
+ * ## The state file is the ownership answer, on a stock root
10
17
  *
11
18
  * Every other lexicon in chant stamps a tag or a label at synthesis and reads
12
19
  * it back off the live resource. Terraform stamps nothing, and there is
@@ -24,10 +31,58 @@
24
31
  * escalates to a delete, which is the correct posture for a thing chant did
25
32
  * not read a verdict for.
26
33
  *
27
- * That places terraform on the trusted-state-file row of the third axis in
28
- * docs/src/content/docs/concepts/lifecycle-models.mdx, where chant elsewhere
29
- * sits on the live-marker row. `docs/pages/observation.mdx` is the reader's
30
- * version of this paragraph.
34
+ * That places a stock terraform root on the trusted-state-file row of the
35
+ * third axis in docs/src/content/docs/concepts/lifecycle-models.mdx, where
36
+ * chant elsewhere sits on the live-marker row. `docs/pages/observation.mdx`
37
+ * is the reader's version of this paragraph.
38
+ *
39
+ * ## The marker is the ownership answer, on a live root
40
+ *
41
+ * choudoufu keeps no authoritative state file. Every taggable resource it
42
+ * manages carries `tofu-estate` and `tofu-address` tags written in the create
43
+ * call, prior state is rebuilt from the live system each run, and the state
44
+ * file, where one exists at all, is a disposable cache. So a live root is on
45
+ * the live-marker row, the row every other chant lexicon sits in.
46
+ *
47
+ * chant does not re-derive that verdict from the tags. `live-plan -json`
48
+ * (choudoufu issue #788) already splits every declared instance four ways,
49
+ * and those four are the classification:
50
+ *
51
+ * | live-plan section | chant |
52
+ * |---|---|
53
+ * | `bound[]`, `source: "marker"` | present, `owned`; the marker named this estate and this address, and it is surfaced as `ResourceMetadata.marker` |
54
+ * | `bound[]`, any other source | present, `owned` by derivation, record, or cache; noted as such, and no marker is surfaced because none was read |
55
+ * | `unowned[]` with `adopt_*` | present, `unknown`; an adoptable match, carrying the exact two tag values #2105 would write |
56
+ * | `unowned[]` without | present, `foreign`; a live resource is in the way at a declared identity and the plan will not touch it |
57
+ * | `omissions[]` | not-observed, `ABSENT` excepted (see below) |
58
+ *
59
+ * The ownership channel this declares is `./live-ownership.ts`'s
60
+ * `TERRAFORM_LIVE_MARKER_KEYS`, and its module doc holds the record of why
61
+ * the keys are declared while the verdicts are set here by hand rather than
62
+ * core's `OwnershipChannel` growing a classifier for them.
63
+ *
64
+ * ### `ABSENT` is absence, and the rest of the omissions are not
65
+ *
66
+ * An omission is choudoufu saying an instance is missing from prior state,
67
+ * with a reason. Most of those reasons are claims of ignorance and become
68
+ * NOT-OBSERVED, which is what the tri-state exists for. One is not:
69
+ * `ABSENT` means "the instance has a usable import identity and the provider
70
+ * reported, normally, that no such object exists", which is exactly chant's
71
+ * OBSERVED-ABSENT, spelled "in neither map". Reporting it as not-observed
72
+ * instead would mean a live root could never propose a create for a resource
73
+ * that genuinely is not there yet, which is the opposite of the honesty the
74
+ * contract is for. `UNOWNED` is the other exception, in the other direction:
75
+ * the `unowned[]` section answers for that address with a real verdict, so
76
+ * the paired omission is never read on its own.
77
+ *
78
+ * ### A block's instances, aggregated
79
+ *
80
+ * chant's entity is the HCL block, `aws_eip.pool`; the document's rows are
81
+ * instances, `aws_eip.pool[0]`. So a block's verdict is the aggregate of its
82
+ * instances, in this precedence: any instance not-observed makes the block
83
+ * not-observed, then foreign, then adoptable, then owned, and a block whose
84
+ * instances are all absent is absent. Partial knowledge is not knowledge,
85
+ * which is the same rule choudoufu applies to its own `INCOMPLETE_BLOCK`.
31
86
  *
32
87
  * ## What is readable at all
33
88
  *
@@ -37,13 +92,28 @@
37
92
  * That is honest, not a gap to close by inventing an address for something
38
93
  * that has none.
39
94
  *
95
+ * A live root reads one block narrower. `live-plan`'s document is prior state
96
+ * for managed resources, so a `data` block has no row in it either and reads
97
+ * `unsupported-kind` there, where the stock reader can answer for it.
98
+ *
40
99
  * ## Tri-state (#1089)
41
100
  *
42
- * A root whose `init` or `show` fails reports EVERY entity declared in that
43
- * root as not-observed with reason `read-failed` and the root named, never
44
- * absent. A failed read must never render as a list of creates. Roots are
45
- * read independently and merged (`mergeObservations`), so one broken backend
46
- * does not un-observe a root that answered.
101
+ * A root whose `init` or `show` fails, or whose `live-plan` fails, reports
102
+ * EVERY entity declared in that root as not-observed with the mapped reason
103
+ * and the root named, never absent. A failed read must never render as a list
104
+ * of creates. Roots are read independently and merged (`mergeObservations`),
105
+ * so one broken backend does not un-observe a root that answered.
106
+ *
107
+ * ## Beyond the declared estate, on a live root
108
+ *
109
+ * `live-ls -estate -json` lists the whole estate off the Resource Groups
110
+ * Tagging API with no configuration read at all, which is a question a state
111
+ * file cannot answer: what does this estate hold that nothing declares? That
112
+ * is what makes `ambientKinds()`, `observeAmbient()` and `teardownOwned()`
113
+ * implementable on this lexicon for the first time. `-consistent` is always
114
+ * passed, because that index lags a tag write by about a minute
115
+ * (`live-ls`'s own help text) and a listing taken right after an apply can
116
+ * otherwise show a resource under both its old and new estate, or neither.
47
117
  *
48
118
  * ## Nothing from `values` is surfaced
49
119
  *
@@ -53,9 +123,12 @@
53
123
  * (address, type, mode, provider, root) and nothing from `values` except the
54
124
  * `id`, which is the physical id every observation carries.
55
125
  */
56
- import type { DescribeResourcesResult } from "@intentius/chant/lexicon";
57
- import { terraformInit, terraformShow } from "./op/activities/terraform.js";
126
+ import type { DescribeResourcesResult, ResourceMetadata, TeardownEnumeration } from "@intentius/chant/lexicon";
127
+ import { type UnobservedReason } from "@intentius/chant/observation";
128
+ import type { OwnershipMarker } from "@intentius/chant/ownership";
129
+ import { choudoufuLiveLs, choudoufuLivePlan, terraformInit, terraformShow } from "./op/activities/terraform.js";
58
130
  export { TERRAFORM_STATE_OWNERSHIP_KEYS } from "./state-ownership.js";
131
+ export { TERRAFORM_LIVE_MARKER_KEYS } from "./live-ownership.js";
59
132
  /** One row out of `values.root_module.resources[]`, at any module depth. */
60
133
  export interface StateResourceRow {
61
134
  /** Fully qualified terraform address, `module.<name>.` prefixes included. */
@@ -93,11 +166,178 @@ export declare function indexStateResources(showJson: unknown): StateIndex;
93
166
  * function to point at.
94
167
  */
95
168
  export declare function classifyStateOwnership(address: string, index: StateIndex): "owned" | "unknown";
96
- /** The activity pair this reader drives. Injectable so tests never run terraform. */
169
+ /** One `bound[]` entry: a declared instance the plan admitted into prior state. */
170
+ export interface LivePlanBoundRow {
171
+ addr: string;
172
+ type?: string;
173
+ /** The import id it bound to, when the resolver produced one. */
174
+ identity?: string;
175
+ /** Which admission path supplied the identity: `marker`, `record`, `derived` or `cache`. */
176
+ source?: string;
177
+ }
178
+ /** One `omissions[]` entry: a declared instance the plan could not read, and why. */
179
+ export interface LivePlanOmissionRow {
180
+ addr: string;
181
+ /** choudoufu's own machine-readable code (`ABSENT`, `FAILED`, `UNOWNED`, …). */
182
+ reason: string;
183
+ detail: string;
184
+ }
185
+ /** One `unowned[]` entry: a live resource at a declared identity without this estate's marker. */
186
+ export interface LivePlanUnownedRow {
187
+ addr: string;
188
+ type?: string;
189
+ identity?: string;
190
+ /** `tofu_estate`: the marker it does carry, when it carries one. Empty means no marker at all. */
191
+ heldBy?: string;
192
+ /** `adopt_tofu_estate`: present exactly when adoption is this run's to offer. */
193
+ adoptEstate?: string;
194
+ /** `adopt_tofu_address`: the escaped address the adopting tag write would carry. */
195
+ adoptAddress?: string;
196
+ }
197
+ /** A `live-plan -json` document, indexed by declared instance address. */
198
+ export interface LivePlanIndex {
199
+ /** `estate`: the estate every section was computed against. */
200
+ estate: string;
201
+ bound: Map<string, LivePlanBoundRow>;
202
+ omissions: Map<string, LivePlanOmissionRow>;
203
+ unowned: Map<string, LivePlanUnownedRow>;
204
+ /** Every address any section named, so a block can find its own instances. */
205
+ addresses: string[];
206
+ /** `diagnostics[]` summaries, for the observation's run-level notes. */
207
+ diagnostics: string[];
208
+ }
209
+ /**
210
+ * Index choudoufu issue #788's document. Unknown fields are ignored and a
211
+ * missing section reads as empty: a document from a newer choudoufu must
212
+ * degrade to "this section said nothing", never to a throw.
213
+ */
214
+ export declare function indexLivePlan(document: unknown): LivePlanIndex;
215
+ /**
216
+ * choudoufu's omission reason codes, mapped onto chant's total vocabulary
217
+ * (`internal/live/projection/result.go`). `"absent"` is not an
218
+ * {@link UnobservedReason}: it is the tri-state's OBSERVED-ABSENT, the one
219
+ * omission that is a claim of knowledge rather than of ignorance.
220
+ *
221
+ * A code this table does not know maps to `read-failed`, which is the safe
222
+ * direction: no NOT-OBSERVED verdict ever becomes a create or a delete.
223
+ */
224
+ export declare const LIVE_PLAN_OMISSION_REASONS: Readonly<Record<string, UnobservedReason | "absent">>;
225
+ /** One `items[]` entry of a `live-ls -json` listing. */
226
+ export interface LiveLsItem {
227
+ /** ARN or other stable identity. */
228
+ id: string;
229
+ /** Resource type, e.g. `aws_vpc`. */
230
+ type: string;
231
+ /** The configuration address decoded from the marker, when the listing could decode one. */
232
+ address?: string;
233
+ /** `tofu-slot`, on a `count` instance. */
234
+ slot?: string;
235
+ /** Whether the cross-referenced configuration directory still declares it. */
236
+ declared: boolean;
237
+ /** Which read found it: `tagging`, or a per-service pass. */
238
+ source?: string;
239
+ /** Every marker tag it carries. */
240
+ tags: Record<string, string>;
241
+ }
242
+ /** One `gaps[]` entry: a declared instance this listing's mechanism cannot reach. */
243
+ export interface LiveLsGap {
244
+ address: string;
245
+ type: string;
246
+ /** `record` or `declaration-carried`, choudoufu's own rung vocabulary. */
247
+ rung: string;
248
+ detail: string;
249
+ }
250
+ /** A `live-ls -json` listing, parsed. */
251
+ export interface LiveLsListing {
252
+ estate: string;
253
+ items: LiveLsItem[];
254
+ gaps: LiveLsGap[];
255
+ }
256
+ /** Parse a `live-ls -json` document. A missing section reads as empty, never as a throw. */
257
+ export declare function readLiveLs(document: unknown): LiveLsListing;
258
+ /**
259
+ * The entity key `buildRoots()` would have produced for a live resource's
260
+ * address.
261
+ *
262
+ * A live address is fully qualified with dots, `module.cdn.null_resource.edge`;
263
+ * the build keys a descended child module's block with a slash per call,
264
+ * `app/module.cdn/null_resource.edge` (#2112). Splitting the `module.<name>.`
265
+ * prefixes back out is what keeps a live row and the block that declared it
266
+ * on the same key.
267
+ */
268
+ export declare function entityKeyFor(root: string, address: string): string;
269
+ /**
270
+ * The entity types this lexicon can enumerate beyond the declared estate
271
+ * (#1278). One: a `resource` block, whose live counterparts `live-ls` lists
272
+ * off the tag index. A `data`, `module` or `provider` block has no live
273
+ * counterpart to enumerate at all.
274
+ */
275
+ export declare function ambientKinds(): string[];
276
+ /** Shared options for the two estate-wide reads. */
277
+ export interface LiveEstateOptions {
278
+ /** Directory the activities start the `chant.config.*` search from. Default: the process cwd. */
279
+ cwd?: string;
280
+ /** Restrict to these root names. Default: every live root the project declares. */
281
+ roots?: string[];
282
+ }
283
+ /**
284
+ * Every live root the project declares, in config order. Reads the project
285
+ * config the same way the activities do, so `terraform.roots` is read once
286
+ * and the same answer reaches both.
287
+ */
288
+ export declare function liveRootNames(cwd?: string): Promise<Array<{
289
+ root: string;
290
+ estate: string;
291
+ }>>;
292
+ /**
293
+ * Report the resources this estate owns that nothing declares (#1278) — the
294
+ * owned-orphan set, which is `live-ls`'s `declared: false` rows.
295
+ *
296
+ * This is the question a state file cannot answer at all, because a state
297
+ * file knows only what it created. The tag index knows what the estate holds,
298
+ * whether or not any configuration still mentions it.
299
+ */
300
+ export declare function observeAmbient(options: {
301
+ environment: string;
302
+ kinds: string[];
303
+ observed: Record<string, ResourceMetadata>;
304
+ } & LiveEstateOptions, deps?: TerraformReadDeps): Promise<Record<string, ResourceMetadata>>;
305
+ /**
306
+ * Name what a teardown of this environment would remove from every live root
307
+ * (#1222): the estate's owned orphans, which are exactly the set choudoufu's
308
+ * own default `policy` verb (`undeclared_tagged = "delete"`) removes on the
309
+ * next apply.
310
+ *
311
+ * Candidates carry the requested identity verbatim, because that identity is
312
+ * what selected them: the roots enumerated here are this project's own, and
313
+ * their estates are what `terraform.roots` declares for this environment.
314
+ * The estate that actually answered rides `name`, so a reviewer of the plan
315
+ * can see which one it was.
316
+ *
317
+ * `live-ls`'s own `gaps[]` become holes rather than silence, per #1089: a
318
+ * declared instance the tag index can never serve is unknown, not clean.
319
+ */
320
+ export declare function teardownOwned(options: {
321
+ environment: string;
322
+ marker: OwnershipMarker;
323
+ } & LiveEstateOptions, deps?: TerraformReadDeps): Promise<TeardownEnumeration>;
324
+ /** The activities this reader drives. Injectable so tests never run a binary. */
97
325
  export interface TerraformReadDeps {
98
326
  init: typeof terraformInit;
99
327
  show: typeof terraformShow;
328
+ livePlan: typeof choudoufuLivePlan;
329
+ liveLs: typeof choudoufuLiveLs;
100
330
  }
331
+ /**
332
+ * The address the live system knows a block by. For a root-module block that
333
+ * is the block's own address; for one inside a child module it is what
334
+ * `terraform show -json` writes in `child_modules[]` and what choudoufu's
335
+ * markers carry, the call chain and the address joined with dots:
336
+ * `module.cdn.null_resource.edge` (#2112). The entity KEY keeps its slashes
337
+ * (`app/module.cdn/null_resource.edge`), so what a build declares and what a
338
+ * read observes still line up one to one.
339
+ */
340
+ export declare function qualifiedAddress(address: string, callers: readonly string[]): string;
101
341
  export interface DescribeResourcesOptions {
102
342
  environment: string;
103
343
  buildOutput: string;
@@ -1 +1 @@
1
- {"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAUxE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAMzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAEnE,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpC,wFAAwF;IACxF,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAgBD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,UAAU,CA6BjE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAE9F;AASD,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,aAAa,CAAC;IAC3B,IAAI,EAAE,OAAO,aAAa,CAAC;CAC5B;AA+GD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,IAAI,GAAE,iBAA6B,GAClC,OAAO,CAAC,uBAAuB,CAAC,CAgDlC"}
1
+ {"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Descend into local child modules (chant #2112).
3
+ *
4
+ * `parseTerraformRootDir` reads one directory, non-recursively, which is
5
+ * Terraform's own root-module scoping and the right unit for a root-scoped
6
+ * check like TF001. Four rules need more than that: TF014 and TF015 are about
7
+ * what a CHILD module may contain, and TF020 needs every reference in a scope
8
+ * before it can call a declaration unused. This module supplies the missing
9
+ * half: a `module` block whose `source` is a local path names a directory,
10
+ * and that directory parses with the same `blocksToEntities` into entities
11
+ * keyed `<root>/module.<name>/<address>` carrying `props.callers`.
12
+ *
13
+ * ## What is followed, and what is not
14
+ *
15
+ * tflint's `--call-module-type` (three states, defaulting to `local`,
16
+ * https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/calling-modules.md)
17
+ * is the model:
18
+ *
19
+ * - `local` (the default): only `./` and `../` sources are read. A registry
20
+ * or git source is NOT fetched, so its contents are never linted and every
21
+ * finding about it is reported against the call site instead, which is
22
+ * where TF004 and TF005 already report. The skipped call sites are named in
23
+ * a warning rather than passed over in silence.
24
+ * - `none`: no descent at all. A root then parses exactly as it did before
25
+ * this module existed.
26
+ * - `all`: reserved. tflint means "fetch registry and git modules too", which
27
+ * needs a `terraform init`/`terraform get` first so the modules are on disk
28
+ * under `.terraform`. chant fetches nothing, so this is refused with a
29
+ * message rather than quietly behaving like `local`.
30
+ *
31
+ * Two more refusals, both about staying inside the repository being read:
32
+ *
33
+ * - A source that resolves outside the project root is refused. `../` is a
34
+ * legal Terraform source and a repository may legitimately share modules
35
+ * between sibling roots, but reading above the project root means linting
36
+ * files the project does not own, so the boundary is the project root and
37
+ * crossing it is a warning, not a parse.
38
+ * - A source already on the current call chain is a cycle (`a` calls `b`
39
+ * calls `a`) and stops there. The visited set is per chain, on RESOLVED
40
+ * paths, so one module called from two different places is still read once
41
+ * per call site, each under its own `module.<name>` key, the way
42
+ * `terraform show -json` reports two `child_modules[]` entries for it.
43
+ *
44
+ * Everything here is best effort, like `./roots.ts`: an unreadable or
45
+ * unparseable child module is a warning and no entities, never a throw, since
46
+ * half a root parsed is more useful than none of it.
47
+ */
48
+ import type { Declarable } from "@intentius/chant/declarable";
49
+ import type { Hcl2Json } from "@intentius/chant/terraform/parse";
50
+ import { type TerraformRootModeOptions } from "./parse.js";
51
+ /** tflint's `--call-module-type`, with the same three states and the same default. */
52
+ export type CallModuleType = "local" | "none" | "all";
53
+ /** What a caller gets when it asks for a mode chant cannot serve. */
54
+ export interface ResolvedCallModuleType {
55
+ /** The mode actually used. `"all"` never survives here. */
56
+ effective: "local" | "none";
57
+ /** Set when the requested mode was refused, ready to push onto a warning list. */
58
+ warning?: string;
59
+ }
60
+ /**
61
+ * Resolve the configured `callModuleType` into one this lexicon implements.
62
+ * `"all"` is refused with a message naming what it would need; everything
63
+ * else passes through, and an absent value is `"local"`, tflint's default.
64
+ */
65
+ export declare function resolveCallModuleType(value?: CallModuleType): ResolvedCallModuleType;
66
+ /** Options for {@link descendModules}. */
67
+ export interface DescendOptions {
68
+ /** Directory the scope's own `.tf` files were read from. */
69
+ dir: string;
70
+ /** Root name, the first segment of every entity key. */
71
+ root: string;
72
+ /** Boundary: a source resolving outside this directory is refused. */
73
+ projectRoot: string;
74
+ /** Resolved mode. `"none"` returns immediately with nothing. */
75
+ callModuleType?: "local" | "none";
76
+ /** Injectable parser (tests); defaults to core's lazy-loaded `@cdktf/hcl2json`. */
77
+ hcl2json?: Hcl2Json;
78
+ /** Mode facts stamped onto the child's entities, exactly as on the root's. */
79
+ modeOptions?: TerraformRootModeOptions;
80
+ /** How deep to follow calls. A guard against a pathological tree, not a policy. */
81
+ maxDepth?: number;
82
+ }
83
+ export interface DescendResult {
84
+ /** The child modules' entities, keyed `<root>/module.<name>/<address>`. */
85
+ entities: Map<string, Declarable>;
86
+ /** One line per refusal or skip, in the order they were met. */
87
+ warnings: string[];
88
+ }
89
+ /**
90
+ * Parse every local child module reachable from `scope`, recursively.
91
+ *
92
+ * `scope` is one already-parsed module scope: the root's own entities on the
93
+ * first call, a child's on a recursive one. Returned entities are the
94
+ * children's only, never the scope's own, so a caller merges them into the
95
+ * map it already has.
96
+ */
97
+ export declare function descendModules(scope: Map<string, Declarable>, opts: DescendOptions): Promise<DescendResult>;
98
+ //# sourceMappingURL=descend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descend.d.ts","sourceRoot":"","sources":["../../src/hcl/descend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAGjE,OAAO,EAKL,KAAK,wBAAwB,EAC9B,MAAM,SAAS,CAAC;AAEjB,sFAAsF;AACtF,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtD,qEAAqE;AACrE,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,EAAE,cAAc,GAAG,sBAAsB,CAYpF;AAED,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC,mFAAmF;IACnF,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAuDD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC9B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,aAAa,CAAC,CA2FxB"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * choudoufu's live resource markers, as chant reads them (#2104).
3
+ *
4
+ * On a live root the ownership record is not a state file and not a chant
5
+ * stamp: it is two AWS tags on the resource itself, `tofu-estate` and
6
+ * `tofu-address`, specified in `live/MARKERS.md` in
7
+ * https://github.com/INTENTIUS/choudoufu. That file calls itself the one
8
+ * integration surface external tools may rely on, so this module implements
9
+ * exactly what it specifies and nothing beyond it. The spec's own tables are
10
+ * this module's tests (`./marker.test.ts`).
11
+ *
12
+ * ## Escape, then compare. Never decode a tag blind
13
+ *
14
+ * A canonical terraform address uses `[`, `]` and `"` to write an instance
15
+ * key, and AWS allows none of the three in a tag value. So an address is
16
+ * escaped before it is written, and the spec's comparison rule is one
17
+ * sentence: escape the address you already know and compare strings. The
18
+ * reverse, decoding a tag and hoping to recover the address, is ambiguous
19
+ * (`this[2]` and `this["2"]` escape alike) and the spec says not to do it
20
+ * where a verdict depends on the answer.
21
+ *
22
+ * The rule itself, from "Escaping rule":
23
+ *
24
+ * 1. escape the content of every instance key first (see
25
+ * {@link escapeForEachKey}); a `count` index is only ever digits, so
26
+ * this is a no-op for one;
27
+ * 2. replace every `[` with `:`;
28
+ * 3. delete every `]`;
29
+ * 4. delete every `"`.
30
+ *
31
+ * Step 1 first is what makes a `:` in an escaped value always mean "an index
32
+ * starts here": a key's own `.` and `:` are already gone by the time steps
33
+ * 2 to 4 run.
34
+ *
35
+ * ## Three escapings on the declared side
36
+ *
37
+ * The key escaping gained a layer twice, and neither change rewrote the
38
+ * markers already on live resources. A marker stamped before choudoufu's
39
+ * issue #178 escaped no key at all; one stamped between #178 and #210
40
+ * doubled `@`, `.` and `:` but did not carry out-of-charset characters into
41
+ * the AWS-legal set. So {@link addressMatches} escapes the declared address
42
+ * three ways and accepts any of them, which is what `AddressMatches` does in
43
+ * choudoufu itself. Writing always uses {@link escapeAddress}, the current
44
+ * form.
45
+ */
46
+ /** `tofu-estate`: the estate that owns the resource. The entire ownership claim. */
47
+ export declare const MARKER_TAG_ESTATE = "tofu-estate";
48
+ /** `tofu-address`: the resource's escaped canonical address, or its first 256-character chunk. */
49
+ export declare const MARKER_TAG_ADDRESS = "tofu-address";
50
+ /** `tofu-slot`: the stable, opaque cardinality slot a `count` instance carries. */
51
+ export declare const MARKER_TAG_SLOT = "tofu-slot";
52
+ /**
53
+ * `tofu-address-2` through `tofu-address-4`, in order. A reader concatenates
54
+ * `tofu-address` and whichever of these are present; they are never
55
+ * meaningful on their own.
56
+ */
57
+ export declare const MARKER_TAG_ADDRESS_CONTINUATIONS: readonly ["tofu-address-2", "tofu-address-3", "tofu-address-4"];
58
+ /**
59
+ * Escape one `for_each` instance key, both layers in the specified order:
60
+ * out-of-charset escaping first, then the `@` / `.` / `:` doubling over its
61
+ * output. Order is load-bearing: the first layer's introducer is `+`, none of
62
+ * the three characters the second layer scans for, so the second never
63
+ * mistakes the first's output for its own escape sequences.
64
+ *
65
+ * Six characters cannot be carried at all and are refused at choudoufu's own
66
+ * lint rather than here (`"`, `\`, any non-printable, `$`, `%`, `[`, `]`);
67
+ * this function escapes what it is given without judging it, because chant
68
+ * never writes a marker, and a key chant meets in a `tofu-address` tag has
69
+ * already passed that lint.
70
+ */
71
+ export declare function escapeForEachKey(key: string): string;
72
+ /**
73
+ * The `tofu-address` value for a canonical terraform address: the current
74
+ * escaping, which is the only one anything ever writes.
75
+ */
76
+ export declare function escapeAddress(address: string): string;
77
+ /**
78
+ * Every escaping a live marker could have been written under, current first:
79
+ * the current one, the pre-#210 one (the doubling alone), and the pre-#178
80
+ * one (no key escaping at all). Duplicates are collapsed, so the common
81
+ * address with no `for_each` key yields exactly one string.
82
+ */
83
+ export declare function escapeAddressVariants(address: string): string[];
84
+ /**
85
+ * Does a live resource's `tofu-address` value name this declared address?
86
+ * The declared side is escaped and the strings are compared, three escapings
87
+ * deep for the migration windows; the tag is never decoded.
88
+ */
89
+ export declare function addressMatches(declaredAddress: string, tagValue: string): boolean;
90
+ /** What {@link readMarker} found on one live resource's tags. */
91
+ export type MarkerVerdict =
92
+ /** Carries `tofu-estate` and a readable `tofu-address`: it belongs to that estate. */
93
+ {
94
+ kind: "owned";
95
+ estate: string;
96
+ address: string;
97
+ slot?: string;
98
+ }
99
+ /** Carries neither key: outside every estate's ownership, reported and never auto-deleted. */
100
+ | {
101
+ kind: "foreign";
102
+ }
103
+ /**
104
+ * Carries `tofu-estate` but no readable `tofu-address`: missing, empty, or
105
+ * a continuation chain with a gap in it. A named error, never guessed at
106
+ * and never read as either "belongs to no one" or "close enough".
107
+ */
108
+ | {
109
+ kind: "malformed";
110
+ estate: string;
111
+ detail: string;
112
+ };
113
+ /**
114
+ * Concatenate `tofu-address` and whatever continuation tags follow it, which
115
+ * is the only sanctioned way to read a split address.
116
+ *
117
+ * A chain with a gap in it (`tofu-address-3` present while `tofu-address-2`
118
+ * is not) cannot be concatenated into anything and returns `undefined` rather
119
+ * than the address up to the gap.
120
+ */
121
+ export declare function joinMarkerAddress(tags: Record<string, string | undefined>): string | undefined;
122
+ /**
123
+ * The ownership verdict `live/MARKERS.md`'s "Ownership semantics" section
124
+ * defines, read off one live resource's tags. Three outcomes, and no fourth:
125
+ * a `tofu-estate` value is the entire ownership claim with no secondary
126
+ * check, neither key present is foreign, and an estate without a readable
127
+ * address is malformed rather than either of the two.
128
+ */
129
+ export declare function readMarker(tags: Record<string, string | undefined> | undefined): MarkerVerdict;
130
+ //# sourceMappingURL=marker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../src/hcl/marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AAEjD,mFAAmF;AACnF,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,iEAInC,CAAC;AA4CX;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAkBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAO/D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEjF;AAED,iEAAiE;AACjE,MAAM,MAAM,aAAa;AACvB,sFAAsF;AACpF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE;AACnE,8FAA8F;GAC5F;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE;AACrB;;;;GAIG;GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAgB9F;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,aAAa,CAe9F"}