@synapsestudios/lintofu 0.0.0-stage → 0.9.1

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 (261) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +151 -2
  3. package/dist/configs/category-recommended.d.ts +3 -0
  4. package/dist/configs/category-recommended.d.ts.map +1 -0
  5. package/dist/configs/category-recommended.js +12 -0
  6. package/dist/configs/category-recommended.js.map +1 -0
  7. package/dist/configs/recommended.d.ts +3 -0
  8. package/dist/configs/recommended.d.ts.map +1 -0
  9. package/dist/configs/recommended.js +12 -0
  10. package/dist/configs/recommended.js.map +1 -0
  11. package/dist/index.d.ts +198 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +65 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/language.d.ts +34 -0
  16. package/dist/language.d.ts.map +1 -0
  17. package/dist/language.js +72 -0
  18. package/dist/language.js.map +1 -0
  19. package/dist/parser/index.d.ts +10 -0
  20. package/dist/parser/index.d.ts.map +1 -0
  21. package/dist/parser/index.js +43 -0
  22. package/dist/parser/index.js.map +1 -0
  23. package/dist/parser/lintofu-parser.wasm +0 -0
  24. package/dist/parser/types.d.ts +261 -0
  25. package/dist/parser/types.d.ts.map +1 -0
  26. package/dist/parser/types.js +3 -0
  27. package/dist/parser/types.js.map +1 -0
  28. package/dist/parser/wasm-exec.cjs +575 -0
  29. package/dist/project-index.d.ts +40 -0
  30. package/dist/project-index.d.ts.map +1 -0
  31. package/dist/project-index.js +89 -0
  32. package/dist/project-index.js.map +1 -0
  33. package/dist/rules/aws/acm-certificate-create-before-destroy-required.d.ts +6 -0
  34. package/dist/rules/aws/acm-certificate-create-before-destroy-required.d.ts.map +1 -0
  35. package/dist/rules/aws/acm-certificate-create-before-destroy-required.js +47 -0
  36. package/dist/rules/aws/acm-certificate-create-before-destroy-required.js.map +1 -0
  37. package/dist/rules/aws/no-api-gateway-deployment-stage-args.d.ts +6 -0
  38. package/dist/rules/aws/no-api-gateway-deployment-stage-args.d.ts.map +1 -0
  39. package/dist/rules/aws/no-api-gateway-deployment-stage-args.js +56 -0
  40. package/dist/rules/aws/no-api-gateway-deployment-stage-args.js.map +1 -0
  41. package/dist/rules/aws/no-aurora-pinned-minor-with-auto-upgrade.d.ts +6 -0
  42. package/dist/rules/aws/no-aurora-pinned-minor-with-auto-upgrade.d.ts.map +1 -0
  43. package/dist/rules/aws/no-aurora-pinned-minor-with-auto-upgrade.js +88 -0
  44. package/dist/rules/aws/no-aurora-pinned-minor-with-auto-upgrade.js.map +1 -0
  45. package/dist/rules/aws/no-db-instance-name-attribute.d.ts +6 -0
  46. package/dist/rules/aws/no-db-instance-name-attribute.d.ts.map +1 -0
  47. package/dist/rules/aws/no-db-instance-name-attribute.js +45 -0
  48. package/dist/rules/aws/no-db-instance-name-attribute.js.map +1 -0
  49. package/dist/rules/aws/no-deprecated-lambda-runtime.d.ts +6 -0
  50. package/dist/rules/aws/no-deprecated-lambda-runtime.d.ts.map +1 -0
  51. package/dist/rules/aws/no-deprecated-lambda-runtime.js +91 -0
  52. package/dist/rules/aws/no-deprecated-lambda-runtime.js.map +1 -0
  53. package/dist/rules/aws/no-eip-vpc-attribute.d.ts +6 -0
  54. package/dist/rules/aws/no-eip-vpc-attribute.d.ts.map +1 -0
  55. package/dist/rules/aws/no-eip-vpc-attribute.js +66 -0
  56. package/dist/rules/aws/no-eip-vpc-attribute.js.map +1 -0
  57. package/dist/rules/aws/no-eks-addon-resolve-conflicts.d.ts +6 -0
  58. package/dist/rules/aws/no-eks-addon-resolve-conflicts.d.ts.map +1 -0
  59. package/dist/rules/aws/no-eks-addon-resolve-conflicts.js +36 -0
  60. package/dist/rules/aws/no-eks-addon-resolve-conflicts.js.map +1 -0
  61. package/dist/rules/aws/no-hardcoded-provider-credentials.d.ts +6 -0
  62. package/dist/rules/aws/no-hardcoded-provider-credentials.d.ts.map +1 -0
  63. package/dist/rules/aws/no-hardcoded-provider-credentials.js +42 -0
  64. package/dist/rules/aws/no-hardcoded-provider-credentials.js.map +1 -0
  65. package/dist/rules/aws/no-iam-policy-attachment.d.ts +6 -0
  66. package/dist/rules/aws/no-iam-policy-attachment.d.ts.map +1 -0
  67. package/dist/rules/aws/no-iam-policy-attachment.js +28 -0
  68. package/dist/rules/aws/no-iam-policy-attachment.js.map +1 -0
  69. package/dist/rules/aws/no-iam-role-inline-policies.d.ts +6 -0
  70. package/dist/rules/aws/no-iam-role-inline-policies.d.ts.map +1 -0
  71. package/dist/rules/aws/no-iam-role-inline-policies.js +43 -0
  72. package/dist/rules/aws/no-iam-role-inline-policies.js.map +1 -0
  73. package/dist/rules/aws/no-instance-cpu-count-attributes.d.ts +6 -0
  74. package/dist/rules/aws/no-instance-cpu-count-attributes.d.ts.map +1 -0
  75. package/dist/rules/aws/no-instance-cpu-count-attributes.js +94 -0
  76. package/dist/rules/aws/no-instance-cpu-count-attributes.js.map +1 -0
  77. package/dist/rules/aws/no-legacy-security-group-rules.d.ts +6 -0
  78. package/dist/rules/aws/no-legacy-security-group-rules.d.ts.map +1 -0
  79. package/dist/rules/aws/no-legacy-security-group-rules.js +39 -0
  80. package/dist/rules/aws/no-legacy-security-group-rules.js.map +1 -0
  81. package/dist/rules/aws/no-mixed-security-group-rule-forms.d.ts +6 -0
  82. package/dist/rules/aws/no-mixed-security-group-rule-forms.d.ts.map +1 -0
  83. package/dist/rules/aws/no-mixed-security-group-rule-forms.js +63 -0
  84. package/dist/rules/aws/no-mixed-security-group-rule-forms.js.map +1 -0
  85. package/dist/rules/aws/no-pinned-minor-with-auto-upgrade.d.ts +6 -0
  86. package/dist/rules/aws/no-pinned-minor-with-auto-upgrade.d.ts.map +1 -0
  87. package/dist/rules/aws/no-pinned-minor-with-auto-upgrade.js +100 -0
  88. package/dist/rules/aws/no-pinned-minor-with-auto-upgrade.js.map +1 -0
  89. package/dist/rules/aws/no-s3-bucket-inline-config.d.ts +6 -0
  90. package/dist/rules/aws/no-s3-bucket-inline-config.d.ts.map +1 -0
  91. package/dist/rules/aws/no-s3-bucket-inline-config.js +67 -0
  92. package/dist/rules/aws/no-s3-bucket-inline-config.js.map +1 -0
  93. package/dist/rules/aws/no-s3-bucket-object.d.ts +6 -0
  94. package/dist/rules/aws/no-s3-bucket-object.d.ts.map +1 -0
  95. package/dist/rules/aws/no-s3-bucket-object.js +41 -0
  96. package/dist/rules/aws/no-s3-bucket-object.js.map +1 -0
  97. package/dist/rules/aws/utils.d.ts +4 -0
  98. package/dist/rules/aws/utils.d.ts.map +1 -0
  99. package/dist/rules/aws/utils.js +17 -0
  100. package/dist/rules/aws/utils.js.map +1 -0
  101. package/dist/rules/cloudflare/access-rule-country-block-requires-enterprise.d.ts +6 -0
  102. package/dist/rules/cloudflare/access-rule-country-block-requires-enterprise.d.ts.map +1 -0
  103. package/dist/rules/cloudflare/access-rule-country-block-requires-enterprise.js +66 -0
  104. package/dist/rules/cloudflare/access-rule-country-block-requires-enterprise.js.map +1 -0
  105. package/dist/rules/cloudflare/dns-record-requires-managed-by-annotation.d.ts +10 -0
  106. package/dist/rules/cloudflare/dns-record-requires-managed-by-annotation.d.ts.map +1 -0
  107. package/dist/rules/cloudflare/dns-record-requires-managed-by-annotation.js +104 -0
  108. package/dist/rules/cloudflare/dns-record-requires-managed-by-annotation.js.map +1 -0
  109. package/dist/rules/cloudflare/ruleset-requires-managed-by-description.d.ts +9 -0
  110. package/dist/rules/cloudflare/ruleset-requires-managed-by-description.d.ts.map +1 -0
  111. package/dist/rules/cloudflare/ruleset-requires-managed-by-description.js +52 -0
  112. package/dist/rules/cloudflare/ruleset-requires-managed-by-description.js.map +1 -0
  113. package/dist/rules/cloudflare/utils.d.ts +17 -0
  114. package/dist/rules/cloudflare/utils.d.ts.map +1 -0
  115. package/dist/rules/cloudflare/utils.js +37 -0
  116. package/dist/rules/cloudflare/utils.js.map +1 -0
  117. package/dist/rules/core/documented-outputs.d.ts +6 -0
  118. package/dist/rules/core/documented-outputs.d.ts.map +1 -0
  119. package/dist/rules/core/documented-outputs.js +41 -0
  120. package/dist/rules/core/documented-outputs.js.map +1 -0
  121. package/dist/rules/core/documented-variables.d.ts +6 -0
  122. package/dist/rules/core/documented-variables.d.ts.map +1 -0
  123. package/dist/rules/core/documented-variables.js +41 -0
  124. package/dist/rules/core/documented-variables.js.map +1 -0
  125. package/dist/rules/core/module-source-pinned.d.ts +6 -0
  126. package/dist/rules/core/module-source-pinned.d.ts.map +1 -0
  127. package/dist/rules/core/module-source-pinned.js +47 -0
  128. package/dist/rules/core/module-source-pinned.js.map +1 -0
  129. package/dist/rules/core/no-bool-as-count.d.ts +6 -0
  130. package/dist/rules/core/no-bool-as-count.d.ts.map +1 -0
  131. package/dist/rules/core/no-bool-as-count.js +69 -0
  132. package/dist/rules/core/no-bool-as-count.js.map +1 -0
  133. package/dist/rules/core/no-duplicate-map-keys.d.ts +6 -0
  134. package/dist/rules/core/no-duplicate-map-keys.d.ts.map +1 -0
  135. package/dist/rules/core/no-duplicate-map-keys.js +42 -0
  136. package/dist/rules/core/no-duplicate-map-keys.js.map +1 -0
  137. package/dist/rules/core/no-empty-list-equality.d.ts +6 -0
  138. package/dist/rules/core/no-empty-list-equality.d.ts.map +1 -0
  139. package/dist/rules/core/no-empty-list-equality.js +48 -0
  140. package/dist/rules/core/no-empty-list-equality.js.map +1 -0
  141. package/dist/rules/core/no-external-refs-in-destroy-provisioner.d.ts +6 -0
  142. package/dist/rules/core/no-external-refs-in-destroy-provisioner.d.ts.map +1 -0
  143. package/dist/rules/core/no-external-refs-in-destroy-provisioner.js +74 -0
  144. package/dist/rules/core/no-external-refs-in-destroy-provisioner.js.map +1 -0
  145. package/dist/rules/core/no-legacy-count-attribute.d.ts +6 -0
  146. package/dist/rules/core/no-legacy-count-attribute.d.ts.map +1 -0
  147. package/dist/rules/core/no-legacy-count-attribute.js +64 -0
  148. package/dist/rules/core/no-legacy-count-attribute.js.map +1 -0
  149. package/dist/rules/core/no-legacy-dot-index.d.ts +6 -0
  150. package/dist/rules/core/no-legacy-dot-index.d.ts.map +1 -0
  151. package/dist/rules/core/no-legacy-dot-index.js +79 -0
  152. package/dist/rules/core/no-legacy-dot-index.js.map +1 -0
  153. package/dist/rules/core/no-legacy-ignore-changes-wildcard.d.ts +6 -0
  154. package/dist/rules/core/no-legacy-ignore-changes-wildcard.d.ts.map +1 -0
  155. package/dist/rules/core/no-legacy-ignore-changes-wildcard.js +40 -0
  156. package/dist/rules/core/no-legacy-ignore-changes-wildcard.js.map +1 -0
  157. package/dist/rules/core/no-legacy-list-function.d.ts +6 -0
  158. package/dist/rules/core/no-legacy-list-function.d.ts.map +1 -0
  159. package/dist/rules/core/no-legacy-list-function.js +67 -0
  160. package/dist/rules/core/no-legacy-list-function.js.map +1 -0
  161. package/dist/rules/core/no-legacy-lookup.d.ts +6 -0
  162. package/dist/rules/core/no-legacy-lookup.d.ts.map +1 -0
  163. package/dist/rules/core/no-legacy-lookup.js +53 -0
  164. package/dist/rules/core/no-legacy-lookup.js.map +1 -0
  165. package/dist/rules/core/no-legacy-map-function.d.ts +6 -0
  166. package/dist/rules/core/no-legacy-map-function.d.ts.map +1 -0
  167. package/dist/rules/core/no-legacy-map-function.js +90 -0
  168. package/dist/rules/core/no-legacy-map-function.js.map +1 -0
  169. package/dist/rules/core/no-legacy-provider-proxy.d.ts +6 -0
  170. package/dist/rules/core/no-legacy-provider-proxy.d.ts.map +1 -0
  171. package/dist/rules/core/no-legacy-provider-proxy.js +43 -0
  172. package/dist/rules/core/no-legacy-provider-proxy.js.map +1 -0
  173. package/dist/rules/core/no-provider-version-constraint.d.ts +6 -0
  174. package/dist/rules/core/no-provider-version-constraint.d.ts.map +1 -0
  175. package/dist/rules/core/no-provider-version-constraint.js +33 -0
  176. package/dist/rules/core/no-provider-version-constraint.js.map +1 -0
  177. package/dist/rules/core/no-quoted-depends-on.d.ts +6 -0
  178. package/dist/rules/core/no-quoted-depends-on.d.ts.map +1 -0
  179. package/dist/rules/core/no-quoted-depends-on.js +55 -0
  180. package/dist/rules/core/no-quoted-depends-on.js.map +1 -0
  181. package/dist/rules/core/no-quoted-ignore-changes.d.ts +6 -0
  182. package/dist/rules/core/no-quoted-ignore-changes.d.ts.map +1 -0
  183. package/dist/rules/core/no-quoted-ignore-changes.js +63 -0
  184. package/dist/rules/core/no-quoted-ignore-changes.js.map +1 -0
  185. package/dist/rules/core/no-quoted-provider-reference.d.ts +6 -0
  186. package/dist/rules/core/no-quoted-provider-reference.d.ts.map +1 -0
  187. package/dist/rules/core/no-quoted-provider-reference.js +69 -0
  188. package/dist/rules/core/no-quoted-provider-reference.js.map +1 -0
  189. package/dist/rules/core/no-quoted-type-constraints.d.ts +6 -0
  190. package/dist/rules/core/no-quoted-type-constraints.d.ts.map +1 -0
  191. package/dist/rules/core/no-quoted-type-constraints.js +55 -0
  192. package/dist/rules/core/no-quoted-type-constraints.js.map +1 -0
  193. package/dist/rules/core/no-reserved-variable-names.d.ts +6 -0
  194. package/dist/rules/core/no-reserved-variable-names.d.ts.map +1 -0
  195. package/dist/rules/core/no-reserved-variable-names.js +41 -0
  196. package/dist/rules/core/no-reserved-variable-names.js.map +1 -0
  197. package/dist/rules/core/no-splat-bracket-index.d.ts +6 -0
  198. package/dist/rules/core/no-splat-bracket-index.d.ts.map +1 -0
  199. package/dist/rules/core/no-splat-bracket-index.js +30 -0
  200. package/dist/rules/core/no-splat-bracket-index.js.map +1 -0
  201. package/dist/rules/core/no-template-provider.d.ts +6 -0
  202. package/dist/rules/core/no-template-provider.d.ts.map +1 -0
  203. package/dist/rules/core/no-template-provider.js +63 -0
  204. package/dist/rules/core/no-template-provider.js.map +1 -0
  205. package/dist/rules/core/no-terraform-env-reference.d.ts +6 -0
  206. package/dist/rules/core/no-terraform-env-reference.d.ts.map +1 -0
  207. package/dist/rules/core/no-terraform-env-reference.js +35 -0
  208. package/dist/rules/core/no-terraform-env-reference.js.map +1 -0
  209. package/dist/rules/core/no-winrm-connection.d.ts +6 -0
  210. package/dist/rules/core/no-winrm-connection.d.ts.map +1 -0
  211. package/dist/rules/core/no-winrm-connection.js +31 -0
  212. package/dist/rules/core/no-winrm-connection.js.map +1 -0
  213. package/dist/rules/core/prefer-bare-expression.d.ts +6 -0
  214. package/dist/rules/core/prefer-bare-expression.d.ts.map +1 -0
  215. package/dist/rules/core/prefer-bare-expression.js +23 -0
  216. package/dist/rules/core/prefer-bare-expression.js.map +1 -0
  217. package/dist/rules/core/provider-source-required.d.ts +6 -0
  218. package/dist/rules/core/provider-source-required.d.ts.map +1 -0
  219. package/dist/rules/core/provider-source-required.js +45 -0
  220. package/dist/rules/core/provider-source-required.js.map +1 -0
  221. package/dist/rules/core/remote-state-outputs-prefix.d.ts +6 -0
  222. package/dist/rules/core/remote-state-outputs-prefix.d.ts.map +1 -0
  223. package/dist/rules/core/remote-state-outputs-prefix.js +54 -0
  224. package/dist/rules/core/remote-state-outputs-prefix.js.map +1 -0
  225. package/dist/rules/core/required-providers-pinned.d.ts +6 -0
  226. package/dist/rules/core/required-providers-pinned.d.ts.map +1 -0
  227. package/dist/rules/core/required-providers-pinned.js +37 -0
  228. package/dist/rules/core/required-providers-pinned.js.map +1 -0
  229. package/dist/rules/core/required-version-declared.d.ts +6 -0
  230. package/dist/rules/core/required-version-declared.d.ts.map +1 -0
  231. package/dist/rules/core/required-version-declared.js +38 -0
  232. package/dist/rules/core/required-version-declared.js.map +1 -0
  233. package/dist/rules/core/typed-variables.d.ts +6 -0
  234. package/dist/rules/core/typed-variables.d.ts.map +1 -0
  235. package/dist/rules/core/typed-variables.js +32 -0
  236. package/dist/rules/core/typed-variables.js.map +1 -0
  237. package/dist/rules/core/utils.d.ts +31 -0
  238. package/dist/rules/core/utils.d.ts.map +1 -0
  239. package/dist/rules/core/utils.js +185 -0
  240. package/dist/rules/core/utils.js.map +1 -0
  241. package/dist/rules/index.d.ts +157 -0
  242. package/dist/rules/index.d.ts.map +1 -0
  243. package/dist/rules/index.js +101 -0
  244. package/dist/rules/index.js.map +1 -0
  245. package/dist/rules/types.d.ts +57 -0
  246. package/dist/rules/types.d.ts.map +1 -0
  247. package/dist/rules/types.js +15 -0
  248. package/dist/rules/types.js.map +1 -0
  249. package/dist/source-code.d.ts +84 -0
  250. package/dist/source-code.d.ts.map +1 -0
  251. package/dist/source-code.js +170 -0
  252. package/dist/source-code.js.map +1 -0
  253. package/dist/types.d.ts +67 -0
  254. package/dist/types.d.ts.map +1 -0
  255. package/dist/types.js +2 -0
  256. package/dist/types.js.map +1 -0
  257. package/dist/visitor-keys.d.ts +3 -0
  258. package/dist/visitor-keys.d.ts.map +1 -0
  259. package/dist/visitor-keys.js +30 -0
  260. package/dist/visitor-keys.js.map +1 -0
  261. package/package.json +88 -4
@@ -0,0 +1,90 @@
1
+ import { literalStringValue } from './utils.js';
2
+ const BARE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
3
+ // Splits alternating key,value arguments into pairs. Returns undefined when the
4
+ // count is odd, any key is not a string literal, or two keys collide, marking
5
+ // the call unsafe to rewrite automatically. Legacy `map` let a later duplicate
6
+ // key win, but a `{ a = 1, a = 2 }` object literal is a parse error, so the fix
7
+ // falls back to report-only when literal keys repeat.
8
+ function pairArgs(args) {
9
+ if (args.length % 2 !== 0)
10
+ return undefined;
11
+ const pairs = [];
12
+ const seen = new Set();
13
+ for (let i = 0; i < args.length; i += 2) {
14
+ const keyExpr = args[i];
15
+ const valueExpr = args[i + 1];
16
+ if (!keyExpr || !valueExpr)
17
+ return undefined;
18
+ const key = literalStringValue(keyExpr);
19
+ if (key === undefined)
20
+ return undefined;
21
+ if (seen.has(key))
22
+ return undefined;
23
+ seen.add(key);
24
+ pairs.push({ key, value: valueExpr });
25
+ }
26
+ return pairs;
27
+ }
28
+ const rule = {
29
+ meta: {
30
+ type: 'problem',
31
+ fixable: 'code',
32
+ docs: {
33
+ description: 'Flag the legacy `map(...)` function, removed in Terraform 0.15, in favor of a `{ key = value }` object literal.',
34
+ recommended: true,
35
+ severity: 'error',
36
+ },
37
+ messages: {
38
+ legacyMapFunction: 'The legacy `map(...)` function was removed in Terraform 0.15. Build the map with a `{ key = value }` object literal instead.',
39
+ },
40
+ schema: [],
41
+ },
42
+ create(context) {
43
+ const sourceCode = context.sourceCode;
44
+ // Byte ranges of variable `type` attribute expressions. `map(string)` there
45
+ // is a type constraint, not the legacy function, so any call inside one of
46
+ // these ranges is skipped. Block visitors run before their descendants, so
47
+ // the ranges are recorded before the inner call is visited.
48
+ const typeConstraintRanges = [];
49
+ return {
50
+ Block(node) {
51
+ if (node.kind !== 'variable')
52
+ return;
53
+ for (const attr of node.body.attributes) {
54
+ if (attr.name !== 'type')
55
+ continue;
56
+ typeConstraintRanges.push([
57
+ attr.expression.range.start.offset,
58
+ attr.expression.range.end.offset,
59
+ ]);
60
+ }
61
+ },
62
+ FunctionCallExpr(node) {
63
+ if (node.name !== 'map')
64
+ return;
65
+ const start = node.range.start.offset;
66
+ const end = node.range.end.offset;
67
+ const inTypeConstraint = typeConstraintRanges.some(([from, to]) => start >= from && end <= to);
68
+ if (inTypeConstraint)
69
+ return;
70
+ const pairs = node.expandFinal ? undefined : pairArgs(node.args);
71
+ if (!pairs) {
72
+ context.report({ node, messageId: 'legacyMapFunction' });
73
+ return;
74
+ }
75
+ const entries = pairs.map(({ key, value }) => {
76
+ const label = BARE_IDENTIFIER.test(key) ? key : JSON.stringify(key);
77
+ return `${label} = ${sourceCode.getText(value)}`;
78
+ });
79
+ const object = entries.length === 0 ? '{}' : `{ ${entries.join(', ')} }`;
80
+ context.report({
81
+ node,
82
+ messageId: 'legacyMapFunction',
83
+ fix: (fixer) => fixer.replaceText(node, object),
84
+ });
85
+ },
86
+ };
87
+ },
88
+ };
89
+ export default rule;
90
+ //# sourceMappingURL=no-legacy-map-function.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-legacy-map-function.js","sourceRoot":"","sources":["../../../src/rules/core/no-legacy-map-function.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'legacyProviderProxy';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-legacy-provider-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-legacy-provider-proxy.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-legacy-provider-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IAAE,UAAU,EAAE,qBAAqB,CAAA;CAAE,CAmCvE,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { literalStringValue } from './utils.js';
2
+ const rule = {
3
+ meta: {
4
+ type: 'problem',
5
+ docs: {
6
+ description: 'Flag empty `provider` blocks that exist only to declare an alias; replace with `configuration_aliases` in `required_providers`.',
7
+ recommended: true,
8
+ severity: 'error',
9
+ },
10
+ messages: {
11
+ legacyProviderProxy: 'Empty proxy `provider` block for alias `{{provider}}.{{alias}}`. Move the alias declaration into `terraform.required_providers` via `configuration_aliases = [{{provider}}.{{alias}}]`.',
12
+ },
13
+ schema: [],
14
+ },
15
+ create(context) {
16
+ return {
17
+ Block(node) {
18
+ if (node.kind !== 'provider')
19
+ return;
20
+ const provider = node.labels[0];
21
+ if (!provider)
22
+ return;
23
+ if (node.body.blocks.length > 0)
24
+ return;
25
+ const [aliasAttr, ...rest] = node.body.attributes;
26
+ if (!aliasAttr || rest.length > 0)
27
+ return;
28
+ if (aliasAttr.name !== 'alias')
29
+ return;
30
+ const alias = literalStringValue(aliasAttr.expression);
31
+ if (alias === undefined)
32
+ return;
33
+ context.report({
34
+ node,
35
+ messageId: 'legacyProviderProxy',
36
+ data: { provider, alias },
37
+ });
38
+ },
39
+ };
40
+ },
41
+ };
42
+ export default rule;
43
+ //# sourceMappingURL=no-legacy-provider-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-legacy-provider-proxy.js","sourceRoot":"","sources":["../../../src/rules/core/no-legacy-provider-proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,IAAI,GAAkE;IAC1E,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,iIAAiI;YACnI,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,OAAO;SAClB;QACD,QAAQ,EAAE;YACR,mBAAmB,EACjB,yLAAyL;SAC5L;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,KAAK,CAAC,IAAI;gBACR,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;oBAAE,OAAO;gBACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAChC,IAAI,CAAC,QAAQ;oBAAE,OAAO;gBACtB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO;gBACxC,MAAM,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;gBAClD,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO;gBAC1C,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO;oBAAE,OAAO;gBACvC,MAAM,KAAK,GAAG,kBAAkB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBACvD,IAAI,KAAK,KAAK,SAAS;oBAAE,OAAO;gBAChC,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI;oBACJ,SAAS,EAAE,qBAAqB;oBAChC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;iBAC1B,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'providerVersionConstraint';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-provider-version-constraint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-provider-version-constraint.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-provider-version-constraint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IACjC,UAAU,EAAE,2BAA2B,CAAC;CACzC,CA6BA,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { findAttribute } from './utils.js';
2
+ const rule = {
3
+ meta: {
4
+ type: 'suggestion',
5
+ docs: {
6
+ description: 'Flag a `version` argument inside a `provider` block; declare the version in `terraform.required_providers` instead.',
7
+ recommended: true,
8
+ severity: 'warn',
9
+ },
10
+ messages: {
11
+ providerVersionConstraint: 'The `version` argument inside `provider "{{provider}}"` is deprecated and only takes effect when `terraform.required_providers` omits a constraint for this provider. Declare the version in `required_providers` instead.',
12
+ },
13
+ schema: [],
14
+ },
15
+ create(context) {
16
+ return {
17
+ Block(node) {
18
+ if (node.kind !== 'provider')
19
+ return;
20
+ const versionAttr = findAttribute(node.body.attributes, 'version');
21
+ if (!versionAttr)
22
+ return;
23
+ context.report({
24
+ node: versionAttr,
25
+ messageId: 'providerVersionConstraint',
26
+ data: { provider: node.labels[0] ?? '<unnamed>' },
27
+ });
28
+ },
29
+ };
30
+ },
31
+ };
32
+ export default rule;
33
+ //# sourceMappingURL=no-provider-version-constraint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-provider-version-constraint.js","sourceRoot":"","sources":["../../../src/rules/core/no-provider-version-constraint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,IAAI,GAEL;IACH,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,qHAAqH;YACvH,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,MAAM;SACjB;QACD,QAAQ,EAAE;YACR,yBAAyB,EACvB,4NAA4N;SAC/N;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,KAAK,CAAC,IAAI;gBACR,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;oBAAE,OAAO;gBACrC,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;gBACnE,IAAI,CAAC,WAAW;oBAAE,OAAO;gBACzB,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI,EAAE,WAAW;oBACjB,SAAS,EAAE,2BAA2B;oBACtC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE;iBAClD,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'quotedDependsOn';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-quoted-depends-on.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-depends-on.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-depends-on.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAgB7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IAAE,UAAU,EAAE,iBAAiB,CAAA;CAAE,CAuCnE,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { findAttribute, literalStringValue } from './utils.js';
2
+ // depends_on is a meta-argument only on these block kinds; elsewhere an
3
+ // attribute named depends_on is a plain value that must not be rewritten.
4
+ const KINDS = new Set(['resource', 'data', 'module', 'output']);
5
+ // A single resource/module address: a root identifier followed by attribute
6
+ // steps, numeric indexes, or quoted-key indexes. Anything else (a literal with
7
+ // spaces, an operator, etc.) is not a bare reference and gets no fix. Each group
8
+ // iteration starts with a fixed `.` or `[`, and the two `[` branches diverge on
9
+ // their next character, so the outer `*` cannot match the same input two ways.
10
+ const REFERENCE =
11
+ // eslint-disable-next-line security/detect-unsafe-regex
12
+ /^[A-Za-z_][A-Za-z0-9_-]*(\.[A-Za-z_][A-Za-z0-9_-]*|\[[0-9]+\]|\["[^"\\]*"\])*$/;
13
+ const rule = {
14
+ meta: {
15
+ type: 'suggestion',
16
+ fixable: 'code',
17
+ docs: {
18
+ description: 'Disallow quoted references in `depends_on`; use bare references.',
19
+ recommended: true,
20
+ severity: 'warn',
21
+ },
22
+ messages: {
23
+ quotedDependsOn: 'Quoted reference in `depends_on` is deprecated. Use a bare reference, e.g. `[aws_instance.example]`.',
24
+ },
25
+ schema: [],
26
+ },
27
+ create(context) {
28
+ return {
29
+ Block(node) {
30
+ if (!KINDS.has(node.kind))
31
+ return;
32
+ const attr = findAttribute(node.body.attributes, 'depends_on');
33
+ if (attr?.expression.type !== 'TupleConsExpr')
34
+ return;
35
+ for (const el of attr.expression.exprs) {
36
+ // literalStringValue returns a string only for an all-literal
37
+ // TemplateExpr, so bare references and the `"${ref}"` form (owned by
38
+ // prefer-bare-expression) both fall through untouched.
39
+ const value = literalStringValue(el);
40
+ if (value === undefined)
41
+ continue;
42
+ context.report({
43
+ node: el,
44
+ messageId: 'quotedDependsOn',
45
+ fix: REFERENCE.test(value)
46
+ ? (fixer) => fixer.replaceText(el, value)
47
+ : undefined,
48
+ });
49
+ }
50
+ },
51
+ };
52
+ },
53
+ };
54
+ export default rule;
55
+ //# sourceMappingURL=no-quoted-depends-on.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-depends-on.js","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-depends-on.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE/D,wEAAwE;AACxE,0EAA0E;AAC1E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEhE,4EAA4E;AAC5E,+EAA+E;AAC/E,iFAAiF;AACjF,gFAAgF;AAChF,+EAA+E;AAC/E,MAAM,SAAS;AACb,wDAAwD;AACxD,gFAAgF,CAAC;AAEnF,MAAM,IAAI,GAA8D;IACtE,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,MAAM;QACf,IAAI,EAAE;YACJ,WAAW,EACT,kEAAkE;YACpE,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,MAAM;SACjB;QACD,QAAQ,EAAE;YACR,eAAe,EACb,sGAAsG;SACzG;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,KAAK,CAAC,IAAI;gBACR,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAClC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;gBAC/D,IAAI,IAAI,EAAE,UAAU,CAAC,IAAI,KAAK,eAAe;oBAAE,OAAO;gBACtD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;oBACvC,8DAA8D;oBAC9D,qEAAqE;oBACrE,uDAAuD;oBACvD,MAAM,KAAK,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;oBACrC,IAAI,KAAK,KAAK,SAAS;wBAAE,SAAS;oBAClC,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,EAAE;wBACR,SAAS,EAAE,iBAAiB;wBAC5B,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;4BACxB,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC;4BACzC,CAAC,CAAC,SAAS;qBACd,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'quotedIgnoreChanges';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-quoted-ignore-changes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-ignore-changes.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-ignore-changes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAY7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IAAE,UAAU,EAAE,qBAAqB,CAAA;CAAE,CAqDvE,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { findAttribute, literalStringValue } from './utils.js';
2
+ // A valid attribute path can be unquoted safely: a bare identifier followed by
3
+ // any number of `.attr`, `[0]`, or `["key"]` steps. Anything else (an
4
+ // interpolation, a `*` wildcard, whitespace) is left quoted. Each group
5
+ // iteration starts with a fixed `.` or `[`, and the two `[` branches diverge on
6
+ // their next character, so the outer `*` cannot match the same input two ways.
7
+ const ATTRIBUTE_PATH =
8
+ // eslint-disable-next-line security/detect-unsafe-regex
9
+ /^[A-Za-z_][A-Za-z0-9_-]*(\.[A-Za-z_][A-Za-z0-9_-]*|\[[0-9]+\]|\["[^"\\]*"\])*$/;
10
+ const rule = {
11
+ meta: {
12
+ type: 'suggestion',
13
+ fixable: 'code',
14
+ docs: {
15
+ description: 'Disallow quoted references in a `lifecycle` `ignore_changes` list; use bare attribute references.',
16
+ recommended: true,
17
+ severity: 'warn',
18
+ },
19
+ messages: {
20
+ quotedIgnoreChanges: 'Quoted reference in `ignore_changes` is deprecated. Use a bare attribute reference, e.g. `[ami, tags]`.',
21
+ },
22
+ schema: [],
23
+ },
24
+ create(context) {
25
+ return {
26
+ Block(node) {
27
+ if (node.kind !== 'lifecycle')
28
+ return;
29
+ const attr = findAttribute(node.body.attributes, 'ignore_changes');
30
+ if (!attr)
31
+ return;
32
+ const expr = attr.expression;
33
+ if (expr.type !== 'TupleConsExpr')
34
+ return;
35
+ // The single-element `["*"]` form belongs to
36
+ // no-legacy-ignore-changes-wildcard.
37
+ const only = expr.exprs[0];
38
+ if (expr.exprs.length === 1 &&
39
+ only !== undefined &&
40
+ literalStringValue(only) === '*') {
41
+ return;
42
+ }
43
+ for (const el of expr.exprs) {
44
+ // literalStringValue returns a string only for an all-literal
45
+ // TemplateExpr, so bare references, interpolated elements, and the
46
+ // `"${ref}"` form all fall through untouched.
47
+ const value = literalStringValue(el);
48
+ if (value === undefined)
49
+ continue;
50
+ context.report({
51
+ node: el,
52
+ messageId: 'quotedIgnoreChanges',
53
+ fix: ATTRIBUTE_PATH.test(value)
54
+ ? (fixer) => fixer.replaceText(el, value)
55
+ : undefined,
56
+ });
57
+ }
58
+ },
59
+ };
60
+ },
61
+ };
62
+ export default rule;
63
+ //# sourceMappingURL=no-quoted-ignore-changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-ignore-changes.js","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-ignore-changes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE/D,+EAA+E;AAC/E,sEAAsE;AACtE,wEAAwE;AACxE,gFAAgF;AAChF,+EAA+E;AAC/E,MAAM,cAAc;AAClB,wDAAwD;AACxD,gFAAgF,CAAC;AAEnF,MAAM,IAAI,GAAkE;IAC1E,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,MAAM;QACf,IAAI,EAAE;YACJ,WAAW,EACT,mGAAmG;YACrG,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,MAAM;SACjB;QACD,QAAQ,EAAE;YACR,mBAAmB,EACjB,yGAAyG;SAC5G;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,KAAK,CAAC,IAAI;gBACR,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;oBAAE,OAAO;gBACtC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;gBACnE,IAAI,CAAC,IAAI;oBAAE,OAAO;gBAClB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;gBAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe;oBAAE,OAAO;gBAE1C,6CAA6C;gBAC7C,qCAAqC;gBACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,IACE,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;oBACvB,IAAI,KAAK,SAAS;oBAClB,kBAAkB,CAAC,IAAI,CAAC,KAAK,GAAG,EAChC,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBAC5B,8DAA8D;oBAC9D,mEAAmE;oBACnE,8CAA8C;oBAC9C,MAAM,KAAK,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;oBACrC,IAAI,KAAK,KAAK,SAAS;wBAAE,SAAS;oBAClC,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,EAAE;wBACR,SAAS,EAAE,qBAAqB;wBAChC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;4BAC7B,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC;4BACzC,CAAC,CAAC,SAAS;qBACd,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'quotedProviderReference';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-quoted-provider-reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-provider-reference.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-provider-reference.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAW7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IAAE,UAAU,EAAE,yBAAyB,CAAA;CAAE,CAkEzE,CAAC;AAEJ,eAAe,IAAI,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { findAttribute, literalStringValue } from './utils.js';
2
+ // A bare provider reference is `aws` or `aws.west`: an identifier, optionally
3
+ // followed by dotted attribute steps. A providers-map key takes the same shape,
4
+ // since a bare qualified key such as `aws.alt` is legal. Each step starts with a
5
+ // distinct char after `.`, so there is no backtracking ambiguity.
6
+ const REFERENCE =
7
+ // eslint-disable-next-line security/detect-unsafe-regex
8
+ /^[A-Za-z_][A-Za-z0-9_-]*(\.[A-Za-z_][A-Za-z0-9_-]*)*$/;
9
+ const rule = {
10
+ meta: {
11
+ type: 'suggestion',
12
+ fixable: 'code',
13
+ docs: {
14
+ description: 'Disallow quoted provider references in `provider` arguments and module `providers` maps; use a bare traversal.',
15
+ recommended: true,
16
+ severity: 'warn',
17
+ },
18
+ messages: {
19
+ quotedProviderReference: 'Quoted provider reference is deprecated. Use a bare traversal, e.g. `aws.west`.',
20
+ },
21
+ schema: [],
22
+ },
23
+ create(context) {
24
+ // `target` is the node to report and replace (it spans the quotes); `read`
25
+ // is the expression to pull the literal string from. For a quoted map key
26
+ // the two differ: the key arrives as an ObjectConsKeyExpr wrapping the
27
+ // literal TemplateExpr, and the wrapper's span includes the quotes.
28
+ function reportQuoted(target, read, pattern) {
29
+ const value = literalStringValue(read);
30
+ if (value === undefined)
31
+ return;
32
+ context.report({
33
+ node: target,
34
+ messageId: 'quotedProviderReference',
35
+ fix: pattern.test(value)
36
+ ? (fixer) => fixer.replaceText(target, value)
37
+ : undefined,
38
+ });
39
+ }
40
+ return {
41
+ Block(node) {
42
+ // resource, data, and import blocks all take a `provider` argument.
43
+ if (node.kind === 'resource' ||
44
+ node.kind === 'data' ||
45
+ node.kind === 'import') {
46
+ const attr = findAttribute(node.body.attributes, 'provider');
47
+ if (attr)
48
+ reportQuoted(attr.expression, attr.expression, REFERENCE);
49
+ return;
50
+ }
51
+ if (node.kind === 'module') {
52
+ const attr = findAttribute(node.body.attributes, 'providers');
53
+ if (attr?.expression.type !== 'ObjectConsExpr')
54
+ return;
55
+ const object = attr.expression;
56
+ for (const item of object.items) {
57
+ const keyInner = item.keyExpr.type === 'ObjectConsKeyExpr'
58
+ ? item.keyExpr.wrapped
59
+ : item.keyExpr;
60
+ reportQuoted(item.keyExpr, keyInner, REFERENCE);
61
+ reportQuoted(item.valueExpr, item.valueExpr, REFERENCE);
62
+ }
63
+ }
64
+ },
65
+ };
66
+ },
67
+ };
68
+ export default rule;
69
+ //# sourceMappingURL=no-quoted-provider-reference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-provider-reference.js","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-provider-reference.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE/D,8EAA8E;AAC9E,gFAAgF;AAChF,iFAAiF;AACjF,kEAAkE;AAClE,MAAM,SAAS;AACb,wDAAwD;AACxD,uDAAuD,CAAC;AAE1D,MAAM,IAAI,GACR;IACE,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,MAAM;QACf,IAAI,EAAE;YACJ,WAAW,EACT,gHAAgH;YAClH,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,MAAM;SACjB;QACD,QAAQ,EAAE;YACR,uBAAuB,EACrB,iFAAiF;SACpF;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,2EAA2E;QAC3E,0EAA0E;QAC1E,uEAAuE;QACvE,oEAAoE;QACpE,SAAS,YAAY,CACnB,MAAkB,EAClB,IAAgB,EAChB,OAAe;YAEf,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO;YAChC,OAAO,CAAC,MAAM,CAAC;gBACb,IAAI,EAAE,MAAM;gBACZ,SAAS,EAAE,yBAAyB;gBACpC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;oBACtB,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC;oBAC7C,CAAC,CAAC,SAAS;aACd,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,KAAK,CAAC,IAAI;gBACR,oEAAoE;gBACpE,IACE,IAAI,CAAC,IAAI,KAAK,UAAU;oBACxB,IAAI,CAAC,IAAI,KAAK,MAAM;oBACpB,IAAI,CAAC,IAAI,KAAK,QAAQ,EACtB,CAAC;oBACD,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;oBAC7D,IAAI,IAAI;wBAAE,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;oBACpE,OAAO;gBACT,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC3B,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;oBAC9D,IAAI,IAAI,EAAE,UAAU,CAAC,IAAI,KAAK,gBAAgB;wBAAE,OAAO;oBACvD,MAAM,MAAM,GAAmB,IAAI,CAAC,UAAU,CAAC;oBAC/C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;wBAChC,MAAM,QAAQ,GACZ,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB;4BACvC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;4BACtB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;wBACnB,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;wBAChD,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;oBAC1D,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEJ,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'quotedTypeConstraint';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-quoted-type-constraints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-type-constraints.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-type-constraints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAmB7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IAAE,UAAU,EAAE,sBAAsB,CAAA;CAAE,CAoCxE,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { findAttribute, literalStringValue } from './utils.js';
2
+ // The legacy `"list"`, `"map"`, and `"set"` forms meant a collection of
3
+ // strings, so their unquoted keyword takes an explicit `string` element type.
4
+ // `"object"` and `"tuple"` have no bare keyword form (they require a type
5
+ // argument), so they are flagged without a fix.
6
+ const REPLACEMENTS = {
7
+ string: 'string',
8
+ number: 'number',
9
+ bool: 'bool',
10
+ any: 'any',
11
+ list: 'list(string)',
12
+ map: 'map(string)',
13
+ set: 'set(string)',
14
+ };
15
+ const FLAGGED = new Set([...Object.keys(REPLACEMENTS), 'object', 'tuple']);
16
+ const rule = {
17
+ meta: {
18
+ type: 'problem',
19
+ fixable: 'code',
20
+ docs: {
21
+ description: 'Disallow quoted type constraints in `variable` blocks; use the unquoted type keyword.',
22
+ recommended: true,
23
+ severity: 'error',
24
+ },
25
+ messages: {
26
+ quotedTypeConstraint: 'Quoted type constraint `"{{name}}"` is not allowed as of Terraform 0.15. Use the unquoted type keyword instead.',
27
+ },
28
+ schema: [],
29
+ },
30
+ create(context) {
31
+ return {
32
+ Block(node) {
33
+ if (node.kind !== 'variable')
34
+ return;
35
+ const attr = findAttribute(node.body.attributes, 'type');
36
+ if (!attr)
37
+ return;
38
+ const value = literalStringValue(attr.expression);
39
+ if (value === undefined || !FLAGGED.has(value))
40
+ return;
41
+ const replacement = REPLACEMENTS[value];
42
+ context.report({
43
+ node: attr.expression,
44
+ messageId: 'quotedTypeConstraint',
45
+ data: { name: value },
46
+ fix: replacement
47
+ ? (fixer) => fixer.replaceText(attr.expression, replacement)
48
+ : undefined,
49
+ });
50
+ },
51
+ };
52
+ },
53
+ };
54
+ export default rule;
55
+ //# sourceMappingURL=no-quoted-type-constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-quoted-type-constraints.js","sourceRoot":"","sources":["../../../src/rules/core/no-quoted-type-constraints.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE/D,wEAAwE;AACxE,8EAA8E;AAC9E,0EAA0E;AAC1E,gDAAgD;AAChD,MAAM,YAAY,GAA2B;IAC3C,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,cAAc;IACpB,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,aAAa;CACnB,CAAC;AAEF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3E,MAAM,IAAI,GAAmE;IAC3E,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,MAAM;QACf,IAAI,EAAE;YACJ,WAAW,EACT,uFAAuF;YACzF,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,OAAO;SAClB;QACD,QAAQ,EAAE;YACR,oBAAoB,EAClB,iHAAiH;SACpH;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,KAAK,CAAC,IAAI;gBACR,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;oBAAE,OAAO;gBACrC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;gBACzD,IAAI,CAAC,IAAI;oBAAE,OAAO;gBAClB,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAClD,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,OAAO;gBACvD,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;gBACxC,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI,EAAE,IAAI,CAAC,UAAU;oBACrB,SAAS,EAAE,sBAAsB;oBACjC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;oBACrB,GAAG,EAAE,WAAW;wBACd,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;wBAC5D,CAAC,CAAC,SAAS;iBACd,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'reservedName';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-reserved-variable-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-reserved-variable-names.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-reserved-variable-names.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAgB7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IAAE,UAAU,EAAE,cAAc,CAAA;CAAE,CA0BhE,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { blockLabel } from './utils.js';
2
+ // Reserved by OpenTofu because they collide with module meta-arguments; a
3
+ // `variable` block may not use any of them as its name.
4
+ const RESERVED_VARIABLE_NAMES = new Set([
5
+ 'source',
6
+ 'version',
7
+ 'providers',
8
+ 'count',
9
+ 'for_each',
10
+ 'lifecycle',
11
+ 'depends_on',
12
+ 'locals',
13
+ ]);
14
+ const rule = {
15
+ meta: {
16
+ type: 'problem',
17
+ docs: {
18
+ description: 'Disallow `variable` blocks named after an OpenTofu reserved meta-argument.',
19
+ recommended: true,
20
+ severity: 'error',
21
+ },
22
+ messages: {
23
+ reservedName: 'Variable name `{{name}}` is reserved by OpenTofu and cannot be used.',
24
+ },
25
+ schema: [],
26
+ },
27
+ create(context) {
28
+ return {
29
+ Block(node) {
30
+ if (node.kind !== 'variable')
31
+ return;
32
+ const name = blockLabel(node);
33
+ if (RESERVED_VARIABLE_NAMES.has(name)) {
34
+ context.report({ node, messageId: 'reservedName', data: { name } });
35
+ }
36
+ },
37
+ };
38
+ },
39
+ };
40
+ export default rule;
41
+ //# sourceMappingURL=no-reserved-variable-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-reserved-variable-names.js","sourceRoot":"","sources":["../../../src/rules/core/no-reserved-variable-names.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,0EAA0E;AAC1E,wDAAwD;AACxD,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,QAAQ;IACR,SAAS;IACT,WAAW;IACX,OAAO;IACP,UAAU;IACV,WAAW;IACX,YAAY;IACZ,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,IAAI,GAA2D;IACnE,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,4EAA4E;YAC9E,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,OAAO;SAClB;QACD,QAAQ,EAAE;YACR,YAAY,EACV,sEAAsE;SACzE;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,KAAK,CAAC,IAAI;gBACR,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;oBAAE,OAAO;gBACrC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC9B,IAAI,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'splatBracketIndex';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-splat-bracket-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-splat-bracket-index.d.ts","sourceRoot":"","sources":["../../../src/rules/core/no-splat-bracket-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE7D,QAAA,MAAM,IAAI,EAAE,sBAAsB,CAAC;IAAE,UAAU,EAAE,mBAAmB,CAAA;CAAE,CA2BrE,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,30 @@
1
+ const rule = {
2
+ meta: {
3
+ type: 'suggestion',
4
+ docs: {
5
+ description: 'Flag a constant index applied to a splat result, a pre-0.12 artifact; index the resource first instead.',
6
+ recommended: true,
7
+ severity: 'warn',
8
+ },
9
+ messages: {
10
+ splatBracketIndex: 'Indexing a splat result with a constant is a pre-0.12 artifact. Index the collection first, e.g. `aws_instance.example[0].id`.',
11
+ },
12
+ schema: [],
13
+ },
14
+ create(context) {
15
+ return {
16
+ // A constant index on a splat parses as a RelativeTraversalExpr whose
17
+ // source is the SplatExpr and whose first step is a TraverseIndex; a
18
+ // non-constant index lands in an IndexExpr instead and is left alone.
19
+ RelativeTraversalExpr(node) {
20
+ if (node.source.type !== 'SplatExpr')
21
+ return;
22
+ if (node.traversal[0]?.type !== 'TraverseIndex')
23
+ return;
24
+ context.report({ node, messageId: 'splatBracketIndex' });
25
+ },
26
+ };
27
+ },
28
+ };
29
+ export default rule;
30
+ //# sourceMappingURL=no-splat-bracket-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-splat-bracket-index.js","sourceRoot":"","sources":["../../../src/rules/core/no-splat-bracket-index.ts"],"names":[],"mappings":"AAEA,MAAM,IAAI,GAAgE;IACxE,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,yGAAyG;YAC3G,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,MAAM;SACjB;QACD,QAAQ,EAAE;YACR,iBAAiB,EACf,gIAAgI;SACnI;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,sEAAsE;YACtE,qEAAqE;YACrE,sEAAsE;YACtE,qBAAqB,CAAC,IAAI;gBACxB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,WAAW;oBAAE,OAAO;gBAC7C,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,eAAe;oBAAE,OAAO;gBACxD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC;YAC3D,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OpenTofuRuleDefinition } from '../../types.js';
2
+ declare const rule: OpenTofuRuleDefinition<{
3
+ MessageIds: 'useTemplatefile' | 'useCloudinitProvider' | 'archivedTemplateProvider';
4
+ }>;
5
+ export default rule;
6
+ //# sourceMappingURL=no-template-provider.d.ts.map