@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
package/plugin/main.go CHANGED
@@ -1,7 +1,7 @@
1
1
  // Command @ttsc/lint is the native backend for the `@ttsc/lint` plugin.
2
2
  //
3
- // The plugin host (ttsc / ttsx) spawns this binary with one of six
4
- // subcommands:
3
+ // The plugin host (ttsc / ttsx) spawns this binary with one of these
4
+ // subcommands (canonical list lives in `linthost/dispatch.go`):
5
5
  //
6
6
  // - `version` / `-v` / `--version` — print the binary banner.
7
7
  // - `check` — typecheck + lint without emit. Failure exit code if any
@@ -13,6 +13,13 @@
13
13
  // - `build` — typecheck + lint, then run the standard tsgo emit pipeline
14
14
  // so JS files land on disk.
15
15
  // - `transform --file=PATH` — single-file emit with the same lint pass.
16
+ // - `lsp-command-ids` — print workspace/executeCommand ids owned by
17
+ // `@ttsc/lint`.
18
+ // - `lsp-code-action-kinds` — print CodeActionKind values offered.
19
+ // - `lsp-diagnostics` — produce LSP diagnostic JSON for one file URI.
20
+ // - `lsp-code-actions` — produce LSP code actions for one file URI.
21
+ // - `lsp-execute-command` — return a WorkspaceEdit for a lint-owned
22
+ // command.
16
23
  //
17
24
  // Diagnostics share the renderer with tsgo's own output, so warnings come
18
25
  // out yellow, errors come out red, and the trailing `Found N errors`
@@ -25,11 +32,50 @@
25
32
  package main
26
33
 
27
34
  import (
35
+ "fmt"
28
36
  "os"
37
+ "runtime"
38
+ "runtime/pprof"
29
39
 
30
40
  "github.com/samchon/ttsc/packages/lint/linthost"
31
41
  )
32
42
 
33
43
  func main() {
34
- os.Exit(linthost.Main(os.Args[1:]))
44
+ // Opt-in CPU profile capture for the lint binary. Set
45
+ // `TTSC_LINT_CPUPROFILE=/path/to/out.prof` before running `ttsc check`
46
+ // to record where the in-process lint engine spends time on a real
47
+ // project. The file is flushed before the process exits; the binary's
48
+ // exit code is unchanged. NOTE: `os.Exit` skips deferred calls, so the
49
+ // profile must be stopped explicitly before exit — `defer
50
+ // pprof.StopCPUProfile()` would silently produce a zero-byte file.
51
+ var profileFile *os.File
52
+ if path := os.Getenv("TTSC_LINT_CPUPROFILE"); path != "" {
53
+ f, err := os.Create(path)
54
+ if err != nil {
55
+ fmt.Fprintf(os.Stderr, "@ttsc/lint: cannot create cpuprofile %q: %v\n", path, err)
56
+ } else if err := pprof.StartCPUProfile(f); err != nil {
57
+ fmt.Fprintf(os.Stderr, "@ttsc/lint: pprof.StartCPUProfile: %v\n", err)
58
+ f.Close()
59
+ } else {
60
+ profileFile = f
61
+ }
62
+ }
63
+ code := linthost.Main(os.Args[1:])
64
+ if profileFile != nil {
65
+ pprof.StopCPUProfile()
66
+ profileFile.Close()
67
+ }
68
+ if path := os.Getenv("TTSC_LINT_MEMPROFILE"); path != "" {
69
+ f, err := os.Create(path)
70
+ if err != nil {
71
+ fmt.Fprintf(os.Stderr, "@ttsc/lint: cannot create memprofile %q: %v\n", path, err)
72
+ } else {
73
+ runtime.GC()
74
+ if err := pprof.WriteHeapProfile(f); err != nil {
75
+ fmt.Fprintf(os.Stderr, "@ttsc/lint: pprof.WriteHeapProfile: %v\n", err)
76
+ }
77
+ f.Close()
78
+ }
79
+ }
80
+ os.Exit(code)
35
81
  }
@@ -19,10 +19,17 @@ import (
19
19
  )
20
20
 
21
21
  // NodeText returns the source text under `node` with leading trivia
22
- // (whitespace + comments) stripped. Mirrors `nodeText` in the built-in
22
+ // (whitespace + comments) stripped AND trailing ASCII whitespace
23
+ // (` `, `\t`, `\r`, `\n`) trimmed. Mirrors `nodeText` in the built-in
23
24
  // engine — useful for rules that compare textual identity (the
24
- // `no-self-assign` / `no-self-compare` shape) or that splice a sub-node's
25
- // text into a fix string.
25
+ // `no-self-assign` / `no-self-compare` shape) or that splice a
26
+ // sub-node's text into a fix string.
27
+ //
28
+ // The trailing trim is deliberate so callers using the returned text
29
+ // as the right-hand side of a `TextEdit{End: ...}` splice don't drag
30
+ // in a node's trailing newline. Callers that need the literal byte
31
+ // range without trimming should call `TokenRange` and read `file.Text()`
32
+ // directly.
26
33
  //
27
34
  // Returns "" when `file` or `node` is nil, or when the computed range
28
35
  // falls outside the file (defensive — shouldn't happen for engine-supplied
package/rule/rule.go CHANGED
@@ -110,17 +110,19 @@ type Reporter interface {
110
110
  }
111
111
 
112
112
  // FixReporter is the optional extension a host implements to receive
113
- // autofix edits alongside a finding. The public `rule.Context` type-asserts
114
- // against this shape so any host whose reporter exposes both methods opts
115
- // into fix support without depending on a private interface name.
113
+ // autofix edits alongside a finding. The public `rule.Context`
114
+ // type-asserts against this shape so any host whose reporter exposes
115
+ // both methods opts into fix support without depending on a private
116
+ // interface name.
116
117
  //
117
- // Contributor rules do NOT implement this interfaceit is the host-side
118
- // counterpart to `Context.ReportFix` / `Context.ReportRangeFix`. A
119
- // contributor authoring a fake reporter for unit tests can declare
120
- // `var _ rule.FixReporter = &myReporter{}` to compile-check that the fake
121
- // satisfies the fix surface. Go interface satisfaction is all-or-nothing:
122
- // a fake that wants the fix path must implement BOTH `ReportFix` and
123
- // `ReportRangeFix`.
118
+ // Rule production code does NOT touch FixReporter directlycall
119
+ // `ctx.ReportFix` / `ctx.ReportRangeFix`, and the host's reporter
120
+ // receives the edits. The only place a contributor sees this interface
121
+ // is in test code that fakes the reporter: such a fake must implement
122
+ // BOTH `Reporter` (`Report` + `ReportRange`) AND `FixReporter`
123
+ // (`ReportFix` + `ReportRangeFix`), because Go interface satisfaction
124
+ // is all-or-nothing. Declaring `var _ rule.FixReporter = &myFake{}`
125
+ // compile-checks the fake covers the fix surface.
124
126
  type FixReporter interface {
125
127
  ReportFix(node *shimast.Node, message string, edits ...TextEdit)
126
128
  ReportRangeFix(pos, end int, message string, edits ...TextEdit)
@@ -1,4 +1,4 @@
1
- import type { ITtscLintFormatConfig } from "./structures/ITtscLintFormatConfig";
1
+ import type { ITtscLintFormat } from "./structures/ITtscLintFormat";
2
2
 
3
3
  /**
4
4
  * Documented defaults for the `format` block's _always-on_ rules
@@ -7,18 +7,21 @@ import type { ITtscLintFormatConfig } from "./structures/ITtscLintFormatConfig";
7
7
  *
8
8
  * Exported so users can spread defaults next to overrides:
9
9
  *
10
- * Import { defaultFormat, type ITtscLintConfig } from "@ttsc/lint";
10
+ * ```ts
11
+ * import { defaultFormat, type ITtscLintConfig } from "@ttsc/lint";
11
12
  *
12
- * Export default { format: { ...defaultFormat, printWidth: 100 }, } satisfies
13
- * ITtscLintConfig;
13
+ * export default {
14
+ * format: { ...defaultFormat, printWidth: 100 },
15
+ * } satisfies ITtscLintConfig;
16
+ * ```
14
17
  *
15
18
  * The values mirror Prettier 1:1 except for the documented `endOfLine`
16
19
  * narrowing (no `"cr"` / `"auto"`).
17
20
  *
18
21
  * Notably absent: `importOrder` and `jsdoc`. `format/sort-imports` and
19
- * `format/jsdoc` are opt-in by setting their corresponding fields; the defaults
20
- * const only seeds the rules that turn on unconditionally with a non-empty
21
- * `format` block.
22
+ * `format/jsdoc` are opt-in by setting their corresponding fields; this
23
+ * const documents only the rules that turn on unconditionally with a
24
+ * non-empty `format` block — the Go host owns runtime activation.
22
25
  */
23
26
  export const defaultFormat = Object.freeze({
24
27
  severity: "off",
@@ -29,4 +32,4 @@ export const defaultFormat = Object.freeze({
29
32
  tabWidth: 2,
30
33
  useTabs: false,
31
34
  endOfLine: "lf",
32
- } satisfies ITtscLintFormatConfig);
35
+ } satisfies ITtscLintFormat);
package/src/index.ts CHANGED
@@ -18,7 +18,11 @@ type TtscPluginContributor = {
18
18
 
19
19
  /** Descriptor shape returned to ttsc's plugin builder by the factory. */
20
20
  type TtscPluginDescriptor = {
21
- capabilities?: { diagnosticsTiming?: boolean; threadingArgs?: boolean };
21
+ capabilities?: {
22
+ diagnosticsTiming?: boolean;
23
+ lsp?: boolean;
24
+ threadingArgs?: boolean;
25
+ };
22
26
  contributors?: TtscPluginContributor[];
23
27
  name: string;
24
28
  reportsTypeScriptDiagnostics?: boolean;
@@ -98,11 +102,10 @@ const FRAMEWORK_KEYS = new Set<string>([
98
102
  * upward from the tsconfig directory.
99
103
  *
100
104
  * The factory locates the config file, evaluates it (via ttsx for TS / ESM
101
- * sources, `require` for CommonJS, `JSON.parse` for JSON), reads its `plugins`
102
- * map, and forwards each contributor's Go source directory to ttsc's plugin
103
- * builder via the descriptor's `contributors` field.
104
- *
105
- * @internal
105
+ * sources, `require` for CommonJS, `JSON.parse` for JSON), reads every
106
+ * `plugins` map (top-level and inside array-form flat configs), and forwards
107
+ * each contributor's Go source directory to ttsc's plugin builder via the
108
+ * descriptor's `contributors` field.
106
109
  */
107
110
  export default function createTtscPlugin(
108
111
  context: TtscPluginFactoryContext<ITtscLintPluginConfig>,
@@ -113,7 +116,7 @@ export default function createTtscPlugin(
113
116
  // declared, so consumers (and the existing key-shape regression
114
117
  // tests) see the same surface as before this feature shipped.
115
118
  const descriptor: TtscPluginDescriptor = {
116
- capabilities: { diagnosticsTiming: true, threadingArgs: true },
119
+ capabilities: { diagnosticsTiming: true, lsp: true, threadingArgs: true },
117
120
  name: "@ttsc/lint",
118
121
  reportsTypeScriptDiagnostics: true,
119
122
  source: path.resolve(__dirname, "..", "plugin"),
@@ -255,14 +258,24 @@ function findLintConfigFile(
255
258
  // as ambiguous and skipped (the Go side raises a hard error on the
256
259
  // duplicate; here we leave it to the binary's own discovery to surface
257
260
  // the issue once with one canonical message).
261
+ const candidateSet = new Set<string>(LINT_CONFIG_FILENAMES);
258
262
  let dir = tsconfigBaseDir(context);
259
263
  while (true) {
260
- const matches = LINT_CONFIG_FILENAMES.map((name) =>
261
- path.join(dir, name),
262
- ).filter(
263
- (candidate) =>
264
- fs.existsSync(candidate) && fs.statSync(candidate).isFile(),
265
- );
264
+ // One `readdirSync` per directory level beats 14 `existsSync`+
265
+ // `statSync` pairs (= 28 stat syscalls) per level; intersect the
266
+ // listing with the candidate set instead.
267
+ let entries: fs.Dirent[];
268
+ try {
269
+ entries = fs.readdirSync(dir, { withFileTypes: true });
270
+ } catch {
271
+ entries = [];
272
+ }
273
+ const matches: string[] = [];
274
+ for (const entry of entries) {
275
+ if (!candidateSet.has(entry.name)) continue;
276
+ if (!entry.isFile() && !entry.isSymbolicLink()) continue;
277
+ matches.push(path.join(dir, entry.name));
278
+ }
266
279
  if (matches.length === 1) {
267
280
  return matches[0];
268
281
  }
@@ -376,7 +389,6 @@ function readCjsConfigPlugins(configPath: string): ConfigPluginEntry[] {
376
389
  const TTSX_EXTRACTOR_SCRIPT = `import * as importedConfig from %CONFIG_IMPORT%;
377
390
 
378
391
  declare const process: {
379
- argv: string[];
380
392
  cwd(): string;
381
393
  stdout: { write(value: string): void };
382
394
  stderr: { write(value: string): void };
@@ -444,7 +456,10 @@ function extractPluginSource(value: unknown): string | undefined {
444
456
  // contributors authored as plain \`module.exports = plugin\` both
445
457
  // resolve identically.
446
458
  let current: Record<string, unknown> = value;
447
- for (let i = 0; i < 4; i++) {
459
+ // 8 hops to match the outer-process unwrapDefault helper; previously
460
+ // 4, which silently misrouted deeply re-exported plugins while
461
+ // unwrapDefault would have unwrapped them.
462
+ for (let i = 0; i < 8; i++) {
448
463
  if (typeof current.source === "string") break;
449
464
  const next = current.default;
450
465
  if (!isObject(next)) break;
@@ -798,7 +813,16 @@ function normalizePluginValue(
798
813
  }`,
799
814
  );
800
815
  }
801
- const mod = requireFromConfig(resolved);
816
+ let mod: unknown;
817
+ try {
818
+ mod = requireFromConfig(resolved);
819
+ } catch (error) {
820
+ throw new Error(
821
+ `@ttsc/lint: lint config ${configPath} plugin ${JSON.stringify(namespace)} failed to load from ${resolved}: ${
822
+ error instanceof Error ? error.message : String(error)
823
+ }`,
824
+ );
825
+ }
802
826
  const plugin = validatePluginShape(unwrapDefault(mod), namespace, resolved);
803
827
  return { namespace, source: plugin.source };
804
828
  }
@@ -1,6 +1,6 @@
1
- import type { ITtscLintFormatConfig } from "./ITtscLintFormatConfig";
1
+ import type { ITtscLintFormat } from "./ITtscLintFormat";
2
2
  import type { ITtscLintPlugin } from "./ITtscLintPlugin";
3
- import type { TtscLintRuleMap } from "./TtscLintRuleMap";
3
+ import type { ITtscLintRules } from "./rules/ITtscLintRules";
4
4
 
5
5
  /**
6
6
  * Top-level object accepted by `@ttsc/lint` config files.
@@ -25,9 +25,15 @@ export interface ITtscLintConfig {
25
25
  /** Contributor plugin objects keyed by namespace. */
26
26
  plugins?: Record<string, ITtscLintPlugin>;
27
27
 
28
- /** Rule-name to severity map. Supports severity tuples with options. */
29
- rules?: TtscLintRuleMap;
28
+ /**
29
+ * Kebab-case built-in rule severities plus namespaced contributor rules.
30
+ *
31
+ * Built-in rules are concrete interface properties for autocomplete and typo
32
+ * checking. Namespaced families and contributor rules use the familiar slash
33
+ * form such as `react/jsx-key` or `demo/no-demo`.
34
+ */
35
+ rules?: ITtscLintRules;
30
36
 
31
- /** Prettier-style flat configuration for the `format/*` rules. */
32
- format?: ITtscLintFormatConfig;
37
+ /** Prettier-style flat configuration for the format rules. */
38
+ format?: ITtscLintFormat;
33
39
  }
@@ -1,7 +1,7 @@
1
1
  import type { TtscLintSeverity } from "./TtscLintSeverity";
2
2
 
3
3
  /**
4
- * Prettier-style flat configuration for the `format/*` rules.
4
+ * Prettier-style flat configuration for the format rules.
5
5
  *
6
6
  * The `format` block is the recommended way to enable formatting in
7
7
  * `@ttsc/lint`. Each key mirrors a Prettier option of the same name — users
@@ -51,7 +51,7 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
51
51
  * Format findings produced from this block are off by default. Set `severity`
52
52
  * only when a project intentionally wants check-time format diagnostics.
53
53
  */
54
- export interface ITtscLintFormatConfig {
54
+ export interface ITtscLintFormat {
55
55
  /**
56
56
  * Check-time severity for format findings generated from this block.
57
57
  *
@@ -0,0 +1,55 @@
1
+ import type { TtscLintSeverity } from "./TtscLintSeverity";
2
+
3
+ /**
4
+ * Per-rule severity setting used by every rule entry in
5
+ * `ITtscLintConfig.rules`.
6
+ *
7
+ * A rule may be configured either as a bare severity string (`"error"`,
8
+ * `"warning"`, `"off"`) or as a single-element tuple containing the same
9
+ * severity. Both forms are equivalent at runtime; the tuple form exists so
10
+ * that severity-only rules and options-bearing rules look uniform when read
11
+ * top-to-bottom in a `ttsc.lint.config.ts` file.
12
+ *
13
+ * Use {@link TtscLintRuleOptionsSetting} when the rule accepts a typed
14
+ * options object.
15
+ *
16
+ * @example
17
+ * const config: ITtscLintConfig = {
18
+ * rules: {
19
+ * eqeqeq: "error",
20
+ * "no-console": ["warning"],
21
+ * "no-debugger": "off",
22
+ * },
23
+ * };
24
+ */
25
+ export type TtscLintRuleSetting =
26
+ | TtscLintSeverity
27
+ | readonly [TtscLintSeverity];
28
+
29
+ /**
30
+ * Per-rule severity-plus-options setting for rules that accept a typed options
31
+ * object.
32
+ *
33
+ * This is the tuple form ESLint users know — `[severity, options]` —
34
+ * kept strongly typed by way of the rule's dedicated options interface
35
+ * (see `TtscLintRuleOptions.ts`). The bare {@link TtscLintRuleSetting}
36
+ * forms remain accepted; omitting the options object means "use the
37
+ * rule's default options".
38
+ *
39
+ * @typeParam TOptions - The rule's options shape. Each rule supplies its
40
+ * own interface from `TtscLintRuleOptions.ts` (for example
41
+ * `ITtscLintBoundariesElementTypesRuleOptions`).
42
+ *
43
+ * @example
44
+ * const config: ITtscLintConfig = {
45
+ * rules: {
46
+ * "boundaries/element-types": [
47
+ * "error",
48
+ * { default: "disallow", rules: [...] },
49
+ * ],
50
+ * },
51
+ * };
52
+ */
53
+ export type TtscLintRuleOptionsSetting<TOptions> =
54
+ | TtscLintRuleSetting
55
+ | readonly [TtscLintSeverity, TOptions];
@@ -1,9 +1,8 @@
1
1
  export * from "./ITtscLintConfig";
2
- export * from "./ITtscLintFormatConfig";
2
+ export * from "./ITtscLintFormat";
3
3
  export * from "./ITtscLintPlugin";
4
4
  export * from "./ITtscLintPluginConfig";
5
5
  export * from "./ITtscLintPluginMeta";
6
- export * from "./TtscLintRule";
7
- export * from "./TtscLintRuleMap";
8
- export * from "./TtscLintRuleOptions";
6
+ export * from "./TtscLintRuleSetting";
9
7
  export * from "./TtscLintSeverity";
8
+ export * from "./rules";
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Options shapes for every rule in {@link ITtscLintBoundariesRules}.
3
+ *
4
+ * The `boundaries/*` family classifies each source file as belonging to a
5
+ * named *element* (a layer, feature, or app within the project). Every
6
+ * rule below shares the same element-declaration block, so the helper
7
+ * interfaces in this file describe that block first and then layer the
8
+ * per-rule options on top.
9
+ *
10
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries
11
+ */
12
+
13
+ /** One source-path element used by the `boundaries/*` rules. */
14
+ export interface ITtscLintBoundariesElement {
15
+ /** Element type name used by `boundaries/element-types` policies. */
16
+ type: string;
17
+
18
+ /**
19
+ * Glob-like source path pattern. Relative patterns are matched against
20
+ * any project-path suffix, so `src/app/**` works in temporary and
21
+ * monorepo roots alike.
22
+ */
23
+ pattern: string;
24
+
25
+ /**
26
+ * File(s) inside the element that may be imported from outside that
27
+ * element. Used by `boundaries/entry-point`.
28
+ */
29
+ entry?: string | readonly string[];
30
+
31
+ /**
32
+ * File(s) inside the element that may only be imported by the same
33
+ * element. Used by `boundaries/no-private`.
34
+ */
35
+ private?: string | readonly string[];
36
+ }
37
+
38
+ /** Dependency policy used by `boundaries/element-types`. */
39
+ export interface ITtscLintBoundariesElementTypesRule {
40
+ /**
41
+ * Source element type(s) the policy applies to. Omit to match all
42
+ * sources.
43
+ */
44
+ from?: string | readonly string[];
45
+
46
+ /** Target element type(s) allowed from the matching source. */
47
+ allow?: string | readonly string[];
48
+
49
+ /** Target element type(s) rejected from the matching source. */
50
+ disallow?: string | readonly string[];
51
+
52
+ /** Optional diagnostic override. */
53
+ message?: string;
54
+ }
55
+
56
+ /**
57
+ * Shared element-declaration block used by every TypeScript source-path
58
+ * `boundaries/*` rule.
59
+ */
60
+ export interface ITtscLintBoundariesElementsOptions {
61
+ /**
62
+ * Source path elements used to classify importers and imported files.
63
+ */
64
+ elements?: readonly ITtscLintBoundariesElement[];
65
+ }
66
+
67
+ /** `boundaries/element-types` rule options. */
68
+ export interface ITtscLintBoundariesElementTypesRuleOptions
69
+ extends ITtscLintBoundariesElementsOptions {
70
+ /**
71
+ * Fallback policy when no rule matches.
72
+ *
73
+ * @default "allow"
74
+ */
75
+ default?: "allow" | "disallow";
76
+
77
+ /** Ordered dependency policies. First matching policy wins. */
78
+ rules?: readonly ITtscLintBoundariesElementTypesRule[];
79
+ }
80
+
81
+ /** `boundaries/external` rule options. */
82
+ export interface ITtscLintBoundariesExternalRuleOptions {
83
+ /**
84
+ * External package/specifier patterns that are allowed. Empty means
85
+ * all.
86
+ */
87
+ allow?: string | readonly string[];
88
+
89
+ /** External package/specifier patterns that are rejected. */
90
+ disallow?: string | readonly string[];
91
+
92
+ /** Optional diagnostic override. */
93
+ message?: string;
94
+ }
95
+
96
+ /** `boundaries/entry-point` rule options. */
97
+ export type ITtscLintBoundariesEntryPointRuleOptions =
98
+ ITtscLintBoundariesElementsOptions;
99
+
100
+ /** `boundaries/no-private` rule options. */
101
+ export type ITtscLintBoundariesNoPrivateRuleOptions =
102
+ ITtscLintBoundariesElementsOptions;
103
+
104
+ /** `boundaries/no-unknown` rule options. */
105
+ export type ITtscLintBoundariesNoUnknownRuleOptions =
106
+ ITtscLintBoundariesElementsOptions;
107
+
108
+ /**
109
+ * `boundaries/dependencies` rule options.
110
+ *
111
+ * The upstream unified rule subsumes `element-types`, `entry-point`,
112
+ * `external`, `no-private`, and `no-unknown` behind a single
113
+ * direction-aware policy block. The v1 native port registers the rule
114
+ * name and decodes this config shape but does not yet emit diagnostics
115
+ * (`v1 stub; full validation deferred` — see `rules_boundaries.go`).
116
+ */
117
+ export interface ITtscLintBoundariesDependenciesRuleOptions
118
+ extends ITtscLintBoundariesElementsOptions {
119
+ /**
120
+ * Fallback policy when no rule matches.
121
+ *
122
+ * @default "allow"
123
+ */
124
+ default?: "allow" | "disallow";
125
+
126
+ /** Ordered dependency policies. First matching policy wins. */
127
+ rules?: readonly ITtscLintBoundariesElementTypesRule[];
128
+ }
@@ -0,0 +1,95 @@
1
+ import type {
2
+ ITtscLintBoundariesDependenciesRuleOptions,
3
+ ITtscLintBoundariesElementTypesRuleOptions,
4
+ ITtscLintBoundariesEntryPointRuleOptions,
5
+ ITtscLintBoundariesExternalRuleOptions,
6
+ ITtscLintBoundariesNoPrivateRuleOptions,
7
+ ITtscLintBoundariesNoUnknownRuleOptions,
8
+ } from "./ITtscLintBoundariesRuleOptions";
9
+ import type {
10
+ TtscLintRuleOptionsSetting,
11
+ TtscLintRuleSetting,
12
+ } from "../TtscLintRuleSetting";
13
+
14
+ /**
15
+ * Architecture-boundary rules that enforce import direction and
16
+ * module visibility between configured source-path *elements*
17
+ * (layers, features, apps in a monorepo).
18
+ *
19
+ * Every rule operates on the *resolved source file* of an import —
20
+ * relative imports are followed to the real `.ts`/`.tsx`/`.d.ts`
21
+ * file before classification.
22
+ *
23
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries
24
+ */
25
+ export interface ITtscLintBoundariesRules {
26
+ /**
27
+ * Enforce allowed dependency directions between configured
28
+ * source-path element types.
29
+ *
30
+ * Each `element` entry declares a name, a matching glob, and the
31
+ * other element types it is allowed to import.
32
+ *
33
+ * Imports that fall outside the allow-list are reported.
34
+ *
35
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries/blob/master/docs/rules/element-types.md
36
+ */
37
+ "boundaries/element-types"?: TtscLintRuleOptionsSetting<ITtscLintBoundariesElementTypesRuleOptions>;
38
+
39
+ /**
40
+ * Require imports that cross element boundaries to target the
41
+ * importee element's configured public entry files (typically
42
+ * `index.ts`), so the public surface of each element is explicit.
43
+ *
44
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries/blob/master/docs/rules/entry-point.md
45
+ */
46
+ "boundaries/entry-point"?: TtscLintRuleOptionsSetting<ITtscLintBoundariesEntryPointRuleOptions>;
47
+
48
+ /**
49
+ * Restrict external package imports by package or specifier
50
+ * pattern.
51
+ *
52
+ * Useful for forbidding direct imports of an underlying library
53
+ * when a project-local facade exists.
54
+ *
55
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries/blob/master/docs/rules/external.md
56
+ */
57
+ "boundaries/external"?: TtscLintRuleOptionsSetting<ITtscLintBoundariesExternalRuleOptions>;
58
+
59
+ /**
60
+ * Reject imports of files declared *private* by a parent element
61
+ * from outside that element.
62
+ *
63
+ * Combines with `element-types` to keep implementation details
64
+ * hidden.
65
+ *
66
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries/blob/master/docs/rules/no-private.md
67
+ */
68
+ "boundaries/no-private"?: TtscLintRuleOptionsSetting<ITtscLintBoundariesNoPrivateRuleOptions>;
69
+
70
+ /**
71
+ * Reject relative imports whose resolved source file falls under
72
+ * no configured element.
73
+ *
74
+ * Catches stray files that escape the project's boundary map.
75
+ *
76
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries/blob/master/docs/rules/no-unknown.md
77
+ */
78
+ "boundaries/no-unknown"?: TtscLintRuleOptionsSetting<ITtscLintBoundariesNoUnknownRuleOptions>;
79
+
80
+ /**
81
+ * Unified dependency-direction rule from upstream
82
+ * `eslint-plugin-boundaries`, intended to replace
83
+ * `element-types` / `entry-point` / `external` / `no-private` /
84
+ * `no-unknown` with a single policy block.
85
+ *
86
+ * The native port registers the rule name and accepts the same
87
+ * `elements` + `rules` config shape as `element-types`, but does not
88
+ * emit diagnostics yet (v1 stub; full direction validation
89
+ * deferred). Configure it today to claim the upstream rule id; the
90
+ * legacy split rules continue to enforce policy.
91
+ *
92
+ * @reference https://github.com/javierbrea/eslint-plugin-boundaries/blob/master/docs/rules/dependencies.md
93
+ */
94
+ "boundaries/dependencies"?: TtscLintRuleOptionsSetting<ITtscLintBoundariesDependenciesRuleOptions>;
95
+ }
@@ -0,0 +1,21 @@
1
+ import type { TtscLintSeverity } from "../TtscLintSeverity";
2
+ import type { TtscLintRuleSetting } from "../TtscLintRuleSetting";
3
+
4
+ /**
5
+ * Catch-all index signature for contributor plugin rules.
6
+ *
7
+ * Plugin authors expose rules under their own namespace prefix
8
+ * (`demo/no-demo`, `myplugin/foo-bar`). The signature here
9
+ * accepts any `"<namespace>/<rule>"` key with either the bare
10
+ * severity form, the severity tuple, or the
11
+ * severity-plus-options tuple. Plugins ship their own typings to
12
+ * tighten the options shape per rule.
13
+ *
14
+ * @reference https://ttsc.dev/lint/development/rules
15
+ */
16
+ export interface ITtscLintContributorRules {
17
+ [ruleName: `${string}/${string}`]:
18
+ | TtscLintRuleSetting
19
+ | readonly [TtscLintSeverity, unknown]
20
+ | undefined;
21
+ }