@intentius/chant-lexicon-terraform 0.124.52 → 0.124.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (641) hide show
  1. package/README.md +14 -10
  2. package/dist/__fixtures__/pr-loop/estate.component.d.ts +7 -0
  3. package/dist/__fixtures__/pr-loop/estate.component.d.ts.map +1 -0
  4. package/dist/__fixtures__/pr-loop/estate.component.js +7 -0
  5. package/dist/__fixtures__/report/generate.d.ts +26 -0
  6. package/dist/__fixtures__/report/generate.d.ts.map +1 -0
  7. package/dist/__fixtures__/report/generate.js +58 -0
  8. package/dist/applied-state.d.ts +27 -0
  9. package/dist/applied-state.d.ts.map +1 -0
  10. package/dist/applied-state.js +44 -0
  11. package/dist/backend-config.d.ts +53 -0
  12. package/dist/backend-config.d.ts.map +1 -0
  13. package/dist/backend-config.js +136 -0
  14. package/dist/behaviour/kinds.d.ts.map +1 -1
  15. package/dist/behaviour/kinds.js +4 -0
  16. package/dist/behaviour/predict.d.ts.map +1 -1
  17. package/dist/behaviour/predict.js +6 -2
  18. package/dist/behaviour/reference-catalog.d.ts +16 -5
  19. package/dist/behaviour/reference-catalog.d.ts.map +1 -1
  20. package/dist/behaviour/reference-catalog.js +16 -5
  21. package/dist/behaviour/request.d.ts.map +1 -1
  22. package/dist/behaviour/request.js +3 -2
  23. package/dist/changed-roots.d.ts +6 -4
  24. package/dist/changed-roots.d.ts.map +1 -1
  25. package/dist/changed-roots.js +14 -18
  26. package/dist/ci-setup.d.ts +11 -0
  27. package/dist/ci-setup.d.ts.map +1 -0
  28. package/dist/ci-setup.js +41 -0
  29. package/dist/commands.d.ts.map +1 -1
  30. package/dist/commands.js +4 -3
  31. package/dist/components/capability-plugin.d.ts +105 -9
  32. package/dist/components/capability-plugin.d.ts.map +1 -1
  33. package/dist/components/capability-plugin.js +357 -36
  34. package/dist/components/compose-group.d.ts +145 -0
  35. package/dist/components/compose-group.d.ts.map +1 -0
  36. package/dist/components/compose-group.js +407 -0
  37. package/dist/components/placeholder-preview.d.ts +78 -0
  38. package/dist/components/placeholder-preview.d.ts.map +1 -0
  39. package/dist/components/placeholder-preview.js +254 -0
  40. package/dist/components/release-inputs.d.ts +29 -0
  41. package/dist/components/release-inputs.d.ts.map +1 -0
  42. package/dist/components/release-inputs.js +57 -0
  43. package/dist/components/trace-facts.d.ts +16 -0
  44. package/dist/components/trace-facts.d.ts.map +1 -0
  45. package/dist/components/trace-facts.js +19 -0
  46. package/dist/compose/apply-events.d.ts +46 -0
  47. package/dist/compose/apply-events.d.ts.map +1 -0
  48. package/dist/compose/apply-events.js +77 -0
  49. package/dist/compose/estate.d.ts +194 -0
  50. package/dist/compose/estate.d.ts.map +1 -0
  51. package/dist/compose/estate.js +363 -0
  52. package/dist/compose/hcl.d.ts +99 -0
  53. package/dist/compose/hcl.d.ts.map +1 -0
  54. package/dist/compose/hcl.js +302 -0
  55. package/dist/compose/module-address.d.ts +24 -0
  56. package/dist/compose/module-address.d.ts.map +1 -0
  57. package/dist/compose/module-address.js +43 -0
  58. package/dist/compose/root.d.ts +127 -0
  59. package/dist/compose/root.d.ts.map +1 -0
  60. package/dist/compose/root.js +586 -0
  61. package/dist/compose/run.d.ts +183 -0
  62. package/dist/compose/run.d.ts.map +1 -0
  63. package/dist/compose/run.js +447 -0
  64. package/dist/compose/slice.d.ts +102 -0
  65. package/dist/compose/slice.d.ts.map +1 -0
  66. package/dist/compose/slice.js +249 -0
  67. package/dist/compose/state-address.d.ts +28 -0
  68. package/dist/compose/state-address.d.ts.map +1 -0
  69. package/dist/compose/state-address.js +154 -0
  70. package/dist/compose/state-merge.d.ts +52 -0
  71. package/dist/compose/state-merge.d.ts.map +1 -0
  72. package/dist/compose/state-merge.js +135 -0
  73. package/dist/compose.d.ts +179 -0
  74. package/dist/compose.d.ts.map +1 -0
  75. package/dist/compose.js +482 -0
  76. package/dist/composites/terraform-apply-op.d.ts.map +1 -1
  77. package/dist/composites/terraform-apply-op.js +7 -3
  78. package/dist/cone.d.ts +53 -0
  79. package/dist/cone.d.ts.map +1 -0
  80. package/dist/cone.js +119 -0
  81. package/dist/config.d.ts +59 -13
  82. package/dist/config.d.ts.map +1 -1
  83. package/dist/config.js +43 -9
  84. package/dist/cost-hold.d.ts +27 -0
  85. package/dist/cost-hold.d.ts.map +1 -0
  86. package/dist/cost-hold.js +21 -0
  87. package/dist/describe-resources.d.ts +74 -12
  88. package/dist/describe-resources.d.ts.map +1 -1
  89. package/dist/describe-resources.js +374 -66
  90. package/dist/drift-read.d.ts +33 -0
  91. package/dist/drift-read.d.ts.map +1 -0
  92. package/dist/drift-read.js +243 -0
  93. package/dist/drift-record.d.ts +147 -0
  94. package/dist/drift-record.d.ts.map +1 -0
  95. package/dist/drift-record.js +383 -0
  96. package/dist/drift-rows.d.ts +61 -0
  97. package/dist/drift-rows.d.ts.map +1 -0
  98. package/dist/drift-rows.js +108 -0
  99. package/dist/exit-codes.d.ts +55 -0
  100. package/dist/exit-codes.d.ts.map +1 -0
  101. package/dist/exit-codes.js +48 -0
  102. package/dist/hcl/edges.d.ts.map +1 -1
  103. package/dist/hcl/edges.js +24 -1
  104. package/dist/hcl/files.d.ts +61 -0
  105. package/dist/hcl/files.d.ts.map +1 -0
  106. package/dist/hcl/files.js +221 -0
  107. package/dist/hcl/instances.d.ts +82 -0
  108. package/dist/hcl/instances.d.ts.map +1 -0
  109. package/dist/hcl/instances.js +390 -0
  110. package/dist/hcl/parse.d.ts +81 -9
  111. package/dist/hcl/parse.d.ts.map +1 -1
  112. package/dist/hcl/parse.js +114 -16
  113. package/dist/hcl/roots.d.ts.map +1 -1
  114. package/dist/hcl/roots.js +5 -0
  115. package/dist/hcl/suppressions.d.ts.map +1 -1
  116. package/dist/hcl/suppressions.js +8 -2
  117. package/dist/index.d.ts +13 -2
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +24 -2
  120. package/dist/integrity.json +8 -5
  121. package/dist/lint/audit-catalog.d.ts.map +1 -1
  122. package/dist/lint/audit-catalog.js +27 -3
  123. package/dist/lint/audit-lineage.d.ts +14 -2
  124. package/dist/lint/audit-lineage.d.ts.map +1 -1
  125. package/dist/lint/post-synth/index.d.ts.map +1 -1
  126. package/dist/lint/post-synth/index.js +4 -0
  127. package/dist/lint/post-synth/record-store.d.ts +54 -0
  128. package/dist/lint/post-synth/record-store.d.ts.map +1 -0
  129. package/dist/lint/post-synth/record-store.js +104 -0
  130. package/dist/lint/post-synth/tf001.d.ts +2 -2
  131. package/dist/lint/post-synth/tf001.js +2 -2
  132. package/dist/lint/post-synth/tf024.d.ts +35 -11
  133. package/dist/lint/post-synth/tf024.d.ts.map +1 -1
  134. package/dist/lint/post-synth/tf024.js +92 -20
  135. package/dist/lint/post-synth/tf046.d.ts +64 -0
  136. package/dist/lint/post-synth/tf046.d.ts.map +1 -0
  137. package/dist/lint/post-synth/tf046.js +175 -0
  138. package/dist/lint/post-synth/tf047.d.ts +36 -0
  139. package/dist/lint/post-synth/tf047.d.ts.map +1 -0
  140. package/dist/lint/post-synth/tf047.js +94 -0
  141. package/dist/live-plan-reasons.d.ts +21 -0
  142. package/dist/live-plan-reasons.d.ts.map +1 -0
  143. package/dist/live-plan-reasons.js +47 -0
  144. package/dist/lock-rows.d.ts +36 -0
  145. package/dist/lock-rows.d.ts.map +1 -0
  146. package/dist/lock-rows.js +60 -0
  147. package/dist/lock-timeout.d.ts +22 -0
  148. package/dist/lock-timeout.d.ts.map +1 -0
  149. package/dist/lock-timeout.js +32 -0
  150. package/dist/lsp/option-keys.d.ts.map +1 -1
  151. package/dist/lsp/option-keys.js +2 -0
  152. package/dist/manifest.json +1 -1
  153. package/dist/module-catalog/index.d.ts +69 -0
  154. package/dist/module-catalog/index.d.ts.map +1 -0
  155. package/dist/module-catalog/index.js +110 -0
  156. package/dist/module-catalog/refresh-cli.d.ts +4 -0
  157. package/dist/module-catalog/refresh-cli.d.ts.map +1 -0
  158. package/dist/module-catalog/refresh-cli.js +64 -0
  159. package/dist/module-catalog/static-tier.d.ts +6 -0
  160. package/dist/module-catalog/static-tier.d.ts.map +1 -0
  161. package/dist/module-catalog/static-tier.js +1650 -0
  162. package/dist/module-catalog/types.d.ts +65 -0
  163. package/dist/module-catalog/types.d.ts.map +1 -0
  164. package/dist/module-catalog/types.js +33 -0
  165. package/dist/okf/index.md +3 -1
  166. package/dist/okf/rules/TF024.md +2 -2
  167. package/dist/okf/rules/TF046.md +11 -0
  168. package/dist/okf/rules/TF047.md +11 -0
  169. package/dist/op/activities/index.d.ts +6 -2
  170. package/dist/op/activities/index.d.ts.map +1 -1
  171. package/dist/op/activities/index.js +5 -1
  172. package/dist/op/activities/live-detect.d.ts +4 -3
  173. package/dist/op/activities/live-detect.d.ts.map +1 -1
  174. package/dist/op/activities/live-detect.js +57 -32
  175. package/dist/op/activities/pin-rollout.d.ts +2 -0
  176. package/dist/op/activities/pin-rollout.d.ts.map +1 -1
  177. package/dist/op/activities/pin-rollout.js +1 -0
  178. package/dist/op/activities/terraform.d.ts +182 -5
  179. package/dist/op/activities/terraform.d.ts.map +1 -1
  180. package/dist/op/activities/terraform.js +224 -24
  181. package/dist/op/activity-contracts.d.ts +27 -0
  182. package/dist/op/activity-contracts.d.ts.map +1 -1
  183. package/dist/op/activity-contracts.js +19 -1
  184. package/dist/op/builders.d.ts +7 -1
  185. package/dist/op/builders.d.ts.map +1 -1
  186. package/dist/op/builders.js +9 -0
  187. package/dist/pin/consumers.d.ts +35 -0
  188. package/dist/pin/consumers.d.ts.map +1 -0
  189. package/dist/pin/consumers.js +70 -0
  190. package/dist/pin/edit.d.ts.map +1 -1
  191. package/dist/pin/edit.js +35 -0
  192. package/dist/pin/rollout.d.ts +2 -0
  193. package/dist/pin/rollout.d.ts.map +1 -1
  194. package/dist/pin/rollout.js +14 -11
  195. package/dist/plan-shape.d.ts +30 -0
  196. package/dist/plan-shape.d.ts.map +1 -0
  197. package/dist/plan-shape.js +125 -0
  198. package/dist/plugin.d.ts.map +1 -1
  199. package/dist/plugin.js +37 -18
  200. package/dist/registry/address.d.ts +63 -0
  201. package/dist/registry/address.d.ts.map +1 -0
  202. package/dist/registry/address.js +65 -0
  203. package/dist/registry/catalog-read.d.ts +14 -0
  204. package/dist/registry/catalog-read.d.ts.map +1 -0
  205. package/dist/registry/catalog-read.js +58 -0
  206. package/dist/registry/deprecated.d.ts +37 -0
  207. package/dist/registry/deprecated.d.ts.map +1 -0
  208. package/dist/registry/deprecated.js +43 -0
  209. package/dist/registry/docs.d.ts +96 -0
  210. package/dist/registry/docs.d.ts.map +1 -0
  211. package/dist/registry/docs.js +210 -0
  212. package/dist/registry/edge/edge.d.ts +46 -0
  213. package/dist/registry/edge/edge.d.ts.map +1 -0
  214. package/dist/registry/edge/edge.js +194 -0
  215. package/dist/registry/edge/index.d.ts +11 -0
  216. package/dist/registry/edge/index.d.ts.map +1 -0
  217. package/dist/registry/edge/index.js +10 -0
  218. package/dist/registry/edge/lambda-edge.d.ts +76 -0
  219. package/dist/registry/edge/lambda-edge.d.ts.map +1 -0
  220. package/dist/registry/edge/lambda-edge.js +95 -0
  221. package/dist/registry/edge/sigv4-web.d.ts +33 -0
  222. package/dist/registry/edge/sigv4-web.d.ts.map +1 -0
  223. package/dist/registry/edge/sigv4-web.js +56 -0
  224. package/dist/registry/edge/token-source.d.ts +73 -0
  225. package/dist/registry/edge/token-source.d.ts.map +1 -0
  226. package/dist/registry/edge/token-source.js +115 -0
  227. package/dist/registry/edge/worker.d.ts +45 -0
  228. package/dist/registry/edge/worker.d.ts.map +1 -0
  229. package/dist/registry/edge/worker.js +26 -0
  230. package/dist/registry/handler.d.ts +25 -0
  231. package/dist/registry/handler.d.ts.map +1 -0
  232. package/dist/registry/handler.js +75 -0
  233. package/dist/registry/headers-file.d.ts +21 -0
  234. package/dist/registry/headers-file.d.ts.map +1 -0
  235. package/dist/registry/headers-file.js +57 -0
  236. package/dist/registry/index.d.ts +31 -0
  237. package/dist/registry/index.d.ts.map +1 -0
  238. package/dist/registry/index.js +30 -0
  239. package/dist/registry/mirror-paths.d.ts +9 -0
  240. package/dist/registry/mirror-paths.d.ts.map +1 -0
  241. package/dist/registry/mirror-paths.js +8 -0
  242. package/dist/registry/mirror.d.ts +130 -0
  243. package/dist/registry/mirror.d.ts.map +1 -0
  244. package/dist/registry/mirror.js +319 -0
  245. package/dist/registry/proxies.d.ts +73 -0
  246. package/dist/registry/proxies.d.ts.map +1 -0
  247. package/dist/registry/proxies.js +111 -0
  248. package/dist/registry/reader.d.ts +57 -0
  249. package/dist/registry/reader.d.ts.map +1 -0
  250. package/dist/registry/reader.js +198 -0
  251. package/dist/registry/semver.d.ts +16 -0
  252. package/dist/registry/semver.d.ts.map +1 -0
  253. package/dist/registry/semver.js +24 -0
  254. package/dist/registry/serve.d.ts +24 -0
  255. package/dist/registry/serve.d.ts.map +1 -0
  256. package/dist/registry/serve.js +64 -0
  257. package/dist/registry/source-forms.d.ts +79 -0
  258. package/dist/registry/source-forms.d.ts.map +1 -0
  259. package/dist/registry/source-forms.js +202 -0
  260. package/dist/registry/targets/artifactory.d.ts +28 -0
  261. package/dist/registry/targets/artifactory.d.ts.map +1 -0
  262. package/dist/registry/targets/artifactory.js +206 -0
  263. package/dist/registry/targets/fake-artifactory.d.ts +30 -0
  264. package/dist/registry/targets/fake-artifactory.d.ts.map +1 -0
  265. package/dist/registry/targets/fake-artifactory.js +142 -0
  266. package/dist/registry/targets/fake-gitlab.d.ts +39 -0
  267. package/dist/registry/targets/fake-gitlab.d.ts.map +1 -0
  268. package/dist/registry/targets/fake-gitlab.js +136 -0
  269. package/dist/registry/targets/fake-hcp.d.ts +50 -0
  270. package/dist/registry/targets/fake-hcp.d.ts.map +1 -0
  271. package/dist/registry/targets/fake-hcp.js +202 -0
  272. package/dist/registry/targets/fake-http.d.ts +31 -0
  273. package/dist/registry/targets/fake-http.d.ts.map +1 -0
  274. package/dist/registry/targets/fake-http.js +87 -0
  275. package/dist/registry/targets/fake-nexus.d.ts +27 -0
  276. package/dist/registry/targets/fake-nexus.d.ts.map +1 -0
  277. package/dist/registry/targets/fake-nexus.js +137 -0
  278. package/dist/registry/targets/gitlab.d.ts +53 -0
  279. package/dist/registry/targets/gitlab.d.ts.map +1 -0
  280. package/dist/registry/targets/gitlab.js +187 -0
  281. package/dist/registry/targets/hcp.d.ts +29 -0
  282. package/dist/registry/targets/hcp.d.ts.map +1 -0
  283. package/dist/registry/targets/hcp.js +310 -0
  284. package/dist/registry/targets/hosted.d.ts +62 -0
  285. package/dist/registry/targets/hosted.d.ts.map +1 -0
  286. package/dist/registry/targets/hosted.js +74 -0
  287. package/dist/registry/targets/index.d.ts +18 -0
  288. package/dist/registry/targets/index.d.ts.map +1 -0
  289. package/dist/registry/targets/index.js +17 -0
  290. package/dist/registry/targets/module-target.d.ts +68 -0
  291. package/dist/registry/targets/module-target.d.ts.map +1 -0
  292. package/dist/registry/targets/module-target.js +63 -0
  293. package/dist/registry/targets/nexus.d.ts +43 -0
  294. package/dist/registry/targets/nexus.d.ts.map +1 -0
  295. package/dist/registry/targets/nexus.js +250 -0
  296. package/dist/registry/targets/zip.d.ts +55 -0
  297. package/dist/registry/targets/zip.d.ts.map +1 -0
  298. package/dist/registry/targets/zip.js +278 -0
  299. package/dist/registry/writer.d.ts +101 -0
  300. package/dist/registry/writer.d.ts.map +1 -0
  301. package/dist/registry/writer.js +109 -0
  302. package/dist/report.d.ts +15 -6
  303. package/dist/report.d.ts.map +1 -1
  304. package/dist/report.js +28 -55
  305. package/dist/rules/record-store.ts +122 -0
  306. package/dist/rules/tf001.ts +2 -2
  307. package/dist/rules/tf024.ts +105 -22
  308. package/dist/rules/tf046.ts +204 -0
  309. package/dist/rules/tf047.ts +114 -0
  310. package/dist/skills/chant-terraform.md +1 -1
  311. package/dist/state/azure-blob.d.ts +9 -0
  312. package/dist/state/azure-blob.d.ts.map +1 -0
  313. package/dist/state/azure-blob.js +8 -0
  314. package/dist/state/backend.d.ts +158 -0
  315. package/dist/state/backend.d.ts.map +1 -0
  316. package/dist/state/backend.js +406 -0
  317. package/dist/state/exec.d.ts +39 -0
  318. package/dist/state/exec.d.ts.map +1 -0
  319. package/dist/state/exec.js +80 -0
  320. package/dist/state/gcs.d.ts +8 -0
  321. package/dist/state/gcs.d.ts.map +1 -0
  322. package/dist/state/gcs.js +7 -0
  323. package/dist/state/index.d.ts +15 -0
  324. package/dist/state/index.d.ts.map +1 -0
  325. package/dist/state/index.js +14 -0
  326. package/dist/state/locks.d.ts +105 -0
  327. package/dist/state/locks.d.ts.map +1 -0
  328. package/dist/state/locks.js +130 -0
  329. package/dist/state/object-store.d.ts +8 -0
  330. package/dist/state/object-store.d.ts.map +1 -0
  331. package/dist/state/object-store.js +7 -0
  332. package/dist/state/root-states.d.ts +131 -0
  333. package/dist/state/root-states.d.ts.map +1 -0
  334. package/dist/state/root-states.js +241 -0
  335. package/dist/state/s3.d.ts +21 -0
  336. package/dist/state/s3.d.ts.map +1 -0
  337. package/dist/state/s3.js +19 -0
  338. package/dist/state/store.d.ts +51 -0
  339. package/dist/state/store.d.ts.map +1 -0
  340. package/dist/state/store.js +185 -0
  341. package/dist/state-ops.d.ts +255 -0
  342. package/dist/state-ops.d.ts.map +1 -0
  343. package/dist/state-ops.js +305 -0
  344. package/dist/state-reads.d.ts +57 -0
  345. package/dist/state-reads.d.ts.map +1 -0
  346. package/dist/state-reads.js +104 -0
  347. package/dist/terragrunt/affected.d.ts.map +1 -1
  348. package/dist/terragrunt/affected.js +2 -1
  349. package/dist/used-sources.d.ts +54 -0
  350. package/dist/used-sources.d.ts.map +1 -0
  351. package/dist/used-sources.js +157 -0
  352. package/package.json +24 -4
  353. package/src/__fixtures__/ACCEPTANCE.md +69 -7
  354. package/src/__fixtures__/compose/apply-failed-in-app.jsonl +12 -0
  355. package/src/__fixtures__/compose/state-app.json +66 -0
  356. package/src/__fixtures__/compose/state-edge.json +40 -0
  357. package/src/__fixtures__/compose/state-net.json +58 -0
  358. package/src/__fixtures__/compose/three-app.plan.json +184 -0
  359. package/src/__fixtures__/compose/three-composed.plan.json +509 -0
  360. package/src/__fixtures__/compose/three-edge.plan.json +144 -0
  361. package/src/__fixtures__/compose/three-net.plan.json +174 -0
  362. package/src/__fixtures__/compose/unknown-composed.plan.json +228 -0
  363. package/src/__fixtures__/compose/working-after-apply.json +145 -0
  364. package/src/__fixtures__/config-blocks/app/main.tf +61 -0
  365. package/src/__fixtures__/config-blocks/app/modules/network/main.tf +4 -0
  366. package/src/__fixtures__/config-blocks/app-json/main.tf.json +39 -0
  367. package/src/__fixtures__/config-files/shadow/main.tf +3 -0
  368. package/src/__fixtures__/config-files/shadow/main.tofu +3 -0
  369. package/src/__fixtures__/config-files/shadow/other.tf +3 -0
  370. package/src/__fixtures__/config-files/tf/main.tf +11 -0
  371. package/src/__fixtures__/config-files/tf-json/main.tf.json +18 -0
  372. package/src/__fixtures__/config-files/tofu/main.tofu +11 -0
  373. package/src/__fixtures__/config-files/tofu-json/main.tofu.json +18 -0
  374. package/src/__fixtures__/config-files/tofu-only/main.tofu +3 -0
  375. package/src/__fixtures__/drift-record/README.md +16 -0
  376. package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
  377. package/src/__fixtures__/drift-rows/live-root-plan.json +70 -0
  378. package/src/__fixtures__/drift-rows/refresh-plan.json +61 -0
  379. package/src/__fixtures__/instance-forms/app/main.tf +110 -0
  380. package/src/__fixtures__/instance-forms/app/modules/svc/main.tf +3 -0
  381. package/src/__fixtures__/instance-vars/app/main.tf +52 -0
  382. package/src/__fixtures__/instance-vars/app/modules/app/main.tf +12 -0
  383. package/src/__fixtures__/instance-vars/app/modules/edge/main.tf +3 -0
  384. package/src/__fixtures__/instance-vars/app/terraform.tfvars +1 -0
  385. package/src/__fixtures__/live-module-keyed/live-graph.json +259 -0
  386. package/src/__fixtures__/live-module-keyed/live-plan.json +87 -0
  387. package/src/__fixtures__/live-module-keyed/root/estate.chdf.hcl +1 -0
  388. package/src/__fixtures__/live-module-keyed/root/main.tf +21 -0
  389. package/src/__fixtures__/live-module-keyed/root/modules/app/main.tf +17 -0
  390. package/src/__fixtures__/live-module-keyed/root/modules/edge/main.tf +7 -0
  391. package/src/__fixtures__/live-module-keyed/root/versions.tf +30 -0
  392. package/src/__fixtures__/live-module-keyed/show-state.json +146 -0
  393. package/src/__fixtures__/pr-loop/README.md +50 -0
  394. package/src/__fixtures__/pr-loop/chant.config.json +13 -0
  395. package/src/__fixtures__/pr-loop/estate.component.ts +10 -0
  396. package/src/__fixtures__/pr-loop/roots/a/main.tf +11 -0
  397. package/src/__fixtures__/pr-loop/roots/app/main.tf +19 -0
  398. package/src/__fixtures__/pr-loop/roots/b/main.tf +7 -0
  399. package/src/__fixtures__/pr-loop/roots/dns/main.tf +3 -0
  400. package/src/__fixtures__/pr-loop/roots/net/main.tf +7 -0
  401. package/src/__fixtures__/report/applied.show.json +51 -0
  402. package/src/__fixtures__/report/generate.ts +63 -0
  403. package/src/__fixtures__/report/plan.show.json +200 -0
  404. package/src/__fixtures__/report/tf-apply/change-set.json +170 -0
  405. package/src/__fixtures__/report/tf-apply/report.json +338 -0
  406. package/src/__fixtures__/report/tf-plan/change-set.json +170 -0
  407. package/src/__fixtures__/report/tf-plan/report.json +320 -0
  408. package/src/__fixtures__/three-cloud-azure.graph.json +290 -0
  409. package/src/__fixtures__/used-sources/root/extra.tofu +1 -0
  410. package/src/__fixtures__/used-sources/root/main.tf +31 -0
  411. package/src/__fixtures__/used-sources/root/modules/net/main.tf +14 -0
  412. package/src/__fixtures__/used-sources/root/modules/net/versions.tf.json +7 -0
  413. package/src/__fixtures__/used-sources/unit/terragrunt.hcl +3 -0
  414. package/src/applied-state.ts +52 -0
  415. package/src/backend-config.test.ts +105 -0
  416. package/src/backend-config.ts +133 -0
  417. package/src/behaviour/kinds.ts +4 -0
  418. package/src/behaviour/predict.ts +5 -2
  419. package/src/behaviour/reference-catalog.plugin.test.ts +65 -0
  420. package/src/behaviour/reference-catalog.ts +16 -5
  421. package/src/behaviour/request.ts +3 -2
  422. package/src/change-set-instances.test.ts +98 -0
  423. package/src/changed-roots.ts +14 -16
  424. package/src/ci-setup.ts +42 -0
  425. package/src/commands.ts +4 -3
  426. package/src/components/capability-plugin.test.ts +198 -19
  427. package/src/components/capability-plugin.ts +383 -35
  428. package/src/components/change-set-graph.e2e.test.ts +11 -5
  429. package/src/components/compose-group.test.ts +486 -0
  430. package/src/components/compose-group.ts +489 -0
  431. package/src/components/demo-composed-roots.e2e.test.ts +440 -0
  432. package/src/components/member-outputs.test.ts +76 -0
  433. package/src/components/placeholder-preview.test.ts +147 -0
  434. package/src/components/placeholder-preview.ts +257 -0
  435. package/src/components/pr-loop-compose.tofu.e2e.test.ts +363 -0
  436. package/src/components/pr-loop.tofu.test.ts +113 -57
  437. package/src/components/release-inputs.ts +69 -0
  438. package/src/components/trace-facts.test.ts +21 -0
  439. package/src/components/trace-facts.ts +27 -0
  440. package/src/compose/apply-events.test.ts +62 -0
  441. package/src/compose/apply-events.ts +100 -0
  442. package/src/compose/estate.choudoufu.e2e.test.ts +112 -0
  443. package/src/compose/estate.test.ts +421 -0
  444. package/src/compose/estate.ts +443 -0
  445. package/src/compose/hcl.ts +311 -0
  446. package/src/compose/module-address.ts +49 -0
  447. package/src/compose/root.test.ts +416 -0
  448. package/src/compose/root.ts +592 -0
  449. package/src/compose/run.test.ts +440 -0
  450. package/src/compose/run.tofu.test.ts +176 -0
  451. package/src/compose/run.ts +527 -0
  452. package/src/compose/slice.test.ts +184 -0
  453. package/src/compose/slice.ts +290 -0
  454. package/src/compose/state-address.ts +157 -0
  455. package/src/compose/state-merge.test.ts +131 -0
  456. package/src/compose/state-merge.ts +148 -0
  457. package/src/compose.test.ts +248 -0
  458. package/src/compose.ts +627 -0
  459. package/src/composites/terraform-apply-op.test.ts +9 -0
  460. package/src/composites/terraform-apply-op.ts +7 -3
  461. package/src/cone.ts +138 -0
  462. package/src/config-file-listers.test.ts +265 -0
  463. package/src/config.ts +44 -9
  464. package/src/cost-hold.ts +29 -0
  465. package/src/describe-resources.engine-facts.test.ts +411 -0
  466. package/src/describe-resources.live-module-keyed.test.ts +290 -0
  467. package/src/describe-resources.ts +416 -70
  468. package/src/drift-read.ts +284 -0
  469. package/src/drift-record.test.ts +223 -0
  470. package/src/drift-record.ts +455 -0
  471. package/src/drift-rows.test.ts +135 -0
  472. package/src/drift-rows.ts +137 -0
  473. package/src/exit-codes.test.ts +23 -0
  474. package/src/exit-codes.ts +59 -0
  475. package/src/hcl/config-blocks.test.ts +174 -0
  476. package/src/hcl/edges.ts +21 -1
  477. package/src/hcl/files.ts +234 -0
  478. package/src/hcl/instance-forms.test.ts +94 -0
  479. package/src/hcl/instances.test.ts +137 -0
  480. package/src/hcl/instances.ts +422 -0
  481. package/src/hcl/parse.test.ts +139 -1
  482. package/src/hcl/parse.ts +149 -16
  483. package/src/hcl/roots.ts +6 -0
  484. package/src/hcl/suppressions.ts +8 -2
  485. package/src/index.ts +79 -0
  486. package/src/lint/audit-catalog.ts +29 -3
  487. package/src/lint/audit-lineage.ts +14 -2
  488. package/src/lint/post-synth/fixtures/TF024/live-with-record-store/main.tf +18 -0
  489. package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/estate.chdf.hcl +1 -0
  490. package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/main.tf +10 -0
  491. package/src/lint/post-synth/fixtures/TF046/azurerm-no-resource-group/main.tf +15 -0
  492. package/src/lint/post-synth/fixtures/TF046/backend-config-only/main.tf +14 -0
  493. package/src/lint/post-synth/fixtures/TF046/derived-s3/backend.tf +7 -0
  494. package/src/lint/post-synth/fixtures/TF046/derived-s3/main.tf +9 -0
  495. package/src/lint/post-synth/fixtures/TF046/explicit-local/main.tf +16 -0
  496. package/src/lint/post-synth/fixtures/TF046/explicit-s3-beside-local-backend/main.tf +15 -0
  497. package/src/lint/post-synth/fixtures/TF046/implied-local/main.tf +9 -0
  498. package/src/lint/post-synth/fixtures/TF046/sidecar-implied/estate.chdf.hcl +1 -0
  499. package/src/lint/post-synth/fixtures/TF046/sidecar-implied/main.tf +5 -0
  500. package/src/lint/post-synth/fixtures/TF047/clear/main.tf +12 -0
  501. package/src/lint/post-synth/fixtures/TF047/refused/main.tf +12 -0
  502. package/src/lint/post-synth/fixtures/TF047/unknown-module/main.tf +12 -0
  503. package/src/lint/post-synth/fixtures/TF047/unknown-version/main.tf +12 -0
  504. package/src/lint/post-synth/index.ts +4 -0
  505. package/src/lint/post-synth/record-store.ts +122 -0
  506. package/src/lint/post-synth/tf001.ts +2 -2
  507. package/src/lint/post-synth/tf024.test.ts +26 -5
  508. package/src/lint/post-synth/tf024.ts +105 -22
  509. package/src/lint/post-synth/tf046.test.ts +137 -0
  510. package/src/lint/post-synth/tf046.ts +204 -0
  511. package/src/lint/post-synth/tf047.test.ts +56 -0
  512. package/src/lint/post-synth/tf047.ts +114 -0
  513. package/src/live-plan-reasons.ts +54 -0
  514. package/src/lock-rows.test.ts +70 -0
  515. package/src/lock-rows.ts +82 -0
  516. package/src/lock-timeout.ts +34 -0
  517. package/src/lsp/completions.test.ts +1 -1
  518. package/src/lsp/option-keys.ts +2 -0
  519. package/src/module-catalog/index.test.ts +93 -0
  520. package/src/module-catalog/index.ts +159 -0
  521. package/src/module-catalog/refresh-cli.ts +68 -0
  522. package/src/module-catalog/static-tier.ts +1659 -0
  523. package/src/module-catalog/types.ts +88 -0
  524. package/src/op/activities/choudoufu-plan-set-op.test.ts +111 -0
  525. package/src/op/activities/index.ts +9 -0
  526. package/src/op/activities/live-detect.ts +55 -26
  527. package/src/op/activities/pin-rollout.ts +3 -0
  528. package/src/op/activities/registry.test.ts +2 -1
  529. package/src/op/activities/terraform.test.ts +55 -0
  530. package/src/op/activities/terraform.ts +312 -27
  531. package/src/op/activity-contracts.test.ts +1 -0
  532. package/src/op/activity-contracts.ts +24 -1
  533. package/src/op/builders.ts +14 -0
  534. package/src/op-wave-step.test.ts +109 -0
  535. package/src/pin/__fixtures__/consumers/live/dev/main.tf +4 -0
  536. package/src/pin/__fixtures__/consumers/live/prod/main.tf +21 -0
  537. package/src/pin/__fixtures__/consumers/units/vpc/terragrunt.hcl +7 -0
  538. package/src/pin/bundle.test.ts +2 -0
  539. package/src/pin/consumers.test.ts +57 -0
  540. package/src/pin/consumers.ts +95 -0
  541. package/src/pin/edit.ts +30 -0
  542. package/src/pin/rollout.ts +16 -11
  543. package/src/plan-shape.test.ts +148 -0
  544. package/src/plan-shape.ts +128 -0
  545. package/src/plugin.ts +39 -19
  546. package/src/registry/__fixtures__/docs/documented/.terraform-docs.yml +3 -0
  547. package/src/registry/__fixtures__/docs/documented/README.md +1 -0
  548. package/src/registry/__fixtures__/docs/documented/main.tf +8 -0
  549. package/src/registry/__fixtures__/docs/json/main.tf.json +14 -0
  550. package/src/registry/__fixtures__/docs/vpc/README.md +3 -0
  551. package/src/registry/__fixtures__/docs/vpc/examples/complete/main.tf +5 -0
  552. package/src/registry/__fixtures__/docs/vpc/examples/simple/README.md +1 -0
  553. package/src/registry/__fixtures__/docs/vpc/examples/simple/main.tf +4 -0
  554. package/src/registry/__fixtures__/docs/vpc/main.tf +14 -0
  555. package/src/registry/__fixtures__/docs/vpc/outputs.tf +9 -0
  556. package/src/registry/__fixtures__/docs/vpc/variables.tf +16 -0
  557. package/src/registry/__fixtures__/proxied-root/main.tf +12 -0
  558. package/src/registry/address.ts +100 -0
  559. package/src/registry/catalog-read.ts +56 -0
  560. package/src/registry/deprecated.test.ts +139 -0
  561. package/src/registry/deprecated.ts +76 -0
  562. package/src/registry/docs.test.ts +140 -0
  563. package/src/registry/docs.ts +299 -0
  564. package/src/registry/edge/bundle.test.ts +50 -0
  565. package/src/registry/edge/edge.test.ts +176 -0
  566. package/src/registry/edge/edge.ts +211 -0
  567. package/src/registry/edge/index.ts +10 -0
  568. package/src/registry/edge/lambda-edge.ts +127 -0
  569. package/src/registry/edge/sigv4-web.ts +79 -0
  570. package/src/registry/edge/token-source.test.ts +258 -0
  571. package/src/registry/edge/token-source.ts +169 -0
  572. package/src/registry/edge/worker.ts +61 -0
  573. package/src/registry/handler.ts +89 -0
  574. package/src/registry/headers-file.ts +61 -0
  575. package/src/registry/index.ts +31 -0
  576. package/src/registry/mirror-paths.ts +10 -0
  577. package/src/registry/mirror.test.ts +198 -0
  578. package/src/registry/mirror.ts +395 -0
  579. package/src/registry/proxies.test.ts +153 -0
  580. package/src/registry/proxies.ts +132 -0
  581. package/src/registry/reader.ts +225 -0
  582. package/src/registry/registry.test.ts +262 -0
  583. package/src/registry/semver.ts +34 -0
  584. package/src/registry/serve.ts +82 -0
  585. package/src/registry/source-forms.test.ts +87 -0
  586. package/src/registry/source-forms.ts +216 -0
  587. package/src/registry/targets/artifactory.test.ts +248 -0
  588. package/src/registry/targets/artifactory.ts +257 -0
  589. package/src/registry/targets/fake-artifactory.ts +158 -0
  590. package/src/registry/targets/fake-gitlab.ts +161 -0
  591. package/src/registry/targets/fake-hcp.ts +233 -0
  592. package/src/registry/targets/fake-http.ts +97 -0
  593. package/src/registry/targets/fake-nexus.ts +152 -0
  594. package/src/registry/targets/gitlab.test.ts +208 -0
  595. package/src/registry/targets/gitlab.ts +223 -0
  596. package/src/registry/targets/hcp.test.ts +230 -0
  597. package/src/registry/targets/hcp.ts +360 -0
  598. package/src/registry/targets/hosted.ts +117 -0
  599. package/src/registry/targets/index.ts +17 -0
  600. package/src/registry/targets/module-target.ts +131 -0
  601. package/src/registry/targets/nexus.test.ts +220 -0
  602. package/src/registry/targets/nexus.ts +314 -0
  603. package/src/registry/targets/zip.test.ts +65 -0
  604. package/src/registry/targets/zip.ts +287 -0
  605. package/src/registry/writer.ts +155 -0
  606. package/src/report.test.ts +82 -1
  607. package/src/report.ts +31 -54
  608. package/src/signal-only-root.test.ts +72 -0
  609. package/src/skills/chant-terraform.md +1 -1
  610. package/src/state/azure-blob.ts +8 -0
  611. package/src/state/backend-verdict.test.ts +187 -0
  612. package/src/state/backend.test.ts +127 -0
  613. package/src/state/backend.ts +488 -0
  614. package/src/state/exec.ts +111 -0
  615. package/src/state/gcs.ts +7 -0
  616. package/src/state/index.ts +15 -0
  617. package/src/state/locks.test.ts +84 -0
  618. package/src/state/locks.ts +201 -0
  619. package/src/state/object-store.ts +7 -0
  620. package/src/state/root-states-floci.e2e.test.ts +66 -0
  621. package/src/state/root-states.test.ts +462 -0
  622. package/src/state/root-states.ts +309 -0
  623. package/src/state/s3.ts +21 -0
  624. package/src/state/store.ts +225 -0
  625. package/src/state-ops.test.ts +182 -0
  626. package/src/state-ops.ts +462 -0
  627. package/src/state-reads.ts +116 -0
  628. package/src/terragrunt/affected.ts +2 -1
  629. package/src/used-sources.test.ts +75 -0
  630. package/src/used-sources.ts +204 -0
  631. package/src/workspace-kinds.test.ts +4 -17
  632. package/workspace-kinds.json +1 -24
  633. package/dist/workspace-member.d.ts +0 -30
  634. package/dist/workspace-member.d.ts.map +0 -1
  635. package/dist/workspace-member.js +0 -91
  636. package/schemas/pulumi.schema.json +0 -34
  637. package/src/testdata/pulumi-member/Pulumi.yaml +0 -2
  638. package/src/testdata/pulumi-member/stack-export.json +0 -53
  639. package/src/testdata/pulumi-unexported/Pulumi.yaml +0 -2
  640. package/src/workspace-member.test.ts +0 -89
  641. package/src/workspace-member.ts +0 -126
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Where a repo calls its modules (chant#4599, terragucci#1289 bundle B): one
3
+ * entry per module call in the roots given, Terragrunt units included, read
4
+ * from the source files with chant's HCL parse and never from a plan, so the
5
+ * scan runs in a check job before anything is planned.
6
+ *
7
+ * Each call carries its root, file and block path, the source as written,
8
+ * the module it names with the pin taken out and normalised
9
+ * ({@link normalizeModuleSource}), and the pin `readModulePin` (./source.ts)
10
+ * reads. A local call (`./`, `../`) names no published module and is left
11
+ * out. The release catalog lists these as a version's consumers, and
12
+ * `deprecatedPins` (../registry/deprecated.ts) checks them against it.
13
+ *
14
+ * The `terragucci_module_pin` metric keeps reading the plan; this is the
15
+ * source-side view of the same calls. The normal form is chant#3924's
16
+ * (../registry/source-forms.ts), shared with `usedSources` (../sources.ts).
17
+ */
18
+ import { join, relative } from "node:path";
19
+ import { MODULE_TYPE, TERRAGRUNT_SOURCE_TYPE, parseTerraformRootDir } from "../hcl/parse.js";
20
+ import { normalizeModuleSource, PUBLIC_REGISTRY_HOST } from "../registry/source-forms.js";
21
+ import { readModulePin } from "./source.js";
22
+ export { normalizeModuleSource, PUBLIC_REGISTRY_HOST };
23
+ /** A source names a local directory, not a published module. */
24
+ export function isLocalSource(source) {
25
+ return source.startsWith("./") || source.startsWith("../");
26
+ }
27
+ function str(v) {
28
+ return typeof v === "string" ? v : undefined;
29
+ }
30
+ /**
31
+ * Every module call in `roots` (directories from `repo`), sorted by root,
32
+ * file and address. A root whose files cannot be parsed throws, naming the
33
+ * root, so a check job fails loudly instead of listing fewer consumers.
34
+ */
35
+ export async function moduleConsumers(repo, roots, parser) {
36
+ const out = [];
37
+ for (const root of [...new Set(roots)].sort()) {
38
+ const dir = join(repo, root);
39
+ const rel = relative(repo, dir).split("\\").join("/") || ".";
40
+ let entities;
41
+ try {
42
+ entities = [...(await parseTerraformRootDir(dir, "consumers", parser)).values()];
43
+ }
44
+ catch (e) {
45
+ throw new Error(`${rel}: ${e.message}`);
46
+ }
47
+ for (const e of entities) {
48
+ if (e.entityType !== MODULE_TYPE && e.entityType !== TERRAGRUNT_SOURCE_TYPE)
49
+ continue;
50
+ const source = str(e.props.body.source);
51
+ if (source === undefined || isLocalSource(source))
52
+ continue;
53
+ const version = e.entityType === MODULE_TYPE ? str(e.props.body.version) : undefined;
54
+ const pin = readModulePin(source, version);
55
+ out.push({
56
+ root: rel,
57
+ file: rel === "." ? e.props.file : `${rel}/${e.props.file}`,
58
+ address: e.props.address,
59
+ kind: e.entityType === MODULE_TYPE ? "terraform" : "terragrunt",
60
+ source,
61
+ module: normalizeModuleSource(pin.module),
62
+ pin: pin.pin,
63
+ at: pin.at,
64
+ ...(pin.param ? { param: pin.param } : {}),
65
+ ...(pin.unpinned ? { unpinned: pin.unpinned } : {}),
66
+ });
67
+ }
68
+ }
69
+ return out.sort((a, b) => a.root.localeCompare(b.root) || a.file.localeCompare(b.file) || a.address.localeCompare(b.address));
70
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/pin/edit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAGjD,4FAA4F;AAC5F,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,yGAAyG;IACzG,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AA2CD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,CAgDxH"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/pin/edit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAIjD,4FAA4F;AAC5F,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,yGAAyG;IACzG,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AA2CD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,CAiDxH"}
package/dist/pin/edit.js CHANGED
@@ -22,6 +22,7 @@
22
22
  * module (terragucci's `tf-rollout` stage, #3421) decides how it is loaded.
23
23
  */
24
24
  import { movePin } from "./source.js";
25
+ import { isJsonConfigFile, jsonConfigTree } from "../hcl/files.js";
25
26
  import { escapeHcl, scanBlocks, unescapeHcl } from "./scan.js";
26
27
  /** Whether a file is read as a Terragrunt configuration rather than a `.tf` file. */
27
28
  export function isTerragruntFile(file) {
@@ -58,6 +59,8 @@ function sites(tree, blocks, terragrunt) {
58
59
  * is reported with its reason and left as it was.
59
60
  */
60
61
  export async function editPins(text, file, request, parser) {
62
+ if (isJsonConfigFile(file))
63
+ return jsonPins(text, file, request);
61
64
  const terragrunt = isTerragruntFile(file);
62
65
  const tree = (await parser.parse(file, text));
63
66
  const blocks = scanBlocks(text, file);
@@ -116,3 +119,35 @@ export async function editPins(text, file, request, parser) {
116
119
  function rewriteLiteral(raw, was, value) {
117
120
  return raw === was ? value : escapeHcl(value);
118
121
  }
122
+ /**
123
+ * The calls of the module in a `.tf.json` or `.tofu.json` file (chant#4457).
124
+ * The pin edit splices HCL text and has no splice for JSON syntax, so a call
125
+ * that would move is refused by name and the file is left as it is; a call
126
+ * already at the new pin, or at another one, reads as it does in HCL.
127
+ */
128
+ function jsonPins(text, file, request) {
129
+ const calls = [];
130
+ let tree;
131
+ try {
132
+ tree = jsonConfigTree(text);
133
+ }
134
+ catch (err) {
135
+ return { content: text, calls: [{ outcome: "refused", reason: `not JSON the binary reads: ${err instanceof Error ? err.message : String(err)}`, file, call: "(file)" }] };
136
+ }
137
+ const modules = (tree.module && typeof tree.module === "object" ? tree.module : {});
138
+ for (const [name, bodies] of Object.entries(modules)) {
139
+ for (const body of Array.isArray(bodies) ? bodies : []) {
140
+ if (typeof body.source !== "string")
141
+ continue;
142
+ const move = movePin(body.source, typeof body.version === "string" ? body.version : undefined, request);
143
+ if (!move)
144
+ continue;
145
+ const at = { file, call: `module.${name}` };
146
+ if (move.outcome === "moved")
147
+ calls.push({ outcome: "refused", reason: "the call is in Terraform's JSON syntax, which the pin edit does not write; move its pin by hand", ...at });
148
+ else
149
+ calls.push({ ...move, ...at });
150
+ }
151
+ }
152
+ return { content: text, calls };
153
+ }
@@ -70,6 +70,8 @@ export interface PinRolloutOptions extends PinRequest {
70
70
  editTs?: TsPinEditor;
71
71
  /** Markdown appended to a wave's PR body, such as the grouped plan summary of #3188 once a caller has the wave's plans. */
72
72
  planSummary?: (wave: PinWave) => Promise<string | undefined>;
73
+ /** The binary the roots run: `tofu` or `choudoufu` reads `.tofu` files too (chant#4457). Default `terraform`. */
74
+ binary?: string;
73
75
  }
74
76
  /** Where one root's pin stood on the base branch. */
75
77
  export interface PinRootState {
@@ -1 +1 @@
1
- {"version":3,"file":"rollout.d.ts","sourceRoot":"","sources":["../../src/pin/rollout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rollout.d.ts","sourceRoot":"","sources":["../../src/pin/rollout.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,7 @@ import { editPins } from "./edit.js";
45
45
  import { checkPinRequest, moduleOf } from "./source.js";
46
46
  import { planPinWaves, restrictWaves, terragruntDependencies } from "./waves.js";
47
47
  import { ghPinForge } from "./forge.js";
48
+ import { isConfigFileFor, listConfigFilesSafe } from "../hcl/files.js";
48
49
  const execFileAsync = /* @__PURE__ */ promisify(execFile);
49
50
  // `gh pr list/create` and `gh api repos/{owner}/{repo}/...` name no host, so
50
51
  // a `gh` call is told the job's forge or `origin`'s host (core's `ghHostEnv`,
@@ -73,22 +74,24 @@ function slug(value) {
73
74
  export function pinWaveBranch(request, wave) {
74
75
  return `chant/pin/${slug(request.module)}/${slug(request.to)}/wave-${wave}`;
75
76
  }
76
- /** The files the pin edit reads in a root directory: its `.tf` files and its `terragrunt.hcl`. */
77
- function rootFiles(worktree, root) {
77
+ /**
78
+ * The files the pin edit reads in a root directory: the configuration files
79
+ * the root's binary reads (the lexicon's one lister, chant#4457) and its
80
+ * `terragrunt.hcl`.
81
+ */
82
+ function rootFiles(worktree, root, binary) {
78
83
  const dir = join(worktree, root);
79
84
  if (!existsSync(dir))
80
85
  return [];
81
- return readdirSync(dir)
82
- .filter((f) => f.endsWith(".tf") || f === "terragrunt.hcl")
83
- .sort()
84
- .map((f) => posix.join(root, f));
86
+ const names = [...listConfigFilesSafe(dir, binary), ...(existsSync(join(dir, "terragrunt.hcl")) ? ["terragrunt.hcl"] : [])];
87
+ return names.sort().map((f) => posix.join(root, f));
85
88
  }
86
- /** Every directory under the worktree with a `.tf` file or a `terragrunt.hcl`. */
87
- function candidateRoots(worktree) {
89
+ /** Every directory under the worktree with a configuration file the binary reads, or a `terragrunt.hcl`. */
90
+ function candidateRoots(worktree, binary) {
88
91
  const out = [];
89
92
  const walk = (rel) => {
90
93
  const entries = readdirSync(join(worktree, rel), { withFileTypes: true });
91
- if (entries.some((e) => e.isFile() && (e.name.endsWith(".tf") || e.name === "terragrunt.hcl")))
94
+ if (entries.some((e) => e.isFile() && (isConfigFileFor(e.name, binary) || e.name === "terragrunt.hcl")))
92
95
  out.push(rel || ".");
93
96
  for (const e of entries)
94
97
  if (e.isDirectory() && !SKIP_DIRS.has(e.name))
@@ -108,7 +111,7 @@ async function editRoot(worktree, root, request, options) {
108
111
  }
109
112
  }
110
113
  else {
111
- files = rootFiles(worktree, root.root);
114
+ files = rootFiles(worktree, root.root, options.binary);
112
115
  }
113
116
  for (const file of files) {
114
117
  const path = join(worktree, file);
@@ -216,7 +219,7 @@ export async function runPinRollout(options) {
216
219
  await run("git", ["worktree", "add", "--quiet", "--detach", worktree, baseRef], repo);
217
220
  try {
218
221
  // 1. Every root's pin on the base branch.
219
- const declared = (options.roots ?? candidateRoots(worktree).map((root) => ({ root }))).map((r) => ({
222
+ const declared = (options.roots ?? candidateRoots(worktree, options.binary).map((root) => ({ root }))).map((r) => ({
220
223
  ...r,
221
224
  root: dirOf(r.root),
222
225
  ...(r.dependsOn ? { dependsOn: r.dependsOn.map(dirOf) } : {}),
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The plan shape of a terraform-family root (#4436): what `terraform show
3
+ * -json` says a plan does, without the values, in the form core's
4
+ * `coveredRound` compares (#4419). `terraform-apply`'s `plan` returns it, and
5
+ * terragucci calls it for the plan JSON of a note (terragucci#1268).
6
+ *
7
+ * Like `./change-set`, this module imports only `@intentius/chant` subpaths,
8
+ * never the lexicon's entry point.
9
+ */
10
+ import type { PlanShape } from "@intentius/chant/components/covered-round";
11
+ export interface TerraformPlanShapeOptions {
12
+ /** The inputs the plan was made without, as `<component>.<output>`. */
13
+ unknownInputs?: string[];
14
+ /** The inputs the plan read with a value, by reference. */
15
+ knownInputs?: Record<string, unknown>;
16
+ }
17
+ /**
18
+ * The shape of `planJson` (`terraform show -json`, from terraform, tofu or
19
+ * choudoufu) for `member`.
20
+ *
21
+ * One entry per `resource_changes` item that is not `no-op` or `read`.
22
+ * `logicalId` is the address, with `#<deposed>` for a deposed object. `type`
23
+ * is the resource type. `properties` are the top-level attributes that differ
24
+ * between `before` and `after` (on a create, those the plan sets or leaves
25
+ * unknown), and `unknown` the ones `after_unknown` marks, so `unknown` is
26
+ * within `properties`. A delete has no properties. Values never enter it, so
27
+ * a sensitive attribute is only a name.
28
+ */
29
+ export declare function terraformPlanShape(planJson: unknown, member: string, options?: TerraformPlanShapeOptions): PlanShape;
30
+ //# sourceMappingURL=plan-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-shape.d.ts","sourceRoot":"","sources":["../src/plan-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAoC,MAAM,2CAA2C,CAAC;AAuD7G,MAAM,WAAW,yBAAyB;IACxC,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,SAAS,CA2CxH"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * The plan shape of a terraform-family root (#4436): what `terraform show
3
+ * -json` says a plan does, without the values, in the form core's
4
+ * `coveredRound` compares (#4419). `terraform-apply`'s `plan` returns it, and
5
+ * terragucci calls it for the plan JSON of a note (terragucci#1268).
6
+ *
7
+ * Like `./change-set`, this module imports only `@intentius/chant` subpaths,
8
+ * never the lexicon's entry point.
9
+ */
10
+ import { normalizePlanShape } from "@intentius/chant/components/covered-round";
11
+ import { actionFor } from "./change-set.js";
12
+ const isObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
13
+ /** Whether an `after_unknown` value marks anything under it unknown. */
14
+ function marks(v) {
15
+ if (v === true)
16
+ return true;
17
+ if (Array.isArray(v))
18
+ return v.some(marks);
19
+ if (isObject(v))
20
+ return Object.values(v).some(marks);
21
+ return false;
22
+ }
23
+ function sameJson(a, b) {
24
+ if (a === b)
25
+ return true;
26
+ if (Array.isArray(a) && Array.isArray(b))
27
+ return a.length === b.length && a.every((x, i) => sameJson(x, b[i]));
28
+ if (isObject(a) && isObject(b)) {
29
+ const ka = Object.keys(a);
30
+ return ka.length === Object.keys(b).length && ka.every((k) => k in b && sameJson(a[k], b[k]));
31
+ }
32
+ return false;
33
+ }
34
+ /** Whether the value at `path` in an `after_unknown` tree is unknown: `true` at the path or on a prefix of it. */
35
+ function unknownAt(tree, path) {
36
+ let at = tree;
37
+ for (const step of path) {
38
+ if (at === true)
39
+ return true;
40
+ if (Array.isArray(at) && typeof step === "number")
41
+ at = at[step];
42
+ else if (isObject(at) && typeof step === "string")
43
+ at = at[step];
44
+ else
45
+ return false;
46
+ }
47
+ return marks(at);
48
+ }
49
+ /**
50
+ * How a change replaces its resource. A `replace_paths` entry names an
51
+ * attribute whose change forces it. When every such attribute is unknown
52
+ * after apply, the plan cannot say the value will differ, so the replacement
53
+ * is `conditional`; one with a known forcing attribute is `true`. A delete
54
+ * and create pair with no `replace_paths` (a tainted object, `-replace`) is
55
+ * `true`. An update with none replaces nothing (`false`); a create or delete
56
+ * has no replacement to state.
57
+ */
58
+ function replacementFor(change, action) {
59
+ const paths = (Array.isArray(change.replace_paths) ? change.replace_paths : []).filter(Array.isArray);
60
+ if (paths.length > 0)
61
+ return paths.every((p) => unknownAt(change.after_unknown, p)) ? "conditional" : "true";
62
+ if (action === "replace")
63
+ return "true";
64
+ if (action === "update")
65
+ return "false";
66
+ return undefined;
67
+ }
68
+ /**
69
+ * The shape of `planJson` (`terraform show -json`, from terraform, tofu or
70
+ * choudoufu) for `member`.
71
+ *
72
+ * One entry per `resource_changes` item that is not `no-op` or `read`.
73
+ * `logicalId` is the address, with `#<deposed>` for a deposed object. `type`
74
+ * is the resource type. `properties` are the top-level attributes that differ
75
+ * between `before` and `after` (on a create, those the plan sets or leaves
76
+ * unknown), and `unknown` the ones `after_unknown` marks, so `unknown` is
77
+ * within `properties`. A delete has no properties. Values never enter it, so
78
+ * a sensitive attribute is only a name.
79
+ */
80
+ export function terraformPlanShape(planJson, member, options = {}) {
81
+ const plan = isObject(planJson) ? planJson : {};
82
+ const raw = Array.isArray(plan.resource_changes) ? plan.resource_changes : [];
83
+ const entries = [];
84
+ for (const r of raw) {
85
+ const rc = isObject(r) ? r : {};
86
+ const change = isObject(rc.change) ? rc.change : {};
87
+ const action = actionFor(change.actions);
88
+ if (action === "no-op" || action === "read")
89
+ continue;
90
+ const address = String(rc.address ?? "");
91
+ const before = isObject(change.before) ? change.before : {};
92
+ const after = isObject(change.after) ? change.after : {};
93
+ const afterUnknown = isObject(change.after_unknown) ? change.after_unknown : {};
94
+ const properties = [];
95
+ const unknown = [];
96
+ if (action !== "delete" && action !== "forget") {
97
+ for (const k of new Set([...Object.keys(before), ...Object.keys(after), ...Object.keys(afterUnknown)])) {
98
+ const isUnknown = marks(afterUnknown[k]);
99
+ const differs = action === "create"
100
+ ? isUnknown || (after[k] !== undefined && after[k] !== null)
101
+ : isUnknown || !sameJson(before[k] ?? null, after[k] ?? null);
102
+ if (!differs)
103
+ continue;
104
+ properties.push(k);
105
+ if (isUnknown)
106
+ unknown.push(k);
107
+ }
108
+ }
109
+ const replacement = replacementFor(change, action);
110
+ entries.push({
111
+ logicalId: typeof rc.deposed === "string" ? `${address}#${rc.deposed}` : address,
112
+ action,
113
+ ...(replacement ? { replacement } : {}),
114
+ ...(typeof rc.type === "string" ? { type: rc.type } : {}),
115
+ properties,
116
+ unknown,
117
+ });
118
+ }
119
+ return normalizePlanShape({
120
+ member,
121
+ entries,
122
+ unknownInputs: options.unknownInputs ?? [],
123
+ ...(options.knownInputs ? { knownInputs: options.knownInputs } : {}),
124
+ });
125
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAoElF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,aAkS7B,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAsElF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,aAqT7B,CAAC"}
package/dist/plugin.js CHANGED
@@ -1,4 +1,4 @@
1
- import { lastMemberReport, readPulumiMember, setLastMemberReport } from "./workspace-member.js";
1
+ import { terraformCiSetup } from "./ci-setup.js";
2
2
  import { terraformBehaviourKinds } from "./behaviour/kinds.js";
3
3
  import { createSkillsLoader } from "@intentius/chant/lexicon-plugin-helpers";
4
4
  import { terraformSerializer } from "./serializer.js";
@@ -8,7 +8,7 @@ import { withCallersChain } from "./lint/post-synth/scope.js";
8
8
  import { terraformAuditCatalog } from "./lint/audit-catalog.js";
9
9
  import { completions } from "./lsp/completions.js";
10
10
  import { hover } from "./lsp/hover.js";
11
- import { terraformConfigSchema } from "./config.js";
11
+ import { ownRoots, terraformConfigSchema } from "./config.js";
12
12
  import { renderTerraformRoots } from "./hcl/roots.js";
13
13
  import { existsSync } from "node:fs";
14
14
  import { join } from "node:path";
@@ -17,6 +17,7 @@ import { descendModules } from "./hcl/descend.js";
17
17
  import { TERRAFORM_STATE_OWNERSHIP_KEYS } from "./state-ownership.js";
18
18
  import { terraformCommands } from "./commands.js";
19
19
  import { terraformCapabilityPack } from "./capabilities/adapter.js";
20
+ import { TERRAFORM_REFERENCE_CATALOG } from "./behaviour/reference-catalog.js";
20
21
  const loadSkills = createSkillsLoader(import.meta.url, [
21
22
  {
22
23
  file: "chant-terraform.md",
@@ -69,8 +70,14 @@ export const terraformPlugin = {
69
70
  behaviourKinds: terraformBehaviourKinds,
70
71
  name: "terraform",
71
72
  capabilityPack: terraformCapabilityPack,
73
+ // Keyed by provider type (#2360); see its module doc for which nodes it reads (#4535).
74
+ referenceCatalog: TERRAFORM_REFERENCE_CATALOG,
72
75
  serializer: terraformSerializer,
73
76
  configSchema: terraformConfigSchema,
77
+ // #4550: the engine install lines for the pull request pipeline's default image.
78
+ ciSetup(ctx) {
79
+ return terraformCiSetup(ctx);
80
+ },
74
81
  // ── Required lifecycle methods ────────────────────────────────
75
82
  async generate(options) {
76
83
  const { generate } = await import("./codegen/generate.js");
@@ -120,6 +127,17 @@ export const terraformPlugin = {
120
127
  const { describeResources } = await import("./describe-resources.js");
121
128
  return describeResources(options);
122
129
  },
130
+ /**
131
+ * Each root's drift, as drift-record stream lines (behold#995): a stock
132
+ * root through its state or a plan, a live root through `live-plan` (and a
133
+ * plan), one resource through `live-plan -resource`. `chant workspace
134
+ * drift` reaches it through `chant lifecycle drift` in a member's reader
135
+ * project. See `./drift-read.ts`.
136
+ */
137
+ async readDrift(options) {
138
+ const { readTerraformDrift } = await import("./drift-read.js");
139
+ return readTerraformDrift(options);
140
+ },
123
141
  /**
124
142
  * The prediction, for whichever estate `options.from` names (#2495). The
125
143
  * producer is `predictTerraformBehaviour` and this is its second caller, not
@@ -156,15 +174,9 @@ export const terraformPlugin = {
156
174
  * project root, which is what relative `dir` paths resolve against.
157
175
  */
158
176
  async buildRoots(ctx) {
159
- setLastMemberReport(undefined);
160
177
  const namespace = ctx.config.terraform;
161
- // A pulumi workspace member (#3179): its checked-in stack export, never the program.
162
- if (namespace?.pulumiMember) {
163
- const read = readPulumiMember({ member: namespace.pulumiMember });
164
- setLastMemberReport(read.report);
165
- return { entities: read.entities, warnings: read.warnings };
166
- }
167
- const roots = namespace?.roots ?? {};
178
+ // A `signalOnly` root (#4484) feeds change detection only, so it builds no entities here.
179
+ const roots = ownRoots(namespace?.roots);
168
180
  if (Object.keys(roots).length === 0)
169
181
  return { entities: new Map(), warnings: [] };
170
182
  return renderTerraformRoots({
@@ -175,10 +187,6 @@ export const terraformPlugin = {
175
187
  moduleRoot: namespace?.moduleRoot,
176
188
  });
177
189
  },
178
- graphMeta() {
179
- const report = lastMemberReport();
180
- return report ? { pulumiMember: report } : undefined;
181
- },
182
190
  /** `chant terraform pin-rollout` (#3189). */
183
191
  commands() {
184
192
  return terraformCommands;
@@ -186,14 +194,16 @@ export const terraformPlugin = {
186
194
  /**
187
195
  * The `terraform.roots` a change touched (#3183): a changed file in the
188
196
  * root's directory, in a local module it calls, or one of its var files.
189
- * See `./changed-roots.ts`.
197
+ * See `./changed-roots.ts`. Every root counts, a `signalOnly` one too
198
+ * (#4484): that is what it is declared for.
190
199
  */
191
200
  async changedUnits(ctx) {
192
- const roots = ctx.config.terraform?.roots ?? {};
201
+ const tf = ctx.config.terraform;
202
+ const roots = tf?.roots ?? {};
193
203
  if (Object.keys(roots).length === 0)
194
204
  return [];
195
205
  const { changedRoots } = await import("./changed-roots.js");
196
- return changedRoots(ctx.projectRoot, roots, ctx.changedFiles);
206
+ return changedRoots(ctx.projectRoot, roots, ctx.changedFiles, tf?.binary);
197
207
  },
198
208
  lintRules() {
199
209
  return rules;
@@ -263,13 +273,22 @@ export const terraformPlugin = {
263
273
  // A local audit knows the root's directory, so it can say whether the
264
274
  // lock file is beside the `.tf` files (TF040); a fetched one cannot.
265
275
  const lockFile = input?.dir !== undefined ? existsSync(join(input.dir, LOCK_FILENAME)) : undefined;
266
- const entities = await parseTerraformRootContent(content, root, undefined, lockFile === undefined ? undefined : { lockFile });
276
+ // An audit has no `terraform.binary` to follow (chant#4457). A root
277
+ // that carries a `.tofu` file is written for OpenTofu, so it is read
278
+ // as a tofu root; any other is read as terraform, the config default.
279
+ const binary = /^# file: .*\.tofu(\.json)?\s*$/m.test(content) ? "tofu" : undefined;
280
+ const modeOptions = {
281
+ ...(binary !== undefined ? { binary } : {}),
282
+ ...(lockFile !== undefined ? { lockFile } : {}),
283
+ };
284
+ const entities = await parseTerraformRootContent(content, root, undefined, Object.keys(modeOptions).length > 0 ? modeOptions : undefined);
267
285
  if (input?.dir === undefined)
268
286
  return entities;
269
287
  const { entities: children } = await descendModules(entities, {
270
288
  dir: input.dir,
271
289
  root,
272
290
  projectRoot: input.baseDir ?? input.dir,
291
+ ...(binary !== undefined ? { modeOptions: { binary } } : {}),
273
292
  });
274
293
  for (const [key, entity] of children)
275
294
  entities.set(key, entity);
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Where a module sits in a Terraform module registry, and how a registry
3
+ * source (`<host>/<namespace>/<name>/<system>`) is split into those parts.
4
+ * Lifted from terragucci's `publish/registry.ts` (18f6431595) for chant#4565.
5
+ * No Node imports, so an edge function can carry it.
6
+ */
7
+ export declare const DISCOVERY = ".well-known/terraform.json";
8
+ export declare const MODULES_V1 = "/v1/modules/";
9
+ export declare const DEFAULT_SYSTEM = "generic";
10
+ /** A registry namespace or module name: letters, digits, `-` and `_`, starting and ending on a letter or digit. */
11
+ export declare const REGISTRY_NAME: RegExp;
12
+ /** A registry module's system (its target provider): lower-case letters and digits. */
13
+ export declare const REGISTRY_SYSTEM: RegExp;
14
+ /** Where a module is in the registry. */
15
+ export interface RegistryAddress {
16
+ namespace: string;
17
+ name: string;
18
+ system: string;
19
+ /** `<host>/<namespace>/<name>/<system>`, the source a root writes. */
20
+ source: string;
21
+ /** The module's directory under the registry root: `v1/modules/<namespace>/<name>/<system>`. */
22
+ path: string;
23
+ }
24
+ /** What placing a module needs from a registry's settings. */
25
+ export interface RegistryPlacement {
26
+ /** The registry's base URL; its host is what sources name. */
27
+ url: string;
28
+ namespace: string;
29
+ /** A namespace per path prefix, the longest prefix winning. */
30
+ namespaces?: Record<string, string>;
31
+ system?: string;
32
+ }
33
+ /** A module name the protocol cannot carry. */
34
+ export declare class RegistryNameError extends Error {
35
+ constructor(message: string);
36
+ }
37
+ /** The host a registry's sources name: its URL without the scheme, lower-cased. */
38
+ export declare const registryHost: (reg: Pick<RegistryPlacement, "url">) => string;
39
+ /** The namespace a module's path goes under: the longest `namespaces` prefix it starts with, else `namespace`. */
40
+ export declare function namespaceFor(reg: Pick<RegistryPlacement, "namespace" | "namespaces">, rel: string): string;
41
+ /** A module's place in the registry: its namespace, its name (the last segment of its path) and its system. */
42
+ export declare function registryAddress(reg: RegistryPlacement, rel: string): RegistryAddress;
43
+ /** A registry source split into its parts. */
44
+ export interface RegistrySource {
45
+ host: string;
46
+ namespace: string;
47
+ name: string;
48
+ system: string;
49
+ }
50
+ /**
51
+ * A registry source split into its host and module, or undefined when the
52
+ * source is not one: `host/ns/name/system`, with an optional `//subdir` and
53
+ * query. The host must look like one (a dot, a port, or `localhost`), so a
54
+ * three-part public registry source with no host is not taken for one.
55
+ * `hosts` names bare hosts a CLI `host` block declares (a Nexus repository's
56
+ * name, chant#4605), which are taken as hosts too.
57
+ */
58
+ export declare function parseRegistrySource(source: string, hosts?: readonly string[]): RegistrySource | undefined;
59
+ /** A key under a registry's prefix in its bucket or directory. */
60
+ export declare const keyFor: (prefix: string | undefined, path: string) => string;
61
+ /** The tarball's name beside its version. */
62
+ export declare const tarballName: (addr: Pick<RegistryAddress, "name">, version: string) => string;
63
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../src/registry/address.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,SAAS,+BAA+B,CAAC;AACtD,eAAO,MAAM,UAAU,iBAAiB,CAAC;AACzC,eAAO,MAAM,cAAc,YAAY,CAAC;AAExC,mHAAmH;AACnH,eAAO,MAAM,aAAa,QAAqD,CAAC;AAChF,uFAAuF;AACvF,eAAO,MAAM,eAAe,QAAqB,CAAC;AAElD,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+CAA+C;AAC/C,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,mFAAmF;AACnF,eAAO,MAAM,YAAY,QAAS,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,KAAG,MAA6C,CAAC;AAEjH,kHAAkH;AAClH,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,YAAY,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ1G;AAED,+GAA+G;AAC/G,wBAAgB,eAAe,CAAC,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,CAMpF;AAED,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,SAAS,MAAM,EAAO,GAAG,cAAc,GAAG,SAAS,CAM7G;AAED,kEAAkE;AAClE,eAAO,MAAM,MAAM,WAAY,MAAM,GAAG,SAAS,QAAQ,MAAM,KAAG,MAGjE,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,WAAW,SAAU,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,WAAW,MAAM,KAAG,MAA0C,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Where a module sits in a Terraform module registry, and how a registry
3
+ * source (`<host>/<namespace>/<name>/<system>`) is split into those parts.
4
+ * Lifted from terragucci's `publish/registry.ts` (18f6431595) for chant#4565.
5
+ * No Node imports, so an edge function can carry it.
6
+ */
7
+ export const DISCOVERY = ".well-known/terraform.json";
8
+ export const MODULES_V1 = "/v1/modules/";
9
+ export const DEFAULT_SYSTEM = "generic";
10
+ /** A registry namespace or module name: letters, digits, `-` and `_`, starting and ending on a letter or digit. */
11
+ export const REGISTRY_NAME = /^[0-9A-Za-z](?:[0-9A-Za-z_-]{0,62}[0-9A-Za-z])?$/;
12
+ /** A registry module's system (its target provider): lower-case letters and digits. */
13
+ export const REGISTRY_SYSTEM = /^[0-9a-z]{1,64}$/;
14
+ /** A module name the protocol cannot carry. */
15
+ export class RegistryNameError extends Error {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = "RegistryNameError";
19
+ }
20
+ }
21
+ /** The host a registry's sources name: its URL without the scheme, lower-cased. */
22
+ export const registryHost = (reg) => new URL(reg.url).host.toLowerCase();
23
+ /** The namespace a module's path goes under: the longest `namespaces` prefix it starts with, else `namespace`. */
24
+ export function namespaceFor(reg, rel) {
25
+ let best;
26
+ for (const [prefix, ns] of Object.entries(reg.namespaces ?? {})) {
27
+ const p = prefix.replace(/^\.\//, "");
28
+ const dir = p.endsWith("/") ? p : `${p}/`;
29
+ if ((rel.startsWith(dir) || rel === p.replace(/\/+$/, "")) && (!best || p.length > best.prefix.length))
30
+ best = { prefix: p, ns };
31
+ }
32
+ return best?.ns ?? reg.namespace;
33
+ }
34
+ /** A module's place in the registry: its namespace, its name (the last segment of its path) and its system. */
35
+ export function registryAddress(reg, rel) {
36
+ const namespace = namespaceFor(reg, rel);
37
+ const name = rel.replace(/\/+$/, "").split("/").pop() ?? "";
38
+ const system = reg.system ?? DEFAULT_SYSTEM;
39
+ if (!REGISTRY_NAME.test(name))
40
+ throw new RegistryNameError(`${rel}: a registry module's name is letters, digits, - and _, and ${JSON.stringify(name)} is not; rename the directory`);
41
+ return { namespace, name, system, source: `${registryHost(reg)}/${namespace}/${name}/${system}`, path: `v1/modules/${namespace}/${name}/${system}` };
42
+ }
43
+ /**
44
+ * A registry source split into its host and module, or undefined when the
45
+ * source is not one: `host/ns/name/system`, with an optional `//subdir` and
46
+ * query. The host must look like one (a dot, a port, or `localhost`), so a
47
+ * three-part public registry source with no host is not taken for one.
48
+ * `hosts` names bare hosts a CLI `host` block declares (a Nexus repository's
49
+ * name, chant#4605), which are taken as hosts too.
50
+ */
51
+ export function parseRegistrySource(source, hosts = []) {
52
+ const base = source.split("?")[0].split("//")[0];
53
+ const m = /^([a-z0-9.-]+(?::\d+)?)\/([^/]+)\/([^/]+)\/([^/]+)$/i.exec(base);
54
+ const known = (h) => hosts.some((k) => k.toLowerCase() === h.toLowerCase());
55
+ if (!m || (!m[1].includes(".") && !m[1].includes(":") && m[1] !== "localhost" && !known(m[1])))
56
+ return undefined;
57
+ return { host: m[1].toLowerCase(), namespace: m[2], name: m[3], system: m[4] };
58
+ }
59
+ /** A key under a registry's prefix in its bucket or directory. */
60
+ export const keyFor = (prefix, path) => {
61
+ const p = (prefix ?? "").replace(/^\/+|\/+$/g, "");
62
+ return p ? `${p}/${path}` : path;
63
+ };
64
+ /** The tarball's name beside its version. */
65
+ export const tarballName = (addr, version) => `${addr.name}-${version}.tar.gz`;