@ttsc/lint 0.13.1 → 0.14.0-dev.20260528

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 (464) hide show
  1. package/README.md +948 -69
  2. package/lib/defaultFormat.d.ts +9 -6
  3. package/lib/defaultFormat.js +9 -6
  4. package/lib/defaultFormat.js.map +1 -1
  5. package/lib/index.d.ts +46 -0
  6. package/lib/index.js +35 -10
  7. package/lib/index.js.map +1 -1
  8. package/lib/structures/ITtscLintConfig.d.ts +12 -6
  9. package/lib/structures/{ITtscLintFormatConfig.d.ts → ITtscLintFormat.d.ts} +2 -2
  10. package/lib/structures/{TtscLintRuleMap.js → ITtscLintFormat.js} +1 -1
  11. package/lib/structures/ITtscLintFormat.js.map +1 -0
  12. package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
  13. package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
  14. package/lib/structures/TtscLintRuleSetting.js.map +1 -0
  15. package/lib/structures/index.d.ts +3 -4
  16. package/lib/structures/index.js +3 -4
  17. package/lib/structures/index.js.map +1 -1
  18. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +104 -0
  19. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +14 -0
  20. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
  21. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +79 -0
  22. package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
  23. package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
  24. package/lib/structures/rules/ITtscLintContributorRules.d.ts +17 -0
  25. package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
  26. package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
  27. package/lib/structures/rules/ITtscLintCoreRules.d.ts +1257 -0
  28. package/lib/structures/{ITtscLintFormatConfig.js → rules/ITtscLintCoreRules.js} +1 -1
  29. package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
  30. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
  31. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
  32. package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
  33. package/lib/structures/rules/ITtscLintCypressRules.d.ts +129 -0
  34. package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
  35. package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
  36. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +157 -0
  37. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
  38. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
  39. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +167 -0
  40. package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
  41. package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
  42. package/lib/structures/rules/ITtscLintJestRules.d.ts +201 -0
  43. package/lib/structures/rules/ITtscLintJestRules.js +3 -0
  44. package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
  45. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +140 -0
  46. package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
  47. package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
  48. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +302 -0
  49. package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
  50. package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
  51. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +185 -0
  52. package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
  53. package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
  54. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +330 -0
  55. package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
  56. package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
  57. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +188 -0
  58. package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
  59. package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
  60. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
  61. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
  62. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
  63. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +51 -0
  64. package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
  65. package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
  66. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +39 -0
  67. package/lib/structures/rules/ITtscLintReactRuleOptions.js +12 -0
  68. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
  69. package/lib/structures/rules/ITtscLintReactRules.d.ts +289 -0
  70. package/lib/structures/rules/ITtscLintReactRules.js +3 -0
  71. package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
  72. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +190 -0
  73. package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
  74. package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
  75. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +66 -0
  76. package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
  77. package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
  78. package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
  79. package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
  80. package/lib/structures/rules/ITtscLintRules.js.map +1 -0
  81. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +148 -0
  82. package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
  83. package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
  84. package/lib/structures/rules/ITtscLintSolidRules.d.ts +181 -0
  85. package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
  86. package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
  87. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +21 -0
  88. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
  89. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
  90. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +174 -0
  91. package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
  92. package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
  93. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +94 -0
  94. package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
  95. package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
  96. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +22 -0
  97. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
  98. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
  99. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +310 -0
  100. package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
  101. package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
  102. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1132 -0
  103. package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
  104. package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
  105. package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
  106. package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
  107. package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
  108. package/lib/structures/rules/ITtscLintVitestRules.d.ts +141 -0
  109. package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
  110. package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
  111. package/lib/structures/rules/index.d.ts +31 -0
  112. package/lib/structures/rules/index.js +48 -0
  113. package/lib/structures/rules/index.js.map +1 -0
  114. package/linthost/ast_helpers.go +30 -5
  115. package/linthost/config.go +48 -17
  116. package/linthost/config_format.go +9 -9
  117. package/linthost/directives.go +67 -25
  118. package/linthost/dispatch.go +14 -3
  119. package/linthost/engine.go +152 -31
  120. package/linthost/fix.go +2 -2
  121. package/linthost/lsp.go +747 -0
  122. package/linthost/print_dispatch.go +2 -2
  123. package/linthost/print_nodes_function.go +2 -2
  124. package/linthost/print_nodes_object.go +1 -1
  125. package/linthost/rule_names.go +14 -0
  126. package/linthost/rules_arrays.go +2 -2
  127. package/linthost/rules_boundaries.go +532 -0
  128. package/linthost/rules_camelcase.go +133 -0
  129. package/linthost/rules_complexity.go +94 -0
  130. package/linthost/rules_consistent_return.go +130 -0
  131. package/linthost/rules_console.go +1 -1
  132. package/linthost/rules_core_extra.go +739 -0
  133. package/linthost/rules_curly.go +70 -0
  134. package/linthost/rules_cypress.go +608 -0
  135. package/linthost/rules_debugger.go +2 -2
  136. package/linthost/rules_default_case.go +39 -0
  137. package/linthost/rules_default_case_last.go +46 -0
  138. package/linthost/rules_dupes.go +3 -3
  139. package/linthost/rules_empty.go +3 -3
  140. package/linthost/rules_escape.go +44 -24
  141. package/linthost/rules_eval.go +2 -2
  142. package/linthost/rules_finally.go +2 -2
  143. package/linthost/rules_format_jsdoc.go +1 -1
  144. package/linthost/rules_format_print_width.go +9 -9
  145. package/linthost/rules_format_quotes.go +1 -1
  146. package/linthost/rules_format_semi.go +1 -1
  147. package/linthost/rules_format_sort_imports.go +1 -1
  148. package/linthost/rules_format_trailing_comma.go +1 -1
  149. package/linthost/rules_functional.go +967 -0
  150. package/linthost/rules_gap.go +24 -45
  151. package/linthost/rules_grouped_accessor_pairs.go +87 -0
  152. package/linthost/rules_guard_for_in.go +198 -0
  153. package/linthost/rules_id_length.go +77 -0
  154. package/linthost/rules_imports.go +70 -2
  155. package/linthost/rules_init_declarations.go +53 -0
  156. package/linthost/rules_jest.go +618 -0
  157. package/linthost/rules_jsdoc.go +502 -0
  158. package/linthost/rules_jsx_a11y.go +1264 -0
  159. package/linthost/rules_logic.go +12 -12
  160. package/linthost/rules_loops.go +1 -1
  161. package/linthost/rules_max_classes_per_file.go +58 -0
  162. package/linthost/rules_max_depth.go +83 -0
  163. package/linthost/rules_max_lines.go +101 -0
  164. package/linthost/rules_max_lines_per_function.go +57 -0
  165. package/linthost/rules_max_nested_callbacks.go +61 -0
  166. package/linthost/rules_max_params.go +49 -0
  167. package/linthost/rules_max_statements.go +59 -0
  168. package/linthost/rules_misc.go +1 -1
  169. package/linthost/rules_nextjs.go +697 -0
  170. package/linthost/rules_no_else_return.go +75 -0
  171. package/linthost/rules_no_empty_named_blocks.go +91 -0
  172. package/linthost/rules_no_extend_native.go +51 -0
  173. package/linthost/rules_no_import_assign.go +140 -0
  174. package/linthost/rules_no_invalid_this.go +52 -0
  175. package/linthost/rules_no_loop_func.go +85 -0
  176. package/linthost/rules_no_magic_numbers.go +123 -0
  177. package/linthost/rules_no_mixed_operators.go +80 -0
  178. package/linthost/rules_no_param_reassign.go +98 -0
  179. package/linthost/rules_no_redeclare.go +270 -0
  180. package/linthost/rules_no_restricted_imports.go +105 -0
  181. package/linthost/rules_no_restricted_syntax.go +49 -0
  182. package/linthost/rules_no_shadow.go +147 -0
  183. package/linthost/rules_no_unreachable.go +77 -0
  184. package/linthost/rules_no_useless_assignment.go +120 -0
  185. package/linthost/rules_no_useless_constructor.go +245 -0
  186. package/linthost/rules_no_useless_return.go +51 -0
  187. package/linthost/rules_params.go +1 -1
  188. package/linthost/rules_playwright.go +788 -0
  189. package/linthost/rules_prefer_arrow_callback.go +124 -0
  190. package/linthost/rules_prefer_destructuring.go +98 -0
  191. package/linthost/rules_prefer_named_capture_group.go +129 -0
  192. package/linthost/rules_prefer_rest_params.go +94 -0
  193. package/linthost/rules_problems.go +41 -30
  194. package/linthost/rules_promise.go +1128 -73
  195. package/linthost/rules_protos.go +2 -2
  196. package/linthost/rules_react.go +773 -0
  197. package/linthost/rules_react_extras.go +227 -0
  198. package/linthost/rules_react_hooks.go +848 -0
  199. package/linthost/rules_react_perf.go +293 -0
  200. package/linthost/rules_react_refresh.go +583 -0
  201. package/linthost/rules_regexp.go +410 -0
  202. package/linthost/rules_security.go +830 -0
  203. package/linthost/rules_self.go +2 -2
  204. package/linthost/rules_solid.go +1073 -0
  205. package/linthost/rules_sort_imports.go +69 -0
  206. package/linthost/rules_sort_keys.go +134 -0
  207. package/linthost/rules_storybook.go +1176 -0
  208. package/linthost/rules_strings.go +4 -4
  209. package/linthost/rules_suggestions.go +38 -38
  210. package/linthost/rules_tanstack_query.go +844 -0
  211. package/linthost/rules_testing_library.go +1204 -0
  212. package/linthost/rules_throw.go +1 -1
  213. package/linthost/rules_ts.go +19 -19
  214. package/linthost/rules_ts_async.go +399 -0
  215. package/linthost/rules_ts_class_literal_property_style.go +115 -0
  216. package/linthost/rules_ts_consistent_type_exports.go +256 -0
  217. package/linthost/rules_ts_explicit_function_return_type.go +67 -0
  218. package/linthost/rules_ts_extra.go +155 -36
  219. package/linthost/rules_ts_no_base_to_string.go +218 -0
  220. package/linthost/rules_ts_no_confusing_void.go +72 -0
  221. package/linthost/rules_ts_no_deprecated.go +195 -0
  222. package/linthost/rules_ts_no_for_in_array.go +84 -0
  223. package/linthost/rules_ts_no_magic_numbers.go +124 -0
  224. package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
  225. package/linthost/rules_ts_no_misused_spread.go +104 -0
  226. package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
  227. package/linthost/rules_ts_no_restricted_types.go +62 -0
  228. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
  229. package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
  230. package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
  231. package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
  232. package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
  233. package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
  234. package/linthost/rules_ts_no_unsafe_argument.go +82 -0
  235. package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
  236. package/linthost/rules_ts_no_unsafe_call.go +82 -0
  237. package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
  238. package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
  239. package/linthost/rules_ts_no_unsafe_return.go +126 -0
  240. package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
  241. package/linthost/rules_ts_no_useless_constructor.go +52 -0
  242. package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
  243. package/linthost/rules_ts_parameter_properties.go +38 -0
  244. package/linthost/rules_ts_prefer_find.go +178 -0
  245. package/linthost/rules_ts_prefer_includes.go +255 -0
  246. package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
  247. package/linthost/rules_ts_prefer_optional_chain.go +228 -0
  248. package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
  249. package/linthost/rules_ts_prefer_readonly.go +73 -0
  250. package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
  251. package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
  252. package/linthost/rules_ts_prefer_return_this_type.go +135 -0
  253. package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
  254. package/linthost/rules_ts_promise_function_async.go +77 -0
  255. package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
  256. package/linthost/rules_ts_require_array_sort_compare.go +96 -0
  257. package/linthost/rules_ts_restrict_plus_operands.go +127 -0
  258. package/linthost/rules_ts_restrict_template_expressions.go +95 -0
  259. package/linthost/rules_ts_simple.go +387 -0
  260. package/linthost/rules_ts_sort_type_constituents.go +144 -0
  261. package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
  262. package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
  263. package/linthost/rules_ts_unbound_method.go +126 -0
  264. package/linthost/rules_tsdoc.go +136 -0
  265. package/linthost/rules_unicorn_better_regex.go +27 -0
  266. package/linthost/rules_unicorn_catch_error_name.go +46 -0
  267. package/linthost/rules_unicorn_consistent_assert.go +47 -0
  268. package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
  269. package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
  270. package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
  271. package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
  272. package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
  273. package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
  274. package/linthost/rules_unicorn_custom_error_definition.go +138 -0
  275. package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
  276. package/linthost/rules_unicorn_error_message.go +64 -0
  277. package/linthost/rules_unicorn_escape_case.go +51 -0
  278. package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
  279. package/linthost/rules_unicorn_explicit_length_check.go +88 -0
  280. package/linthost/rules_unicorn_filename_case.go +29 -0
  281. package/linthost/rules_unicorn_import_style.go +28 -0
  282. package/linthost/rules_unicorn_isolated_functions.go +29 -0
  283. package/linthost/rules_unicorn_new_for_builtins.go +87 -0
  284. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
  285. package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
  286. package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
  287. package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
  288. package/linthost/rules_unicorn_no_array_for_each.go +40 -0
  289. package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
  290. package/linthost/rules_unicorn_no_array_reduce.go +41 -0
  291. package/linthost/rules_unicorn_no_array_reverse.go +44 -0
  292. package/linthost/rules_unicorn_no_array_sort.go +43 -0
  293. package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
  294. package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
  295. package/linthost/rules_unicorn_no_console_spaces.go +61 -0
  296. package/linthost/rules_unicorn_no_document_cookie.go +41 -0
  297. package/linthost/rules_unicorn_no_empty_file.go +44 -0
  298. package/linthost/rules_unicorn_no_for_loop.go +102 -0
  299. package/linthost/rules_unicorn_no_hex_escape.go +42 -0
  300. package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
  301. package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
  302. package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
  303. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
  304. package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
  305. package/linthost/rules_unicorn_no_lonely_if.go +44 -0
  306. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
  307. package/linthost/rules_unicorn_no_named_default.go +54 -0
  308. package/linthost/rules_unicorn_no_negated_condition.go +85 -0
  309. package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
  310. package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
  311. package/linthost/rules_unicorn_no_new_array.go +30 -0
  312. package/linthost/rules_unicorn_no_new_buffer.go +31 -0
  313. package/linthost/rules_unicorn_no_null.go +24 -0
  314. package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
  315. package/linthost/rules_unicorn_no_process_exit.go +43 -0
  316. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
  317. package/linthost/rules_unicorn_no_static_only_class.go +56 -0
  318. package/linthost/rules_unicorn_no_thenable.go +74 -0
  319. package/linthost/rules_unicorn_no_this_assignment.go +35 -0
  320. package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
  321. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
  322. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
  323. package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
  324. package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
  325. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
  326. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
  327. package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
  328. package/linthost/rules_unicorn_no_unused_properties.go +30 -0
  329. package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
  330. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
  331. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
  332. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
  333. package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
  334. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
  335. package/linthost/rules_unicorn_no_useless_spread.go +67 -0
  336. package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
  337. package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
  338. package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
  339. package/linthost/rules_unicorn_number_literal_case.go +69 -0
  340. package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
  341. package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
  342. package/linthost/rules_unicorn_prefer_array_find.go +51 -0
  343. package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
  344. package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
  345. package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
  346. package/linthost/rules_unicorn_prefer_array_some.go +67 -0
  347. package/linthost/rules_unicorn_prefer_at.go +77 -0
  348. package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
  349. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
  350. package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
  351. package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
  352. package/linthost/rules_unicorn_prefer_code_point.go +49 -0
  353. package/linthost/rules_unicorn_prefer_date_now.go +78 -0
  354. package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
  355. package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
  356. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
  357. package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
  358. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
  359. package/linthost/rules_unicorn_prefer_event_target.go +36 -0
  360. package/linthost/rules_unicorn_prefer_export_from.go +129 -0
  361. package/linthost/rules_unicorn_prefer_global_this.go +127 -0
  362. package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
  363. package/linthost/rules_unicorn_prefer_includes.go +149 -0
  364. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
  365. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
  366. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
  367. package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
  368. package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
  369. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
  370. package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
  371. package/linthost/rules_unicorn_prefer_module.go +50 -0
  372. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
  373. package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
  374. package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
  375. package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
  376. package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
  377. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
  378. package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
  379. package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
  380. package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
  381. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
  382. package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
  383. package/linthost/rules_unicorn_prefer_set_has.go +42 -0
  384. package/linthost/rules_unicorn_prefer_set_size.go +48 -0
  385. package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
  386. package/linthost/rules_unicorn_prefer_single_call.go +96 -0
  387. package/linthost/rules_unicorn_prefer_spread.go +51 -0
  388. package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
  389. package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
  390. package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
  391. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
  392. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
  393. package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
  394. package/linthost/rules_unicorn_prefer_switch.go +103 -0
  395. package/linthost/rules_unicorn_prefer_ternary.go +71 -0
  396. package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
  397. package/linthost/rules_unicorn_prefer_type_error.go +127 -0
  398. package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
  399. package/linthost/rules_unicorn_relative_url_style.go +49 -0
  400. package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
  401. package/linthost/rules_unicorn_require_module_attributes.go +54 -0
  402. package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
  403. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
  404. package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
  405. package/linthost/rules_unicorn_string_content.go +27 -0
  406. package/linthost/rules_unicorn_switch_case_braces.go +42 -0
  407. package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
  408. package/linthost/rules_unicorn_template_indent.go +28 -0
  409. package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
  410. package/linthost/rules_unicorn_throw_new_error.go +61 -0
  411. package/linthost/rules_var.go +4 -4
  412. package/linthost/rules_vitest.go +568 -0
  413. package/package.json +3 -3
  414. package/plugin/main.go +49 -3
  415. package/rule/astutil/astutil.go +10 -3
  416. package/rule/rule.go +12 -10
  417. package/src/defaultFormat.ts +11 -8
  418. package/src/index.ts +40 -16
  419. package/src/structures/ITtscLintConfig.ts +12 -6
  420. package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
  421. package/src/structures/TtscLintRuleSetting.ts +55 -0
  422. package/src/structures/index.ts +3 -4
  423. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
  424. package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
  425. package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
  426. package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
  427. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
  428. package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
  429. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
  430. package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
  431. package/src/structures/rules/ITtscLintJestRules.ts +220 -0
  432. package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
  433. package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
  434. package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
  435. package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
  436. package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
  437. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
  438. package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
  439. package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
  440. package/src/structures/rules/ITtscLintReactRules.ts +321 -0
  441. package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
  442. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
  443. package/src/structures/rules/ITtscLintRules.ts +77 -0
  444. package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
  445. package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
  446. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
  447. package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
  448. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
  449. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
  450. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
  451. package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
  452. package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
  453. package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
  454. package/src/structures/rules/index.ts +31 -0
  455. package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
  456. package/lib/structures/TtscLintRule.d.ts +0 -17
  457. package/lib/structures/TtscLintRule.js.map +0 -1
  458. package/lib/structures/TtscLintRuleMap.d.ts +0 -46
  459. package/lib/structures/TtscLintRuleMap.js.map +0 -1
  460. package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
  461. package/lib/structures/TtscLintRuleOptions.js.map +0 -1
  462. package/src/structures/TtscLintRule.ts +0 -160
  463. package/src/structures/TtscLintRuleMap.ts +0 -55
  464. package/src/structures/TtscLintRuleOptions.ts +0 -151
@@ -0,0 +1,78 @@
1
+ // unicorn/prefer-date-now: three idioms compute the current epoch
2
+ // milliseconds at runtime — `new Date().getTime()`, `new Date().valueOf()`,
3
+ // and `+new Date()`. All three allocate a Date instance only to throw
4
+ // it away. `Date.now()` does the same thing with no allocation and
5
+ // reads as exactly what it means; the rule asks authors to switch.
6
+ //
7
+ // AST-only: visit `KindCallExpression` (the `.getTime()` / `.valueOf()`
8
+ // callers) and `KindPrefixUnaryExpression` (the `+new Date()` form).
9
+ // Fire on:
10
+ //
11
+ // - `(new Date()).getTime()` / `(new Date()).valueOf()` — a call
12
+ // with no arguments whose callee is a PropertyAccessExpression
13
+ // on a NewExpression with callee `Date`.
14
+ // - `+new Date()` — a `+` prefix whose operand is a NewExpression
15
+ // with callee `Date`.
16
+ //
17
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-date-now.md
18
+ package linthost
19
+
20
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
21
+
22
+ type unicornPreferDateNow struct{}
23
+
24
+ func (unicornPreferDateNow) Name() string { return "unicorn/prefer-date-now" }
25
+ func (unicornPreferDateNow) Visits() []shimast.Kind {
26
+ return []shimast.Kind{shimast.KindCallExpression, shimast.KindPrefixUnaryExpression}
27
+ }
28
+ func (unicornPreferDateNow) Check(ctx *Context, node *shimast.Node) {
29
+ switch node.Kind {
30
+ case shimast.KindCallExpression:
31
+ call := node.AsCallExpression()
32
+ if call == nil || call.Expression == nil {
33
+ return
34
+ }
35
+ if call.Arguments != nil && len(call.Arguments.Nodes) > 0 {
36
+ return
37
+ }
38
+ access := stripParens(call.Expression)
39
+ if access == nil || access.Kind != shimast.KindPropertyAccessExpression {
40
+ return
41
+ }
42
+ propAccess := access.AsPropertyAccessExpression()
43
+ if propAccess == nil {
44
+ return
45
+ }
46
+ method := identifierText(propAccess.Name())
47
+ if method != "getTime" && method != "valueOf" {
48
+ return
49
+ }
50
+ receiver := stripParens(propAccess.Expression)
51
+ if receiver == nil || receiver.Kind != shimast.KindNewExpression {
52
+ return
53
+ }
54
+ ne := receiver.AsNewExpression()
55
+ if ne == nil || identifierText(ne.Expression) != "Date" {
56
+ return
57
+ }
58
+ ctx.Report(node, "Prefer `Date.now()` over `new Date().getTime()` / `+new Date()`.")
59
+ case shimast.KindPrefixUnaryExpression:
60
+ prefix := node.AsPrefixUnaryExpression()
61
+ if prefix == nil || prefix.Operator != shimast.KindPlusToken || prefix.Operand == nil {
62
+ return
63
+ }
64
+ operand := stripParens(prefix.Operand)
65
+ if operand == nil || operand.Kind != shimast.KindNewExpression {
66
+ return
67
+ }
68
+ ne := operand.AsNewExpression()
69
+ if ne == nil || identifierText(ne.Expression) != "Date" {
70
+ return
71
+ }
72
+ ctx.Report(node, "Prefer `Date.now()` over `new Date().getTime()` / `+new Date()`.")
73
+ }
74
+ }
75
+
76
+ func init() {
77
+ Register(unicornPreferDateNow{})
78
+ }
@@ -0,0 +1,144 @@
1
+ // unicorn/prefer-default-parameters: the legacy pattern of reassigning
2
+ // an undefined-or-falsy parameter to a literal at the top of a function
3
+ // body (`name = name ?? "guest"`) has been redundant since ES2015. A
4
+ // default-parameter expression (`name = "guest"`) covers the same case,
5
+ // reads as exactly what it means, and avoids both the visual noise and
6
+ // the missed-edit risk of keeping the name in three places.
7
+ //
8
+ // AST-only: visit every function-like declaration. Fire when the first
9
+ // body statement is `<param> = <param> ?? <literal>` — an
10
+ // `ExpressionStatement` containing an `=` `BinaryExpression` whose LHS
11
+ // is a bare identifier matching a parameter name, and whose RHS is a
12
+ // `??` `BinaryExpression` whose LHS is the same identifier and whose
13
+ // RHS is a primitive literal. The rule is conservative on purpose: it
14
+ // stays away from `||` (which has different semantics for falsy
15
+ // non-undefined values) and the explicit-ternary shape, since both add
16
+ // branches the default-parameter rewrite does not strictly preserve.
17
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-default-parameters.md
18
+ package linthost
19
+
20
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
21
+
22
+ type unicornPreferDefaultParameters struct{}
23
+
24
+ func (unicornPreferDefaultParameters) Name() string {
25
+ return "unicorn/prefer-default-parameters"
26
+ }
27
+ func (unicornPreferDefaultParameters) Visits() []shimast.Kind {
28
+ return []shimast.Kind{
29
+ shimast.KindFunctionDeclaration,
30
+ shimast.KindArrowFunction,
31
+ shimast.KindFunctionExpression,
32
+ shimast.KindMethodDeclaration,
33
+ }
34
+ }
35
+ func (unicornPreferDefaultParameters) Check(ctx *Context, node *shimast.Node) {
36
+ body := defaultParameterFunctionBody(node)
37
+ if body == nil {
38
+ return
39
+ }
40
+ if body.Statements == nil || len(body.Statements.Nodes) == 0 {
41
+ return
42
+ }
43
+ first := body.Statements.Nodes[0]
44
+ if first == nil || first.Kind != shimast.KindExpressionStatement {
45
+ return
46
+ }
47
+ exprStmt := first.AsExpressionStatement()
48
+ if exprStmt == nil || exprStmt.Expression == nil {
49
+ return
50
+ }
51
+ expr := stripParens(exprStmt.Expression)
52
+ if expr == nil || expr.Kind != shimast.KindBinaryExpression {
53
+ return
54
+ }
55
+ assign := expr.AsBinaryExpression()
56
+ if assign == nil || assign.OperatorToken == nil || assign.OperatorToken.Kind != shimast.KindEqualsToken {
57
+ return
58
+ }
59
+ target := identifierText(stripParens(assign.Left))
60
+ if target == "" {
61
+ return
62
+ }
63
+ if !functionHasParameterNamed(node, target) {
64
+ return
65
+ }
66
+ rhs := stripParens(assign.Right)
67
+ if rhs == nil || rhs.Kind != shimast.KindBinaryExpression {
68
+ return
69
+ }
70
+ coalesce := rhs.AsBinaryExpression()
71
+ if coalesce == nil || coalesce.OperatorToken == nil ||
72
+ coalesce.OperatorToken.Kind != shimast.KindQuestionQuestionToken {
73
+ return
74
+ }
75
+ if identifierText(stripParens(coalesce.Left)) != target {
76
+ return
77
+ }
78
+ if !isLiteralExpression(stripParens(coalesce.Right)) {
79
+ return
80
+ }
81
+ ctx.Report(expr, "Prefer default parameters over `param = param ?? default` reassignments.")
82
+ }
83
+
84
+ // defaultParameterFunctionBody returns the BlockStatement body of a
85
+ // function-like node, or nil when the function has an expression body
86
+ // (arrow `=> expr`) or an overload signature without a body. The
87
+ // rule only fires on statement-level reassignments, so a body-less
88
+ // shape is a non-match by definition.
89
+ func defaultParameterFunctionBody(node *shimast.Node) *shimast.Block {
90
+ if node == nil {
91
+ return nil
92
+ }
93
+ var body *shimast.Node
94
+ switch node.Kind {
95
+ case shimast.KindFunctionDeclaration:
96
+ if fn := node.AsFunctionDeclaration(); fn != nil {
97
+ body = fn.Body
98
+ }
99
+ case shimast.KindFunctionExpression:
100
+ if fn := node.AsFunctionExpression(); fn != nil {
101
+ body = fn.Body
102
+ }
103
+ case shimast.KindArrowFunction:
104
+ if fn := node.AsArrowFunction(); fn != nil {
105
+ body = fn.Body
106
+ }
107
+ case shimast.KindMethodDeclaration:
108
+ if fn := node.AsMethodDeclaration(); fn != nil {
109
+ body = fn.Body
110
+ }
111
+ }
112
+ if body == nil || body.Kind != shimast.KindBlock {
113
+ return nil
114
+ }
115
+ return body.AsBlock()
116
+ }
117
+
118
+ // functionHasParameterNamed reports whether any parameter of the
119
+ // function-like node is a plain `Identifier` whose lexical text equals
120
+ // `name`. Destructured parameters are intentionally ignored — the rule
121
+ // cannot prove which inner binding a top-of-body reassignment refers to
122
+ // without semantic analysis.
123
+ func functionHasParameterNamed(node *shimast.Node, name string) bool {
124
+ if node == nil || name == "" {
125
+ return false
126
+ }
127
+ for _, p := range node.Parameters() {
128
+ if p == nil {
129
+ continue
130
+ }
131
+ decl := p.AsParameterDeclaration()
132
+ if decl == nil {
133
+ continue
134
+ }
135
+ if identifierText(decl.Name()) == name {
136
+ return true
137
+ }
138
+ }
139
+ return false
140
+ }
141
+
142
+ func init() {
143
+ Register(unicornPreferDefaultParameters{})
144
+ }
@@ -0,0 +1,40 @@
1
+ // unicorn/prefer-dom-node-append: `Node#appendChild` accepts a single
2
+ // child node, returns the appended node, and throws when handed a string
3
+ // — its `Node#append` successor accepts a variadic list of nodes and
4
+ // strings, returns `undefined`, and is the supported modern shape. The
5
+ // legacy form is what the rule discourages.
6
+ //
7
+ // AST-only: visit each `CallExpression`, match a property-access callee
8
+ // whose method identifier is `appendChild`, and fire on the call. The
9
+ // receiver expression is not type-checked — the syntactic shape is the
10
+ // signal the rule wants to discourage, regardless of whether the value is
11
+ // known to be a `Node` at the type level.
12
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-append.md
13
+ package linthost
14
+
15
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
16
+
17
+ type unicornPreferDomNodeAppend struct{}
18
+
19
+ func (unicornPreferDomNodeAppend) Name() string { return "unicorn/prefer-dom-node-append" }
20
+ func (unicornPreferDomNodeAppend) Visits() []shimast.Kind {
21
+ return []shimast.Kind{shimast.KindCallExpression}
22
+ }
23
+ func (unicornPreferDomNodeAppend) Check(ctx *Context, node *shimast.Node) {
24
+ call := node.AsCallExpression()
25
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
26
+ return
27
+ }
28
+ access := call.Expression.AsPropertyAccessExpression()
29
+ if access == nil {
30
+ return
31
+ }
32
+ if identifierText(access.Name()) != "appendChild" {
33
+ return
34
+ }
35
+ ctx.Report(node, "Prefer `Node#append()` over `Node#appendChild()`.")
36
+ }
37
+
38
+ func init() {
39
+ Register(unicornPreferDomNodeAppend{})
40
+ }
@@ -0,0 +1,55 @@
1
+ // unicorn/prefer-dom-node-dataset: `Element#dataset` exposes every
2
+ // `data-*` attribute as a typed string property, including coordinated
3
+ // kebab-case → camelCase mapping and conversion to/from values. Reaching
4
+ // for `getAttribute("data-foo")` or `setAttribute("data-foo", …)`
5
+ // reintroduces string-key bookkeeping the platform already covers.
6
+ //
7
+ // AST-only: visit each `CallExpression`, match a property-access callee
8
+ // whose method identifier is `getAttribute` or `setAttribute`, and fire
9
+ // when the first argument is a `StringLiteral` whose text starts with
10
+ // `data-`. The literal-prefix gate isolates the data-attribute path from
11
+ // every other attribute the same methods reach.
12
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-dataset.md
13
+ package linthost
14
+
15
+ import (
16
+ "strings"
17
+
18
+ shimast "github.com/microsoft/typescript-go/shim/ast"
19
+ )
20
+
21
+ type unicornPreferDomNodeDataset struct{}
22
+
23
+ func (unicornPreferDomNodeDataset) Name() string { return "unicorn/prefer-dom-node-dataset" }
24
+ func (unicornPreferDomNodeDataset) Visits() []shimast.Kind {
25
+ return []shimast.Kind{shimast.KindCallExpression}
26
+ }
27
+ func (unicornPreferDomNodeDataset) Check(ctx *Context, node *shimast.Node) {
28
+ call := node.AsCallExpression()
29
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
30
+ return
31
+ }
32
+ access := call.Expression.AsPropertyAccessExpression()
33
+ if access == nil {
34
+ return
35
+ }
36
+ method := identifierText(access.Name())
37
+ if method != "getAttribute" && method != "setAttribute" {
38
+ return
39
+ }
40
+ if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
41
+ return
42
+ }
43
+ first := call.Arguments.Nodes[0]
44
+ if first == nil || first.Kind != shimast.KindStringLiteral {
45
+ return
46
+ }
47
+ if !strings.HasPrefix(stringLiteralText(first), "data-") {
48
+ return
49
+ }
50
+ ctx.Report(node, "Prefer `.dataset` over `getAttribute` / `setAttribute` for `data-*` attributes.")
51
+ }
52
+
53
+ func init() {
54
+ Register(unicornPreferDomNodeDataset{})
55
+ }
@@ -0,0 +1,41 @@
1
+ // unicorn/prefer-dom-node-remove: `parent.removeChild(child)` requires
2
+ // the caller to thread the parent through to detach a node — `child.remove()`
3
+ // is the supported modern shape and avoids the dangling-reference class
4
+ // of bugs where the wrong parent is consulted.
5
+ //
6
+ // AST-only: visit each `CallExpression`, match a property-access callee
7
+ // whose method identifier is `removeChild`, and fire when the call has
8
+ // exactly one argument. The single-argument gate isolates the canonical
9
+ // detach shape from custom `removeChild` overloads that take more.
10
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-remove.md
11
+ package linthost
12
+
13
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
14
+
15
+ type unicornPreferDomNodeRemove struct{}
16
+
17
+ func (unicornPreferDomNodeRemove) Name() string { return "unicorn/prefer-dom-node-remove" }
18
+ func (unicornPreferDomNodeRemove) Visits() []shimast.Kind {
19
+ return []shimast.Kind{shimast.KindCallExpression}
20
+ }
21
+ func (unicornPreferDomNodeRemove) Check(ctx *Context, node *shimast.Node) {
22
+ call := node.AsCallExpression()
23
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
24
+ return
25
+ }
26
+ access := call.Expression.AsPropertyAccessExpression()
27
+ if access == nil {
28
+ return
29
+ }
30
+ if identifierText(access.Name()) != "removeChild" {
31
+ return
32
+ }
33
+ if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
34
+ return
35
+ }
36
+ ctx.Report(node, "Prefer `ChildNode#remove()` over `parentNode.removeChild(child)`.")
37
+ }
38
+
39
+ func init() {
40
+ Register(unicornPreferDomNodeRemove{})
41
+ }
@@ -0,0 +1,37 @@
1
+ // unicorn/prefer-dom-node-text-content: `HTMLElement#innerText` triggers
2
+ // layout, ignores hidden subtrees, and varies across engines — its
3
+ // `Node#textContent` counterpart returns the raw concatenated text of
4
+ // every descendant text node and is the supported modern shape.
5
+ //
6
+ // AST-only and identifier-text-driven: visit every
7
+ // `PropertyAccessExpression`, match the property name `innerText`, and
8
+ // fire on the property-access node. The receiver expression is not
9
+ // type-checked; the legacy property name is the signal the rule
10
+ // discourages.
11
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-text-content.md
12
+ package linthost
13
+
14
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
15
+
16
+ type unicornPreferDomNodeTextContent struct{}
17
+
18
+ func (unicornPreferDomNodeTextContent) Name() string {
19
+ return "unicorn/prefer-dom-node-text-content"
20
+ }
21
+ func (unicornPreferDomNodeTextContent) Visits() []shimast.Kind {
22
+ return []shimast.Kind{shimast.KindPropertyAccessExpression}
23
+ }
24
+ func (unicornPreferDomNodeTextContent) Check(ctx *Context, node *shimast.Node) {
25
+ access := node.AsPropertyAccessExpression()
26
+ if access == nil {
27
+ return
28
+ }
29
+ if identifierText(access.Name()) != "innerText" {
30
+ return
31
+ }
32
+ ctx.Report(node, "Prefer `Node#textContent` over `HTMLElement#innerText`.")
33
+ }
34
+
35
+ func init() {
36
+ Register(unicornPreferDomNodeTextContent{})
37
+ }
@@ -0,0 +1,36 @@
1
+ // unicorn/prefer-event-target: Node's `EventEmitter` is the legacy
2
+ // event API. The browser and modern Node (`>=15`) both ship the
3
+ // standard `EventTarget` interface, which works in both runtimes
4
+ // without a polyfill. Code that needs to run in both should prefer
5
+ // `EventTarget` so it stays portable.
6
+ //
7
+ // AST-only: visit `NewExpression`. Match when the callee is a bare
8
+ // identifier whose name is `EventEmitter`. The receiver is not
9
+ // type-checked — the rule's signal is the literal `new EventEmitter()`
10
+ // shape; a `new events.EventEmitter()` qualified form would not match,
11
+ // matching upstream's own AST-only behavior.
12
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-event-target.md
13
+ package linthost
14
+
15
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
16
+
17
+ type unicornPreferEventTarget struct{}
18
+
19
+ func (unicornPreferEventTarget) Name() string { return "unicorn/prefer-event-target" }
20
+ func (unicornPreferEventTarget) Visits() []shimast.Kind {
21
+ return []shimast.Kind{shimast.KindNewExpression}
22
+ }
23
+ func (unicornPreferEventTarget) Check(ctx *Context, node *shimast.Node) {
24
+ ne := node.AsNewExpression()
25
+ if ne == nil || ne.Expression == nil {
26
+ return
27
+ }
28
+ if identifierText(ne.Expression) != "EventEmitter" {
29
+ return
30
+ }
31
+ ctx.Report(node, "Prefer `EventTarget` over `EventEmitter` when sharing code between Node and the browser.")
32
+ }
33
+
34
+ func init() {
35
+ Register(unicornPreferEventTarget{})
36
+ }
@@ -0,0 +1,129 @@
1
+ // unicorn/prefer-export-from: when the only purpose of a local import is
2
+ // to re-export it under the same name, the canonical shape is the
3
+ // `export { X } from "Y"` re-export, which skips the intermediate local
4
+ // binding entirely. The split `import { X } from "Y"; export { X };`
5
+ // form is longer, allocates a binding that never gets used, and reads
6
+ // as if the author meant to consume `X` locally before deciding not to.
7
+ //
8
+ // AST-only minimum-viable port: visit `SourceFile` and walk top-level
9
+ // statements once. Build a map from each unrenamed named-binding of an
10
+ // `import { X } from "Y"` declaration to its module specifier text, then
11
+ // fire on every later `export { X };` statement (no rename, no
12
+ // `from`-clause) whose identifier appears in that map. Default and
13
+ // namespace imports, renamed bindings, and re-exports with their own
14
+ // `from`-clause are out of scope; the MVP only catches the textbook
15
+ // "import then immediately re-export" pair.
16
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-export-from.md
17
+ package linthost
18
+
19
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
20
+
21
+ type unicornPreferExportFrom struct{}
22
+
23
+ func (unicornPreferExportFrom) Name() string { return "unicorn/prefer-export-from" }
24
+ func (unicornPreferExportFrom) Visits() []shimast.Kind {
25
+ return []shimast.Kind{shimast.KindSourceFile}
26
+ }
27
+ func (unicornPreferExportFrom) Check(ctx *Context, node *shimast.Node) {
28
+ statements := node.Statements()
29
+ if len(statements) == 0 {
30
+ return
31
+ }
32
+ // Map of locally-imported simple binding name → true. Built on a
33
+ // first pass so a re-export earlier in the file does not accidentally
34
+ // match an import declared later; the upstream rule is anchored on
35
+ // "imported above, re-exported below" ordering.
36
+ imported := map[string]bool{}
37
+ for _, stmt := range statements {
38
+ if stmt == nil || stmt.Kind != shimast.KindImportDeclaration {
39
+ continue
40
+ }
41
+ decl := stmt.AsImportDeclaration()
42
+ if decl == nil || decl.ImportClause == nil {
43
+ continue
44
+ }
45
+ clause := decl.ImportClause.AsImportClause()
46
+ if clause == nil || clause.NamedBindings == nil ||
47
+ clause.NamedBindings.Kind != shimast.KindNamedImports {
48
+ continue
49
+ }
50
+ // A default-bound or namespace-mixed import is out of scope: the
51
+ // MVP only rewrites pure `import { X } from "Y"` pairs.
52
+ if clause.Name() != nil {
53
+ continue
54
+ }
55
+ named := clause.NamedBindings.AsNamedImports()
56
+ if named == nil || named.Elements == nil {
57
+ continue
58
+ }
59
+ for _, spec := range named.Elements.Nodes {
60
+ s := spec.AsImportSpecifier()
61
+ if s == nil {
62
+ continue
63
+ }
64
+ // PropertyName is set only when the specifier is renamed
65
+ // (`import { a as b }`); skip those — `export { b }` would
66
+ // require `export { b as b } from "Y"` which is itself a
67
+ // useless rename.
68
+ if s.PropertyName != nil {
69
+ continue
70
+ }
71
+ name := identifierText(s.Name())
72
+ if name == "" {
73
+ continue
74
+ }
75
+ imported[name] = true
76
+ }
77
+ }
78
+ if len(imported) == 0 {
79
+ return
80
+ }
81
+ for _, stmt := range statements {
82
+ if stmt == nil || stmt.Kind != shimast.KindExportDeclaration {
83
+ continue
84
+ }
85
+ decl := stmt.AsExportDeclaration()
86
+ if decl == nil || decl.ExportClause == nil {
87
+ continue
88
+ }
89
+ // Skip `export { X } from "Y"` — already in the target shape.
90
+ if decl.ModuleSpecifier != nil {
91
+ continue
92
+ }
93
+ if decl.ExportClause.Kind != shimast.KindNamedExports {
94
+ continue
95
+ }
96
+ named := decl.ExportClause.AsNamedExports()
97
+ if named == nil || named.Elements == nil || len(named.Elements.Nodes) == 0 {
98
+ continue
99
+ }
100
+ matched := false
101
+ for _, el := range named.Elements.Nodes {
102
+ spec := el.AsExportSpecifier()
103
+ if spec == nil {
104
+ continue
105
+ }
106
+ // PropertyName != nil means `export { a as b }` — a rename
107
+ // the from-clause rewrite cannot preserve without also
108
+ // touching the import side. Skip.
109
+ if spec.PropertyName != nil {
110
+ continue
111
+ }
112
+ name := identifierText(spec.Name())
113
+ if name == "" {
114
+ continue
115
+ }
116
+ if imported[name] {
117
+ matched = true
118
+ break
119
+ }
120
+ }
121
+ if matched {
122
+ ctx.Report(stmt, "Use `export { X } from \"Y\"` instead of importing then re-exporting.")
123
+ }
124
+ }
125
+ }
126
+
127
+ func init() {
128
+ Register(unicornPreferExportFrom{})
129
+ }
@@ -0,0 +1,127 @@
1
+ // unicorn/prefer-global-this: `window`, `self`, and `global` are
2
+ // environment-specific global aliases. Using them locks code to a
3
+ // single runtime (browser, worker, Node) and forces feature-detection
4
+ // boilerplate when the same code needs to run elsewhere. `globalThis`
5
+ // is the standardized cross-runtime alias and the canonical form for
6
+ // the same reference.
7
+ //
8
+ // AST-only: visit every `Identifier`. The rule fires only when the
9
+ // identifier sits in a value-expression position; declaration names,
10
+ // property-access right sides, parameter names, property-assignment
11
+ // keys, and type references are filtered out by parent-kind gating so
12
+ // the diagnostic is anchored on actual reads of the global.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-global-this.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ type unicornPreferGlobalThis struct{}
19
+
20
+ func (unicornPreferGlobalThis) Name() string { return "unicorn/prefer-global-this" }
21
+ func (unicornPreferGlobalThis) Visits() []shimast.Kind {
22
+ return []shimast.Kind{shimast.KindIdentifier}
23
+ }
24
+ func (unicornPreferGlobalThis) Check(ctx *Context, node *shimast.Node) {
25
+ name := identifierText(node)
26
+ switch name {
27
+ case "window", "self", "global":
28
+ default:
29
+ return
30
+ }
31
+ if !isUnicornValuePositionIdentifier(node) {
32
+ return
33
+ }
34
+ ctx.Report(node, "Prefer `globalThis` over `window` / `self` / `global`.")
35
+ }
36
+
37
+ // isUnicornValuePositionIdentifier reports whether `node` (a bare
38
+ // Identifier) appears in a value-expression position rather than as a
39
+ // binding name, property key, member-access right side, or type
40
+ // reference. Declaration names and property keys are read positions
41
+ // for the *name* itself, so they must not contribute to rules that
42
+ // flag *uses* of a global.
43
+ func isUnicornValuePositionIdentifier(node *shimast.Node) bool {
44
+ if node == nil || node.Kind != shimast.KindIdentifier || node.Parent == nil {
45
+ return false
46
+ }
47
+ parent := node.Parent
48
+ switch parent.Kind {
49
+ case shimast.KindVariableDeclaration:
50
+ decl := parent.AsVariableDeclaration()
51
+ if decl != nil && decl.Name() == node {
52
+ return false
53
+ }
54
+ case shimast.KindBindingElement:
55
+ elem := parent.AsBindingElement()
56
+ if elem != nil && elem.Name() == node {
57
+ return false
58
+ }
59
+ case shimast.KindParameter:
60
+ param := parent.AsParameterDeclaration()
61
+ if param != nil && param.Name() == node {
62
+ return false
63
+ }
64
+ case shimast.KindFunctionDeclaration:
65
+ fn := parent.AsFunctionDeclaration()
66
+ if fn != nil && fn.Name() == node {
67
+ return false
68
+ }
69
+ case shimast.KindFunctionExpression:
70
+ fn := parent.AsFunctionExpression()
71
+ if fn != nil && fn.Name() == node {
72
+ return false
73
+ }
74
+ case shimast.KindClassDeclaration:
75
+ cls := parent.AsClassDeclaration()
76
+ if cls != nil && cls.Name() == node {
77
+ return false
78
+ }
79
+ case shimast.KindClassExpression:
80
+ cls := parent.AsClassExpression()
81
+ if cls != nil && cls.Name() == node {
82
+ return false
83
+ }
84
+ case shimast.KindPropertyAccessExpression:
85
+ access := parent.AsPropertyAccessExpression()
86
+ if access != nil && access.Name() == node {
87
+ return false
88
+ }
89
+ case shimast.KindPropertyAssignment:
90
+ prop := parent.AsPropertyAssignment()
91
+ if prop != nil && prop.Name() == node {
92
+ return false
93
+ }
94
+ case shimast.KindShorthandPropertyAssignment:
95
+ // `{window}` shorthand — the identifier is both name and read,
96
+ // but the read here is the value position, so allow.
97
+ case shimast.KindMethodDeclaration,
98
+ shimast.KindGetAccessor,
99
+ shimast.KindSetAccessor,
100
+ shimast.KindPropertyDeclaration:
101
+ // These have a Name() slot that is not a value expression.
102
+ return false
103
+ case shimast.KindTypeReference,
104
+ shimast.KindQualifiedName,
105
+ shimast.KindImportSpecifier,
106
+ shimast.KindExportSpecifier,
107
+ shimast.KindNamespaceImport,
108
+ shimast.KindImportClause,
109
+ shimast.KindNamespaceExport,
110
+ shimast.KindLabeledStatement,
111
+ shimast.KindBreakStatement,
112
+ shimast.KindContinueStatement,
113
+ shimast.KindJsxAttribute,
114
+ shimast.KindEnumDeclaration,
115
+ shimast.KindEnumMember,
116
+ shimast.KindModuleDeclaration,
117
+ shimast.KindTypeParameter,
118
+ shimast.KindInterfaceDeclaration,
119
+ shimast.KindTypeAliasDeclaration:
120
+ return false
121
+ }
122
+ return true
123
+ }
124
+
125
+ func init() {
126
+ Register(unicornPreferGlobalThis{})
127
+ }