@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
@@ -0,0 +1,39 @@
1
+ // defaultCase: a `switch` statement that omits the `default` clause
2
+ // silently drops every discriminant value not matched by an explicit
3
+ // `case` label. The rule wants the catch-all path written out so an
4
+ // unhandled discriminant becomes an intentional branch — even if that
5
+ // branch is a `// no default` comment marker.
6
+ //
7
+ // AST-only: each visited `SwitchStatement` checks its `CaseBlock`
8
+ // clauses for any node of kind `DefaultClause`. The rule reports on the
9
+ // switch keyword itself rather than the case block so the diagnostic
10
+ // lands at the head of the statement.
11
+ // https://eslint.org/docs/latest/rules/default-case
12
+ package linthost
13
+
14
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
15
+
16
+ type defaultCase struct{}
17
+
18
+ func (defaultCase) Name() string { return "default-case" }
19
+ func (defaultCase) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSwitchStatement} }
20
+ func (defaultCase) Check(ctx *Context, node *shimast.Node) {
21
+ sw := node.AsSwitchStatement()
22
+ if sw == nil || sw.CaseBlock == nil {
23
+ return
24
+ }
25
+ block := sw.CaseBlock.AsCaseBlock()
26
+ if block == nil || block.Clauses == nil {
27
+ return
28
+ }
29
+ for _, clause := range block.Clauses.Nodes {
30
+ if clause != nil && clause.Kind == shimast.KindDefaultClause {
31
+ return
32
+ }
33
+ }
34
+ ctx.Report(node, "Expected a default case.")
35
+ }
36
+
37
+ func init() {
38
+ Register(defaultCase{})
39
+ }
@@ -0,0 +1,46 @@
1
+ // defaultCaseLast: a `switch` statement whose `default` clause is not
2
+ // the final clause changes fall-through semantics in a way that almost
3
+ // never matches the author's intent — running `default` then falling
4
+ // into `case "b"` is rarely what a misordered switch wants. The rule
5
+ // requires `default` to appear after every `case` label.
6
+ //
7
+ // AST-only: each visited `SwitchStatement` walks its `CaseBlock`
8
+ // clauses, and any `DefaultClause` that is not the last element is
9
+ // reported on the clause itself.
10
+ // https://eslint.org/docs/latest/rules/default-case-last
11
+ package linthost
12
+
13
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
14
+
15
+ type defaultCaseLast struct{}
16
+
17
+ func (defaultCaseLast) Name() string { return "default-case-last" }
18
+ func (defaultCaseLast) Visits() []shimast.Kind {
19
+ return []shimast.Kind{shimast.KindSwitchStatement}
20
+ }
21
+ func (defaultCaseLast) Check(ctx *Context, node *shimast.Node) {
22
+ sw := node.AsSwitchStatement()
23
+ if sw == nil || sw.CaseBlock == nil {
24
+ return
25
+ }
26
+ block := sw.CaseBlock.AsCaseBlock()
27
+ if block == nil || block.Clauses == nil {
28
+ return
29
+ }
30
+ clauses := block.Clauses.Nodes
31
+ if len(clauses) == 0 {
32
+ return
33
+ }
34
+ last := clauses[len(clauses)-1]
35
+ for i := 0; i < len(clauses)-1; i++ {
36
+ clause := clauses[i]
37
+ if clause != nil && clause.Kind == shimast.KindDefaultClause {
38
+ _ = last
39
+ ctx.Report(clause, "Default clause should be the last clause.")
40
+ }
41
+ }
42
+ }
43
+
44
+ func init() {
45
+ Register(defaultCaseLast{})
46
+ }
@@ -2,7 +2,7 @@ package linthost
2
2
 
3
3
  import shimast "github.com/microsoft/typescript-go/shim/ast"
4
4
 
5
- // no-duplicate-case: duplicated `case` labels in a single switch.
5
+ // noDuplicateCase: duplicated `case` labels in a single switch.
6
6
  // https://eslint.org/docs/latest/rules/no-duplicate-case
7
7
  type noDuplicateCase struct{}
8
8
 
@@ -38,7 +38,7 @@ func (noDuplicateCase) Check(ctx *Context, node *shimast.Node) {
38
38
  }
39
39
  }
40
40
 
41
- // no-dupe-keys: duplicated property names in a single object literal.
41
+ // noDupeKeys: duplicated property names in a single object literal.
42
42
  // https://eslint.org/docs/latest/rules/no-dupe-keys
43
43
  type noDupeKeys struct{}
44
44
 
@@ -63,7 +63,7 @@ func (noDupeKeys) Check(ctx *Context, node *shimast.Node) {
63
63
  }
64
64
  }
65
65
 
66
- // no-dupe-args: duplicated parameter names in a single function head.
66
+ // noDupeArgs: duplicated parameter names in a single function head.
67
67
  // https://eslint.org/docs/latest/rules/no-dupe-args
68
68
  type noDupeArgs struct{}
69
69
 
@@ -2,7 +2,7 @@ package linthost
2
2
 
3
3
  import shimast "github.com/microsoft/typescript-go/shim/ast"
4
4
 
5
- // no-empty: empty block statements (`{}`), but allow empty catch
5
+ // noEmpty: empty block statements (`{}`), but allow empty catch
6
6
  // clauses since they're idiomatic for "ignore the error".
7
7
  // https://eslint.org/docs/latest/rules/no-empty
8
8
  type noEmpty struct{}
@@ -27,7 +27,7 @@ func (noEmpty) Check(ctx *Context, node *shimast.Node) {
27
27
  ctx.Report(node, "Empty block statement.")
28
28
  }
29
29
 
30
- // no-empty-function: empty function / method / arrow / accessor bodies.
30
+ // noEmptyFunction: empty function / method / arrow / accessor bodies.
31
31
  // https://eslint.org/docs/latest/rules/no-empty-function
32
32
  type noEmptyFunction struct{}
33
33
 
@@ -60,7 +60,7 @@ func (noEmptyFunction) Check(ctx *Context, node *shimast.Node) {
60
60
  }
61
61
  }
62
62
 
63
- // no-empty-pattern: `({}) => x` or `function ({}) {}` — destructuring
63
+ // noEmptyPattern: `({}) => x` or `function ({}) {}` — destructuring
64
64
  // patterns with no bindings are usually a bug.
65
65
  // https://eslint.org/docs/latest/rules/no-empty-pattern
66
66
  type noEmptyPattern struct{}
@@ -6,7 +6,7 @@ import (
6
6
  shimast "github.com/microsoft/typescript-go/shim/ast"
7
7
  )
8
8
 
9
- // no-useless-escape: flag backslashes that escape characters which do not
9
+ // noUselessEscape: flag backslashes that escape characters which do not
10
10
  // require escaping. Inside string/template literals the meaningful
11
11
  // escapes are limited to a fixed set; everywhere else the backslash is
12
12
  // noise from a copy/paste accident or a confused author. ESLint
@@ -41,13 +41,16 @@ func (noUselessEscape) Check(ctx *Context, node *shimast.Node) {
41
41
  if isInsideTaggedTemplate(node) {
42
42
  return
43
43
  }
44
- src := ctx.File.Text()
45
- pos := node.Pos()
46
- end := node.End()
47
- if pos < 0 || end > len(src) || pos >= end {
44
+ // tsgo's `node.Pos()` points at the start of leading trivia; the regex
45
+ // scanner relies on `raw[0] == '/'`, so we have to anchor on the
46
+ // post-trivia token start. String/template scans tolerate leading
47
+ // trivia bytes by accident, but using `tokenRange` for every branch
48
+ // keeps reported offsets aligned with the actual literal.
49
+ pos, end := tokenRange(ctx.File, node)
50
+ if pos < 0 || pos >= end {
48
51
  return
49
52
  }
50
- raw := src[pos:end]
53
+ raw := ctx.File.Text()[pos:end]
51
54
  // Determine quote/scan delimiters based on node kind so the
52
55
  // single-char escape whitelist matches ESLint per-context.
53
56
  switch node.Kind {
@@ -66,12 +69,18 @@ func (noUselessEscape) Check(ctx *Context, node *shimast.Node) {
66
69
  const stringValidEscapes = "'\"\\bfnrtv0xuU\n\r"
67
70
  const templateValidEscapes = "`'\"\\bfnrtv0xuU$\n\r"
68
71
 
69
- // regexValidEscapes covers characters that are *always* meaningful when
70
- // preceded by `\` in a regex pattern. Character classes and group syntax
71
- // inside a regex add more legitimate escapes (`\d`, `\w`, …); we handle
72
- // those by allowing every ASCII letter (which makes the fix conservative
73
- // — it never deletes a backslash whose meaning could be context-sensitive).
74
- const regexValidEscapes = "^$\\.*+?()[]{}|/-\n\r"
72
+ // regexNonClassValidEscapes covers characters that are meaningful when
73
+ // preceded by `\` outside a character class — every regex meta-char plus
74
+ // the line terminators. Inside a `[...]` most of these characters lose
75
+ // their special meaning (`.`, `*`, `+`, `?`, `(`, `)`, `{`, `}`, `|`, `$`,
76
+ // `/` are all literal in a class), so the in-class allowlist is narrower:
77
+ // backslash, the class-delimiting `]`, the range operator `-`, and `^`
78
+ // (which would otherwise turn the class into a negation if the escape
79
+ // were stripped). Standard shorthand escapes (`\d`, `\w`, …) and the
80
+ // Unicode/hex/control escapes are handled separately in
81
+ // `isUselessRegexEscape` and apply in both contexts.
82
+ const regexNonClassValidEscapes = "^$\\.*+?()[]{}|/-\n\r"
83
+ const regexClassValidEscapes = "\\]-^\n\r"
75
84
 
76
85
  // reportStringEscapes walks the raw source bytes of a string or template
77
86
  // literal and reports each backslash whose following character is not in
@@ -212,29 +221,40 @@ func isUselessStringEscape(ch byte, whitelist string) bool {
212
221
 
213
222
  // isUselessRegexEscape reports whether a backslash before `ch` is redundant
214
223
  // in a regex pattern. `inClass` is true when the escape occurs inside a `[…]`
215
- // character class, which widens the set of meaningful escapes.
224
+ // character class, which narrows the set of meaningful meta-char escapes:
225
+ // most regex meta-chars (`.`, `*`, `+`, `?`, `(`, `)`, `{`, `}`, `|`, `^`,
226
+ // `$`, `/`) are literal inside a class, so escaping them there is noise.
216
227
  func isUselessRegexEscape(ch byte, inClass bool) bool {
217
228
  if ch < 0x20 {
218
229
  return false
219
230
  }
220
- // Regex meta-chars and their friends.
221
- if strings.IndexByte(regexValidEscapes, ch) >= 0 {
222
- return false
223
- }
224
- // Inside a character class `]`, `\`, and `-` are still meaningful
225
- // beyond the always-list; everything else stays useless.
226
231
  if inClass {
227
- switch ch {
228
- case ']', '\\', '-', 'b':
232
+ if strings.IndexByte(regexClassValidEscapes, ch) >= 0 {
229
233
  return false
230
234
  }
235
+ } else if strings.IndexByte(regexNonClassValidEscapes, ch) >= 0 {
236
+ return false
231
237
  }
232
- // Common regex shorthand: \d \D \w \W \s \S \b \B \f \n \r \t \v \0
238
+ // Common regex shorthand: \d \D \w \W \s \S \b \f \n \r \t \v \0 \x \u \c \p \P,
239
+ // plus decimal back-references \1..\9. `\B` (non-word-boundary) and `\k<name>`
240
+ // (named backref) are only meaningful outside a character class; `\q{...}` is
241
+ // a v-flag string-disjunction escape that is also class-only-meaningful.
233
242
  switch ch {
234
- case 'd', 'D', 'w', 'W', 's', 'S', 'b', 'B', 'f', 'n', 'r', 't', 'v', '0',
235
- 'x', 'u', 'c', 'p', 'P', 'k', 'q':
243
+ case 'd', 'D', 'w', 'W', 's', 'S', 'b', 'f', 'n', 'r', 't', 'v', '0',
244
+ 'x', 'u', 'c', 'p', 'P',
245
+ '1', '2', '3', '4', '5', '6', '7', '8', '9':
236
246
  return false
237
247
  }
248
+ if !inClass {
249
+ switch ch {
250
+ case 'B', 'k':
251
+ return false
252
+ }
253
+ } else {
254
+ if ch == 'q' {
255
+ return false
256
+ }
257
+ }
238
258
  return true
239
259
  }
240
260
 
@@ -2,7 +2,7 @@ package linthost
2
2
 
3
3
  import shimast "github.com/microsoft/typescript-go/shim/ast"
4
4
 
5
- // no-eval: forbid `eval(...)` calls. Members of nested namespaces (e.g.
5
+ // noEval: forbid `eval(...)` calls. Members of nested namespaces (e.g.
6
6
  // `globalThis.eval(...)`) are not flagged here — that's
7
7
  // `no-implied-eval`, which we don't ship in v0.
8
8
  // https://eslint.org/docs/latest/rules/no-eval
@@ -20,7 +20,7 @@ func (noEval) Check(ctx *Context, node *shimast.Node) {
20
20
  }
21
21
  }
22
22
 
23
- // no-script-url: forbid `"javascript:..."` literals. Often used to inject
23
+ // noScriptUrl: forbid `"javascript:..."` literals. Often used to inject
24
24
  // inline JS via DOM `href`/`src`; legacy and dangerous.
25
25
  // https://eslint.org/docs/latest/rules/no-script-url
26
26
  type noScriptURL struct{}
@@ -2,7 +2,7 @@ package linthost
2
2
 
3
3
  import shimast "github.com/microsoft/typescript-go/shim/ast"
4
4
 
5
- // no-unsafe-finally: `return` / `break` / `continue` / `throw` inside a
5
+ // noUnsafeFinally: `return` / `break` / `continue` / `throw` inside a
6
6
  // `finally` clause silently overrides the in-flight exception or value.
7
7
  // https://eslint.org/docs/latest/rules/no-unsafe-finally
8
8
  type noUnsafeFinally struct{}
@@ -83,7 +83,7 @@ func keywordOfControl(node *shimast.Node) string {
83
83
  return "control flow"
84
84
  }
85
85
 
86
- // no-useless-catch: `catch (err) { throw err; }` adds no behavior.
86
+ // noUselessCatch: `catch (err) { throw err; }` adds no behavior.
87
87
  // https://eslint.org/docs/latest/rules/no-useless-catch
88
88
  type noUselessCatch struct{}
89
89
 
@@ -0,0 +1,167 @@
1
+ package linthost
2
+
3
+ import (
4
+ shimast "github.com/microsoft/typescript-go/shim/ast"
5
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
6
+ )
7
+
8
+ // formatArrowParens normalizes the parentheses around a single-parameter
9
+ // arrow function, mirroring Prettier's `arrowParens`:
10
+ //
11
+ // - prefer "always" (Prettier default): a bare `x => x` gains parens,
12
+ // becoming `(x) => x`.
13
+ // - prefer "avoid": `(x) => x` drops them, becoming `x => x`.
14
+ //
15
+ // Only a single parameter that is a plain identifier with no type
16
+ // annotation, default, rest, optional `?`, or modifier is affected, every
17
+ // other shape (`(x: T)`, `({ x })`, `(...x)`, `(x = 1)`, `(x?)`, `(x, y)`,
18
+ // `()`) keeps its parentheses in both modes, exactly as Prettier does.
19
+ // `async x => x` is handled too: the modifier sits before the parameter, so
20
+ // the parameter-name span is unaffected.
21
+ //
22
+ // The rule rewrites only the parameter span (`x` <-> `(x)`), never the body
23
+ // or the `=>`, so a chained arrow `a => b => …` has each eligible arm
24
+ // normalized independently. Idempotent: a parameter already in the
25
+ // preferred shape compares equal and emits nothing.
26
+ type formatArrowParens struct{}
27
+
28
+ type formatArrowParensOptions struct {
29
+ Prefer string `json:"prefer"`
30
+ }
31
+
32
+ func (formatArrowParens) Name() string { return "format/arrow-parens" }
33
+ func (formatArrowParens) IsFormat() bool { return true }
34
+
35
+ func (formatArrowParens) Visits() []shimast.Kind {
36
+ return []shimast.Kind{shimast.KindArrowFunction}
37
+ }
38
+
39
+ func (formatArrowParens) Check(ctx *Context, node *shimast.Node) {
40
+ if ctx == nil || ctx.File == nil || node == nil {
41
+ return
42
+ }
43
+ arrow := node.AsArrowFunction()
44
+ if arrow == nil || arrow.Parameters == nil {
45
+ return
46
+ }
47
+ params := arrow.Parameters.Nodes
48
+ if len(params) != 1 || params[0] == nil {
49
+ return
50
+ }
51
+ param := params[0]
52
+ if !isBareIdentifierParam(param) {
53
+ return
54
+ }
55
+ // A type-parameter list (`<T>(x) => …`) forces the parameter parens in
56
+ // both modes (a bare `<T>x =>` is not valid), so leave such an arrow
57
+ // alone, its parens are mandatory, not stylistic.
58
+ if arrow.TypeParameters != nil && len(arrow.TypeParameters.Nodes) > 0 {
59
+ return
60
+ }
61
+ // A return-type annotation (`(x): T => …`) also requires the parens.
62
+ if arrow.Type != nil {
63
+ return
64
+ }
65
+
66
+ var opts formatArrowParensOptions
67
+ _ = ctx.DecodeOptions(&opts)
68
+ prefer := opts.Prefer
69
+ if prefer != "avoid" {
70
+ prefer = "always"
71
+ }
72
+
73
+ src := ctx.File.Text()
74
+ nameStart := shimscanner.SkipTrivia(src, param.Pos())
75
+ nameEnd := param.End()
76
+ if nameStart < 0 || nameEnd <= nameStart || nameEnd > len(src) {
77
+ return
78
+ }
79
+
80
+ // Is the parameter already wrapped in `(` … `)`? Scan over whitespace on
81
+ // each side; the sole parameter of an arrow is delimited by the
82
+ // parameter-list parens when present.
83
+ openParen := scanBackForByte(src, nameStart, '(')
84
+ closeParen := scanForwardForByte(src, nameEnd, ')')
85
+ wrapped := openParen >= 0 && closeParen >= 0
86
+
87
+ switch prefer {
88
+ case "avoid":
89
+ if !wrapped {
90
+ return // already bare
91
+ }
92
+ // Replace `( … name … )` with just the name.
93
+ ctx.ReportRangeFix(
94
+ openParen,
95
+ closeParen+1,
96
+ "Single-parameter arrow should omit parentheses.",
97
+ TextEdit{Pos: openParen, End: closeParen + 1, Text: src[nameStart:nameEnd]},
98
+ )
99
+ default: // always
100
+ if wrapped {
101
+ return // already parenthesized
102
+ }
103
+ ctx.ReportRangeFix(
104
+ nameStart,
105
+ nameEnd,
106
+ "Single-parameter arrow should keep parentheses.",
107
+ TextEdit{Pos: nameStart, End: nameEnd, Text: "(" + src[nameStart:nameEnd] + ")"},
108
+ )
109
+ }
110
+ }
111
+
112
+ // isBareIdentifierParam reports whether `param` is a plain identifier
113
+ // parameter: no rest `...`, no optional `?`, no type annotation, no default,
114
+ // no modifier (a parameter property), and an identifier name. Only such a
115
+ // parameter is eligible for arrow-paren normalization; every richer shape
116
+ // keeps its parentheses in both Prettier modes.
117
+ func isBareIdentifierParam(param *shimast.Node) bool {
118
+ decl := param.AsParameterDeclaration()
119
+ if decl == nil {
120
+ return false
121
+ }
122
+ if decl.DotDotDotToken != nil || decl.QuestionToken != nil ||
123
+ decl.Type != nil || decl.Initializer != nil {
124
+ return false
125
+ }
126
+ if mods := param.Modifiers(); mods != nil && len(mods.Nodes) > 0 {
127
+ return false
128
+ }
129
+ name := param.Name()
130
+ return name != nil && name.Kind == shimast.KindIdentifier
131
+ }
132
+
133
+ // scanBackForByte returns the offset of the nearest `target` byte at or
134
+ // before `from`-1, scanning over whitespace only; -1 if a non-whitespace,
135
+ // non-target byte is reached first.
136
+ func scanBackForByte(src string, from int, target byte) int {
137
+ for i := from - 1; i >= 0; i-- {
138
+ c := src[i]
139
+ if c == target {
140
+ return i
141
+ }
142
+ if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
143
+ return -1
144
+ }
145
+ }
146
+ return -1
147
+ }
148
+
149
+ // scanForwardForByte returns the offset of the nearest `target` byte at or
150
+ // after `from`, scanning over whitespace only; -1 if a non-whitespace,
151
+ // non-target byte is reached first.
152
+ func scanForwardForByte(src string, from int, target byte) int {
153
+ for i := from; i < len(src); i++ {
154
+ c := src[i]
155
+ if c == target {
156
+ return i
157
+ }
158
+ if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
159
+ return -1
160
+ }
161
+ }
162
+ return -1
163
+ }
164
+
165
+ func init() {
166
+ Register(formatArrowParens{})
167
+ }
@@ -0,0 +1,117 @@
1
+ package linthost
2
+
3
+ import (
4
+ shimast "github.com/microsoft/typescript-go/shim/ast"
5
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
6
+ )
7
+
8
+ // formatBracketSpacing normalizes the inner padding of single-line brace
9
+ // pairs, mirroring Prettier's `bracketSpacing`:
10
+ //
11
+ // - prefer true (Prettier default): one space just inside the braces,
12
+ // `{ x: 1 }`, `{ a, b }`, `import { foo } from "m"`.
13
+ // - prefer false: no inner space, `{x: 1}`, `{a, b}`, `import {foo}`.
14
+ //
15
+ // It applies to object literals, object binding patterns (destructuring),
16
+ // named imports/exports, and type literals, the brace kinds Prettier's
17
+ // bracketSpacing governs. Block, class, interface, enum, and module braces
18
+ // are NOT affected (their layout is owned by the indentation rules).
19
+ //
20
+ // The rule touches only a brace pair that opens and closes on the SAME
21
+ // line: a multi-line container's interior is the indentation rules' surface,
22
+ // and an empty `{}` has no interior to pad. It rewrites just the whitespace
23
+ // run immediately inside each brace, so it never disturbs the contents.
24
+ // Idempotent: a pair already in the preferred shape compares equal.
25
+ type formatBracketSpacing struct{}
26
+
27
+ type formatBracketSpacingOptions struct {
28
+ Spacing *bool `json:"spacing"`
29
+ }
30
+
31
+ func (formatBracketSpacing) Name() string { return "format/bracket-spacing" }
32
+ func (formatBracketSpacing) IsFormat() bool { return true }
33
+
34
+ func (formatBracketSpacing) Visits() []shimast.Kind {
35
+ return []shimast.Kind{
36
+ shimast.KindObjectLiteralExpression,
37
+ shimast.KindObjectBindingPattern,
38
+ shimast.KindNamedImports,
39
+ shimast.KindNamedExports,
40
+ shimast.KindTypeLiteral,
41
+ }
42
+ }
43
+
44
+ func (formatBracketSpacing) Check(ctx *Context, node *shimast.Node) {
45
+ if ctx == nil || ctx.File == nil || node == nil {
46
+ return
47
+ }
48
+ var opts formatBracketSpacingOptions
49
+ _ = ctx.DecodeOptions(&opts)
50
+ spacing := true
51
+ if opts.Spacing != nil {
52
+ spacing = *opts.Spacing
53
+ }
54
+
55
+ src := ctx.File.Text()
56
+ start := shimscanner.SkipTrivia(src, node.Pos())
57
+ end := node.End()
58
+ if start < 0 || end <= start || end > len(src) {
59
+ return
60
+ }
61
+ // The node's first byte should be `{` and last `}`; a parenthesized or
62
+ // otherwise-wrapped form is out of scope.
63
+ if src[start] != '{' || src[end-1] != '}' {
64
+ return
65
+ }
66
+ inner := src[start+1 : end-1]
67
+ if len(inner) == 0 {
68
+ return // empty `{}`, nothing to pad
69
+ }
70
+ // Multi-line: the interior belongs to the indentation rules.
71
+ for i := 0; i < len(inner); i++ {
72
+ if inner[i] == '\n' || inner[i] == '\r' {
73
+ return
74
+ }
75
+ }
76
+ // Only-whitespace interior (`{ }`) is treated as empty: collapse to the
77
+ // canonical empty form rather than padding nothing.
78
+ trimmed := trimASCIISpace(inner)
79
+ if len(trimmed) == 0 {
80
+ return
81
+ }
82
+
83
+ // Compute the desired interior: exactly one leading+trailing space when
84
+ // spacing is on, none when off.
85
+ var want string
86
+ if spacing {
87
+ want = " " + trimmed + " "
88
+ } else {
89
+ want = trimmed
90
+ }
91
+ if inner == want {
92
+ return
93
+ }
94
+ ctx.ReportRangeFix(
95
+ start+1,
96
+ end-1,
97
+ "Normalize brace spacing to match bracketSpacing.",
98
+ TextEdit{Pos: start + 1, End: end - 1, Text: want},
99
+ )
100
+ }
101
+
102
+ // trimASCIISpace strips leading and trailing spaces and tabs from s.
103
+ func trimASCIISpace(s string) string {
104
+ i := 0
105
+ for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
106
+ i++
107
+ }
108
+ j := len(s)
109
+ for j > i && (s[j-1] == ' ' || s[j-1] == '\t') {
110
+ j--
111
+ }
112
+ return s[i:j]
113
+ }
114
+
115
+ func init() {
116
+ Register(formatBracketSpacing{})
117
+ }