@ttsc/lint 0.13.0 → 0.14.0-dev.20250530.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 (498) hide show
  1. package/README.md +955 -85
  2. package/lib/defaultFormat.d.ts +15 -8
  3. package/lib/defaultFormat.js +15 -8
  4. package/lib/defaultFormat.js.map +1 -1
  5. package/lib/index.d.ts +46 -0
  6. package/lib/index.js +60 -37
  7. package/lib/index.js.map +1 -1
  8. package/lib/structures/ITtscLintConfig.d.ts +12 -6
  9. package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
  10. package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
  11. package/lib/structures/TtscLintRuleSetting.js.map +1 -0
  12. package/lib/structures/format/ITtscLintFormat.d.ts +128 -0
  13. package/lib/structures/{TtscLintRuleMap.js → format/ITtscLintFormat.js} +1 -1
  14. package/lib/structures/format/ITtscLintFormat.js.map +1 -0
  15. package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +17 -0
  16. package/lib/structures/{ITtscLintFormatConfig.js → format/ITtscLintFormatJsDoc.js} +1 -1
  17. package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
  18. package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
  19. package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
  20. package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
  21. package/lib/structures/format/index.d.ts +3 -0
  22. package/lib/structures/format/index.js +20 -0
  23. package/lib/structures/format/index.js.map +1 -0
  24. package/lib/structures/index.d.ts +3 -4
  25. package/lib/structures/index.js +3 -4
  26. package/lib/structures/index.js.map +1 -1
  27. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +95 -0
  28. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +13 -0
  29. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
  30. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +75 -0
  31. package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
  32. package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
  33. package/lib/structures/rules/ITtscLintContributorRules.d.ts +16 -0
  34. package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
  35. package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
  36. package/lib/structures/rules/ITtscLintCoreRules.d.ts +1229 -0
  37. package/lib/structures/rules/ITtscLintCoreRules.js +3 -0
  38. package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
  39. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
  40. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
  41. package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
  42. package/lib/structures/rules/ITtscLintCypressRules.d.ts +125 -0
  43. package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
  44. package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
  45. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +154 -0
  46. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
  47. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
  48. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +162 -0
  49. package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
  50. package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
  51. package/lib/structures/rules/ITtscLintJestRules.d.ts +190 -0
  52. package/lib/structures/rules/ITtscLintJestRules.js +3 -0
  53. package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
  54. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +133 -0
  55. package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
  56. package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
  57. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +294 -0
  58. package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
  59. package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
  60. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +180 -0
  61. package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
  62. package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
  63. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +312 -0
  64. package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
  65. package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
  66. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +179 -0
  67. package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
  68. package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
  69. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
  70. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
  71. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
  72. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +49 -0
  73. package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
  74. package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
  75. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +37 -0
  76. package/lib/structures/rules/ITtscLintReactRuleOptions.js +11 -0
  77. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
  78. package/lib/structures/rules/ITtscLintReactRules.d.ts +276 -0
  79. package/lib/structures/rules/ITtscLintReactRules.js +3 -0
  80. package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
  81. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +182 -0
  82. package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
  83. package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
  84. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +65 -0
  85. package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
  86. package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
  87. package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
  88. package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
  89. package/lib/structures/rules/ITtscLintRules.js.map +1 -0
  90. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +141 -0
  91. package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
  92. package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
  93. package/lib/structures/rules/ITtscLintSolidRules.d.ts +178 -0
  94. package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
  95. package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
  96. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +20 -0
  97. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
  98. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
  99. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +165 -0
  100. package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
  101. package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
  102. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +88 -0
  103. package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
  104. package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
  105. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +21 -0
  106. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
  107. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
  108. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +293 -0
  109. package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
  110. package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
  111. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1074 -0
  112. package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
  113. package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
  114. package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
  115. package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
  116. package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
  117. package/lib/structures/rules/ITtscLintVitestRules.d.ts +133 -0
  118. package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
  119. package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
  120. package/lib/structures/rules/index.d.ts +31 -0
  121. package/lib/structures/rules/index.js +48 -0
  122. package/lib/structures/rules/index.js.map +1 -0
  123. package/linthost/ast_helpers.go +30 -5
  124. package/linthost/compile.go +33 -2
  125. package/linthost/config.go +118 -71
  126. package/linthost/config_format.go +270 -104
  127. package/linthost/directives.go +67 -25
  128. package/linthost/dispatch.go +14 -3
  129. package/linthost/engine.go +160 -40
  130. package/linthost/fix.go +10 -3
  131. package/linthost/flags_gen.go +17 -15
  132. package/linthost/format.go +222 -25
  133. package/linthost/format_editor_settings.go +262 -0
  134. package/linthost/host.go +40 -3
  135. package/linthost/lsp.go +898 -0
  136. package/linthost/print_dispatch.go +5 -2
  137. package/linthost/print_engine.go +5 -5
  138. package/linthost/print_nodes_call.go +149 -67
  139. package/linthost/print_nodes_function.go +27 -2
  140. package/linthost/print_nodes_list.go +40 -5
  141. package/linthost/print_nodes_object.go +1 -1
  142. package/linthost/print_nodes_ternary.go +86 -0
  143. package/linthost/rule_names.go +14 -0
  144. package/linthost/rules_arrays.go +2 -2
  145. package/linthost/rules_boundaries.go +532 -0
  146. package/linthost/rules_camelcase.go +133 -0
  147. package/linthost/rules_complexity.go +95 -0
  148. package/linthost/rules_consistent_return.go +130 -0
  149. package/linthost/rules_console.go +1 -1
  150. package/linthost/rules_core_extra.go +739 -0
  151. package/linthost/rules_curly.go +70 -0
  152. package/linthost/rules_cypress.go +608 -0
  153. package/linthost/rules_debugger.go +2 -2
  154. package/linthost/rules_default_case.go +39 -0
  155. package/linthost/rules_default_case_last.go +46 -0
  156. package/linthost/rules_dupes.go +3 -3
  157. package/linthost/rules_empty.go +3 -3
  158. package/linthost/rules_escape.go +44 -24
  159. package/linthost/rules_eval.go +2 -2
  160. package/linthost/rules_finally.go +2 -2
  161. package/linthost/rules_format_arrow_parens.go +167 -0
  162. package/linthost/rules_format_bracket_spacing.go +117 -0
  163. package/linthost/rules_format_clause_join.go +172 -0
  164. package/linthost/rules_format_declaration_header.go +595 -0
  165. package/linthost/rules_format_indent.go +372 -0
  166. package/linthost/rules_format_jsdoc.go +5 -5
  167. package/linthost/rules_format_orphan_semi.go +106 -0
  168. package/linthost/rules_format_parameter_properties.go +175 -0
  169. package/linthost/rules_format_print_width.go +66 -55
  170. package/linthost/rules_format_quote_props.go +169 -0
  171. package/linthost/rules_format_quotes.go +76 -30
  172. package/linthost/rules_format_semi.go +186 -11
  173. package/linthost/rules_format_sort_imports.go +437 -118
  174. package/linthost/rules_format_statement_split.go +343 -0
  175. package/linthost/rules_format_ternary_nullish_parens.go +77 -0
  176. package/linthost/rules_format_trailing_comma.go +22 -3
  177. package/linthost/rules_format_whitespace.go +336 -0
  178. package/linthost/rules_functional.go +967 -0
  179. package/linthost/rules_gap.go +24 -45
  180. package/linthost/rules_grouped_accessor_pairs.go +87 -0
  181. package/linthost/rules_guard_for_in.go +198 -0
  182. package/linthost/rules_id_length.go +77 -0
  183. package/linthost/rules_imports.go +70 -2
  184. package/linthost/rules_init_declarations.go +53 -0
  185. package/linthost/rules_jest.go +618 -0
  186. package/linthost/rules_jsdoc.go +502 -0
  187. package/linthost/rules_jsx_a11y.go +1264 -0
  188. package/linthost/rules_logic.go +12 -12
  189. package/linthost/rules_loops.go +1 -1
  190. package/linthost/rules_max_classes_per_file.go +58 -0
  191. package/linthost/rules_max_depth.go +83 -0
  192. package/linthost/rules_max_lines.go +101 -0
  193. package/linthost/rules_max_lines_per_function.go +57 -0
  194. package/linthost/rules_max_nested_callbacks.go +61 -0
  195. package/linthost/rules_max_params.go +49 -0
  196. package/linthost/rules_max_statements.go +59 -0
  197. package/linthost/rules_misc.go +1 -1
  198. package/linthost/rules_nextjs.go +697 -0
  199. package/linthost/rules_no_else_return.go +75 -0
  200. package/linthost/rules_no_empty_named_blocks.go +91 -0
  201. package/linthost/rules_no_extend_native.go +51 -0
  202. package/linthost/rules_no_import_assign.go +140 -0
  203. package/linthost/rules_no_invalid_this.go +52 -0
  204. package/linthost/rules_no_loop_func.go +85 -0
  205. package/linthost/rules_no_magic_numbers.go +123 -0
  206. package/linthost/rules_no_mixed_operators.go +80 -0
  207. package/linthost/rules_no_param_reassign.go +98 -0
  208. package/linthost/rules_no_redeclare.go +270 -0
  209. package/linthost/rules_no_restricted_imports.go +105 -0
  210. package/linthost/rules_no_restricted_syntax.go +49 -0
  211. package/linthost/rules_no_shadow.go +147 -0
  212. package/linthost/rules_no_unreachable.go +77 -0
  213. package/linthost/rules_no_useless_assignment.go +120 -0
  214. package/linthost/rules_no_useless_constructor.go +245 -0
  215. package/linthost/rules_no_useless_return.go +51 -0
  216. package/linthost/rules_params.go +1 -1
  217. package/linthost/rules_playwright.go +788 -0
  218. package/linthost/rules_prefer_arrow_callback.go +124 -0
  219. package/linthost/rules_prefer_destructuring.go +98 -0
  220. package/linthost/rules_prefer_named_capture_group.go +129 -0
  221. package/linthost/rules_prefer_rest_params.go +94 -0
  222. package/linthost/rules_problems.go +41 -30
  223. package/linthost/rules_promise.go +1057 -2
  224. package/linthost/rules_protos.go +2 -2
  225. package/linthost/rules_react.go +773 -0
  226. package/linthost/rules_react_extras.go +227 -0
  227. package/linthost/rules_react_hooks.go +848 -0
  228. package/linthost/rules_react_perf.go +293 -0
  229. package/linthost/rules_react_refresh.go +583 -0
  230. package/linthost/rules_regexp.go +410 -0
  231. package/linthost/rules_security.go +830 -0
  232. package/linthost/rules_self.go +2 -2
  233. package/linthost/rules_solid.go +1073 -0
  234. package/linthost/rules_sort_imports.go +69 -0
  235. package/linthost/rules_sort_keys.go +134 -0
  236. package/linthost/rules_storybook.go +1176 -0
  237. package/linthost/rules_strings.go +4 -4
  238. package/linthost/rules_suggestions.go +38 -38
  239. package/linthost/rules_tanstack_query.go +844 -0
  240. package/linthost/rules_testing_library.go +1204 -0
  241. package/linthost/rules_throw.go +1 -1
  242. package/linthost/rules_ts.go +19 -19
  243. package/linthost/rules_ts_async.go +399 -0
  244. package/linthost/rules_ts_class_literal_property_style.go +115 -0
  245. package/linthost/rules_ts_consistent_type_exports.go +256 -0
  246. package/linthost/rules_ts_explicit_function_return_type.go +67 -0
  247. package/linthost/rules_ts_extra.go +159 -36
  248. package/linthost/rules_ts_no_base_to_string.go +218 -0
  249. package/linthost/rules_ts_no_confusing_void.go +72 -0
  250. package/linthost/rules_ts_no_deprecated.go +195 -0
  251. package/linthost/rules_ts_no_for_in_array.go +84 -0
  252. package/linthost/rules_ts_no_magic_numbers.go +124 -0
  253. package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
  254. package/linthost/rules_ts_no_misused_spread.go +104 -0
  255. package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
  256. package/linthost/rules_ts_no_restricted_types.go +62 -0
  257. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
  258. package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
  259. package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
  260. package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
  261. package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
  262. package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
  263. package/linthost/rules_ts_no_unsafe_argument.go +82 -0
  264. package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
  265. package/linthost/rules_ts_no_unsafe_call.go +82 -0
  266. package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
  267. package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
  268. package/linthost/rules_ts_no_unsafe_return.go +126 -0
  269. package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
  270. package/linthost/rules_ts_no_useless_constructor.go +52 -0
  271. package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
  272. package/linthost/rules_ts_parameter_properties.go +38 -0
  273. package/linthost/rules_ts_prefer_find.go +178 -0
  274. package/linthost/rules_ts_prefer_includes.go +255 -0
  275. package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
  276. package/linthost/rules_ts_prefer_optional_chain.go +228 -0
  277. package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
  278. package/linthost/rules_ts_prefer_readonly.go +73 -0
  279. package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
  280. package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
  281. package/linthost/rules_ts_prefer_return_this_type.go +135 -0
  282. package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
  283. package/linthost/rules_ts_promise_function_async.go +77 -0
  284. package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
  285. package/linthost/rules_ts_require_array_sort_compare.go +96 -0
  286. package/linthost/rules_ts_restrict_plus_operands.go +127 -0
  287. package/linthost/rules_ts_restrict_template_expressions.go +95 -0
  288. package/linthost/rules_ts_simple.go +387 -0
  289. package/linthost/rules_ts_sort_type_constituents.go +144 -0
  290. package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
  291. package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
  292. package/linthost/rules_ts_unbound_method.go +126 -0
  293. package/linthost/rules_tsdoc.go +136 -0
  294. package/linthost/rules_unicorn_better_regex.go +27 -0
  295. package/linthost/rules_unicorn_catch_error_name.go +46 -0
  296. package/linthost/rules_unicorn_consistent_assert.go +47 -0
  297. package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
  298. package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
  299. package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
  300. package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
  301. package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
  302. package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
  303. package/linthost/rules_unicorn_custom_error_definition.go +138 -0
  304. package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
  305. package/linthost/rules_unicorn_error_message.go +64 -0
  306. package/linthost/rules_unicorn_escape_case.go +51 -0
  307. package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
  308. package/linthost/rules_unicorn_explicit_length_check.go +88 -0
  309. package/linthost/rules_unicorn_filename_case.go +29 -0
  310. package/linthost/rules_unicorn_import_style.go +28 -0
  311. package/linthost/rules_unicorn_isolated_functions.go +29 -0
  312. package/linthost/rules_unicorn_new_for_builtins.go +87 -0
  313. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
  314. package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
  315. package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
  316. package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
  317. package/linthost/rules_unicorn_no_array_for_each.go +40 -0
  318. package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
  319. package/linthost/rules_unicorn_no_array_reduce.go +41 -0
  320. package/linthost/rules_unicorn_no_array_reverse.go +44 -0
  321. package/linthost/rules_unicorn_no_array_sort.go +43 -0
  322. package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
  323. package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
  324. package/linthost/rules_unicorn_no_console_spaces.go +61 -0
  325. package/linthost/rules_unicorn_no_document_cookie.go +41 -0
  326. package/linthost/rules_unicorn_no_empty_file.go +44 -0
  327. package/linthost/rules_unicorn_no_for_loop.go +102 -0
  328. package/linthost/rules_unicorn_no_hex_escape.go +42 -0
  329. package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
  330. package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
  331. package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
  332. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
  333. package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
  334. package/linthost/rules_unicorn_no_lonely_if.go +44 -0
  335. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
  336. package/linthost/rules_unicorn_no_named_default.go +54 -0
  337. package/linthost/rules_unicorn_no_negated_condition.go +85 -0
  338. package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
  339. package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
  340. package/linthost/rules_unicorn_no_new_array.go +30 -0
  341. package/linthost/rules_unicorn_no_new_buffer.go +31 -0
  342. package/linthost/rules_unicorn_no_null.go +24 -0
  343. package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
  344. package/linthost/rules_unicorn_no_process_exit.go +43 -0
  345. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
  346. package/linthost/rules_unicorn_no_static_only_class.go +56 -0
  347. package/linthost/rules_unicorn_no_thenable.go +74 -0
  348. package/linthost/rules_unicorn_no_this_assignment.go +35 -0
  349. package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
  350. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
  351. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
  352. package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
  353. package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
  354. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
  355. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
  356. package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
  357. package/linthost/rules_unicorn_no_unused_properties.go +30 -0
  358. package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
  359. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
  360. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
  361. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
  362. package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
  363. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
  364. package/linthost/rules_unicorn_no_useless_spread.go +67 -0
  365. package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
  366. package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
  367. package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
  368. package/linthost/rules_unicorn_number_literal_case.go +69 -0
  369. package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
  370. package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
  371. package/linthost/rules_unicorn_prefer_array_find.go +51 -0
  372. package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
  373. package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
  374. package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
  375. package/linthost/rules_unicorn_prefer_array_some.go +67 -0
  376. package/linthost/rules_unicorn_prefer_at.go +77 -0
  377. package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
  378. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
  379. package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
  380. package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
  381. package/linthost/rules_unicorn_prefer_code_point.go +49 -0
  382. package/linthost/rules_unicorn_prefer_date_now.go +78 -0
  383. package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
  384. package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
  385. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
  386. package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
  387. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
  388. package/linthost/rules_unicorn_prefer_event_target.go +36 -0
  389. package/linthost/rules_unicorn_prefer_export_from.go +129 -0
  390. package/linthost/rules_unicorn_prefer_global_this.go +127 -0
  391. package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
  392. package/linthost/rules_unicorn_prefer_includes.go +149 -0
  393. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
  394. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
  395. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
  396. package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
  397. package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
  398. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
  399. package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
  400. package/linthost/rules_unicorn_prefer_module.go +50 -0
  401. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
  402. package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
  403. package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
  404. package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
  405. package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
  406. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
  407. package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
  408. package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
  409. package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
  410. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
  411. package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
  412. package/linthost/rules_unicorn_prefer_set_has.go +42 -0
  413. package/linthost/rules_unicorn_prefer_set_size.go +48 -0
  414. package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
  415. package/linthost/rules_unicorn_prefer_single_call.go +96 -0
  416. package/linthost/rules_unicorn_prefer_spread.go +51 -0
  417. package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
  418. package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
  419. package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
  420. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
  421. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
  422. package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
  423. package/linthost/rules_unicorn_prefer_switch.go +103 -0
  424. package/linthost/rules_unicorn_prefer_ternary.go +71 -0
  425. package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
  426. package/linthost/rules_unicorn_prefer_type_error.go +127 -0
  427. package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
  428. package/linthost/rules_unicorn_relative_url_style.go +49 -0
  429. package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
  430. package/linthost/rules_unicorn_require_module_attributes.go +54 -0
  431. package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
  432. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
  433. package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
  434. package/linthost/rules_unicorn_string_content.go +27 -0
  435. package/linthost/rules_unicorn_switch_case_braces.go +42 -0
  436. package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
  437. package/linthost/rules_unicorn_template_indent.go +28 -0
  438. package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
  439. package/linthost/rules_unicorn_throw_new_error.go +61 -0
  440. package/linthost/rules_var.go +10 -4
  441. package/linthost/rules_vitest.go +568 -0
  442. package/package.json +3 -3
  443. package/plugin/main.go +49 -3
  444. package/rule/astutil/astutil.go +10 -3
  445. package/rule/rule.go +12 -10
  446. package/src/defaultFormat.ts +17 -10
  447. package/src/index.ts +65 -43
  448. package/src/structures/ITtscLintConfig.ts +14 -8
  449. package/src/structures/TtscLintRuleSetting.ts +55 -0
  450. package/src/structures/format/ITtscLintFormat.ts +141 -0
  451. package/src/structures/format/ITtscLintFormatJsDoc.ts +18 -0
  452. package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
  453. package/src/structures/format/index.ts +3 -0
  454. package/src/structures/index.ts +3 -4
  455. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +117 -0
  456. package/src/structures/rules/ITtscLintBoundariesRules.ts +91 -0
  457. package/src/structures/rules/ITtscLintContributorRules.ts +20 -0
  458. package/src/structures/rules/ITtscLintCoreRules.ts +1378 -0
  459. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
  460. package/src/structures/rules/ITtscLintCypressRules.ts +141 -0
  461. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +200 -0
  462. package/src/structures/rules/ITtscLintFunctionalRules.ts +197 -0
  463. package/src/structures/rules/ITtscLintJestRules.ts +209 -0
  464. package/src/structures/rules/ITtscLintJsdocRules.ts +146 -0
  465. package/src/structures/rules/ITtscLintJsxA11yRules.ts +331 -0
  466. package/src/structures/rules/ITtscLintNextjsRules.ts +201 -0
  467. package/src/structures/rules/ITtscLintPlaywrightRules.ts +343 -0
  468. package/src/structures/rules/ITtscLintPromiseRules.ts +196 -0
  469. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
  470. package/src/structures/rules/ITtscLintReactPerfRules.ts +53 -0
  471. package/src/structures/rules/ITtscLintReactRuleOptions.ts +41 -0
  472. package/src/structures/rules/ITtscLintReactRules.ts +308 -0
  473. package/src/structures/rules/ITtscLintRegexpRules.ts +204 -0
  474. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +88 -0
  475. package/src/structures/rules/ITtscLintRules.ts +77 -0
  476. package/src/structures/rules/ITtscLintSecurityRules.ts +155 -0
  477. package/src/structures/rules/ITtscLintSolidRules.ts +199 -0
  478. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +22 -0
  479. package/src/structures/rules/ITtscLintStorybookRules.ts +184 -0
  480. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +96 -0
  481. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +23 -0
  482. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +325 -0
  483. package/src/structures/rules/ITtscLintTypeScriptRules.ts +1172 -0
  484. package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
  485. package/src/structures/rules/ITtscLintVitestRules.ts +146 -0
  486. package/src/structures/rules/index.ts +31 -0
  487. package/lib/structures/ITtscLintFormatConfig.d.ts +0 -153
  488. package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
  489. package/lib/structures/TtscLintRule.d.ts +0 -17
  490. package/lib/structures/TtscLintRule.js.map +0 -1
  491. package/lib/structures/TtscLintRuleMap.d.ts +0 -46
  492. package/lib/structures/TtscLintRuleMap.js.map +0 -1
  493. package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
  494. package/lib/structures/TtscLintRuleOptions.js.map +0 -1
  495. package/src/structures/ITtscLintFormatConfig.ts +0 -168
  496. package/src/structures/TtscLintRule.ts +0 -160
  497. package/src/structures/TtscLintRuleMap.ts +0 -55
  498. package/src/structures/TtscLintRuleOptions.ts +0 -151
@@ -125,13 +125,13 @@ type RuleResolver interface {
125
125
  // ResolveRules implements RuleResolver. A flat RuleConfig has no glob scoping,
126
126
  // so every file receives the full map unchanged.
127
127
  func (c RuleConfig) ResolveRules(string) ResolvedRuleConfig {
128
- return ResolvedRuleConfig{Rules: c}
128
+ return ResolvedRuleConfig{Rules: normalizeRuleConfigKeys(c)}
129
129
  }
130
130
 
131
131
  // ActiveRuleNames implements RuleResolver. Returns rule names whose severity
132
132
  // is not SeverityOff, sorted for deterministic engine dispatch-table construction.
133
133
  func (c RuleConfig) ActiveRuleNames() []string {
134
- return sortedRuleNames(c, func(sev Severity) bool { return sev != SeverityOff })
134
+ return sortedRuleNames(normalizeRuleConfigKeys(c), func(sev Severity) bool { return sev != SeverityOff })
135
135
  }
136
136
 
137
137
  // EnabledRuleConfig implements RuleResolver. Returns a copy containing only the
@@ -140,7 +140,7 @@ func (c RuleConfig) EnabledRuleConfig() RuleConfig {
140
140
  out := RuleConfig{}
141
141
  for name, sev := range c {
142
142
  if sev != SeverityOff {
143
- out[name] = sev
143
+ out[normalizeBuiltinRuleName(name)] = sev
144
144
  }
145
145
  }
146
146
  return out
@@ -151,6 +151,17 @@ func (c RuleConfig) EnabledRuleConfig() RuleConfig {
151
151
  // predate option support.
152
152
  func (RuleConfig) RuleOptions(string) json.RawMessage { return nil }
153
153
 
154
+ func normalizeRuleConfigKeys(c RuleConfig) RuleConfig {
155
+ if len(c) == 0 {
156
+ return c
157
+ }
158
+ out := RuleConfig{}
159
+ for name, sev := range c {
160
+ out[normalizeBuiltinRuleName(name)] = sev
161
+ }
162
+ return out
163
+ }
164
+
154
165
  // InlineRuleResolver pairs a severity map with an options map. The fields
155
166
  // are public so tests can construct one without going through
156
167
  // ParseRulesWithOptions.
@@ -162,7 +173,7 @@ type InlineRuleResolver struct {
162
173
  // ResolveRules implements RuleResolver. Inline rules have no glob scoping;
163
174
  // the full map applies to every file.
164
175
  func (r InlineRuleResolver) ResolveRules(string) ResolvedRuleConfig {
165
- return ResolvedRuleConfig{Rules: r.Rules}
176
+ return ResolvedRuleConfig{Rules: normalizeRuleConfigKeys(r.Rules)}
166
177
  }
167
178
 
168
179
  // ActiveRuleNames implements RuleResolver by delegating to the inner RuleConfig.
@@ -182,7 +193,14 @@ func (r InlineRuleResolver) RuleOptions(name string) json.RawMessage {
182
193
  if r.Options == nil {
183
194
  return nil
184
195
  }
185
- return r.Options[name]
196
+ if raw := r.Options[name]; len(raw) > 0 {
197
+ return raw
198
+ }
199
+ canonical := normalizeBuiltinRuleName(name)
200
+ if raw := r.Options[canonical]; len(raw) > 0 {
201
+ return raw
202
+ }
203
+ return nil
186
204
  }
187
205
 
188
206
  // ConfigStore holds the parsed representation of a lint config file. It
@@ -210,7 +228,14 @@ func (s *ConfigStore) RuleOptions(name string) json.RawMessage {
210
228
  if s == nil {
211
229
  return nil
212
230
  }
213
- return s.options[name]
231
+ if raw := s.options[name]; len(raw) > 0 {
232
+ return raw
233
+ }
234
+ canonical := normalizeBuiltinRuleName(name)
235
+ if raw := s.options[canonical]; len(raw) > 0 {
236
+ return raw
237
+ }
238
+ return nil
214
239
  }
215
240
 
216
241
  // ConfigEntry is the parsed form of one config file in the extends chain.
@@ -245,7 +270,7 @@ func (s *ConfigStore) ResolveRules(fileName string) ResolvedRuleConfig {
245
270
  continue
246
271
  }
247
272
  for name, sev := range entry.Rules {
248
- out[name] = sev
273
+ out[normalizeBuiltinRuleName(name)] = sev
249
274
  }
250
275
  }
251
276
  return ResolvedRuleConfig{Rules: out}
@@ -266,7 +291,7 @@ func (s *ConfigStore) ActiveRuleNames() []string {
266
291
  }
267
292
  for name, sev := range entry.Rules {
268
293
  if sev != SeverityOff {
269
- active[name] = sev
294
+ active[normalizeBuiltinRuleName(name)] = sev
270
295
  }
271
296
  }
272
297
  }
@@ -289,8 +314,9 @@ func (s *ConfigStore) EnabledRuleConfig() RuleConfig {
289
314
  if sev == SeverityOff {
290
315
  continue
291
316
  }
292
- if out[name] != SeverityError {
293
- out[name] = sev
317
+ canonical := normalizeBuiltinRuleName(name)
318
+ if out[canonical] != SeverityError {
319
+ out[canonical] = sev
294
320
  }
295
321
  }
296
322
  }
@@ -310,7 +336,7 @@ func (s *ConfigStore) Flatten() RuleConfig {
310
336
  continue
311
337
  }
312
338
  for name, sev := range entry.Rules {
313
- out[name] = sev
339
+ out[normalizeBuiltinRuleName(name)] = sev
314
340
  }
315
341
  }
316
342
  return out
@@ -565,7 +591,18 @@ func collectConfigObject(store *ConfigStore, raw any, baseDir, path string, chai
565
591
  if !ok {
566
592
  return fmt.Errorf("@ttsc/lint: %s.rules must be a rule severity map, got %T", path, rulesValue)
567
593
  }
594
+ // `format/*` rules are configured exclusively through the `format`
595
+ // block; they are never valid keys in `rules`. Silently drop any that
596
+ // appear, the same way an unknown rule name is ignored (see
597
+ // parseExternalRuleMapInto): a config must not carry a formatter
598
+ // setting in two places, and a stray `format/*` here is simply not the
599
+ // formatting surface, so it has no effect rather than erroring.
568
600
  rulesMap = typedMap
601
+ for key := range rulesMap {
602
+ if isFormatRuleName(key) {
603
+ delete(rulesMap, key)
604
+ }
605
+ }
569
606
  }
570
607
  merged := mergeRuleMaps(formatRulesRaw, rulesMap)
571
608
  if len(merged) > 0 {
@@ -620,7 +657,7 @@ func collectExternalRuleMapWithOptions(out RuleConfig, opts RuleOptionsMap, raw
620
657
  if err != nil {
621
658
  return fmt.Errorf("@ttsc/lint: rule %q: %w", name, err)
622
659
  }
623
- canonical := normalizeExternalRuleName(name)
660
+ canonical := normalizeBuiltinRuleName(name)
624
661
  out[canonical] = sev
625
662
  if opts != nil && len(ruleOpts) > 0 {
626
663
  opts[canonical] = ruleOpts
@@ -649,14 +686,6 @@ func rejectUnknownConfigKeys(value map[string]any, path string) error {
649
686
  return nil
650
687
  }
651
688
 
652
- // normalizeExternalRuleName strips the standard typescript-eslint namespace
653
- // prefixes so that rules like "@typescript-eslint/no-explicit-any" and the
654
- // bare "no-explicit-any" key both resolve to the same engine-internal name.
655
- func normalizeExternalRuleName(name string) string {
656
- name = strings.TrimPrefix(name, "@typescript-eslint/")
657
- return strings.TrimPrefix(name, "typescript-eslint/")
658
- }
659
-
660
689
  // parsePatternList coerces a raw config value to a string slice for use as a
661
690
  // `files` or `ignores` pattern list. Accepts a bare string (single-pattern
662
691
  // shorthand) or a string array. Empty patterns are rejected eagerly.
@@ -743,7 +772,7 @@ func LoadConfigResolver(entry *PluginEntry, cwd, tsconfigPath string) (RuleResol
743
772
  return nil, err
744
773
  }
745
774
  if discovered == "" {
746
- return nil, fmt.Errorf("@ttsc/lint: no lint.config.* or ttsc-lint.config.* file found (searched upward from %s); create one or set \"configFile\" on the tsconfig plugin entry", cwd)
775
+ return nil, fmt.Errorf("%w (searched upward from %s); create one or set \"configFile\" on the tsconfig plugin entry", errNoLintConfigFile, cwd)
747
776
  }
748
777
  return loadConfigResolver(discovered)
749
778
  }
@@ -1029,13 +1058,66 @@ func loadJSONConfigFile(location string) (any, error) {
1029
1058
  return out, nil
1030
1059
  }
1031
1060
 
1061
+ // serializableConfigKeys is the single source of truth for the ITtscLintConfig
1062
+ // keys that survive the JSON round trip from a config-loader subprocess back to
1063
+ // the Go sidecar. Both the .js/.cjs/.mjs loader (loadScriptConfigFile) and the
1064
+ // .ts/.cts/.mts loader (typeScriptConfigLoaderSource) splice this list into the
1065
+ // `toSerializableConfig` key whitelist of their generated scripts, so the set
1066
+ // of copied keys is defined here once rather than duplicated per loader.
1067
+ var serializableConfigKeys = []string{"files", "ignores", "extends", "plugins", "rules", "format"}
1068
+
1069
+ // serializableConfigKeysLiteral renders serializableConfigKeys as a
1070
+ // JS/TS array literal (e.g. `"files", "ignores", ...`) for splicing into the
1071
+ // generated loader scripts' `toSerializableConfig` whitelist.
1072
+ func serializableConfigKeysLiteral() string {
1073
+ quoted := make([]string, len(serializableConfigKeys))
1074
+ for i, key := range serializableConfigKeys {
1075
+ quoted[i] = fmt.Sprintf("%q", key)
1076
+ }
1077
+ return strings.Join(quoted, ", ")
1078
+ }
1079
+
1080
+ // runConfigLoaderCommand runs a prepared config-loader subprocess (`cmd`),
1081
+ // then turns its result into a parsed config object. It owns the shared tail
1082
+ // of both subprocess-backed loaders: capturing stdout, distinguishing a
1083
+ // timeout from a process error (extracting the subprocess stderr when present),
1084
+ // JSON-parsing the output, and rejecting a non-object result. `ctx` is the
1085
+ // timeout context the caller bound `cmd` to; `location` is the config file path
1086
+ // for error messages; `label` is the human-readable subject (e.g. "config
1087
+ // file" or "TypeScript config file") spliced into the load/parse error
1088
+ // prefixes so each loader keeps its own wording.
1089
+ func runConfigLoaderCommand(ctx context.Context, cmd *exec.Cmd, location, label string) (any, error) {
1090
+ output, err := cmd.Output()
1091
+ if err != nil {
1092
+ if ctx.Err() == context.DeadlineExceeded {
1093
+ return nil, fmt.Errorf("@ttsc/lint: load %s %s: timed out after %s", label, location, configLoaderTimeout)
1094
+ }
1095
+ stderr := ""
1096
+ if exit, ok := err.(*exec.ExitError); ok {
1097
+ stderr = strings.TrimSpace(string(exit.Stderr))
1098
+ }
1099
+ if stderr != "" {
1100
+ return nil, fmt.Errorf("@ttsc/lint: load %s %s: %s", label, location, stderr)
1101
+ }
1102
+ return nil, fmt.Errorf("@ttsc/lint: load %s %s: %w", label, location, err)
1103
+ }
1104
+ var out any
1105
+ if err := json.Unmarshal(output, &out); err != nil {
1106
+ return nil, fmt.Errorf("@ttsc/lint: parse %s %s output: %w", label, location, err)
1107
+ }
1108
+ if !isConfigObject(out) {
1109
+ return nil, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
1110
+ }
1111
+ return out, nil
1112
+ }
1113
+
1032
1114
  // loadScriptConfigFile evaluates a .js/.cjs/.mjs config file by running a
1033
1115
  // Node subprocess that dynamic-imports the file, resolves the exported config
1034
1116
  // through the same 8-hop default/config unwrap used by the TS loader, and
1035
1117
  // serializes the result as JSON to stdout. The subprocess has a
1036
1118
  // configLoaderTimeout deadline to prevent user code from hanging indefinitely.
1037
1119
  func loadScriptConfigFile(location string) (any, error) {
1038
- const script = `
1120
+ script := fmt.Sprintf(`
1039
1121
  const { pathToFileURL } = require("node:url");
1040
1122
 
1041
1123
  (async () => {
@@ -1075,14 +1157,14 @@ const { pathToFileURL } = require("node:url");
1075
1157
  // whose only key is ` + "`" + `format` + "`" + ` is not silently dropped.
1076
1158
  function toSerializableConfig(value) {
1077
1159
  const out = {};
1078
- for (const key of ["files", "ignores", "extends", "plugins", "rules", "format"]) {
1160
+ for (const key of [%s]) {
1079
1161
  if (Object.prototype.hasOwnProperty.call(value, key)) {
1080
1162
  out[key] = value[key];
1081
1163
  }
1082
1164
  }
1083
1165
  return out;
1084
1166
  }
1085
- `
1167
+ `, serializableConfigKeysLiteral())
1086
1168
  node := os.Getenv("TTSC_NODE_BINARY")
1087
1169
  if node == "" {
1088
1170
  node = "node"
@@ -1090,28 +1172,7 @@ function toSerializableConfig(value) {
1090
1172
  ctx, cancel := context.WithTimeout(context.Background(), configLoaderTimeout)
1091
1173
  defer cancel()
1092
1174
  cmd := exec.CommandContext(ctx, node, "-e", script, location)
1093
- output, err := cmd.Output()
1094
- if err != nil {
1095
- if ctx.Err() == context.DeadlineExceeded {
1096
- return nil, fmt.Errorf("@ttsc/lint: load config file %s: timed out after %s", location, configLoaderTimeout)
1097
- }
1098
- stderr := ""
1099
- if exit, ok := err.(*exec.ExitError); ok {
1100
- stderr = strings.TrimSpace(string(exit.Stderr))
1101
- }
1102
- if stderr != "" {
1103
- return nil, fmt.Errorf("@ttsc/lint: load config file %s: %s", location, stderr)
1104
- }
1105
- return nil, fmt.Errorf("@ttsc/lint: load config file %s: %w", location, err)
1106
- }
1107
- var out any
1108
- if err := json.Unmarshal(output, &out); err != nil {
1109
- return nil, fmt.Errorf("@ttsc/lint: parse config file %s output: %w", location, err)
1110
- }
1111
- if !isConfigObject(out) {
1112
- return nil, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
1113
- }
1114
- return out, nil
1175
+ return runConfigLoaderCommand(ctx, cmd, location, "config file")
1115
1176
  }
1116
1177
 
1117
1178
  // loadTypeScriptConfigFile evaluates a .ts/.cts/.mts config file by writing
@@ -1170,28 +1231,7 @@ func loadTypeScriptConfigFile(location string) (any, error) {
1170
1231
  defer cancel()
1171
1232
  cmd := ttsxCommandContext(ctx, args...)
1172
1233
  cmd.Env = nodeConfigLoaderEnv(location)
1173
- output, err := cmd.Output()
1174
- if err != nil {
1175
- if ctx.Err() == context.DeadlineExceeded {
1176
- return nil, fmt.Errorf("@ttsc/lint: load TypeScript config file %s: timed out after %s", location, configLoaderTimeout)
1177
- }
1178
- stderr := ""
1179
- if exit, ok := err.(*exec.ExitError); ok {
1180
- stderr = strings.TrimSpace(string(exit.Stderr))
1181
- }
1182
- if stderr != "" {
1183
- return nil, fmt.Errorf("@ttsc/lint: load TypeScript config file %s: %s", location, stderr)
1184
- }
1185
- return nil, fmt.Errorf("@ttsc/lint: load TypeScript config file %s: %w", location, err)
1186
- }
1187
- var out any
1188
- if err := json.Unmarshal(output, &out); err != nil {
1189
- return nil, fmt.Errorf("@ttsc/lint: parse TypeScript config file %s output: %w", location, err)
1190
- }
1191
- if !isConfigObject(out) {
1192
- return nil, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
1193
- }
1194
- return out, nil
1234
+ return runConfigLoaderCommand(ctx, cmd, location, "TypeScript config file")
1195
1235
  }
1196
1236
 
1197
1237
  // isConfigObject reports whether `value` is a top-level config object. A lint
@@ -1279,14 +1319,14 @@ function hasOwn(value: Record<string, unknown>, key: string): boolean {
1279
1319
  // whose only key is "format" is not silently dropped.
1280
1320
  function toSerializableConfig(value: Record<string, unknown>): Record<string, unknown> {
1281
1321
  const out: Record<string, unknown> = {};
1282
- for (const key of ["files", "ignores", "extends", "plugins", "rules", "format"]) {
1322
+ for (const key of [%s]) {
1283
1323
  if (hasOwn(value, key)) {
1284
1324
  out[key] = value[key];
1285
1325
  }
1286
1326
  }
1287
1327
  return out;
1288
1328
  }
1289
- `, importLiteral)
1329
+ `, importLiteral, serializableConfigKeysLiteral())
1290
1330
  }
1291
1331
 
1292
1332
  // typeScriptConfigLoaderTsconfig generates the JSON content of the ephemeral
@@ -1704,5 +1744,12 @@ func (c RuleConfig) Severity(name string) Severity {
1704
1744
  if c == nil {
1705
1745
  return SeverityOff
1706
1746
  }
1707
- return c[name]
1747
+ if sev, ok := c[name]; ok {
1748
+ return sev
1749
+ }
1750
+ canonical := normalizeBuiltinRuleName(name)
1751
+ if sev, ok := c[canonical]; ok {
1752
+ return sev
1753
+ }
1754
+ return SeverityOff
1708
1755
  }