@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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// unicorn/no-useless-switch-case: a `case` clause with no statements
|
|
2
|
+
// that sits immediately above the `default` clause falls through to
|
|
3
|
+
// `default` for free — the value it matches would have hit `default`
|
|
4
|
+
// regardless. Keeping the empty case adds noise without changing the
|
|
5
|
+
// switch's behavior, so the rule reports it.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit each `SwitchStatement`, walk its case-block clauses,
|
|
8
|
+
// and report any non-default `CaseClause` whose statements list is
|
|
9
|
+
// empty and whose immediate next sibling is the `DefaultClause`. The
|
|
10
|
+
// empty-body check distinguishes intentional grouped cases that share a
|
|
11
|
+
// non-trivial body from the redundant fall-into-default shape.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-switch-case.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornNoUselessSwitchCase struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornNoUselessSwitchCase) Name() string { return "unicorn/no-useless-switch-case" }
|
|
20
|
+
func (unicornNoUselessSwitchCase) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindSwitchStatement}
|
|
22
|
+
}
|
|
23
|
+
func (unicornNoUselessSwitchCase) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
sw := node.AsSwitchStatement()
|
|
25
|
+
if sw == nil || sw.CaseBlock == nil {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
block := sw.CaseBlock.AsCaseBlock()
|
|
29
|
+
if block == nil || block.Clauses == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
clauses := block.Clauses.Nodes
|
|
33
|
+
for i := 0; i < len(clauses)-1; i++ {
|
|
34
|
+
clause := clauses[i]
|
|
35
|
+
if clause == nil || clause.Kind != shimast.KindCaseClause {
|
|
36
|
+
continue
|
|
37
|
+
}
|
|
38
|
+
next := clauses[i+1]
|
|
39
|
+
if next == nil || next.Kind != shimast.KindDefaultClause {
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
cd := clause.AsCaseOrDefaultClause()
|
|
43
|
+
if cd == nil {
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
if cd.Statements != nil && len(cd.Statements.Nodes) != 0 {
|
|
47
|
+
continue
|
|
48
|
+
}
|
|
49
|
+
ctx.Report(clause, "Useless `case` clause — it falls through to the `default` which would handle this value anyway.")
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func init() {
|
|
54
|
+
Register(unicornNoUselessSwitchCase{})
|
|
55
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// unicorn/no-useless-undefined: `return undefined;` produces the same
|
|
2
|
+
// value as the bare `return;` form, and `void 0` is the canonical
|
|
3
|
+
// roundabout spelling of the same constant. Writing the keyword
|
|
4
|
+
// explicitly adds noise without changing behavior.
|
|
5
|
+
//
|
|
6
|
+
// Minimum-viable port: only the `return` statement shape fires. The
|
|
7
|
+
// call-argument case is intentionally skipped because matching it
|
|
8
|
+
// safely requires knowing which callees accept omission, and the
|
|
9
|
+
// parameter-default case (`function f(x = undefined)`) is deferred.
|
|
10
|
+
//
|
|
11
|
+
// AST-only: visit each `ReturnStatement` whose expression after
|
|
12
|
+
// `stripParens` is either the `undefined` keyword/identifier or the
|
|
13
|
+
// `void 0` shape (a `VoidExpression` whose operand is the numeric
|
|
14
|
+
// literal `0`). Reports on the return statement itself so the
|
|
15
|
+
// diagnostic anchors on the keyword rather than the operand.
|
|
16
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-undefined.md
|
|
17
|
+
package linthost
|
|
18
|
+
|
|
19
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
20
|
+
|
|
21
|
+
type unicornNoUselessUndefined struct{}
|
|
22
|
+
|
|
23
|
+
func (unicornNoUselessUndefined) Name() string { return "unicorn/no-useless-undefined" }
|
|
24
|
+
func (unicornNoUselessUndefined) Visits() []shimast.Kind {
|
|
25
|
+
return []shimast.Kind{shimast.KindReturnStatement}
|
|
26
|
+
}
|
|
27
|
+
func (unicornNoUselessUndefined) Check(ctx *Context, node *shimast.Node) {
|
|
28
|
+
ret := node.AsReturnStatement()
|
|
29
|
+
if ret == nil || ret.Expression == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
expr := stripParens(ret.Expression)
|
|
33
|
+
if expr == nil {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
if expr.Kind == shimast.KindUndefinedKeyword || identifierText(expr) == "undefined" {
|
|
37
|
+
ctx.Report(node, "Don't `return undefined;` — `return undefined;` and bare `return;` have the same effect.")
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
if expr.Kind == shimast.KindVoidExpression {
|
|
41
|
+
void := expr.AsVoidExpression()
|
|
42
|
+
if void == nil || void.Expression == nil {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
operand := stripParens(void.Expression)
|
|
46
|
+
if operand != nil && operand.Kind == shimast.KindNumericLiteral &&
|
|
47
|
+
numericLiteralText(operand) == "0" {
|
|
48
|
+
ctx.Report(node, "Don't `return undefined;` — `return undefined;` and bare `return;` have the same effect.")
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func init() {
|
|
54
|
+
Register(unicornNoUselessUndefined{})
|
|
55
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// unicorn/no-zero-fractions: numeric literals such as `1.0`, `1.`, and
|
|
2
|
+
// `.0` carry a redundant fractional component or a trailing dot whose
|
|
3
|
+
// only visual effect is to mislead the reader into thinking the value
|
|
4
|
+
// needs floating-point semantics. The rule rewrites the source pattern
|
|
5
|
+
// out by reporting on the literal node.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit `KindNumericLiteral`, read the raw source text via
|
|
8
|
+
// `nodeText` so the parser-normalized `.Text` (which drops the trailing
|
|
9
|
+
// dot and zero-pad) doesn't mask the smell, and match three regular
|
|
10
|
+
// expressions covering the canonical shapes:
|
|
11
|
+
//
|
|
12
|
+
// - `1.0`, `1.00`, `-1.0e5` — fractional part is all zeros.
|
|
13
|
+
// - `1.` — trailing dot with no fractional digits.
|
|
14
|
+
// - `.0`, `-.0e3` — leading dot with an all-zero fractional part.
|
|
15
|
+
//
|
|
16
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-zero-fractions.md
|
|
17
|
+
package linthost
|
|
18
|
+
|
|
19
|
+
import (
|
|
20
|
+
"regexp"
|
|
21
|
+
"strings"
|
|
22
|
+
|
|
23
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
var (
|
|
27
|
+
unicornNoZeroFractionsTrailingZero = regexp.MustCompile(`^-?\d+\.0+([eE][+-]?\d+)?$`)
|
|
28
|
+
unicornNoZeroFractionsTrailingDot = regexp.MustCompile(`^-?\d+\.$`)
|
|
29
|
+
unicornNoZeroFractionsLeadingDot = regexp.MustCompile(`^-?\.0+([eE][+-]?\d+)?$`)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
type unicornNoZeroFractions struct{}
|
|
33
|
+
|
|
34
|
+
func (unicornNoZeroFractions) Name() string { return "unicorn/no-zero-fractions" }
|
|
35
|
+
func (unicornNoZeroFractions) Visits() []shimast.Kind {
|
|
36
|
+
return []shimast.Kind{shimast.KindNumericLiteral}
|
|
37
|
+
}
|
|
38
|
+
func (unicornNoZeroFractions) Check(ctx *Context, node *shimast.Node) {
|
|
39
|
+
source := strings.TrimSpace(nodeText(ctx.File, node))
|
|
40
|
+
if source == "" {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
if unicornNoZeroFractionsTrailingZero.MatchString(source) ||
|
|
44
|
+
unicornNoZeroFractionsTrailingDot.MatchString(source) ||
|
|
45
|
+
unicornNoZeroFractionsLeadingDot.MatchString(source) {
|
|
46
|
+
ctx.Report(node, "Don't use a redundant `.0` fraction or trailing dot on a number literal.")
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func init() {
|
|
51
|
+
Register(unicornNoZeroFractions{})
|
|
52
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// unicorn/number-literal-case: hex / binary / octal numeric literals
|
|
2
|
+
// have a conventional canonical form — the radix prefix is lowercase
|
|
3
|
+
// (`0x`, `0b`, `0o`) while hex digits are uppercase (`0xFF`). Mixed-case
|
|
4
|
+
// alternatives (`0Xff`, `0xff`, `0xFf`, `0XFF`) read inconsistently and
|
|
5
|
+
// the rule normalizes the codebase by reporting every literal that
|
|
6
|
+
// isn't already canonical.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit `KindNumericLiteral` and `KindBigIntLiteral`, read
|
|
9
|
+
// the raw source text via `nodeText` so the prefix and digit casing
|
|
10
|
+
// survive the parser's normalization, and report when the prefix letter
|
|
11
|
+
// is uppercase OR any hex digit is lowercase. Decimal literals lack a
|
|
12
|
+
// prefix and never fire.
|
|
13
|
+
//
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/number-literal-case.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import (
|
|
18
|
+
"strings"
|
|
19
|
+
|
|
20
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
type unicornNumberLiteralCase struct{}
|
|
24
|
+
|
|
25
|
+
func (unicornNumberLiteralCase) Name() string { return "unicorn/number-literal-case" }
|
|
26
|
+
func (unicornNumberLiteralCase) Visits() []shimast.Kind {
|
|
27
|
+
return []shimast.Kind{shimast.KindNumericLiteral, shimast.KindBigIntLiteral}
|
|
28
|
+
}
|
|
29
|
+
func (unicornNumberLiteralCase) Check(ctx *Context, node *shimast.Node) {
|
|
30
|
+
source := strings.TrimSpace(nodeText(ctx.File, node))
|
|
31
|
+
if len(source) < 2 || source[0] != '0' {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
prefix := source[1]
|
|
35
|
+
switch prefix {
|
|
36
|
+
case 'x', 'X':
|
|
37
|
+
if unicornNumberLiteralCaseHexNeedsFix(source, prefix) {
|
|
38
|
+
ctx.Report(node, "Number literals should use a lowercase prefix and uppercase digits — e.g. `0xFF` instead of `0xff`.")
|
|
39
|
+
}
|
|
40
|
+
case 'b', 'B', 'o', 'O':
|
|
41
|
+
// Binary / octal digits are 0-1 / 0-7; only the prefix letter
|
|
42
|
+
// can be in the wrong case.
|
|
43
|
+
if prefix == 'B' || prefix == 'O' {
|
|
44
|
+
ctx.Report(node, "Number literals should use a lowercase prefix and uppercase digits — e.g. `0xFF` instead of `0xff`.")
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// unicornNumberLiteralCaseHexNeedsFix reports whether the hex literal's
|
|
50
|
+
// raw source text deviates from `0x` + uppercase digits. The trailing
|
|
51
|
+
// `n` of a hex bigint literal (`0xFFn`) is allowed.
|
|
52
|
+
func unicornNumberLiteralCaseHexNeedsFix(source string, prefix byte) bool {
|
|
53
|
+
if prefix != 'x' {
|
|
54
|
+
return true
|
|
55
|
+
}
|
|
56
|
+
digits := source[2:]
|
|
57
|
+
digits = strings.TrimSuffix(digits, "n")
|
|
58
|
+
for i := 0; i < len(digits); i++ {
|
|
59
|
+
ch := digits[i]
|
|
60
|
+
if ch >= 'a' && ch <= 'f' {
|
|
61
|
+
return true
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
func init() {
|
|
68
|
+
Register(unicornNumberLiteralCase{})
|
|
69
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// unicorn/numeric-separators-style: ES2021 numeric separators (`_`)
|
|
2
|
+
// only help readability when the grouping itself is conventional —
|
|
3
|
+
// thousands for decimal (`1_000_000`) and four-digit groups for hex /
|
|
4
|
+
// binary / octal (`0xFFFF_FFFF`). Off-by-one groupings (`1_2345`) read
|
|
5
|
+
// worse than the unseparated form. The rule fires when any literal
|
|
6
|
+
// already uses `_` but its groups don't match the canonical pattern.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit `KindNumericLiteral`, read the raw source via
|
|
9
|
+
// `nodeText` so the underscores survive parser normalization, pick the
|
|
10
|
+
// canonical group size from the prefix (`0x`/`0X` → 4, `0b`/`0B` → 4,
|
|
11
|
+
// `0o`/`0O` → 4, anything else → 3), and reject any literal that
|
|
12
|
+
// contains an underscore but whose integer portion fails the
|
|
13
|
+
// canonical-grouping regex.
|
|
14
|
+
//
|
|
15
|
+
// Conservative MVP: only the integer portion is checked. Floats and
|
|
16
|
+
// scientific notation that contain `_` follow the decimal grouping
|
|
17
|
+
// rule applied to the leading integer digits.
|
|
18
|
+
//
|
|
19
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/numeric-separators-style.md
|
|
20
|
+
package linthost
|
|
21
|
+
|
|
22
|
+
import (
|
|
23
|
+
"regexp"
|
|
24
|
+
"strings"
|
|
25
|
+
|
|
26
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
var (
|
|
30
|
+
unicornNumericSeparatorsDecimal = regexp.MustCompile(`^[0-9]{1,3}(_[0-9]{3})*$`)
|
|
31
|
+
unicornNumericSeparatorsRadix4 = regexp.MustCompile(`^[0-9A-Fa-f]{1,4}(_[0-9A-Fa-f]{4})*$`)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
type unicornNumericSeparatorsStyle struct{}
|
|
35
|
+
|
|
36
|
+
func (unicornNumericSeparatorsStyle) Name() string { return "unicorn/numeric-separators-style" }
|
|
37
|
+
func (unicornNumericSeparatorsStyle) Visits() []shimast.Kind {
|
|
38
|
+
return []shimast.Kind{shimast.KindNumericLiteral, shimast.KindBigIntLiteral}
|
|
39
|
+
}
|
|
40
|
+
func (unicornNumericSeparatorsStyle) Check(ctx *Context, node *shimast.Node) {
|
|
41
|
+
source := strings.TrimSpace(nodeText(ctx.File, node))
|
|
42
|
+
if source == "" || !strings.Contains(source, "_") {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
// Strip a trailing BigInt `n` so the digit-grouping regex doesn't see it.
|
|
46
|
+
source = strings.TrimSuffix(source, "n")
|
|
47
|
+
|
|
48
|
+
// Pick the integer portion and the canonical grouping pattern based
|
|
49
|
+
// on prefix; floats fall through to the decimal rule applied to the
|
|
50
|
+
// leading integer digits before the `.` or `e`/`E`.
|
|
51
|
+
integer := source
|
|
52
|
+
pattern := unicornNumericSeparatorsDecimal
|
|
53
|
+
if len(source) >= 2 && source[0] == '0' {
|
|
54
|
+
switch source[1] {
|
|
55
|
+
case 'x', 'X', 'b', 'B', 'o', 'O':
|
|
56
|
+
integer = source[2:]
|
|
57
|
+
pattern = unicornNumericSeparatorsRadix4
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if pattern == unicornNumericSeparatorsDecimal {
|
|
61
|
+
if dot := strings.IndexAny(integer, ".eE"); dot >= 0 {
|
|
62
|
+
integer = integer[:dot]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if !strings.Contains(integer, "_") {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
if !pattern.MatchString(integer) {
|
|
69
|
+
ctx.Report(node, "Use canonical separator grouping for numeric literals (3 digits for decimal, 4 for hex).")
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
func init() {
|
|
74
|
+
Register(unicornNumericSeparatorsStyle{})
|
|
75
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// unicorn/prefer-add-event-listener: assigning a function to an
|
|
2
|
+
// `on*` DOM property (`el.onclick = …`) installs at most one handler
|
|
3
|
+
// — any prior assignment is silently overwritten. `addEventListener`
|
|
4
|
+
// composes: every listener that registers receives the event, and
|
|
5
|
+
// `removeEventListener` revokes exactly the listener that was added.
|
|
6
|
+
// The property-assignment form is therefore a fragile shape that the
|
|
7
|
+
// rule encourages replacing with the explicit listener API.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: visit each `BinaryExpression`, restrict to `=` assignments
|
|
10
|
+
// whose LHS is a property access, and match property names that start
|
|
11
|
+
// with `on` followed by at least one lowercase letter (so unrelated
|
|
12
|
+
// names like `onnxruntime` or `onClickHandler` don't fire). The
|
|
13
|
+
// assignment node itself is reported so the diagnostic underlines the
|
|
14
|
+
// statement the reader needs to rewrite.
|
|
15
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-add-event-listener.md
|
|
16
|
+
package linthost
|
|
17
|
+
|
|
18
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
19
|
+
|
|
20
|
+
type unicornPreferAddEventListener struct{}
|
|
21
|
+
|
|
22
|
+
func (unicornPreferAddEventListener) Name() string { return "unicorn/prefer-add-event-listener" }
|
|
23
|
+
func (unicornPreferAddEventListener) Visits() []shimast.Kind {
|
|
24
|
+
return []shimast.Kind{shimast.KindBinaryExpression}
|
|
25
|
+
}
|
|
26
|
+
func (unicornPreferAddEventListener) Check(ctx *Context, node *shimast.Node) {
|
|
27
|
+
bin := node.AsBinaryExpression()
|
|
28
|
+
if bin == nil || bin.OperatorToken == nil {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
if bin.OperatorToken.Kind != shimast.KindEqualsToken {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
lhs := stripParens(bin.Left)
|
|
35
|
+
if lhs == nil || lhs.Kind != shimast.KindPropertyAccessExpression {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
access := lhs.AsPropertyAccessExpression()
|
|
39
|
+
if access == nil {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
name := identifierText(access.Name())
|
|
43
|
+
if !isUnicornOnEventName(name) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
ctx.Report(node, "Prefer `addEventListener` / `removeEventListener` over assigning to `on*` properties.")
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// isUnicornOnEventName reports whether `name` is `on<lower>...` of at
|
|
50
|
+
// least 3 characters. The third-character lowercase gate prevents
|
|
51
|
+
// matches on `onClick`, `onnxruntime`, and other names that begin with
|
|
52
|
+
// `on` but are not DOM event handlers.
|
|
53
|
+
func isUnicornOnEventName(name string) bool {
|
|
54
|
+
if len(name) < 3 {
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
if name[0] != 'o' || name[1] != 'n' {
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
c := name[2]
|
|
61
|
+
return c >= 'a' && c <= 'z'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
func init() {
|
|
65
|
+
Register(unicornPreferAddEventListener{})
|
|
66
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// unicorn/prefer-array-find: `arr.filter(predicate)[0]` walks the full
|
|
2
|
+
// array and allocates an intermediate result just to discard everything
|
|
3
|
+
// after the first match. `arr.find(predicate)` returns the same value
|
|
4
|
+
// without the wasted work and reads as the actual intent.
|
|
5
|
+
//
|
|
6
|
+
// AST-only: visit each `ElementAccessExpression`. The receiver must be a
|
|
7
|
+
// `CallExpression` whose callee is a `PropertyAccess(_, filter)` and the
|
|
8
|
+
// index argument must be the numeric literal `0`. Reports on the element
|
|
9
|
+
// access so editors highlight the whole `.filter(...)[0]` chain.
|
|
10
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md
|
|
11
|
+
package linthost
|
|
12
|
+
|
|
13
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
14
|
+
|
|
15
|
+
type unicornPreferArrayFind struct{}
|
|
16
|
+
|
|
17
|
+
func (unicornPreferArrayFind) Name() string { return "unicorn/prefer-array-find" }
|
|
18
|
+
func (unicornPreferArrayFind) Visits() []shimast.Kind {
|
|
19
|
+
return []shimast.Kind{shimast.KindElementAccessExpression}
|
|
20
|
+
}
|
|
21
|
+
func (unicornPreferArrayFind) Check(ctx *Context, node *shimast.Node) {
|
|
22
|
+
access := node.AsElementAccessExpression()
|
|
23
|
+
if access == nil || access.Expression == nil || access.ArgumentExpression == nil {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
index := stripParens(access.ArgumentExpression)
|
|
27
|
+
if index == nil || index.Kind != shimast.KindNumericLiteral {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if numericLiteralText(index) != "0" {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
receiver := stripParens(access.Expression)
|
|
34
|
+
if receiver == nil || receiver.Kind != shimast.KindCallExpression {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
call := receiver.AsCallExpression()
|
|
38
|
+
if call == nil || call.Expression == nil ||
|
|
39
|
+
call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
prop := call.Expression.AsPropertyAccessExpression()
|
|
43
|
+
if prop == nil || identifierText(prop.Name()) != "filter" {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
ctx.Report(node, "Prefer `Array#find()` over `Array#filter(...)[0]`.")
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
func init() {
|
|
50
|
+
Register(unicornPreferArrayFind{})
|
|
51
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// unicorn/prefer-array-flat: `[].concat(a, b, c)` is the legacy flatten
|
|
2
|
+
// idiom — it works because `Array#concat` spreads array arguments — but
|
|
3
|
+
// it loses readability the moment a non-array sneaks into the argument
|
|
4
|
+
// list (it then gets pushed in as a single element instead of being
|
|
5
|
+
// flattened). `Array#flat()` has stable, type-aware semantics and is the
|
|
6
|
+
// supported one-line equivalent.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
9
|
+
// whose receiver is an empty array-literal expression and whose method
|
|
10
|
+
// identifier is `concat`, and fire when at least one argument is
|
|
11
|
+
// supplied. The empty-array receiver gate is what isolates the
|
|
12
|
+
// flattening idiom from ordinary `.concat()` usage on real arrays.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
type unicornPreferArrayFlat struct{}
|
|
19
|
+
|
|
20
|
+
func (unicornPreferArrayFlat) Name() string { return "unicorn/prefer-array-flat" }
|
|
21
|
+
func (unicornPreferArrayFlat) Visits() []shimast.Kind {
|
|
22
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
23
|
+
}
|
|
24
|
+
func (unicornPreferArrayFlat) Check(ctx *Context, node *shimast.Node) {
|
|
25
|
+
call := node.AsCallExpression()
|
|
26
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
30
|
+
if access == nil {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
if identifierText(access.Name()) != "concat" {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
receiver := stripParens(access.Expression)
|
|
37
|
+
if receiver == nil || receiver.Kind != shimast.KindArrayLiteralExpression {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
arr := receiver.AsArrayLiteralExpression()
|
|
41
|
+
if arr == nil || arr.Elements == nil || len(arr.Elements.Nodes) != 0 {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
ctx.Report(node, "Prefer `Array#flat()` over `[].concat(...arrays)`.")
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func init() {
|
|
51
|
+
Register(unicornPreferArrayFlat{})
|
|
52
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// unicorn/prefer-array-flat-map: the pair `someArr.map(fn).flat()` walks
|
|
2
|
+
// the source array twice — once to map and once to flatten — when a
|
|
3
|
+
// single `flatMap` call would do both in one pass. The rule flags the
|
|
4
|
+
// chained shape so authors collapse it to the built-in.
|
|
5
|
+
//
|
|
6
|
+
// AST-only: a `CallExpression` whose callee is `.flat` AND whose
|
|
7
|
+
// receiver is itself a `CallExpression` whose callee is `.map` matches.
|
|
8
|
+
// The `.flat(...)` call must be argument-less or explicitly `.flat(1)`
|
|
9
|
+
// — `.map(fn).flat(2)` is NOT equivalent to `.flatMap(fn)` because the
|
|
10
|
+
// latter only flattens one level. The diagnostic anchors on the outer
|
|
11
|
+
// call so editors highlight the whole `.map(...).flat(...)` chain.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat-map.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferArrayFlatMap struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferArrayFlatMap) Name() string { return "unicorn/prefer-array-flat-map" }
|
|
20
|
+
func (unicornPreferArrayFlatMap) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferArrayFlatMap) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
call := node.AsCallExpression()
|
|
25
|
+
if call == nil || call.Expression == nil ||
|
|
26
|
+
call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
outerAccess := call.Expression.AsPropertyAccessExpression()
|
|
30
|
+
if outerAccess == nil || identifierText(outerAccess.Name()) != "flat" {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
// `.flat(2)` and deeper are NOT equivalent to `.flatMap` — only the
|
|
34
|
+
// default depth (no arg) or explicit depth 1 collapse cleanly.
|
|
35
|
+
if call.Arguments != nil && len(call.Arguments.Nodes) > 0 {
|
|
36
|
+
if len(call.Arguments.Nodes) != 1 {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
arg := stripParens(call.Arguments.Nodes[0])
|
|
40
|
+
if arg == nil || arg.Kind != shimast.KindNumericLiteral ||
|
|
41
|
+
numericLiteralText(arg) != "1" {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
receiver := stripParens(outerAccess.Expression)
|
|
46
|
+
if receiver == nil || receiver.Kind != shimast.KindCallExpression {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
innerCall := receiver.AsCallExpression()
|
|
50
|
+
if innerCall == nil || innerCall.Expression == nil ||
|
|
51
|
+
innerCall.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
innerAccess := innerCall.Expression.AsPropertyAccessExpression()
|
|
55
|
+
if innerAccess == nil || identifierText(innerAccess.Name()) != "map" {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
ctx.Report(node, "Prefer `Array#flatMap` over `Array#map().flat()`.")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func init() {
|
|
62
|
+
Register(unicornPreferArrayFlatMap{})
|
|
63
|
+
}
|