@ttsc/lint 0.13.0 → 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.
- package/README.md +948 -69
- package/lib/defaultFormat.d.ts +9 -6
- package/lib/defaultFormat.js +9 -6
- package/lib/defaultFormat.js.map +1 -1
- package/lib/index.d.ts +46 -0
- package/lib/index.js +60 -37
- package/lib/index.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +12 -6
- package/lib/structures/{ITtscLintFormatConfig.d.ts → ITtscLintFormat.d.ts} +2 -2
- package/lib/structures/{TtscLintRuleMap.js → ITtscLintFormat.js} +1 -1
- package/lib/structures/ITtscLintFormat.js.map +1 -0
- package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
- package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
- package/lib/structures/TtscLintRuleSetting.js.map +1 -0
- package/lib/structures/index.d.ts +3 -4
- package/lib/structures/index.js +3 -4
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +104 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +14 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +79 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +17 -0
- package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
- package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +1257 -0
- package/lib/structures/{ITtscLintFormatConfig.js → rules/ITtscLintCoreRules.js} +1 -1
- package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +129 -0
- package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
- package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +157 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +167 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJestRules.d.ts +201 -0
- package/lib/structures/rules/ITtscLintJestRules.js +3 -0
- package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +140 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +302 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +185 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +330 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +188 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +51 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +39 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +12 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRules.d.ts +289 -0
- package/lib/structures/rules/ITtscLintReactRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +190 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +66 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
- package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
- package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
- package/lib/structures/rules/ITtscLintRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +148 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +181 -0
- package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
- package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +21 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +174 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +94 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +22 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +310 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1132 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +141 -0
- package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
- package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
- package/lib/structures/rules/index.d.ts +31 -0
- package/lib/structures/rules/index.js +48 -0
- package/lib/structures/rules/index.js.map +1 -0
- package/linthost/ast_helpers.go +30 -5
- package/linthost/compile.go +33 -2
- package/linthost/config.go +48 -17
- package/linthost/config_format.go +9 -9
- package/linthost/directives.go +67 -25
- package/linthost/dispatch.go +14 -3
- package/linthost/engine.go +160 -40
- package/linthost/fix.go +2 -2
- package/linthost/flags_gen.go +17 -15
- package/linthost/host.go +40 -3
- package/linthost/lsp.go +747 -0
- package/linthost/print_dispatch.go +2 -2
- package/linthost/print_nodes_function.go +2 -2
- package/linthost/print_nodes_object.go +1 -1
- package/linthost/rule_names.go +14 -0
- package/linthost/rules_arrays.go +2 -2
- package/linthost/rules_boundaries.go +532 -0
- package/linthost/rules_camelcase.go +133 -0
- package/linthost/rules_complexity.go +94 -0
- package/linthost/rules_consistent_return.go +130 -0
- package/linthost/rules_console.go +1 -1
- package/linthost/rules_core_extra.go +739 -0
- package/linthost/rules_curly.go +70 -0
- package/linthost/rules_cypress.go +608 -0
- package/linthost/rules_debugger.go +2 -2
- package/linthost/rules_default_case.go +39 -0
- package/linthost/rules_default_case_last.go +46 -0
- package/linthost/rules_dupes.go +3 -3
- package/linthost/rules_empty.go +3 -3
- package/linthost/rules_escape.go +44 -24
- package/linthost/rules_eval.go +2 -2
- package/linthost/rules_finally.go +2 -2
- package/linthost/rules_format_jsdoc.go +1 -1
- package/linthost/rules_format_print_width.go +9 -9
- package/linthost/rules_format_quotes.go +1 -1
- package/linthost/rules_format_semi.go +1 -1
- package/linthost/rules_format_sort_imports.go +1 -1
- package/linthost/rules_format_trailing_comma.go +1 -1
- package/linthost/rules_functional.go +967 -0
- package/linthost/rules_gap.go +24 -45
- package/linthost/rules_grouped_accessor_pairs.go +87 -0
- package/linthost/rules_guard_for_in.go +198 -0
- package/linthost/rules_id_length.go +77 -0
- package/linthost/rules_imports.go +70 -2
- package/linthost/rules_init_declarations.go +53 -0
- package/linthost/rules_jest.go +618 -0
- package/linthost/rules_jsdoc.go +502 -0
- package/linthost/rules_jsx_a11y.go +1264 -0
- package/linthost/rules_logic.go +12 -12
- package/linthost/rules_loops.go +1 -1
- package/linthost/rules_max_classes_per_file.go +58 -0
- package/linthost/rules_max_depth.go +83 -0
- package/linthost/rules_max_lines.go +101 -0
- package/linthost/rules_max_lines_per_function.go +57 -0
- package/linthost/rules_max_nested_callbacks.go +61 -0
- package/linthost/rules_max_params.go +49 -0
- package/linthost/rules_max_statements.go +59 -0
- package/linthost/rules_misc.go +1 -1
- package/linthost/rules_nextjs.go +697 -0
- package/linthost/rules_no_else_return.go +75 -0
- package/linthost/rules_no_empty_named_blocks.go +91 -0
- package/linthost/rules_no_extend_native.go +51 -0
- package/linthost/rules_no_import_assign.go +140 -0
- package/linthost/rules_no_invalid_this.go +52 -0
- package/linthost/rules_no_loop_func.go +85 -0
- package/linthost/rules_no_magic_numbers.go +123 -0
- package/linthost/rules_no_mixed_operators.go +80 -0
- package/linthost/rules_no_param_reassign.go +98 -0
- package/linthost/rules_no_redeclare.go +270 -0
- package/linthost/rules_no_restricted_imports.go +105 -0
- package/linthost/rules_no_restricted_syntax.go +49 -0
- package/linthost/rules_no_shadow.go +147 -0
- package/linthost/rules_no_unreachable.go +77 -0
- package/linthost/rules_no_useless_assignment.go +120 -0
- package/linthost/rules_no_useless_constructor.go +245 -0
- package/linthost/rules_no_useless_return.go +51 -0
- package/linthost/rules_params.go +1 -1
- package/linthost/rules_playwright.go +788 -0
- package/linthost/rules_prefer_arrow_callback.go +124 -0
- package/linthost/rules_prefer_destructuring.go +98 -0
- package/linthost/rules_prefer_named_capture_group.go +129 -0
- package/linthost/rules_prefer_rest_params.go +94 -0
- package/linthost/rules_problems.go +41 -30
- package/linthost/rules_promise.go +1128 -73
- package/linthost/rules_protos.go +2 -2
- package/linthost/rules_react.go +773 -0
- package/linthost/rules_react_extras.go +227 -0
- package/linthost/rules_react_hooks.go +848 -0
- package/linthost/rules_react_perf.go +293 -0
- package/linthost/rules_react_refresh.go +583 -0
- package/linthost/rules_regexp.go +410 -0
- package/linthost/rules_security.go +830 -0
- package/linthost/rules_self.go +2 -2
- package/linthost/rules_solid.go +1073 -0
- package/linthost/rules_sort_imports.go +69 -0
- package/linthost/rules_sort_keys.go +134 -0
- package/linthost/rules_storybook.go +1176 -0
- package/linthost/rules_strings.go +4 -4
- package/linthost/rules_suggestions.go +38 -38
- package/linthost/rules_tanstack_query.go +844 -0
- package/linthost/rules_testing_library.go +1204 -0
- package/linthost/rules_throw.go +1 -1
- package/linthost/rules_ts.go +19 -19
- package/linthost/rules_ts_async.go +399 -0
- package/linthost/rules_ts_class_literal_property_style.go +115 -0
- package/linthost/rules_ts_consistent_type_exports.go +256 -0
- package/linthost/rules_ts_explicit_function_return_type.go +67 -0
- package/linthost/rules_ts_extra.go +155 -36
- package/linthost/rules_ts_no_base_to_string.go +218 -0
- package/linthost/rules_ts_no_confusing_void.go +72 -0
- package/linthost/rules_ts_no_deprecated.go +195 -0
- package/linthost/rules_ts_no_for_in_array.go +84 -0
- package/linthost/rules_ts_no_magic_numbers.go +124 -0
- package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
- package/linthost/rules_ts_no_misused_spread.go +104 -0
- package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
- package/linthost/rules_ts_no_restricted_types.go +62 -0
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
- package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
- package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
- package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
- package/linthost/rules_ts_no_unsafe_argument.go +82 -0
- package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
- package/linthost/rules_ts_no_unsafe_call.go +82 -0
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
- package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
- package/linthost/rules_ts_no_unsafe_return.go +126 -0
- package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
- package/linthost/rules_ts_no_useless_constructor.go +52 -0
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
- package/linthost/rules_ts_parameter_properties.go +38 -0
- package/linthost/rules_ts_prefer_find.go +178 -0
- package/linthost/rules_ts_prefer_includes.go +255 -0
- package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
- package/linthost/rules_ts_prefer_optional_chain.go +228 -0
- package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
- package/linthost/rules_ts_prefer_readonly.go +73 -0
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
- package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
- package/linthost/rules_ts_prefer_return_this_type.go +135 -0
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
- package/linthost/rules_ts_promise_function_async.go +77 -0
- package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
- package/linthost/rules_ts_require_array_sort_compare.go +96 -0
- package/linthost/rules_ts_restrict_plus_operands.go +127 -0
- package/linthost/rules_ts_restrict_template_expressions.go +95 -0
- package/linthost/rules_ts_simple.go +387 -0
- package/linthost/rules_ts_sort_type_constituents.go +144 -0
- package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
- package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
- package/linthost/rules_ts_unbound_method.go +126 -0
- package/linthost/rules_tsdoc.go +136 -0
- package/linthost/rules_unicorn_better_regex.go +27 -0
- package/linthost/rules_unicorn_catch_error_name.go +46 -0
- package/linthost/rules_unicorn_consistent_assert.go +47 -0
- package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
- package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
- package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
- package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
- package/linthost/rules_unicorn_custom_error_definition.go +138 -0
- package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
- package/linthost/rules_unicorn_error_message.go +64 -0
- package/linthost/rules_unicorn_escape_case.go +51 -0
- package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
- package/linthost/rules_unicorn_explicit_length_check.go +88 -0
- package/linthost/rules_unicorn_filename_case.go +29 -0
- package/linthost/rules_unicorn_import_style.go +28 -0
- package/linthost/rules_unicorn_isolated_functions.go +29 -0
- package/linthost/rules_unicorn_new_for_builtins.go +87 -0
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
- package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
- package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
- package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
- package/linthost/rules_unicorn_no_array_for_each.go +40 -0
- package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
- package/linthost/rules_unicorn_no_array_reduce.go +41 -0
- package/linthost/rules_unicorn_no_array_reverse.go +44 -0
- package/linthost/rules_unicorn_no_array_sort.go +43 -0
- package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
- package/linthost/rules_unicorn_no_console_spaces.go +61 -0
- package/linthost/rules_unicorn_no_document_cookie.go +41 -0
- package/linthost/rules_unicorn_no_empty_file.go +44 -0
- package/linthost/rules_unicorn_no_for_loop.go +102 -0
- package/linthost/rules_unicorn_no_hex_escape.go +42 -0
- package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
- package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
- package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
- package/linthost/rules_unicorn_no_lonely_if.go +44 -0
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
- package/linthost/rules_unicorn_no_named_default.go +54 -0
- package/linthost/rules_unicorn_no_negated_condition.go +85 -0
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
- package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
- package/linthost/rules_unicorn_no_new_array.go +30 -0
- package/linthost/rules_unicorn_no_new_buffer.go +31 -0
- package/linthost/rules_unicorn_no_null.go +24 -0
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
- package/linthost/rules_unicorn_no_process_exit.go +43 -0
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
- package/linthost/rules_unicorn_no_static_only_class.go +56 -0
- package/linthost/rules_unicorn_no_thenable.go +74 -0
- package/linthost/rules_unicorn_no_this_assignment.go +35 -0
- package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
- package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
- package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
- package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
- package/linthost/rules_unicorn_no_unused_properties.go +30 -0
- package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
- package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
- package/linthost/rules_unicorn_no_useless_spread.go +67 -0
- package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
- package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
- package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
- package/linthost/rules_unicorn_number_literal_case.go +69 -0
- package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
- package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
- package/linthost/rules_unicorn_prefer_array_find.go +51 -0
- package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
- package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
- package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
- package/linthost/rules_unicorn_prefer_array_some.go +67 -0
- package/linthost/rules_unicorn_prefer_at.go +77 -0
- package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
- package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
- package/linthost/rules_unicorn_prefer_code_point.go +49 -0
- package/linthost/rules_unicorn_prefer_date_now.go +78 -0
- package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
- package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
- package/linthost/rules_unicorn_prefer_event_target.go +36 -0
- package/linthost/rules_unicorn_prefer_export_from.go +129 -0
- package/linthost/rules_unicorn_prefer_global_this.go +127 -0
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
- package/linthost/rules_unicorn_prefer_includes.go +149 -0
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
- package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
- package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
- package/linthost/rules_unicorn_prefer_module.go +50 -0
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
- package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
- package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
- package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
- package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
- package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
- package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
- package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
- package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
- package/linthost/rules_unicorn_prefer_set_has.go +42 -0
- package/linthost/rules_unicorn_prefer_set_size.go +48 -0
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
- package/linthost/rules_unicorn_prefer_single_call.go +96 -0
- package/linthost/rules_unicorn_prefer_spread.go +51 -0
- package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
- package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
- package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
- package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
- package/linthost/rules_unicorn_prefer_switch.go +103 -0
- package/linthost/rules_unicorn_prefer_ternary.go +71 -0
- package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
- package/linthost/rules_unicorn_prefer_type_error.go +127 -0
- package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
- package/linthost/rules_unicorn_relative_url_style.go +49 -0
- package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
- package/linthost/rules_unicorn_require_module_attributes.go +54 -0
- package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
- package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
- package/linthost/rules_unicorn_string_content.go +27 -0
- package/linthost/rules_unicorn_switch_case_braces.go +42 -0
- package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
- package/linthost/rules_unicorn_template_indent.go +28 -0
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
- package/linthost/rules_unicorn_throw_new_error.go +61 -0
- package/linthost/rules_var.go +10 -4
- package/linthost/rules_vitest.go +568 -0
- package/package.json +3 -3
- package/plugin/main.go +49 -3
- package/rule/astutil/astutil.go +10 -3
- package/rule/rule.go +12 -10
- package/src/defaultFormat.ts +11 -8
- package/src/index.ts +65 -43
- package/src/structures/ITtscLintConfig.ts +12 -6
- package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
- package/src/structures/TtscLintRuleSetting.ts +55 -0
- package/src/structures/index.ts +3 -4
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
- package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
- package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
- package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
- package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
- package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
- package/src/structures/rules/ITtscLintJestRules.ts +220 -0
- package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
- package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
- package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
- package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
- package/src/structures/rules/ITtscLintReactRules.ts +321 -0
- package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
- package/src/structures/rules/ITtscLintRules.ts +77 -0
- package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
- package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
- package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
- package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
- package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
- package/src/structures/rules/index.ts +31 -0
- package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
- package/lib/structures/TtscLintRule.d.ts +0 -17
- package/lib/structures/TtscLintRule.js.map +0 -1
- package/lib/structures/TtscLintRuleMap.d.ts +0 -46
- package/lib/structures/TtscLintRuleMap.js.map +0 -1
- package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
- package/lib/structures/TtscLintRuleOptions.js.map +0 -1
- package/src/structures/TtscLintRule.ts +0 -160
- package/src/structures/TtscLintRuleMap.ts +0 -55
- 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
|
|
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
|
-
|
|
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
|
}
|
package/rule/astutil/astutil.go
CHANGED
|
@@ -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
|
|
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
|
|
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`
|
|
114
|
-
// against this shape so any host whose reporter exposes
|
|
115
|
-
// into fix support without depending on a private
|
|
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
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
// `
|
|
118
|
+
// Rule production code does NOT touch FixReporter directly — call
|
|
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)
|
package/src/defaultFormat.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
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
|
-
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { defaultFormat, type ITtscLintConfig } from "@ttsc/lint";
|
|
11
12
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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;
|
|
20
|
-
* const only
|
|
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
|
|
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?: {
|
|
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
|
|
102
|
-
* map
|
|
103
|
-
*
|
|
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: { 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
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -456,14 +471,14 @@ function extractPluginSource(value: unknown): string | undefined {
|
|
|
456
471
|
`;
|
|
457
472
|
|
|
458
473
|
/**
|
|
459
|
-
* Resolves the contributor plugin entries declared in a .ts/.mjs lint
|
|
460
|
-
*
|
|
474
|
+
* Resolves the contributor plugin entries declared in a .ts/.mjs lint config,
|
|
475
|
+
* memoized through the shared on-disk config cache.
|
|
461
476
|
*
|
|
462
|
-
* Evaluating such a config spawns a full `ttsx` subprocess. A monorepo
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
477
|
+
* Evaluating such a config spawns a full `ttsx` subprocess. A monorepo build
|
|
478
|
+
* runs one `ttsc` process per package, and each would otherwise re-spawn `ttsx`
|
|
479
|
+
* for the same shared config; the cache collapses that to a single evaluation.
|
|
480
|
+
* The cache is keyed by the config file's path and exact contents (see
|
|
481
|
+
* `configCacheKey`), so an edit re-evaluates cleanly.
|
|
467
482
|
*/
|
|
468
483
|
function readTtsxConfigPlugins(
|
|
469
484
|
configPath: string,
|
|
@@ -485,9 +500,9 @@ function readTtsxConfigPlugins(
|
|
|
485
500
|
|
|
486
501
|
/**
|
|
487
502
|
* Reports whether a cached plugin entry is still usable: a well-formed
|
|
488
|
-
* namespace and an absolute `source` that still points at a directory.
|
|
489
|
-
*
|
|
490
|
-
*
|
|
503
|
+
* namespace and an absolute `source` that still points at a directory. Pure
|
|
504
|
+
* predicate — never throws — so a malformed cache entry simply triggers
|
|
505
|
+
* re-evaluation instead of aborting plugin discovery.
|
|
491
506
|
*/
|
|
492
507
|
function isValidConfigPluginEntry(entry: unknown): entry is ConfigPluginEntry {
|
|
493
508
|
if (
|
|
@@ -655,15 +670,15 @@ function evaluateTtsxConfigPlugins(
|
|
|
655
670
|
// ────────────────────────────────────────────────────────────────────────────
|
|
656
671
|
|
|
657
672
|
/**
|
|
658
|
-
* Namespaces the on-disk config cache. Kept in lockstep with the Go
|
|
659
|
-
*
|
|
673
|
+
* Namespaces the on-disk config cache. Kept in lockstep with the Go sidecar's
|
|
674
|
+
* `configCacheVersion`; bump both when the cached shape changes.
|
|
660
675
|
*/
|
|
661
676
|
const CONFIG_CACHE_VERSION = "v1";
|
|
662
677
|
|
|
663
678
|
/**
|
|
664
|
-
* Directory shared by this factory and the Go sidecar for cached lint
|
|
665
|
-
*
|
|
666
|
-
*
|
|
679
|
+
* Directory shared by this factory and the Go sidecar for cached lint configs.
|
|
680
|
+
* The two write different files (the `kind` segment of the cache key keeps
|
|
681
|
+
* their namespaces apart), so they coexist without collision.
|
|
667
682
|
*/
|
|
668
683
|
function configCacheDir(): string {
|
|
669
684
|
return path.join(os.tmpdir(), "ttsc-lint-config-cache");
|
|
@@ -675,10 +690,10 @@ function configCacheDisabled(): boolean {
|
|
|
675
690
|
}
|
|
676
691
|
|
|
677
692
|
/**
|
|
678
|
-
* Content-addressed cache key for a lint config file. Mirrors the Go
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
693
|
+
* Content-addressed cache key for a lint config file. Mirrors the Go sidecar's
|
|
694
|
+
* `configCacheKey`: a version tag, a namespace `kind`, the config's absolute
|
|
695
|
+
* path, and its exact bytes. Returns "" — a "do not cache" signal — when the
|
|
696
|
+
* file cannot be read or the env opt-out is set.
|
|
682
697
|
*/
|
|
683
698
|
function configCacheKey(kind: string, configPath: string): string {
|
|
684
699
|
if (configCacheDisabled()) return "";
|
|
@@ -700,9 +715,9 @@ function configCacheKey(kind: string, configPath: string): string {
|
|
|
700
715
|
}
|
|
701
716
|
|
|
702
717
|
/**
|
|
703
|
-
* Returns the cached plugin-entry list for `cacheKey`, or undefined on any
|
|
704
|
-
*
|
|
705
|
-
*
|
|
718
|
+
* Returns the cached plugin-entry list for `cacheKey`, or undefined on any miss
|
|
719
|
+
* — a missing file, an unreadable file, or content that is not a JSON array.
|
|
720
|
+
* Every failure is a soft miss: the caller re-evaluates.
|
|
706
721
|
*/
|
|
707
722
|
function readConfigPluginCache(
|
|
708
723
|
cacheKey: string,
|
|
@@ -718,9 +733,7 @@ function readConfigPluginCache(
|
|
|
718
733
|
}
|
|
719
734
|
try {
|
|
720
735
|
const parsed: unknown = JSON.parse(body);
|
|
721
|
-
return Array.isArray(parsed)
|
|
722
|
-
? (parsed as ConfigPluginEntry[])
|
|
723
|
-
: undefined;
|
|
736
|
+
return Array.isArray(parsed) ? (parsed as ConfigPluginEntry[]) : undefined;
|
|
724
737
|
} catch {
|
|
725
738
|
return undefined;
|
|
726
739
|
}
|
|
@@ -729,8 +742,8 @@ function readConfigPluginCache(
|
|
|
729
742
|
/**
|
|
730
743
|
* Writes `entries` to the config cache under `cacheKey`. Best-effort: any
|
|
731
744
|
* failure leaves the cache cold rather than aborting plugin discovery. The
|
|
732
|
-
* temp-file + rename keeps a concurrent reader in a sibling `ttsc` process
|
|
733
|
-
*
|
|
745
|
+
* temp-file + rename keeps a concurrent reader in a sibling `ttsc` process from
|
|
746
|
+
* observing a half-written file.
|
|
734
747
|
*/
|
|
735
748
|
function writeConfigPluginCache(
|
|
736
749
|
cacheKey: string,
|
|
@@ -800,7 +813,16 @@ function normalizePluginValue(
|
|
|
800
813
|
}`,
|
|
801
814
|
);
|
|
802
815
|
}
|
|
803
|
-
|
|
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
|
+
}
|
|
804
826
|
const plugin = validatePluginShape(unwrapDefault(mod), namespace, resolved);
|
|
805
827
|
return { namespace, source: plugin.source };
|
|
806
828
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ITtscLintFormat } from "./ITtscLintFormat";
|
|
2
2
|
import type { ITtscLintPlugin } from "./ITtscLintPlugin";
|
|
3
|
-
import type {
|
|
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
|
-
/**
|
|
29
|
-
|
|
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
|
|
32
|
-
format?:
|
|
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
|
|
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
|
|
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];
|
package/src/structures/index.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export * from "./ITtscLintConfig";
|
|
2
|
-
export * from "./
|
|
2
|
+
export * from "./ITtscLintFormat";
|
|
3
3
|
export * from "./ITtscLintPlugin";
|
|
4
4
|
export * from "./ITtscLintPluginConfig";
|
|
5
5
|
export * from "./ITtscLintPluginMeta";
|
|
6
|
-
export * from "./
|
|
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
|
+
}
|