@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,78 @@
|
|
|
1
|
+
// unicorn/prefer-date-now: three idioms compute the current epoch
|
|
2
|
+
// milliseconds at runtime — `new Date().getTime()`, `new Date().valueOf()`,
|
|
3
|
+
// and `+new Date()`. All three allocate a Date instance only to throw
|
|
4
|
+
// it away. `Date.now()` does the same thing with no allocation and
|
|
5
|
+
// reads as exactly what it means; the rule asks authors to switch.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit `KindCallExpression` (the `.getTime()` / `.valueOf()`
|
|
8
|
+
// callers) and `KindPrefixUnaryExpression` (the `+new Date()` form).
|
|
9
|
+
// Fire on:
|
|
10
|
+
//
|
|
11
|
+
// - `(new Date()).getTime()` / `(new Date()).valueOf()` — a call
|
|
12
|
+
// with no arguments whose callee is a PropertyAccessExpression
|
|
13
|
+
// on a NewExpression with callee `Date`.
|
|
14
|
+
// - `+new Date()` — a `+` prefix whose operand is a NewExpression
|
|
15
|
+
// with callee `Date`.
|
|
16
|
+
//
|
|
17
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-date-now.md
|
|
18
|
+
package linthost
|
|
19
|
+
|
|
20
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
21
|
+
|
|
22
|
+
type unicornPreferDateNow struct{}
|
|
23
|
+
|
|
24
|
+
func (unicornPreferDateNow) Name() string { return "unicorn/prefer-date-now" }
|
|
25
|
+
func (unicornPreferDateNow) Visits() []shimast.Kind {
|
|
26
|
+
return []shimast.Kind{shimast.KindCallExpression, shimast.KindPrefixUnaryExpression}
|
|
27
|
+
}
|
|
28
|
+
func (unicornPreferDateNow) Check(ctx *Context, node *shimast.Node) {
|
|
29
|
+
switch node.Kind {
|
|
30
|
+
case shimast.KindCallExpression:
|
|
31
|
+
call := node.AsCallExpression()
|
|
32
|
+
if call == nil || call.Expression == nil {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
if call.Arguments != nil && len(call.Arguments.Nodes) > 0 {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
access := stripParens(call.Expression)
|
|
39
|
+
if access == nil || access.Kind != shimast.KindPropertyAccessExpression {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
propAccess := access.AsPropertyAccessExpression()
|
|
43
|
+
if propAccess == nil {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
method := identifierText(propAccess.Name())
|
|
47
|
+
if method != "getTime" && method != "valueOf" {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
receiver := stripParens(propAccess.Expression)
|
|
51
|
+
if receiver == nil || receiver.Kind != shimast.KindNewExpression {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
ne := receiver.AsNewExpression()
|
|
55
|
+
if ne == nil || identifierText(ne.Expression) != "Date" {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
ctx.Report(node, "Prefer `Date.now()` over `new Date().getTime()` / `+new Date()`.")
|
|
59
|
+
case shimast.KindPrefixUnaryExpression:
|
|
60
|
+
prefix := node.AsPrefixUnaryExpression()
|
|
61
|
+
if prefix == nil || prefix.Operator != shimast.KindPlusToken || prefix.Operand == nil {
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
operand := stripParens(prefix.Operand)
|
|
65
|
+
if operand == nil || operand.Kind != shimast.KindNewExpression {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
ne := operand.AsNewExpression()
|
|
69
|
+
if ne == nil || identifierText(ne.Expression) != "Date" {
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
ctx.Report(node, "Prefer `Date.now()` over `new Date().getTime()` / `+new Date()`.")
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
func init() {
|
|
77
|
+
Register(unicornPreferDateNow{})
|
|
78
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// unicorn/prefer-default-parameters: the legacy pattern of reassigning
|
|
2
|
+
// an undefined-or-falsy parameter to a literal at the top of a function
|
|
3
|
+
// body (`name = name ?? "guest"`) has been redundant since ES2015. A
|
|
4
|
+
// default-parameter expression (`name = "guest"`) covers the same case,
|
|
5
|
+
// reads as exactly what it means, and avoids both the visual noise and
|
|
6
|
+
// the missed-edit risk of keeping the name in three places.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit every function-like declaration. Fire when the first
|
|
9
|
+
// body statement is `<param> = <param> ?? <literal>` — an
|
|
10
|
+
// `ExpressionStatement` containing an `=` `BinaryExpression` whose LHS
|
|
11
|
+
// is a bare identifier matching a parameter name, and whose RHS is a
|
|
12
|
+
// `??` `BinaryExpression` whose LHS is the same identifier and whose
|
|
13
|
+
// RHS is a primitive literal. The rule is conservative on purpose: it
|
|
14
|
+
// stays away from `||` (which has different semantics for falsy
|
|
15
|
+
// non-undefined values) and the explicit-ternary shape, since both add
|
|
16
|
+
// branches the default-parameter rewrite does not strictly preserve.
|
|
17
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-default-parameters.md
|
|
18
|
+
package linthost
|
|
19
|
+
|
|
20
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
21
|
+
|
|
22
|
+
type unicornPreferDefaultParameters struct{}
|
|
23
|
+
|
|
24
|
+
func (unicornPreferDefaultParameters) Name() string {
|
|
25
|
+
return "unicorn/prefer-default-parameters"
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferDefaultParameters) Visits() []shimast.Kind {
|
|
28
|
+
return []shimast.Kind{
|
|
29
|
+
shimast.KindFunctionDeclaration,
|
|
30
|
+
shimast.KindArrowFunction,
|
|
31
|
+
shimast.KindFunctionExpression,
|
|
32
|
+
shimast.KindMethodDeclaration,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
func (unicornPreferDefaultParameters) Check(ctx *Context, node *shimast.Node) {
|
|
36
|
+
body := defaultParameterFunctionBody(node)
|
|
37
|
+
if body == nil {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
if body.Statements == nil || len(body.Statements.Nodes) == 0 {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
first := body.Statements.Nodes[0]
|
|
44
|
+
if first == nil || first.Kind != shimast.KindExpressionStatement {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
exprStmt := first.AsExpressionStatement()
|
|
48
|
+
if exprStmt == nil || exprStmt.Expression == nil {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
expr := stripParens(exprStmt.Expression)
|
|
52
|
+
if expr == nil || expr.Kind != shimast.KindBinaryExpression {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
assign := expr.AsBinaryExpression()
|
|
56
|
+
if assign == nil || assign.OperatorToken == nil || assign.OperatorToken.Kind != shimast.KindEqualsToken {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
target := identifierText(stripParens(assign.Left))
|
|
60
|
+
if target == "" {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
if !functionHasParameterNamed(node, target) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
rhs := stripParens(assign.Right)
|
|
67
|
+
if rhs == nil || rhs.Kind != shimast.KindBinaryExpression {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
coalesce := rhs.AsBinaryExpression()
|
|
71
|
+
if coalesce == nil || coalesce.OperatorToken == nil ||
|
|
72
|
+
coalesce.OperatorToken.Kind != shimast.KindQuestionQuestionToken {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
if identifierText(stripParens(coalesce.Left)) != target {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
if !isLiteralExpression(stripParens(coalesce.Right)) {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
ctx.Report(expr, "Prefer default parameters over `param = param ?? default` reassignments.")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// defaultParameterFunctionBody returns the BlockStatement body of a
|
|
85
|
+
// function-like node, or nil when the function has an expression body
|
|
86
|
+
// (arrow `=> expr`) or an overload signature without a body. The
|
|
87
|
+
// rule only fires on statement-level reassignments, so a body-less
|
|
88
|
+
// shape is a non-match by definition.
|
|
89
|
+
func defaultParameterFunctionBody(node *shimast.Node) *shimast.Block {
|
|
90
|
+
if node == nil {
|
|
91
|
+
return nil
|
|
92
|
+
}
|
|
93
|
+
var body *shimast.Node
|
|
94
|
+
switch node.Kind {
|
|
95
|
+
case shimast.KindFunctionDeclaration:
|
|
96
|
+
if fn := node.AsFunctionDeclaration(); fn != nil {
|
|
97
|
+
body = fn.Body
|
|
98
|
+
}
|
|
99
|
+
case shimast.KindFunctionExpression:
|
|
100
|
+
if fn := node.AsFunctionExpression(); fn != nil {
|
|
101
|
+
body = fn.Body
|
|
102
|
+
}
|
|
103
|
+
case shimast.KindArrowFunction:
|
|
104
|
+
if fn := node.AsArrowFunction(); fn != nil {
|
|
105
|
+
body = fn.Body
|
|
106
|
+
}
|
|
107
|
+
case shimast.KindMethodDeclaration:
|
|
108
|
+
if fn := node.AsMethodDeclaration(); fn != nil {
|
|
109
|
+
body = fn.Body
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if body == nil || body.Kind != shimast.KindBlock {
|
|
113
|
+
return nil
|
|
114
|
+
}
|
|
115
|
+
return body.AsBlock()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// functionHasParameterNamed reports whether any parameter of the
|
|
119
|
+
// function-like node is a plain `Identifier` whose lexical text equals
|
|
120
|
+
// `name`. Destructured parameters are intentionally ignored — the rule
|
|
121
|
+
// cannot prove which inner binding a top-of-body reassignment refers to
|
|
122
|
+
// without semantic analysis.
|
|
123
|
+
func functionHasParameterNamed(node *shimast.Node, name string) bool {
|
|
124
|
+
if node == nil || name == "" {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
for _, p := range node.Parameters() {
|
|
128
|
+
if p == nil {
|
|
129
|
+
continue
|
|
130
|
+
}
|
|
131
|
+
decl := p.AsParameterDeclaration()
|
|
132
|
+
if decl == nil {
|
|
133
|
+
continue
|
|
134
|
+
}
|
|
135
|
+
if identifierText(decl.Name()) == name {
|
|
136
|
+
return true
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
func init() {
|
|
143
|
+
Register(unicornPreferDefaultParameters{})
|
|
144
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// unicorn/prefer-dom-node-append: `Node#appendChild` accepts a single
|
|
2
|
+
// child node, returns the appended node, and throws when handed a string
|
|
3
|
+
// — its `Node#append` successor accepts a variadic list of nodes and
|
|
4
|
+
// strings, returns `undefined`, and is the supported modern shape. The
|
|
5
|
+
// legacy form is what the rule discourages.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
8
|
+
// whose method identifier is `appendChild`, and fire on the call. The
|
|
9
|
+
// receiver expression is not type-checked — the syntactic shape is the
|
|
10
|
+
// signal the rule wants to discourage, regardless of whether the value is
|
|
11
|
+
// known to be a `Node` at the type level.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-append.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferDomNodeAppend struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferDomNodeAppend) Name() string { return "unicorn/prefer-dom-node-append" }
|
|
20
|
+
func (unicornPreferDomNodeAppend) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferDomNodeAppend) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
call := node.AsCallExpression()
|
|
25
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
29
|
+
if access == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
if identifierText(access.Name()) != "appendChild" {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
ctx.Report(node, "Prefer `Node#append()` over `Node#appendChild()`.")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func init() {
|
|
39
|
+
Register(unicornPreferDomNodeAppend{})
|
|
40
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// unicorn/prefer-dom-node-dataset: `Element#dataset` exposes every
|
|
2
|
+
// `data-*` attribute as a typed string property, including coordinated
|
|
3
|
+
// kebab-case → camelCase mapping and conversion to/from values. Reaching
|
|
4
|
+
// for `getAttribute("data-foo")` or `setAttribute("data-foo", …)`
|
|
5
|
+
// reintroduces string-key bookkeeping the platform already covers.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
8
|
+
// whose method identifier is `getAttribute` or `setAttribute`, and fire
|
|
9
|
+
// when the first argument is a `StringLiteral` whose text starts with
|
|
10
|
+
// `data-`. The literal-prefix gate isolates the data-attribute path from
|
|
11
|
+
// every other attribute the same methods reach.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-dataset.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import (
|
|
16
|
+
"strings"
|
|
17
|
+
|
|
18
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
type unicornPreferDomNodeDataset struct{}
|
|
22
|
+
|
|
23
|
+
func (unicornPreferDomNodeDataset) Name() string { return "unicorn/prefer-dom-node-dataset" }
|
|
24
|
+
func (unicornPreferDomNodeDataset) Visits() []shimast.Kind {
|
|
25
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferDomNodeDataset) Check(ctx *Context, node *shimast.Node) {
|
|
28
|
+
call := node.AsCallExpression()
|
|
29
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
33
|
+
if access == nil {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
method := identifierText(access.Name())
|
|
37
|
+
if method != "getAttribute" && method != "setAttribute" {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
first := call.Arguments.Nodes[0]
|
|
44
|
+
if first == nil || first.Kind != shimast.KindStringLiteral {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
if !strings.HasPrefix(stringLiteralText(first), "data-") {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
ctx.Report(node, "Prefer `.dataset` over `getAttribute` / `setAttribute` for `data-*` attributes.")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func init() {
|
|
54
|
+
Register(unicornPreferDomNodeDataset{})
|
|
55
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// unicorn/prefer-dom-node-remove: `parent.removeChild(child)` requires
|
|
2
|
+
// the caller to thread the parent through to detach a node — `child.remove()`
|
|
3
|
+
// is the supported modern shape and avoids the dangling-reference class
|
|
4
|
+
// of bugs where the wrong parent is consulted.
|
|
5
|
+
//
|
|
6
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
7
|
+
// whose method identifier is `removeChild`, and fire when the call has
|
|
8
|
+
// exactly one argument. The single-argument gate isolates the canonical
|
|
9
|
+
// detach shape from custom `removeChild` overloads that take more.
|
|
10
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-remove.md
|
|
11
|
+
package linthost
|
|
12
|
+
|
|
13
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
14
|
+
|
|
15
|
+
type unicornPreferDomNodeRemove struct{}
|
|
16
|
+
|
|
17
|
+
func (unicornPreferDomNodeRemove) Name() string { return "unicorn/prefer-dom-node-remove" }
|
|
18
|
+
func (unicornPreferDomNodeRemove) Visits() []shimast.Kind {
|
|
19
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
20
|
+
}
|
|
21
|
+
func (unicornPreferDomNodeRemove) Check(ctx *Context, node *shimast.Node) {
|
|
22
|
+
call := node.AsCallExpression()
|
|
23
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
27
|
+
if access == nil {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if identifierText(access.Name()) != "removeChild" {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
ctx.Report(node, "Prefer `ChildNode#remove()` over `parentNode.removeChild(child)`.")
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func init() {
|
|
40
|
+
Register(unicornPreferDomNodeRemove{})
|
|
41
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// unicorn/prefer-dom-node-text-content: `HTMLElement#innerText` triggers
|
|
2
|
+
// layout, ignores hidden subtrees, and varies across engines — its
|
|
3
|
+
// `Node#textContent` counterpart returns the raw concatenated text of
|
|
4
|
+
// every descendant text node and is the supported modern shape.
|
|
5
|
+
//
|
|
6
|
+
// AST-only and identifier-text-driven: visit every
|
|
7
|
+
// `PropertyAccessExpression`, match the property name `innerText`, and
|
|
8
|
+
// fire on the property-access node. The receiver expression is not
|
|
9
|
+
// type-checked; the legacy property name is the signal the rule
|
|
10
|
+
// discourages.
|
|
11
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-text-content.md
|
|
12
|
+
package linthost
|
|
13
|
+
|
|
14
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
15
|
+
|
|
16
|
+
type unicornPreferDomNodeTextContent struct{}
|
|
17
|
+
|
|
18
|
+
func (unicornPreferDomNodeTextContent) Name() string {
|
|
19
|
+
return "unicorn/prefer-dom-node-text-content"
|
|
20
|
+
}
|
|
21
|
+
func (unicornPreferDomNodeTextContent) Visits() []shimast.Kind {
|
|
22
|
+
return []shimast.Kind{shimast.KindPropertyAccessExpression}
|
|
23
|
+
}
|
|
24
|
+
func (unicornPreferDomNodeTextContent) Check(ctx *Context, node *shimast.Node) {
|
|
25
|
+
access := node.AsPropertyAccessExpression()
|
|
26
|
+
if access == nil {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
if identifierText(access.Name()) != "innerText" {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
ctx.Report(node, "Prefer `Node#textContent` over `HTMLElement#innerText`.")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
func init() {
|
|
36
|
+
Register(unicornPreferDomNodeTextContent{})
|
|
37
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// unicorn/prefer-event-target: Node's `EventEmitter` is the legacy
|
|
2
|
+
// event API. The browser and modern Node (`>=15`) both ship the
|
|
3
|
+
// standard `EventTarget` interface, which works in both runtimes
|
|
4
|
+
// without a polyfill. Code that needs to run in both should prefer
|
|
5
|
+
// `EventTarget` so it stays portable.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit `NewExpression`. Match when the callee is a bare
|
|
8
|
+
// identifier whose name is `EventEmitter`. The receiver is not
|
|
9
|
+
// type-checked — the rule's signal is the literal `new EventEmitter()`
|
|
10
|
+
// shape; a `new events.EventEmitter()` qualified form would not match,
|
|
11
|
+
// matching upstream's own AST-only behavior.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-event-target.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferEventTarget struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferEventTarget) Name() string { return "unicorn/prefer-event-target" }
|
|
20
|
+
func (unicornPreferEventTarget) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindNewExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferEventTarget) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
ne := node.AsNewExpression()
|
|
25
|
+
if ne == nil || ne.Expression == nil {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
if identifierText(ne.Expression) != "EventEmitter" {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
ctx.Report(node, "Prefer `EventTarget` over `EventEmitter` when sharing code between Node and the browser.")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
func init() {
|
|
35
|
+
Register(unicornPreferEventTarget{})
|
|
36
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// unicorn/prefer-export-from: when the only purpose of a local import is
|
|
2
|
+
// to re-export it under the same name, the canonical shape is the
|
|
3
|
+
// `export { X } from "Y"` re-export, which skips the intermediate local
|
|
4
|
+
// binding entirely. The split `import { X } from "Y"; export { X };`
|
|
5
|
+
// form is longer, allocates a binding that never gets used, and reads
|
|
6
|
+
// as if the author meant to consume `X` locally before deciding not to.
|
|
7
|
+
//
|
|
8
|
+
// AST-only minimum-viable port: visit `SourceFile` and walk top-level
|
|
9
|
+
// statements once. Build a map from each unrenamed named-binding of an
|
|
10
|
+
// `import { X } from "Y"` declaration to its module specifier text, then
|
|
11
|
+
// fire on every later `export { X };` statement (no rename, no
|
|
12
|
+
// `from`-clause) whose identifier appears in that map. Default and
|
|
13
|
+
// namespace imports, renamed bindings, and re-exports with their own
|
|
14
|
+
// `from`-clause are out of scope; the MVP only catches the textbook
|
|
15
|
+
// "import then immediately re-export" pair.
|
|
16
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-export-from.md
|
|
17
|
+
package linthost
|
|
18
|
+
|
|
19
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
20
|
+
|
|
21
|
+
type unicornPreferExportFrom struct{}
|
|
22
|
+
|
|
23
|
+
func (unicornPreferExportFrom) Name() string { return "unicorn/prefer-export-from" }
|
|
24
|
+
func (unicornPreferExportFrom) Visits() []shimast.Kind {
|
|
25
|
+
return []shimast.Kind{shimast.KindSourceFile}
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferExportFrom) Check(ctx *Context, node *shimast.Node) {
|
|
28
|
+
statements := node.Statements()
|
|
29
|
+
if len(statements) == 0 {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
// Map of locally-imported simple binding name → true. Built on a
|
|
33
|
+
// first pass so a re-export earlier in the file does not accidentally
|
|
34
|
+
// match an import declared later; the upstream rule is anchored on
|
|
35
|
+
// "imported above, re-exported below" ordering.
|
|
36
|
+
imported := map[string]bool{}
|
|
37
|
+
for _, stmt := range statements {
|
|
38
|
+
if stmt == nil || stmt.Kind != shimast.KindImportDeclaration {
|
|
39
|
+
continue
|
|
40
|
+
}
|
|
41
|
+
decl := stmt.AsImportDeclaration()
|
|
42
|
+
if decl == nil || decl.ImportClause == nil {
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
clause := decl.ImportClause.AsImportClause()
|
|
46
|
+
if clause == nil || clause.NamedBindings == nil ||
|
|
47
|
+
clause.NamedBindings.Kind != shimast.KindNamedImports {
|
|
48
|
+
continue
|
|
49
|
+
}
|
|
50
|
+
// A default-bound or namespace-mixed import is out of scope: the
|
|
51
|
+
// MVP only rewrites pure `import { X } from "Y"` pairs.
|
|
52
|
+
if clause.Name() != nil {
|
|
53
|
+
continue
|
|
54
|
+
}
|
|
55
|
+
named := clause.NamedBindings.AsNamedImports()
|
|
56
|
+
if named == nil || named.Elements == nil {
|
|
57
|
+
continue
|
|
58
|
+
}
|
|
59
|
+
for _, spec := range named.Elements.Nodes {
|
|
60
|
+
s := spec.AsImportSpecifier()
|
|
61
|
+
if s == nil {
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
64
|
+
// PropertyName is set only when the specifier is renamed
|
|
65
|
+
// (`import { a as b }`); skip those — `export { b }` would
|
|
66
|
+
// require `export { b as b } from "Y"` which is itself a
|
|
67
|
+
// useless rename.
|
|
68
|
+
if s.PropertyName != nil {
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
name := identifierText(s.Name())
|
|
72
|
+
if name == "" {
|
|
73
|
+
continue
|
|
74
|
+
}
|
|
75
|
+
imported[name] = true
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if len(imported) == 0 {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
for _, stmt := range statements {
|
|
82
|
+
if stmt == nil || stmt.Kind != shimast.KindExportDeclaration {
|
|
83
|
+
continue
|
|
84
|
+
}
|
|
85
|
+
decl := stmt.AsExportDeclaration()
|
|
86
|
+
if decl == nil || decl.ExportClause == nil {
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
// Skip `export { X } from "Y"` — already in the target shape.
|
|
90
|
+
if decl.ModuleSpecifier != nil {
|
|
91
|
+
continue
|
|
92
|
+
}
|
|
93
|
+
if decl.ExportClause.Kind != shimast.KindNamedExports {
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
named := decl.ExportClause.AsNamedExports()
|
|
97
|
+
if named == nil || named.Elements == nil || len(named.Elements.Nodes) == 0 {
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
matched := false
|
|
101
|
+
for _, el := range named.Elements.Nodes {
|
|
102
|
+
spec := el.AsExportSpecifier()
|
|
103
|
+
if spec == nil {
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
// PropertyName != nil means `export { a as b }` — a rename
|
|
107
|
+
// the from-clause rewrite cannot preserve without also
|
|
108
|
+
// touching the import side. Skip.
|
|
109
|
+
if spec.PropertyName != nil {
|
|
110
|
+
continue
|
|
111
|
+
}
|
|
112
|
+
name := identifierText(spec.Name())
|
|
113
|
+
if name == "" {
|
|
114
|
+
continue
|
|
115
|
+
}
|
|
116
|
+
if imported[name] {
|
|
117
|
+
matched = true
|
|
118
|
+
break
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if matched {
|
|
122
|
+
ctx.Report(stmt, "Use `export { X } from \"Y\"` instead of importing then re-exporting.")
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
func init() {
|
|
128
|
+
Register(unicornPreferExportFrom{})
|
|
129
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// unicorn/prefer-global-this: `window`, `self`, and `global` are
|
|
2
|
+
// environment-specific global aliases. Using them locks code to a
|
|
3
|
+
// single runtime (browser, worker, Node) and forces feature-detection
|
|
4
|
+
// boilerplate when the same code needs to run elsewhere. `globalThis`
|
|
5
|
+
// is the standardized cross-runtime alias and the canonical form for
|
|
6
|
+
// the same reference.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit every `Identifier`. The rule fires only when the
|
|
9
|
+
// identifier sits in a value-expression position; declaration names,
|
|
10
|
+
// property-access right sides, parameter names, property-assignment
|
|
11
|
+
// keys, and type references are filtered out by parent-kind gating so
|
|
12
|
+
// the diagnostic is anchored on actual reads of the global.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-global-this.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
type unicornPreferGlobalThis struct{}
|
|
19
|
+
|
|
20
|
+
func (unicornPreferGlobalThis) Name() string { return "unicorn/prefer-global-this" }
|
|
21
|
+
func (unicornPreferGlobalThis) Visits() []shimast.Kind {
|
|
22
|
+
return []shimast.Kind{shimast.KindIdentifier}
|
|
23
|
+
}
|
|
24
|
+
func (unicornPreferGlobalThis) Check(ctx *Context, node *shimast.Node) {
|
|
25
|
+
name := identifierText(node)
|
|
26
|
+
switch name {
|
|
27
|
+
case "window", "self", "global":
|
|
28
|
+
default:
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
if !isUnicornValuePositionIdentifier(node) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
ctx.Report(node, "Prefer `globalThis` over `window` / `self` / `global`.")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// isUnicornValuePositionIdentifier reports whether `node` (a bare
|
|
38
|
+
// Identifier) appears in a value-expression position rather than as a
|
|
39
|
+
// binding name, property key, member-access right side, or type
|
|
40
|
+
// reference. Declaration names and property keys are read positions
|
|
41
|
+
// for the *name* itself, so they must not contribute to rules that
|
|
42
|
+
// flag *uses* of a global.
|
|
43
|
+
func isUnicornValuePositionIdentifier(node *shimast.Node) bool {
|
|
44
|
+
if node == nil || node.Kind != shimast.KindIdentifier || node.Parent == nil {
|
|
45
|
+
return false
|
|
46
|
+
}
|
|
47
|
+
parent := node.Parent
|
|
48
|
+
switch parent.Kind {
|
|
49
|
+
case shimast.KindVariableDeclaration:
|
|
50
|
+
decl := parent.AsVariableDeclaration()
|
|
51
|
+
if decl != nil && decl.Name() == node {
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
case shimast.KindBindingElement:
|
|
55
|
+
elem := parent.AsBindingElement()
|
|
56
|
+
if elem != nil && elem.Name() == node {
|
|
57
|
+
return false
|
|
58
|
+
}
|
|
59
|
+
case shimast.KindParameter:
|
|
60
|
+
param := parent.AsParameterDeclaration()
|
|
61
|
+
if param != nil && param.Name() == node {
|
|
62
|
+
return false
|
|
63
|
+
}
|
|
64
|
+
case shimast.KindFunctionDeclaration:
|
|
65
|
+
fn := parent.AsFunctionDeclaration()
|
|
66
|
+
if fn != nil && fn.Name() == node {
|
|
67
|
+
return false
|
|
68
|
+
}
|
|
69
|
+
case shimast.KindFunctionExpression:
|
|
70
|
+
fn := parent.AsFunctionExpression()
|
|
71
|
+
if fn != nil && fn.Name() == node {
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
74
|
+
case shimast.KindClassDeclaration:
|
|
75
|
+
cls := parent.AsClassDeclaration()
|
|
76
|
+
if cls != nil && cls.Name() == node {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
case shimast.KindClassExpression:
|
|
80
|
+
cls := parent.AsClassExpression()
|
|
81
|
+
if cls != nil && cls.Name() == node {
|
|
82
|
+
return false
|
|
83
|
+
}
|
|
84
|
+
case shimast.KindPropertyAccessExpression:
|
|
85
|
+
access := parent.AsPropertyAccessExpression()
|
|
86
|
+
if access != nil && access.Name() == node {
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
case shimast.KindPropertyAssignment:
|
|
90
|
+
prop := parent.AsPropertyAssignment()
|
|
91
|
+
if prop != nil && prop.Name() == node {
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
case shimast.KindShorthandPropertyAssignment:
|
|
95
|
+
// `{window}` shorthand — the identifier is both name and read,
|
|
96
|
+
// but the read here is the value position, so allow.
|
|
97
|
+
case shimast.KindMethodDeclaration,
|
|
98
|
+
shimast.KindGetAccessor,
|
|
99
|
+
shimast.KindSetAccessor,
|
|
100
|
+
shimast.KindPropertyDeclaration:
|
|
101
|
+
// These have a Name() slot that is not a value expression.
|
|
102
|
+
return false
|
|
103
|
+
case shimast.KindTypeReference,
|
|
104
|
+
shimast.KindQualifiedName,
|
|
105
|
+
shimast.KindImportSpecifier,
|
|
106
|
+
shimast.KindExportSpecifier,
|
|
107
|
+
shimast.KindNamespaceImport,
|
|
108
|
+
shimast.KindImportClause,
|
|
109
|
+
shimast.KindNamespaceExport,
|
|
110
|
+
shimast.KindLabeledStatement,
|
|
111
|
+
shimast.KindBreakStatement,
|
|
112
|
+
shimast.KindContinueStatement,
|
|
113
|
+
shimast.KindJsxAttribute,
|
|
114
|
+
shimast.KindEnumDeclaration,
|
|
115
|
+
shimast.KindEnumMember,
|
|
116
|
+
shimast.KindModuleDeclaration,
|
|
117
|
+
shimast.KindTypeParameter,
|
|
118
|
+
shimast.KindInterfaceDeclaration,
|
|
119
|
+
shimast.KindTypeAliasDeclaration:
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
return true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
func init() {
|
|
126
|
+
Register(unicornPreferGlobalThis{})
|
|
127
|
+
}
|