oxlint-tui 1.3.0 → 1.4.0
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 +9 -10
- package/dist/index.mjs +2 -258
- package/dist/rule-descriptions.br +0 -0
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
# oxlint-tui
|
|
2
2
|
|
|
3
|
-
A lightweight, dependency-free Node.js Terminal User Interface (TUI) for browsing, toggling and visualizing [oxlint](https://github.com/oxc-project/oxc) rules
|
|
3
|
+
A lightweight, dependency-free Node.js Terminal User Interface (TUI) for browsing, toggling, and visualizing [oxlint](https://github.com/oxc-project/oxc) rules.
|
|
4
4
|
|
|
5
|
-
It automatically loads your local configuration to show you the status of
|
|
5
|
+
It automatically loads your local configuration (if one exists) to show you the current status of your project. You can then toggle rules on the fly to see how they affect your codebase without altering your actual configuration file.
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**It serves as a playground:** Toggle rules in memory, run the linter, and see the results immediately.
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
11
|
## Why?
|
|
12
12
|
|
|
13
|
-
Configuring linters often involves jumping between your editor, a massive JSON file, and web documentation. `oxlint-tui` tries to make the process easier by giving you an **interactive dashboard** right in your terminal.
|
|
13
|
+
Configuring linters often involves jumping between your editor, a massive JSON file, and web documentation. `oxlint-tui` tries to make the process easier by giving you an **interactive dashboard** right in your terminal. It allows you to "try before you buy"—enabling strict rules temporarily to see how many errors they would produce.
|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
17
|
+
- **Non-Destructive**: Toggling rules happens entirely in memory. No changes are written to disk, making it safe to experiment without messing up your config or comments.
|
|
18
|
+
- **Config Aware**: Automatically reads `.oxlintrc.json` to initialize the state, but works perfectly even if no config file exists.
|
|
19
|
+
- **Details**: View category, scope, fix, default, and type-aware rule parameters at a glance.
|
|
19
20
|
- **View Docs**: Press <kbd>ENTER</kbd> on any rule to open its official documentation in your browser.
|
|
20
21
|
- **Zero Dependencies**: Written in pure Node.js without any heavy TUI libraries.
|
|
21
22
|
|
|
@@ -31,7 +32,7 @@ npx oxlint-tui
|
|
|
31
32
|
|
|
32
33
|
### Custom Config Path
|
|
33
34
|
|
|
34
|
-
If
|
|
35
|
+
If you want to load an initial state from a specific config file:
|
|
35
36
|
|
|
36
37
|
```bash
|
|
37
38
|
npx oxlint-tui ./configs/oxlint.json
|
|
@@ -68,9 +69,7 @@ oxlint-tui
|
|
|
68
69
|
- Node.js >= 16
|
|
69
70
|
- `oxlint` (The tool runs `npx oxlint --rules --format=json` internally to fetch definitions)
|
|
70
71
|
|
|
71
|
-
##
|
|
72
|
-
|
|
73
|
-
The goal is to build this into a tool that not only reads the information provided by the oxlint CLI and your configuration file - but also allows to fully customize the configuration. Oxlint provides a lot more flexibility than just toggling rules on/off, so making this fully functional is going to require more work.
|
|
72
|
+
## Contributing
|
|
74
73
|
|
|
75
74
|
If you're willing and able, please feel free to [contribute to this project](https://github.com/holoflash/oxlint-tui/blob/main/CONTRIBUTING.md).
|
|
76
75
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,259 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import e from"node:fs";import t from"readline";import{execSync as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
- a block body \`() => { ... }\`
|
|
6
|
-
- or a concise body \`() => expression\` with an implicit return.`,"block-scoped-var":`Enforces that variables are both declared and used within the same block scope.
|
|
7
|
-
This rule prevents accidental use of variables outside their intended block, mimicking C-style block scoping in JavaScript.`,"capitalized-comments":`Enforces or disallows capitalization of the first letter of a comment.`,"class-methods-use-this":"Enforce that class methods utilize `this`.",complexity:`Enforces a maximum cyclomatic complexity in a program, which is the number
|
|
8
|
-
of linearly independent paths in a program.`,"constructor-super":`Requires \`super()\` calls in constructors of derived classes and disallows \`super()\` calls
|
|
9
|
-
in constructors of non-derived classes.
|
|
10
|
-
|
|
11
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
12
|
-
enforces this check.`,curly:"This rule enforces the use of curly braces `{}` for all control statements\n(`if`, `else`, `for`, `while`, `do`, `with`).\nIt ensures that all blocks are enclosed in curly braces to improve code clarity and maintainability.","default-case-last":"Requires the `default` clause in `switch` statements to be the last one.","default-case":"Enforces that all `switch` statements include a `default` case,\nunless explicitly marked with a configured comment.","default-param-last":`Requires default parameters in functions to be the last ones.`,eqeqeq:"Requires the use of the `===` and `!==` operators, disallowing the use of `==` and `!=`.","for-direction":"Disallow `for` loops where the update clause moves the counter in the wrong\ndirection, preventing the loop from reaching its stop condition.","func-names":`Require or disallow named function expressions.`,"func-style":`Enforce the consistent use of either function declarations or expressions assigned to variables.`,"getter-return":"Requires all getters to have a `return` statement.","grouped-accessor-pairs":`Require grouped accessor pairs in object literals and classes`,"guard-for-in":`Require for-in loops to include an if statement.`,"id-length":`This rule enforces a minimum and/or maximum identifier length convention by counting the
|
|
13
|
-
graphemes for a given identifier.`,"init-declarations":`Require or disallow initialization in variable declarations.`,"max-classes-per-file":`Enforce a maximum number of classes per file`,"max-depth":`Enforce a maximum depth that blocks can be nested. This rule helps to limit the complexity
|
|
14
|
-
of nested blocks, improving readability and maintainability by ensuring that code does not
|
|
15
|
-
become too deeply nested.`,"max-lines-per-function":`Enforce a maximum number of lines of code in a function. This rule ensures
|
|
16
|
-
that functions do not exceed a specified line count, promoting smaller,
|
|
17
|
-
more focused functions that are easier to maintain and understand.`,"max-lines":`Enforce a maximum number of lines per file.`,"max-nested-callbacks":`Enforce a maximum depth that callbacks can be nested. This rule helps to limit
|
|
18
|
-
the complexity of callback nesting, ensuring that callbacks do not become too
|
|
19
|
-
deeply nested, improving code readability and maintainability.`,"max-params":`Enforce a maximum number of parameters in function definitions which by
|
|
20
|
-
default is three.`,"max-statements":`Enforce a maximum number of statements in a function. This rule ensures
|
|
21
|
-
that functions do not exceed a specified statements count, promoting smaller,
|
|
22
|
-
more focused functions that are easier to maintain and understand.`,"new-cap":`This rule requires constructor names to begin with a capital letter.`,"no-alert":`Disallow the use of alert, confirm, and prompt`,"no-array-constructor":"Disallows creating arrays with the `Array` constructor.","no-async-promise-executor":`Disallow using an async function as a Promise executor.`,"no-await-in-loop":"This rule disallows the use of `await` within loop bodies. (for, for-in, for-of, while, do-while).","no-bitwise":`Disallow bitwise operators`,"no-caller":"Disallow the use of `arguments.caller` or `arguments.callee`.","no-case-declarations":`Disallow lexical declarations in case clauses.`,"no-class-assign":`Disallow reassigning class variables.
|
|
23
|
-
|
|
24
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
25
|
-
enforces this check.`,"no-compare-neg-zero":"Disallow comparing against `-0`","no-cond-assign":`Disallow assignment operators in conditional expressions`,"no-console":`Disallow the use of console.`,"no-const-assign":"Disallow reassigning `const` variables.","no-constant-binary-expression":`Disallow expressions where the operation doesn't affect the value`,"no-constant-condition":`Disallow constant expressions in conditions`,"no-constructor-return":`Disallow returning value from constructor`,"no-continue":"Disallow `continue` statements","no-control-regex":`Disallows control characters and some escape sequences that match
|
|
26
|
-
control characters in regular expressions.`,"no-debugger":"Checks for usage of the `debugger` statement","no-delete-var":"The purpose of the `delete` operator is to remove a property from an\nobject.","no-div-regex":`Disallow equal signs explicitly at the beginning of regular expressions.`,"no-dupe-class-members":`Disallow duplicate class members.
|
|
27
|
-
|
|
28
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
29
|
-
enforces this check.`,"no-dupe-else-if":`Disallow duplicate conditions in if-else-if chains`,"no-dupe-keys":`Disallow duplicate keys in object literals.
|
|
30
|
-
|
|
31
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
32
|
-
enforces this check.`,"no-duplicate-case":`Disallow duplicate case labels`,"no-duplicate-imports":`Disallow duplicate module imports.`,"no-else-return":"Disallow `else` blocks after `return` statements in `if` statements","no-empty-character-class":`Disallow empty character classes in regular expressions`,"no-empty-function":`Disallows the usages of empty functions`,"no-empty-pattern":`Disallow empty destructuring patterns.`,"no-empty-static-block":`Disallows the usages of empty static blocks`,"no-empty":`Disallows empty block statements`,"no-eq-null":"Disallow `null` comparisons without type-checking operators.","no-eval":"Disallows referencing the `eval` function. This rule is aimed at preventing\npotentially dangerous, unnecessary, and slow code by disallowing the use of\nthe `eval()` function.","no-ex-assign":`Disallow reassigning exceptions in catch clauses`,"no-extend-native":"Prevents extending native global objects such as `Object`, `String`, or `Array` with new\nproperties.","no-extra-bind":`Disallow unnecessary calls to .bind()`,"no-extra-boolean-cast":`This rule disallows unnecessary boolean casts.`,"no-extra-label":`Disallow unnecessary labels.`,"no-fallthrough":`Disallow fallthrough of \`case\` statements
|
|
33
|
-
|
|
34
|
-
This rule is aimed at eliminating unintentional fallthrough of one case
|
|
35
|
-
to the other. As such, it flags any fallthrough scenarios that are not
|
|
36
|
-
marked by a comment.`,"no-func-assign":`Disallow reassigning \`function\` declarations.
|
|
37
|
-
|
|
38
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
39
|
-
enforces this check.`,"no-global-assign":`Disallow modifications to read-only global variables.`,"no-implicit-coercion":'Disallows shorthand type conversions using operators like `!!`, `+`, `""+ `, etc.',"no-import-assign":`Disallow assigning to imported bindings.`,"no-inline-comments":`Disallows comments on the same line as code.`,"no-inner-declarations":`Disallow variable or function declarations in nested blocks.`,"no-invalid-regexp":`Disallow invalid regular expression strings in RegExp constructors.`,"no-irregular-whitespace":`Disallows the use of irregular whitespace characters in the code.`,"no-iterator":"Disallow the use of the `iterator` property","no-label-var":`Disallow labels that share a name with a variable.`,"no-labels":`Disallow labeled statements.`,"no-lone-blocks":`Disallows unnecessary standalone block statements.`,"no-lonely-if":"Disallow `if` statements as the only statement in `else` blocks","no-loop-func":`Disallows function declarations and expressions inside loop statements
|
|
40
|
-
when they reference variables declared in the outer scope that may change
|
|
41
|
-
across iterations.`,"no-loss-of-precision":`Disallow precision loss of number literal.`,"no-magic-numbers":`This rule aims to make code more readable and refactoring easier by ensuring that special numbers are declared as constants to make their meaning explicit.
|
|
42
|
-
The current implementation does not support BigInt numbers inside array indexes.`,"no-misleading-character-class":"This rule reports regular expressions which include multiple code point characters in character class syntax. This includes:\n\n- Characters with combining marks (e.g., `Á` where `A` is followed by a combining acute accent)\n- Characters with emoji modifiers (e.g., `👶🏻`)\n- Pairs of regional indicator symbols (e.g., `🇯🇵`)\n- Characters joined by zero-width joiner (ZWJ) (e.g., `👨👩👦`)\n- Surrogate pairs without the Unicode flag (e.g., `/^[👍]$/`)","no-multi-assign":`Disallow use of chained assignment expressions.`,"no-multi-str":`Disallow multiline strings.`,"no-negated-condition":`Disallow negated conditions.`,"no-nested-ternary":`Disallows nested ternary expressions to improve code readability and maintainability.`,"no-new-func":"The rule disallow `new` operators with the `Function` object.","no-new-native-nonconstructor":"Disallow `new` operators with global non-constructor functions (`Symbol`, `BigInt`).\n\nThis rule can be disabled for TypeScript code, as the TypeScript compiler\nenforces this check.","no-new-wrappers":"Disallow `new` operators with the `String`, `Number`, and `Boolean` objects","no-new":`Disallow new operators outside of assignments or comparisons.`,"no-nonoctal-decimal-escape":`This rule disallows \\8 and \\9 escape sequences in string literals`,"no-obj-calls":`Disallow calling some global objects as functions.
|
|
43
|
-
|
|
44
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
45
|
-
enforces this check.`,"no-object-constructor":`Disallow calls to the Object constructor without an argument`,"no-param-reassign":`Disallow reassigning function parameters or, optionally, their properties.`,"no-plusplus":"Disallow the unary operators `++` and `--`.","no-promise-executor-return":`Disallow returning values from Promise executor functions.`,"no-proto":"Disallow the use of the `proto` property.","no-prototype-builtins":`Disallow calling some Object.prototype methods directly on objects`,"no-redeclare":`This rule disallows redeclaring variables within the same scope, ensuring that each variable
|
|
46
|
-
is declared only once. It helps avoid confusion and unintended behavior in code.`,"no-regex-spaces":`Disallow 2+ consecutive spaces in regular expressions.`,"no-restricted-globals":`This rule allows you to specify global variable names that you don't want to use in your application.`,"no-restricted-imports":`This rule allows you to specify imports that you don’t want to use in your application.
|
|
47
|
-
It applies to static imports only, not dynamic ones.`,"no-return-assign":`Disallows assignment operators in return statements.`,"no-script-url":`Disallow javascript: urls`,"no-self-assign":`Disallow assignments where both sides are exactly the same.`,"no-self-compare":`Disallow comparisons where both sides are exactly the same`,"no-sequences":`Disallows the use of the comma operator.`,"no-setter-return":`Setters cannot return values.
|
|
48
|
-
|
|
49
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
50
|
-
enforces this check.`,"no-shadow-restricted-names":"Disallows the redefining of global variables such as `undefined`, `NaN`, `Infinity`,\n`eval`, and `arguments`.","no-sparse-arrays":`Disallow sparse arrays.`,"no-template-curly-in-string":"Disallow template literal placeholder syntax in regular strings. This rule ensures that\nexpressions like `${variable}` are only used within template literals, avoiding incorrect\nusage in regular strings.","no-ternary":`Disallow ternary operators`,"no-this-before-super":"Requires calling `super()` before using `this` or `super`.\n\nThis rule can be disabled for TypeScript code, as the TypeScript compiler\nenforces this check.","no-throw-literal":`Disallows throwing literals or non-Error objects as exceptions.`,"no-unassigned-vars":`Disallow let or var variables that are read but never assigned`,"no-undef":`Disallow the use of undeclared variables.
|
|
51
|
-
|
|
52
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
53
|
-
enforces this check.`,"no-undefined":"Disallow the use of `undefined` as an identifier","no-unexpected-multiline":`In most cases, semicolons are not required in JavaScript in order for code to be parsed
|
|
54
|
-
and executed as expected. Typically this occurs because semicolons are automatically
|
|
55
|
-
inserted based on a fixed set of rules. This rule exists to detect those cases where a semicolon
|
|
56
|
-
is NOT inserted automatically, and may be parsed differently than expected.`,"no-unneeded-ternary":`Disallow ternary operators when simpler alternatives exist`,"no-unreachable":"Disallow unreachable code after `return`, `throw`, `continue`, and `break` statements.\n\nThis rule can be disabled for TypeScript code if `allowUnreachableCode: false` is configured\nin the `tsconfig.json`, as the TypeScript compiler enforces this check.","no-unsafe-finally":"Disallow control flow statements in `finally` blocks.","no-unsafe-negation":`Disallows negating the left operand of relational operators to prevent logical errors
|
|
57
|
-
caused by misunderstanding operator precedence or accidental use of negation.
|
|
58
|
-
|
|
59
|
-
This rule can be disabled for TypeScript code, as the TypeScript compiler
|
|
60
|
-
enforces this check.`,"no-unsafe-optional-chaining":`Disallow use of optional chaining in contexts where the undefined value is not allowed`,"no-unused-expressions":`This rule disallows unused expressions.`,"no-unused-labels":`Disallow unused labels.`,"no-unused-private-class-members":`Disallow unused private class members`,"no-unused-vars":`Disallows variable declarations, imports, or type declarations that are
|
|
61
|
-
not used in code.`,"no-useless-backreference":`Disallows backreferences in regular expressions that will always be ignored
|
|
62
|
-
because the capture group they refer to has not matched and cannot match
|
|
63
|
-
at the time the backreference is evaluated.`,"no-useless-call":"Disallow unnecessary calls to `.call()` and `.apply()`","no-useless-catch":`Disallow unnecessary catch clauses`,"no-useless-computed-key":`Disallow unnecessary computed property keys in objects and classes`,"no-useless-concat":`Disallow unnecessary concatenation of literals or template literals`,"no-useless-constructor":`Disallow constructors that can be safely removed without changing how the class works.`,"no-useless-escape":`Disallow unnecessary escape characters.`,"no-useless-rename":`Disallow renaming import, export, and destructured assignments to the same name.`,"no-useless-return":`Disallows redundant return statements.`,"no-var":"ECMAScript 2015 allows programmers to create variables with block scope\ninstead of function scope using the `let` and `const` keywords. Block\nscope is common in many other programming languages and helps\nprogrammers avoid mistakes.","no-void":"Disallows the use of the `void` operator.","no-warning-comments":`Disallows warning comments such as TODO, FIXME, XXX in code.`,"no-with":"Disallow `with` statements.","operator-assignment":"This rule requires or disallows assignment operator shorthand where possible.\nIt encourages the use of shorthand assignment operators like `+=`, `-=`, `*=`, `/=`, etc.\nto make the code more concise and readable.","prefer-destructuring":`Require destructuring from arrays and/or objects`,"prefer-exponentiation-operator":`Disallow the use of Math.pow in favor of the \\\\ operator`,"prefer-numeric-literals":`Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal
|
|
64
|
-
literals.`,"prefer-object-has-own":"Disallow use of `Object.prototype.hasOwnProperty.call()` and prefer use of `Object.hasOwn()`","prefer-object-spread":"Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead","prefer-promise-reject-errors":`Require using Error objects as Promise rejection reasons.`,"prefer-rest-params":"Disallows the use of the `arguments` object and instead enforces the use of rest parameters.","prefer-spread":"Require spread operators instead of `.apply()`","prefer-template":`Require template literals instead of string concatenation.`,"preserve-caught-error":`Enforces that when re-throwing an error in a catch block, the original error
|
|
65
|
-
is preserved using the 'cause' property.`,radix:"Enforce the consistent use of the radix argument when using `parseInt()`.","require-await":"Disallow async functions which have no `await` expression.","require-yield":`This rule generates warnings for generator functions that do not have the yield keyword.`,"sort-imports":`This rule checks all import declarations and verifies that all imports are first sorted
|
|
66
|
-
by the used member syntax and then alphabetically by the first member or alias name.
|
|
67
|
-
|
|
68
|
-
When declaring multiple imports, a sorted list of import declarations make it easier for developers to read
|
|
69
|
-
the code and find necessary imports later.`,"sort-keys":`When declaring multiple properties, sorting property names alphabetically makes it easier
|
|
70
|
-
to find and/or diff necessary properties at a later time.`,"sort-vars":`When declaring multiple variables within the same block, sorting variable names make it
|
|
71
|
-
easier to find necessary variable easier at a later time.`,"symbol-description":`Require symbol descriptions.`,"unicode-bom":`Require or disallow Unicode byte order mark (BOM)`,"use-isnan":"Disallows checking against NaN without using `isNaN()` call.","valid-typeof":"Enforce comparing `typeof` expressions against valid strings.","vars-on-top":"Enforces that all `var` declarations are placed at the top of their containing scope.",yoda:`Require or disallow "Yoda" conditions.
|
|
72
|
-
This rule aims to enforce consistent style of conditions which compare a variable to a literal value.`},import:{"consistent-type-specifier-style":`This rule either enforces or bans the use of inline type-only markers for named imports.`,default:`If a default import is requested, this rule will report if there is no
|
|
73
|
-
default export in the imported module.`,export:`Reports funny business with exports, like repeated exports of names or defaults.`,"exports-last":`This rule enforces that all exports are declared at the bottom of the file.
|
|
74
|
-
This rule will report any export declarations that comes before any non-export statements.`,extensions:`Some file resolve algorithms allow you to omit the file extension within the import source path.
|
|
75
|
-
For example the node resolver (which does not yet support ESM/import) can resolve ./foo/bar to the absolute path /User/someone/foo/bar.js because the .js extension is resolved automatically by default in CJS.
|
|
76
|
-
Depending on the resolver you can configure more extensions to get resolved automatically.
|
|
77
|
-
In order to provide a consistent use of file extensions across your code base, this rule can enforce or disallow the use of certain file extensions.`,first:`Forbids any non-import statements before imports except directives.`,"group-exports":`Reports when named exports are not grouped together in a single export declaration
|
|
78
|
-
or when multiple assignments to CommonJS module.exports
|
|
79
|
-
or exports object are present in a single file.`,"max-dependencies":`Forbid modules to have too many dependencies (import or require statements).`,named:`Verifies that all named imports are part of the set of named exports in
|
|
80
|
-
the referenced module.
|
|
81
|
-
|
|
82
|
-
For \`export\`, verifies that all named exports exist in the referenced
|
|
83
|
-
module.
|
|
84
|
-
|
|
85
|
-
Note: for packages, the plugin will find exported names from
|
|
86
|
-
\`jsnext:main\` (deprecated) or \`module\`, if present in \`package.json\`.
|
|
87
|
-
Redux's npm module includes this key, and thereby is lintable, for
|
|
88
|
-
example.
|
|
89
|
-
|
|
90
|
-
A module path that is ignored or not unambiguously an ES module will not
|
|
91
|
-
be reported when imported. Note that type imports and exports, as used
|
|
92
|
-
by Flow, are always ignored.`,namespace:`Enforces names exist at the time they are dereferenced, when imported as
|
|
93
|
-
a full namespace (i.e. \`import * as foo from './foo'; foo.bar();\` will
|
|
94
|
-
report if bar is not exported by \`./foo.\`). Will report at the import
|
|
95
|
-
declaration if there are no exported names found. Also, will report for
|
|
96
|
-
computed references (i.e. \`foo["bar"]()\`). Reports on assignment to a
|
|
97
|
-
member of an imported namespace.`,"no-absolute-path":`This rule forbids the import of modules using absolute paths.`,"no-amd":"Forbids the use of AMD `require` and `define` calls.","no-anonymous-default-export":`Reports if a module's default export is unnamed.
|
|
98
|
-
This includes several types of unnamed data types;
|
|
99
|
-
literals, object expressions, arrays, anonymous functions, arrow functions,
|
|
100
|
-
and anonymous class declarations.`,"no-commonjs":"Forbids the use of CommonJS `require` calls. Also forbids `module.exports` and `exports.*`.","no-cycle":`Ensures that there is no resolvable path back to this module via its dependencies.
|
|
101
|
-
|
|
102
|
-
This includes cycles of depth 1 (imported module imports me) to an effectively
|
|
103
|
-
infinite value, if the \`maxDepth\` option is not set.`,"no-default-export":`Forbids a module from having default exports. This helps your editor
|
|
104
|
-
provide better auto-import functionality, as named exports offer more
|
|
105
|
-
explicit and predictable imports compared to default exports.`,"no-duplicates":`Reports if a resolved path is imported more than once in the same module.
|
|
106
|
-
This helps avoid unnecessary duplicate imports and keeps the code clean.`,"no-dynamic-require":"Forbids imports that use an expression for the module argument. This includes\ndynamically resolved paths in `require` or `import` statements.","no-empty-named-blocks":`Enforces that named import blocks are not empty.`,"no-mutable-exports":`Forbids the use of mutable exports with var or let.`,"no-named-as-default-member":`Reports the use of an exported name (named export) as a property on the
|
|
107
|
-
default export. This occurs when trying to access a named export through
|
|
108
|
-
the default export, which is incorrect.`,"no-named-as-default":`Reports use of an exported name as the locally imported name of a default export.
|
|
109
|
-
This happens when an imported default export is assigned a name that conflicts
|
|
110
|
-
with a named export from the same module.`,"no-named-default":`Reports use of a default export as a locally named import.`,"no-named-export":`Prohibit named exports.`,"no-namespace":`Enforce a convention of not using namespaced (a.k.a. "wildcard" \\*) imports.`,"no-self-import":`Forbids a module from importing itself. This can sometimes happen accidentally,
|
|
111
|
-
especially during refactoring.`,"no-unassigned-import":`This rule aims to remove modules with side-effects by reporting when a module is imported but not assigned.`,"no-webpack-loader-syntax":`Forbids using Webpack loader syntax directly in import or require statements.`,"prefer-default-export":`In exporting files, this rule checks if there is default export or not.`,unambiguous:"Warn if a `module` could be mistakenly parsed as a `script` instead of\nas a pure ES module."},jest:{"consistent-test-it":"Jest allows you to choose how you want to define your tests, using the `it` or\nthe `test` keywords, with multiple permutations for each:\n\n- it: `it`, `xit`, `fit`, `it.only`, `it.skip`.\n- test: `test`, `xtest`, `test.only`, `test.skip`.","expect-expect":"This rule triggers when there is no call made to `expect` in a test, ensure that there is at least one `expect` call made in a test.","max-expects":"This rule enforces a maximum number of `expect()` calls in a single test.","max-nested-describe":"This rule enforces a maximum depth to nested `describe()` calls.","no-alias-methods":`This rule ensures that only the canonical name as used in the Jest documentation is used in the code.`,"no-commented-out-tests":"This rule raises a warning about commented out tests. It's similar to the\n`no-disabled-tests` rule.","no-conditional-expect":`This rule prevents the use of expect in conditional blocks, such as ifs & catch(s).
|
|
112
|
-
This includes using expect in callbacks to functions named catch, which are assumed to be promises.`,"no-conditional-in-test":`Disallow conditional statements in tests.`,"no-confusing-set-timeout":`Disallow confusing usages of jest.setTimeout`,"no-deprecated-functions":`Over the years Jest has accrued some debt in the form of functions that have
|
|
113
|
-
either been renamed for clarity, or replaced with more powerful APIs.
|
|
114
|
-
|
|
115
|
-
This rule can also autofix a number of these deprecations for you.`,"no-disabled-tests":`This rule raises a warning about disabled tests.`,"no-done-callback":`This rule checks the function parameter of hooks & tests for use of the done argument, suggesting you return a promise instead.`,"no-duplicate-hooks":`Disallows duplicate hooks in describe blocks.`,"no-export":`Prevents using exports if a file has one or more tests in it.`,"no-focused-tests":"This rule reminds you to remove `.only` from your tests by raising a warning\nwhenever you are using the exclusivity feature.","no-hooks":"Disallows Jest setup and teardown hooks, such as `beforeAll`.","no-identical-title":`This rule looks at the title of every test and test suite.
|
|
116
|
-
It will report when two test suites or two test cases at the same level of a test suite have the same title.`,"no-interpolation-in-snapshots":`Prevents the use of string interpolations in snapshots.`,"no-jasmine-globals":`This rule reports on any usage of Jasmine globals, which is not ported to
|
|
117
|
-
Jest, and suggests alternatives from Jest's own API.`,"no-large-snapshots":`Disallow large snapshots.`,"no-mocks-import":`This rule reports imports from a path containing a mocks component.`,"no-restricted-jest-methods":"Restrict the use of specific `jest` and `vi` methods.","no-restricted-matchers":`Ban specific matchers & modifiers from being used, and can suggest alternatives.`,"no-standalone-expect":"Prevents `expect` statements outside of a `test` or `it` block. An `expect`\nwithin a helper function (but outside of a `test` or `it` block) will not\ntrigger this rule.\n\nStatements like `expect.hasAssertions()` will NOT trigger this rule since these\ncalls will execute if they are not in a test block.","no-test-prefixes":"Require using `.only` and `.skip` over `f` and `x`.","no-test-return-statement":`Disallow explicitly returning from tests.`,"no-untyped-mock-factory":"This rule triggers a warning if `mock()` or `doMock()` is used without a generic\ntype parameter or return type.","padding-around-test-blocks":"This rule enforces a line of padding before and after 1 or more\n`test`/`it` statements.","prefer-called-with":"Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()`","prefer-comparison-matcher":"This rule checks for comparisons in tests that could be replaced with one of the\nfollowing built-in comparison matchers:\n\n- `toBeGreaterThan`\n- `toBeGreaterThanOrEqual`\n- `toBeLessThan`\n- `toBeLessThanOrEqual`","prefer-each":"This rule enforces using `each` rather than manual loops.","prefer-equality-matcher":`Jest has built-in matchers for expecting equality, which allow for more readable
|
|
118
|
-
tests and error messages if an expectation fails.`,"prefer-expect-resolves":"Prefer `await expect(...).resolves` over `expect(await ...)` when testing\npromises.","prefer-hooks-in-order":`Ensures that hooks are in the order that they are called in.`,"prefer-hooks-on-top":`While hooks can be setup anywhere in a test file, they are always called in a
|
|
119
|
-
specific order, which means it can be confusing if they're intermixed with test
|
|
120
|
-
cases.`,"prefer-jest-mocked":"When working with mocks of functions using Jest, it's recommended to use the\n`jest.mocked()` helper function to properly type the mocked functions. This rule\nenforces the use of `jest.mocked()` for better type safety and readability.\n\nRestricted types:\n\n- `jest.Mock`\n- `jest.MockedFunction`\n- `jest.MockedClass`\n- `jest.MockedObject`","prefer-lowercase-title":"Enforce `it`, `test`, `describe`, and `bench` to have descriptions that begin with a\nlowercase letter. This provides more readable test failures.","prefer-mock-promise-shorthand":`When working with mocks of functions that return promises, Jest provides some
|
|
121
|
-
API sugar functions to reduce the amount of boilerplate you have to write.
|
|
122
|
-
These methods should be preferred when possible.`,"prefer-spy-on":"When mocking a function by overwriting a property you have to manually restore\nthe original implementation when cleaning up. When using `jest.spyOn()` Jest\nkeeps track of changes, and they can be restored with `jest.restoreAllMocks()`,\n`mockFn.mockRestore()` or by setting `restoreMocks` to `true` in the Jest\nconfig.\n\nNote: The mock created by `jest.spyOn()` still behaves the same as the original\nfunction. The original function can be overwritten with\n`mockFn.mockImplementation()` or by some of the\nother mock functions.","prefer-strict-equal":"This rule triggers a warning if `toEqual()` is used to assert equality.","prefer-to-be":"Recommends using `toBe` matcher for primitive literals and specific\nmatchers for `null`, `undefined`, and `NaN`.","prefer-to-contain":"In order to have a better failure message, `toContain()` should be used upon\nasserting expectations on an array containing an object.","prefer-to-have-been-called-times":"In order to have a better failure message, `toHaveBeenCalledTimes` should be used\ninstead of directly checking the length of `mock.calls`.","prefer-to-have-been-called":"Suggests using `toHaveBeenCalled()` or `not.toHaveBeenCalled()` over `toHaveBeenCalledTimes(0)` or `toBeCalledTimes(0)`.","prefer-to-have-length":"In order to have a better failure message, `toHaveLength()` should be used upon\nasserting expectations on objects length property.","prefer-todo":"When test cases are empty then it is better to mark them as `test.todo` as it\nwill be highlighted in the summary output.","require-hook":"This rule flags any expression that is either at the toplevel of a test file or\ndirectly within the body of a `describe`, except for the following:\n\n- `import` statements\n- `const` variables\n- `let` declarations, and initializations to `null` or `undefined`\n- Classes\n- Types\n- Calls to the standard Jest globals","require-to-throw-message":"This rule triggers a warning if `toThrow()` or `toThrowError()` is used without an error message.","require-top-level-describe":"Requires test cases and hooks to be inside a top-level `describe` block.","valid-describe-callback":`This rule validates that the second parameter of a \`describe()\` function is a
|
|
123
|
-
callback function. This callback function:
|
|
124
|
-
|
|
125
|
-
- should not be
|
|
126
|
-
async
|
|
127
|
-
- should not contain any parameters
|
|
128
|
-
- should not contain any \`return\` statements`,"valid-expect":"Checks that `expect()` is called correctly.","valid-title":`Checks that the titles of Jest and Vitest blocks are valid.
|
|
129
|
-
|
|
130
|
-
Titles must be:
|
|
131
|
-
|
|
132
|
-
- not empty,
|
|
133
|
-
- strings,
|
|
134
|
-
- not prefixed with their block name,
|
|
135
|
-
- have no leading or trailing spaces.`},jsdoc:{"check-access":'Checks that `@access` tags use one of the following values:\n\n- "package", "private", "protected", "public"\n\nAlso reports:\n\n- Mixing of `@access` with `@public`, `@private`, `@protected`, or `@package` on the same doc block.\n- Use of multiple instances of `@access` (or the `@public`, etc) on the same doc block.',"check-property-names":`Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.`,"check-tag-names":`Reports invalid block tag names.
|
|
136
|
-
Additionally checks for tag names that are redundant when using a type checker such as TypeScript.`,"empty-tags":"Expects the following tags to be empty of any content:\n\n- `@abstract`\n- `@async`\n- `@generator`\n- `@global`\n- `@hideconstructor`\n- `@ignore`\n- `@inner`\n- `@instance`\n- `@override`\n- `@readonly`\n- `@inheritDoc`\n- `@internal`\n- `@overload`\n- `@package`\n- `@private`\n- `@protected`\n- `@public`\n- `@static`","implements-on-classes":"Reports an issue with any non-constructor function using `@implements`.","no-defaults":"This rule reports defaults being used on the relevant portion of `@param` or `@default`.\nIt also optionally reports the presence of the square-bracketed optional arguments at all.","require-param-description":"Requires that each `@param` tag has a description value.","require-param-name":"Requires that all `@param` tags have names.","require-param-type":"Requires that each `@param` tag has a type value (within curly brackets).","require-param":"Requires that all function parameters are documented with JSDoc `@param` tags.","require-property-description":"Requires that all `@property` tags have descriptions.","require-property-name":"Requires that all `@property` tags have names.","require-property-type":"Requires that each `@property` tag has a type value (within curly brackets).","require-property":"Requires that all `@typedef` and `@namespace` tags have `@property` tags\nwhen their type is a plain `object`, `Object`, or `PlainObject`.\n\nNote: this rule can be configured via jsdoc settings option.","require-returns-description":"Requires that the `@returns` tag has a description value.\nThe error will not be reported if the return value is `void `or `undefined` or if it is `Promise<void>` or `Promise<undefined>`.","require-returns-type":"Requires that `@returns` tag has a type value (in curly brackets).","require-returns":"Requires that return statements are documented.\nWill also report if multiple `@returns` tags are present.","require-yields":"Requires that yields are documented.\nWill also report if multiple `@yields` tags are present."},jsx_a11y:{"alt-text":`Enforce that all elements that require alternative text have meaningful
|
|
137
|
-
information to relay back to the end user.`,"anchor-ambiguous-text":"Inspects anchor link text for the use of ambiguous words.\n\nThis rule checks the text from the anchor element `aria-label` if available.\nIn absence of an anchor `aria-label` it combines the following text of it's children:\n\n- `aria-label` if available\n- if the child is an image, the `alt` text\n- the text content of the HTML element","anchor-has-content":"Enforce that anchors have content and that the content is accessible to screen readers.\nAccessible means that it is not hidden using the `aria-hidden` prop.\n\nAlternatively, you may use the `title` prop or the `aria-label` prop.","anchor-is-valid":`The HTML \`<a>\` element, with a valid href attribute, is formally defined as representing a hyperlink.
|
|
138
|
-
That is, a link between one HTML document and another, or between one location inside an HTML document and another location inside the same document.
|
|
139
|
-
|
|
140
|
-
While before it was possible to attach logic to an anchor element, with the advent of JSX libraries,
|
|
141
|
-
it's now easier to attach logic to any HTML element, anchors included.
|
|
142
|
-
|
|
143
|
-
This rule is designed to prevent users to attach logic at the click of anchors, and also makes
|
|
144
|
-
sure that the \`href\` provided to the anchor element is valid. If the anchor has logic attached to it,
|
|
145
|
-
the rules suggests to turn it to a \`button\`, because that's likely what the user wants.
|
|
146
|
-
|
|
147
|
-
Anchor \`<a></a>\` elements should be used for navigation, while \`<button></button>\` should be
|
|
148
|
-
used for user interaction.
|
|
149
|
-
|
|
150
|
-
Consider the following:
|
|
151
|
-
|
|
152
|
-
All these anchor implementations indicate that the element is only used to execute JavaScript code. All the above should be replaced with:`,"aria-activedescendant-has-tabindex":`Enforce elements with aria-activedescendant are tabbable.`,"aria-props":`Enforces that elements do not use invalid ARIA attributes.`,"aria-proptypes":`Enforces that elements do not use invalid ARIA state and property values.`,"aria-role":`Elements with ARIA roles must use a valid, non-abstract ARIA role. A
|
|
153
|
-
reference to role definitions can be found at
|
|
154
|
-
WAI-ARIA site.`,"aria-unsupported-elements":`Enforces that reserved DOM elements do not contain ARIA roles, states,
|
|
155
|
-
or properties.`,"autocomplete-valid":`Enforces that an element's autocomplete attribute must be a valid value.`,"click-events-have-key-events":`Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, onKeyPress.`,"heading-has-content":`Enforce that heading elements (h1, h2, etc.) have content and
|
|
156
|
-
that the content is accessible to screen readers.
|
|
157
|
-
Accessible means that it is not hidden using the aria-hidden prop.`,"html-has-lang":`Ensures that every HTML document has a lang attribute`,"iframe-has-title":`Enforce iframe elements have a title attribute.`,"img-redundant-alt":'Enforce that `img` alt attributes do not contain redundant words like\n"image", "picture", or "photo".',"label-has-associated-control":`Enforce that a label tag has a text label and an associated control.`,lang:"The lang prop on the `<html>` element must be a valid IETF's BCP 47 language tag.","media-has-caption":"Checks if `<audio>` and `<video>` elements have a `<track>` element for captions.\nThis ensures media content is accessible to all users, including those with hearing impairments.","mouse-events-have-key-events":"Enforce `onMouseOver`/`onMouseOut` are accompanied by `onFocus`/`onBlur`.","no-access-key":"Enforces that the `accessKey` prop is not used on any element to avoid complications with keyboard commands used by a screenreader.","no-aria-hidden-on-focusable":'Enforces that `aria-hidden="true"` is not set on focusable elements.',"no-autofocus":"Enforce that `autoFocus` prop is not used on elements.","no-distracting-elements":`Enforces that no distracting elements are used.`,"no-noninteractive-tabindex":`This rule checks that non-interactive elements don't have a tabIndex which would make them interactive via keyboard navigation.`,"no-redundant-roles":"Enforces that the explicit `role` property is not the same as\nimplicit/default role property on element.","no-static-element-interactions":`Enforces that static HTML elements with event handlers must have appropriate ARIA roles.`,"prefer-tag-over-role":"Enforces using semantic HTML tags over `role` attribute.","role-has-required-aria-props":`Enforces that elements with ARIA roles must have all required attributes
|
|
158
|
-
for that role.`,"role-supports-aria-props":'Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`.\nMany ARIA attributes (states and properties) can only be used on elements with particular roles.\nSome elements have implicit roles, such as `<a href="#" />`, which will resolve to `role="link"`.',scope:"The scope prop should be used only on `<th>` elements.","tabindex-no-positive":"Enforces that positive values for the `tabIndex` attribute are not used\nin JSX."},nextjs:{"google-font-display":`Enforce font-display behavior with Google Fonts.`,"google-font-preconnect":'Enforces the presence of `rel="preconnect"` when using Google Fonts via `<link>` tags.',"inline-script-id":"Enforces that all `next/script` components with inline content or `dangerouslySetInnerHTML` must have an `id` prop.","next-script-for-ga":"Enforces the use of the `next/script` component when implementing Google Analytics in Next.js applications,\ninstead of using regular `<script>` tags.","no-assign-module-variable":"Prevents the assignment or declaration of variables named `module` in Next.js applications.","no-async-client-component":`Prevents the use of async functions for client components in Next.js applications.
|
|
159
|
-
This rule checks for any async function that:
|
|
160
|
-
|
|
161
|
-
- Is marked with "use client" directive
|
|
162
|
-
- Has a name starting with an uppercase letter (indicating it's a component)
|
|
163
|
-
- Is either exported as default or assigned to a variable`,"no-before-interactive-script-outside-document":"Prevents the usage of `next/script`'s `beforeInteractive` strategy outside of `pages/_document.js`.\nThis rule ensures that scripts with the `beforeInteractive` loading strategy are only used in the\ndocument component where they are most effective.","no-css-tags":'Prevents manual inclusion of stylesheets using `<link>` tags in Next.js applications.\nThis rule checks for `<link>` tags with `rel="stylesheet"` that reference local CSS files.',"no-document-import-in-page":"Prevent importing `next/document` outside of `pages/_document.js`.","no-duplicate-head":"Prevent duplicate usage of `<Head>` in `pages/_document.js`.","no-head-element":"Prevents the usage of the native `<head>` element inside a Next.js application.","no-head-import-in-document":"Prevents the usage of `next/head` inside a Next.js document.","no-html-link-for-pages":"Prevents the usage of `<a>` elements to navigate between Next.js pages.","no-img-element":"Prevent the usage of `<img>` element due to slower\nLCP and higher bandwidth.","no-page-custom-font":`Prevent page-only custom fonts.`,"no-script-component-in-head":"Prevent usage of `next/script` in `next/head` component.","no-styled-jsx-in-document":"Prevent usage of styled-jsx in `pages/_document.js`.","no-sync-scripts":"This rule prevents the use of synchronous `<script>` tags in Next.js applications.\nIt requires that any `<script>` tag with a `src` attribute must also have either\nthe `async` or `defer` attribute.","no-title-in-document-head":"Prevent usage of `<title>` with `Head` component from `next/document`.","no-typos":`Detects common typos in Next.js data fetching function names.`,"no-unwanted-polyfillio":`Prevent use of unsafe polyfill.io domains and duplicate polyfills.`},node:{"global-require":"Require `require()` calls to be placed at top-level module scope","no-exports-assign":"Disallows assignment to `exports`.","no-new-require":"Warn about calling `new` on `require`.","no-process-env":"Disallows use of `process.env`."},oxc:{"approx-constant":"Disallows the use of approximate constants, instead preferring the use\nof the constants in the `Math` object.","bad-array-method-on-arguments":`This rule applies when an array method is called on the arguments object itself.`,"bad-bitwise-operator":`This rule applies when bitwise operators are used where logical operators are expected.`,"bad-char-at-comparison":"This rule warns when the return value of the `charAt` method is used to compare a string of length greater than 1.","bad-comparison-sequence":`This rule applies when the comparison operator is applied two or more times in a row.`,"bad-min-max-func":"Checks whether the clamp function `Math.min(Math.max(x, y), z)` always evaluate to a\nconstant result because the arguments are in the wrong order.","bad-object-literal-comparison":`Checks for comparisons between object and array literals.`,"bad-replace-all-arg":"This rule warns when the `replaceAll` method is called with a regular expression that does not have the global flag (g).","branches-sharing-code":"Checks if the `if` and `else` blocks contain shared code that can be moved out of the blocks.","const-comparisons":`Checks for redundant or logically impossible comparisons. This includes:
|
|
164
|
-
|
|
165
|
-
- Ineffective double comparisons against constants.
|
|
166
|
-
- Impossible comparisons involving constants.
|
|
167
|
-
- Redundant comparisons where both operands are the same (e.g., a < a).`,"double-comparisons":`This rule checks for double comparisons in logical expressions.`,"erasing-op":"Checks for erasing operations, e.g., `x \\* 0``.\n\nBased on https://rust-lang.github.io/rust-clippy/master/#/erasing_op","misrefactored-assign-op":"https://rust-lang.github.io/rust-clippy/master/#/misrefactoredassignop\n\nChecks for `a op= a op b` or `a op= b op a` patterns.","missing-throw":"Checks whether the `throw` keyword is missing in front of a `new` expression.","no-accumulating-spread":"Prevents using object or array spreads on accumulators in `Array.prototype.reduce()` and in loops.","no-async-await":"Disallows the use of `async`/`await`.\n\nThis rule should generally not be used in modern JavaScript/TypeScript\ncodebases without good reason.","no-async-endpoint-handlers":"Disallows the use of `async` functions as Express endpoint handlers.","no-barrel-file":`Disallow the use of barrel files where the file contains \`export *\` statements,
|
|
168
|
-
and the total number of modules exceed a threshold.
|
|
169
|
-
|
|
170
|
-
The default threshold is 100.`,"no-const-enum":"Disallow TypeScript `const enum`","no-map-spread":`Disallow the use of object or array spreads in
|
|
171
|
-
\`Array.prototype.map\`
|
|
172
|
-
and
|
|
173
|
-
\`Array.prototype.flatMap\`
|
|
174
|
-
to add properties/elements to array items.
|
|
175
|
-
|
|
176
|
-
This rule only seeks to report cases where the spread operator is used
|
|
177
|
-
to merge objects or arrays, not where it is used to copy them.`,"no-optional-chaining":`Disallow optional chaining.`,"no-rest-spread-properties":`Disallow Object Rest/Spread Properties.`,"no-this-in-exported-function":"Disallows the use of `this` in exported functions.","number-arg-out-of-range":`Checks whether the radix or precision arguments of number-related functions exceeds the limit.`,"only-used-in-recursion":`Checks for arguments that are only used in recursion with no side-effects.
|
|
178
|
-
|
|
179
|
-
Inspired by the \`onlyusedin_recursion\` rule in Clippy.`,"uninvoked-array-callback":`This rule applies when an Array function has a callback argument used for an array with empty slots.`},promise:{"always-return":"Require returning inside each `then()` to create readable and reusable Promise chains.\nWe also allow someone to throw inside a `then()` which is essentially the same as return `Promise.reject()`.","avoid-new":"Disallow creating promises with `new Promise()`.","catch-or-return":"Ensure that each time a `then()` is applied to a promise, a `catch()`\nmust be applied as well. Exceptions are made for promises returned from\na function.","no-callback-in-promise":"Disallows calling a callback function (`cb()`) inside a `Promise.prototype.then()`\nor `Promise.prototype.catch()`.","no-multiple-resolved":`This rule warns of paths that resolve multiple times in executor functions that Promise constructors.`,"no-nesting":`Disallow nested then() or catch() statements.`,"no-new-statics":"Disallows calling new on static `Promise` methods.","no-promise-in-callback":`Disallows the use of Promises within error-first callback functions.`,"no-return-in-finally":`Disallow return statements in a finally() callback of a promise.`,"no-return-wrap":"Prevents unnecessary wrapping of return values in promises with either `Promise.resolve`\nor `Promise.reject`.\n\nThis rule enforces the following stances:\n\n1. When a promise is to be resolved, instead of returning `Promise.resolve(value)` it is\n better to return the raw value with `return value` instead.\n\n2. When a promise is to be rejected, instead of returning `Promise.reject(error)`, instead\n the raw error value should be thrown as in `throw error`.\n\nThere is an option to turn off the enforcing of 2, see the options section below.","param-names":`Enforce standard parameter names for Promise constructors.`,"prefer-await-to-callbacks":"The rule encourages the use of `async/await` for handling asynchronous code\ninstead of traditional callback functions. `async/await`, introduced in ES2017,\nprovides a clearer and more concise syntax for writing asynchronous code,\nmaking it easier to read and maintain.","prefer-await-to-then":"Prefer `await` to `then()`/`catch()`/`finally()` for reading Promise values","prefer-catch":"Prefer `catch` to `then(a, b)` and `then(null, b)`. This rule disallows the passing of an\nargument into the second parameter of `then` calls for handling promise errors.","spec-only":`Disallow use of non-standard Promise static methods.`,"valid-params":`Enforces the proper number of arguments are passed to Promise functions.
|
|
180
|
-
|
|
181
|
-
This rule is generally unnecessary if using TypeScript.`},react:{"button-has-type":"Enforces explicit `type` attribute for all the `button` HTML elements.","checked-requires-onchange-or-readonly":"This rule enforces `onChange` or `readOnly` attribute for checked property of input elements.\nIt also warns when `checked` and `defaultChecked` properties are used together.","display-name":"Enforces that React components have a `displayName` property.","exhaustive-deps":"Verifies the list of dependencies for Hooks like `useEffect` and similar.","forbid-dom-props":`This rule prevents passing of props to elements. This rule only applies to DOM Nodes (e.g. <div />) and not Components (e.g. <Component />). The list of forbidden props can be customized with the forbid option.`,"forbid-elements":`Allows you to configure a list of forbidden elements and to specify their desired replacements.`,"forward-ref-uses-ref":"Requires that components wrapped with `forwardRef` must have a `ref` parameter.\nOmitting the `ref` argument is usually a bug,\nand components not using `ref` don't need to be wrapped by `forwardRef`.","iframe-missing-sandbox":`Enforce sandbox attribute on iframe elements`,"jsx-boolean-value":`Enforce a consistent boolean attribute style in your code.`,"jsx-curly-brace-presence":`Disallow unnecessary JSX expressions when literals alone are
|
|
182
|
-
sufficient or enforce JSX expressions on literals in JSX children or
|
|
183
|
-
attributes.
|
|
184
|
-
|
|
185
|
-
This rule allows you to enforce curly braces or disallow unnecessary
|
|
186
|
-
curly braces in JSX props and/or children.
|
|
187
|
-
|
|
188
|
-
For situations where JSX expressions are unnecessary, please refer to
|
|
189
|
-
the React doc
|
|
190
|
-
and this page about JSX
|
|
191
|
-
gotchas.`,"jsx-filename-extension":"Enforces consistent use of the `.jsx` file extension.","jsx-fragments":`Enforces the shorthand or standard form for React Fragments.`,"jsx-handler-names":`Ensures that any component or prop methods used to handle events are correctly prefixed.`,"jsx-key":"Enforce `key` prop for elements in array","jsx-max-depth":`Enforces a maximum depth for nested JSX elements and fragments.`,"jsx-no-comment-textnodes":"This rule prevents comment strings (e.g. beginning with `//` or `/*`) from being\naccidentally injected as a text node in JSX statements.","jsx-no-duplicate-props":`This rule prevents duplicate props in JSX elements.`,"jsx-no-script-url":"Disallow usage of `javascript:` URLs.","jsx-no-target-blank":`This rule aims to prevent user generated link hrefs and form actions from creating security vulnerabilities by
|
|
192
|
-
requiring \`rel='noreferrer'\` for external link hrefs and form actions, and optionally any dynamically generated
|
|
193
|
-
link hrefs and form actions.`,"jsx-no-undef":`Disallow undeclared variables in JSX`,"jsx-no-useless-fragment":`Disallow unnecessary fragments.`,"jsx-pascal-case":`Enforce PascalCase for user-defined JSX components`,"jsx-props-no-spread-multi":`Enforces that any unique expression is only spread once.`,"jsx-props-no-spreading":`Disallow JSX prop spreading`,"no-array-index-key":`Warn if an element uses an Array index in its key.`,"no-children-prop":`Checks that children are not passed using a prop.`,"no-danger-with-children":"Disallows when a DOM element is using both `children` and `dangerouslySetInnerHTML` properties.","no-danger":"This rule prevents the use of `dangerouslySetInnerHTML` prop.","no-did-mount-set-state":"Disallows using `setState` in the `componentDidMount` lifecycle method.\n\nThis rule is not relevant for function components, and so can potentially be\ndisabled for modern React codebases.","no-direct-mutation-state":`This rule forbids the direct mutation of \`this.state\` in React components.
|
|
194
|
-
|
|
195
|
-
Note that this rule only applies to class components, it does not apply to function
|
|
196
|
-
components. For modern React codebases, this rule may not be necessary or relevant.`,"no-find-dom-node":"This rule disallows the use of `findDOMNode`, which was deprecated in 2018 and removed in React 19.","no-is-mounted":"This rule prevents using `isMounted` in classes.","no-namespace":`Enforce that namespaces are not used in React elements.`,"no-redundant-should-component-update":"Disallow usage of `shouldComponentUpdate` when extending `React.PureComponent`.\n\nNote that usage of `PureComponent` is\nnot recommended in modern React.","no-render-return-value":"This rule will warn you if you try to use the `ReactDOM.render()` return value.","no-set-state":"Disallow the usage of `this.setState` in React components.","no-string-refs":`This rule prevents using string literals in ref attributes.`,"no-this-in-sfc":"Prevents using `this` in stateless functional components.","no-unescaped-entities":`This rule prevents characters that you may have meant as JSX escape characters from being accidentally injected as a text node in JSX statements.`,"no-unknown-property":`Disallow usage of unknown DOM properties.`,"no-unsafe":`This rule identifies and restricts the use of unsafe React lifecycle methods.`,"no-will-update-set-state":"Disallows using `setState` in the `componentWillUpdate` lifecycle method.","only-export-components":`Ensures that modules only export React components (and related HMR-safe items) so
|
|
197
|
-
that Fast Refresh (a.k.a. hot reloading) can safely preserve component state.
|
|
198
|
-
Concretely, it validates the shape of your module’s exports and common entrypoints
|
|
199
|
-
(e.g. \`createRoot(...).render(<App />)\`) to match what integrations like
|
|
200
|
-
\`react-refresh\` expect.
|
|
201
|
-
|
|
202
|
-
This rule is based on the rule from \`eslint-plugin-react-refresh\`.`,"prefer-es6-class":`React offers you two ways to create traditional components: using the ES5
|
|
203
|
-
create-react-class module or the new ES2015 class system.`,"react-in-jsx-scope":'Enforces that React is imported and in-scope when using JSX syntax.\n\nNote that this rule is not necessary on React 17+ if you are using\nthe new JSX Transform, and you can disable this rule and skip importing\n`React` in files with JSX syntax.\n\nIf your `tsconfig.json` has `jsx` set to `react-jsx` or `react-jsxdev`, you are using the new JSX Transform.\nFor JavaScript projects using Babel, you are using the new JSX Transform if your React preset configuration\n(in `.babelrc` or `babel.config.js`) has `runtime: "automatic"`.\n\nFor more information, see\nthe React blog post on JSX Transform.',"require-render-return":`Enforce ES5 or ES2015 class for returning value in the \`render\` function.
|
|
204
|
-
|
|
205
|
-
This rule is not relevant for function components, and so can potentially be
|
|
206
|
-
disabled for modern React codebases.`,"rules-of-hooks":`Enforces the Rules of Hooks, ensuring that React Hooks are only called
|
|
207
|
-
in valid contexts and in the correct order.`,"self-closing-comp":`Detects components without children which can be self-closed to avoid
|
|
208
|
-
unnecessary extra closing tags.`,"state-in-constructor":`Enforces the state initialization style to be either in a
|
|
209
|
-
constructor or with a class property.
|
|
210
|
-
|
|
211
|
-
This rule is not relevant for function components, and so can potentially be
|
|
212
|
-
disabled for modern React codebases.`,"style-prop-object":"Require that the value of the prop `style` be an object or a variable that is an object.","void-dom-elements-no-children":"Disallow void DOM elements (e.g. `<img />`, `<br />`) from receiving children."},react_perf:{"jsx-no-jsx-as-prop":`Prevent JSX elements that are local to the current method from being
|
|
213
|
-
used as values of JSX props.`,"jsx-no-new-array-as-prop":`Prevent Arrays that are local to the current method from being used
|
|
214
|
-
as values of JSX props.`,"jsx-no-new-function-as-prop":`Prevent Functions that are local to the current method from being used
|
|
215
|
-
as values of JSX props.`,"jsx-no-new-object-as-prop":`Prevent Objects that are local to the current method from being used
|
|
216
|
-
as values of JSX props.`},typescript:{"adjacent-overload-signatures":`Require that function overload signatures be consecutive.`,"array-type":"Require consistently using either `T[]` or `Array<T>` for arrays.","await-thenable":`This rule disallows awaiting a value that is not a Thenable.`,"ban-ts-comment":`This rule lets you set which directive comments you want to allow in your codebase.`,"ban-tslint-comment":"This rule disallows `tslint:<rule-flag>` comments","ban-types":`This rule bans specific types and can suggest alternatives. Note that it does not ban the corresponding runtime objects from being used.`,"consistent-generic-constructors":`When constructing a generic class, you can specify the type arguments on either the left-hand side (as a type annotation) or the right-hand side (as part of the constructor call).
|
|
217
|
-
|
|
218
|
-
This rule enforces consistency in the way generic constructors are used.`,"consistent-indexed-object-style":`Choose between requiring either \`Record\` type or indexed signature types.
|
|
219
|
-
|
|
220
|
-
These two types are equivalent, this rule enforces consistency in picking one style over the other:`,"consistent-type-definitions":"Enforce type definitions to consistently use either `interface` or `type`.","consistent-type-imports":`Enforce consistent usage of type imports.`,"explicit-function-return-type":`This rule enforces that functions have an explicit return type annotation.`,"explicit-module-boundary-types":`Require explicit return and argument types on exported functions' and classes' public class methods.`,"no-array-delete":`This rule disallows using the delete operator on array values.`,"no-base-to-string":`This rule requires toString() and toLocaleString() calls to only be called on objects which provide useful information when stringified.`,"no-confusing-non-null-assertion":`Disallow non-null assertion in locations that may be confusing.`,"no-confusing-void-expression":`This rule forbids using void expressions in confusing locations such as arrow function returns.`,"no-deprecated":"Disallow using code marked as `@deprecated`.","no-duplicate-enum-values":`Disallow duplicate enum member values.`,"no-duplicate-type-constituents":`This rule disallows duplicate constituents of union or intersection types.`,"no-dynamic-delete":`Disallow using the delete operator on computed key expressions.`,"no-empty-interface":`Disallow the declaration of empty interfaces.`,"no-empty-object-type":"To avoid confusion around the `{}` type allowing any non-nullish value, this rule bans usage of the `{}` type. That includes interfaces and object type aliases with no fields.","no-explicit-any":"Disallows explicit use of the `any` type.","no-extra-non-null-assertion":`Disallow extra non-null assertions.`,"no-extraneous-class":`This rule reports when a class has no non-static members, such as for a
|
|
221
|
-
class used exclusively as a static namespace. This rule also reports
|
|
222
|
-
classes that have only a constructor and no fields. Those classes can
|
|
223
|
-
generally be replaced with a standalone function.`,"no-floating-promises":'This rule disallows "floating" Promises in TypeScript code, which is a Promise that is created without any code to handle its resolution or rejection.\n\nThis rule will report Promise-valued statements that are not treated in one of the following ways:\n\n- Calling its `.then()` with two arguments\n- Calling its `.catch()` with one argument\n- `await`ing it\n- `return`ing it\n- `void`ing it\n\nThis rule also reports when an Array containing Promises is created and not properly handled. The main way to resolve this is by using one of the Promise concurrency methods to create a single Promise, then handling that according to the procedure above. These methods include:\n\n- `Promise.all()`\n- `Promise.allSettled()`\n- `Promise.any()`\n- `Promise.race()`',"no-for-in-array":`This rule disallows iterating over an array with a for-in loop.`,"no-implied-eval":`This rule disallows the use of eval-like methods.`,"no-import-type-side-effects":"Enforce the use of top-level `import type` qualifier when an import only\nhas specifiers with inline type qualifiers.","no-inferrable-types":`Disallow explicit type declarations for variables or parameters initialized to a number, string, or boolean`,"no-meaningless-void-operator":`This rule disallows the void operator when its argument is already of type void or undefined.`,"no-misused-new":"Enforces valid definition of new and constructor. This rule prevents classes from defining\na method named `new` and interfaces from defining a method named `constructor`.","no-misused-promises":`This rule forbids providing Promises to logical locations such as if statements in places where the TypeScript
|
|
224
|
-
compiler allows them but they are not handled properly. These situations can often arise due to a missing
|
|
225
|
-
\`await\` keyword or just a misunderstanding of the way async functions are handled/awaited.`,"no-misused-spread":`This rule disallows spreading syntax in places where it doesn't make sense or could cause runtime errors.`,"no-mixed-enums":`This rule disallows enums from having both string and numeric members.`,"no-namespace":`Disallow TypeScript namespaces.`,"no-non-null-asserted-nullish-coalescing":`Disallow non-null assertions in the left operand of a nullish coalescing operator.`,"no-non-null-asserted-optional-chain":`Disallow non-null assertions after an optional chain expression.`,"no-non-null-assertion":`Disallow non-null assertions using the ! postfix operator.`,"no-redundant-type-constituents":`This rule disallows type constituents of unions and intersections that are redundant.`,"no-require-imports":"Forbids the use of CommonJS `require` calls.","no-restricted-types":`Disallow certain types from being used.`,"no-this-alias":"Disallow aliasing of `this`.","no-unnecessary-boolean-literal-compare":`This rule disallows unnecessary equality comparisons with boolean literals.`,"no-unnecessary-parameter-property-assignment":`Prevents unnecessary assignment of parameter properties.`,"no-unnecessary-template-expression":`Disallows unnecessary template expressions (interpolations) that can be simplified.`,"no-unnecessary-type-arguments":`This rule disallows type arguments that are identical to the default type parameter.`,"no-unnecessary-type-assertion":`This rule disallows type assertions that do not change the type of an expression.`,"no-unnecessary-type-constraint":`Disallow unnecessary constraints on generic types.`,"no-unsafe-argument":"This rule disallows calling a function with an argument which is typed as `any`.","no-unsafe-assignment":"This rule disallows assigning a value with type `any` to variables and properties.","no-unsafe-call":"This rule disallows calling a value with type `any`.","no-unsafe-declaration-merging":`Disallow unsafe declaration merging.`,"no-unsafe-enum-comparison":`This rule disallows comparing an enum value with a non-enum value.`,"no-unsafe-function-type":`Disallow using the unsafe built-in Function type.`,"no-unsafe-member-access":"This rule disallows member access on a value with type `any`.","no-unsafe-return":"This rule disallows returning a value with type `any` from a function.","no-unsafe-type-assertion":`Disallows unsafe type assertions that narrow a type.`,"no-unsafe-unary-minus":`This rule disallows using the unary minus operator on a value which is not of type 'number' | 'bigint'.`,"no-useless-empty-export":`Disallow empty exports that don't change anything in a module file.`,"no-var-requires":"Disallow `require` statements except in import statements.\n\nNOTE: This rule is intentionally missing the `allow` option from the original typescript-eslint rule.\nThis rule is deprecated in the upstream plugin and the `typescript/no-require-imports` rule should be\nused instead.","no-wrapper-object-types":`Disallow the use of wrapper object types.`,"non-nullable-type-assertion-style":`This rule prefers a non-null assertion over an explicit type cast for non-nullable types.`,"only-throw-error":`This rule disallows throwing non-Error values.`,"prefer-as-const":"Enforce the use of `as const` over literal type.","prefer-enum-initializers":`Require each enum member value to be explicitly initialized.`,"prefer-for-of":`Enforces the use of for-of loop instead of a for loop with a simple iteration.`,"prefer-function-type":`Enforce using function types instead of interfaces with call signatures.`,"prefer-includes":"Enforce using `.includes()` instead of `.indexOf() !== -1` or `/regex/.test()`.","prefer-literal-enum-member":`Explicit enum value must only be a literal value (string, number, boolean, etc).`,"prefer-namespace-keyword":`This rule reports when the module keyword is used instead of namespace.
|
|
226
|
-
This rule does not report on the use of TypeScript module declarations to describe external APIs (declare module 'foo' {}).`,"prefer-nullish-coalescing":"Enforce using the nullish coalescing operator (`??`) instead of logical OR (`||`)\nor conditional expressions when the left operand might be `null` or `undefined`.","prefer-optional-chain":`Enforce using concise optional chain expressions instead of chained logical AND
|
|
227
|
-
operators, negated logical OR operators, or empty objects.
|
|
228
|
-
|
|
229
|
-
Note that this rule is in the nursery category while we ensure it is working
|
|
230
|
-
correctly in as many edge-case scenarios as possible. The logic for this is
|
|
231
|
-
complex and the autofix may cause logic changes in some edge-cases.`,"prefer-promise-reject-errors":`This rule enforces passing an Error object to Promise.reject().`,"prefer-reduce-type-parameter":`This rule prefers using a type parameter for the accumulator in Array.reduce instead of casting.`,"prefer-return-this-type":"This rule enforces using `this` types for return types when possible.","prefer-ts-expect-error":`Enforce using @ts-expect-error over @ts-ignore.`,"promise-function-async":`This rule requires any function or method that returns a Promise to be marked as async.`,"related-getter-setter-pairs":`This rule enforces that getters and setters for the same property are defined together and have related types.`,"require-array-sort-compare":`This rule requires Array.sort() to be called with a comparison function.`,"require-await":`This rule disallows async functions which do not have an await expression.`,"restrict-plus-operands":`This rule requires both operands of addition to be the same type and be number, string, or any.`,"restrict-template-expressions":`This rule restricts the types allowed in template literal expressions.`,"return-await":`This rule enforces consistent returning of awaited values from async functions.`,"strict-boolean-expressions":`Disallow certain types in boolean expressions.`,"switch-exhaustiveness-check":`This rule requires switch statements to be exhaustive when switching on union types.`,"triple-slash-reference":`Disallow certain triple slash directives in favor of ES module import declarations.`,"unbound-method":`This rule enforces unbound methods are called with their expected scope.`,"use-unknown-in-catch-callback-variable":"This rule enforces using `unknown` for catch clause variables instead of `any`."},unicorn:{"catch-error-name":"This rule enforces consistent and descriptive naming for error variables\nin `catch` statements, preventing the use of vague names like `badName`\nor `_` when the error is used.","consistent-assert":"Enforces consistent usage of the `assert` module.","consistent-date-clone":"The Date constructor can clone a `Date` object directly when passed as an argument,\nmaking timestamp conversion unnecessary. This rule enforces the use of the\ndirect `Date` cloning instead of using `.getTime()` for conversion.","consistent-empty-array-spread":`When spreading a ternary in an array, we can use both [] and '' as fallbacks,
|
|
232
|
-
but it's better to have consistent types in both branches.`,"consistent-existence-index-check":"Enforce consistent style for element existence checks with `indexOf()`,\n`lastIndexOf()`, `findIndex()`, and `findLastIndex()`. This ensures\nthat comparisons are performed in a standard and clear way.","consistent-function-scoping":`Disallow functions that are declared in a scope which does not capture
|
|
233
|
-
any variables from the outer scope.`,"empty-brace-spaces":`Removes the extra spaces or new line characters inside a pair of braces
|
|
234
|
-
that does not contain additional code. This ensures that braces are clean
|
|
235
|
-
and do not contain unnecessary spaces or newlines.`,"error-message":"Enforces providing a `message` when creating built-in `Error` objects to\nimprove readability and debugging.","escape-case":`Enforces defining escape sequence values with uppercase characters rather than lowercase ones.
|
|
236
|
-
This promotes readability by making the escaped value more distinguishable from the identifier.`,"explicit-length-check":`Enforce explicitly comparing the length or size property of a value.`,"filename-case":"Enforces a consistent case style for filenames to improve project organization and maintainability.\nBy default, `kebab-case` is enforced, but other styles can be configured.\n\nFiles named `index.js`, `index.ts`, etc. are exempt from this rule as they cannot reliably be\nrenamed to other casings (mainly just a problem with PascalCase).","new-for-builtins":"Enforces the use of `new` for the following builtins: `Object`, `Array`, `ArrayBuffer`, `BigInt64Array`,\n`BigUint64Array`, `DataView`, `Date`, `Error`, `Float32Array`, `Float64Array`, `Function`, `Int8Array`,\n`Int16Array`, `Int32Array`, `Map`, `WeakMap`, `Set`, `WeakSet`, `Promise`, `RegExp`, `Uint8Array`,\n`Uint16Array`, `Uint32Array`, `Uint8ClampedArray`, `SharedArrayBuffer`, `Proxy`, `WeakRef`, `FinalizationRegistry`.\n\nDisallows the use of `new` for the following builtins: `String`, `Number`, `Boolean`, `Symbol`, `BigInt`.","no-abusive-eslint-disable":"Disallows `oxlint-disable` or `eslint-disable` comments without specifying rules.","no-accessor-recursion":`Disallow recursive access to this within getters and setters`,"no-anonymous-default-export":`Disallows anonymous functions and classes as default exports.`,"no-array-callback-reference":`Prevents passing a function reference directly to iterator methods`,"no-array-for-each":"Forbids the use of `Array#forEach` in favor of a for loop.","no-array-method-this-argument":"Disallows the use of the `thisArg` parameter in array iteration methods such as\n`map`, `filter`, `some`, `every`, and similar.","no-array-reduce":"Disallow `Array#reduce()` and `Array#reduceRight()`.","no-array-reverse":"Prefer using `Array#toReversed()` over `Array#reverse()`.","no-array-sort":"Prefer using `Array#toSorted()` over `Array#sort()`.","no-await-expression-member":"Disallows member access from `await` expressions.","no-await-in-promise-methods":"Disallow using `await` in `Promise` method parameters","no-console-spaces":"Disallows leading/trailing space inside `console.log()` and similar methods.","no-document-cookie":"Disallow direct use of\n`document.cookie`.","no-empty-file":`Disallows files that do not contain any meaningful code.
|
|
237
|
-
|
|
238
|
-
This includes files that consist only of:
|
|
239
|
-
|
|
240
|
-
- Whitespace
|
|
241
|
-
- Comments
|
|
242
|
-
- Directives (e.g., \`"use strict"\`)
|
|
243
|
-
- Empty statements (\`;\`)
|
|
244
|
-
- Empty blocks (\`{}\`)
|
|
245
|
-
- Hashbangs (\`#!/usr/bin/env node\`)`,"no-hex-escape":`Enforces a convention of using Unicode escapes instead of hexadecimal escapes for consistency and clarity.`,"no-immediate-mutation":`Disallows mutating a variable immediately after initialization.`,"no-instanceof-array":"Require `Array.isArray()` instead of `instanceof Array`.","no-instanceof-builtins":"Disallows the use of `instanceof` with ECMAScript built-in constructors because:\n\n- it breaks across execution contexts (`iframe`, Web Worker, Node VM, etc.);\n- it is often misleading (e.g. `instanceof Array` fails for a subclass);\n- there is always a clearer and safer alternative (`Array.isArray`, `typeof`, `Buffer.isBuffer`, …).","no-invalid-fetch-options":"Disallow invalid options in `fetch()` and `new Request()`. Specifically, this rule ensures that\na body is not provided when the method is `GET` or `HEAD`, as it will result in a `TypeError`.","no-invalid-remove-event-listener":"It warns when you use a non-function value as the second argument of `removeEventListener`.","no-length-as-slice-end":"Disallow using `length` as the end argument of a `slice` call.","no-lonely-if":"Disallow `if` statements as the only statement in `if` blocks without `else`.","no-magic-array-flat-depth":"Disallow magic numbers for `Array.prototype.flat` depth.","no-negation-in-equality-check":`Disallow negated expressions on the left of (in)equality checks.`,"no-nested-ternary":`This rule disallows deeply nested ternary expressions.
|
|
246
|
-
Nested ternary expressions that are only one level deep and wrapped in parentheses are allowed.`,"no-new-array":"Disallow `new Array()`.","no-new-buffer":"Disallows the deprecated `new Buffer()` constructor.","no-null":"Disallow the use of the `null` literal, to encourage using `undefined` instead.","no-object-as-default-parameter":`Disallow the use of an object literal as a default value for a parameter.`,"no-process-exit":"Disallow `process.exit()`.","no-single-promise-in-promise-methods":`Disallow passing single-element arrays to Promise methods`,"no-static-only-class":`Disallow classes that only have static members.`,"no-thenable":"Disallow `then` property","no-this-assignment":"Disallow assigning `this` to a variable.","no-typeof-undefined":"Disallow `typeof` comparisons with `undefined`.","no-unnecessary-array-flat-depth":"Disallows passing `1` to `Array.prototype.flat`","no-unnecessary-array-splice-count":"Disallows passing `.length` or `Infinity` as the `deleteCount` or `skipCount` argument of `Array#splice()` or `Array#toSpliced()`.","no-unnecessary-await":`Disallow awaiting on non-promise values.`,"no-unnecessary-slice-end":`Omitting the end argument defaults it to the object's .length.
|
|
247
|
-
Passing it explicitly or using Infinity is unnecessary`,"no-unreadable-array-destructuring":`Disallow unreadable array destructuring`,"no-unreadable-iife":`This rule disallows IIFEs with a parenthesized arrow function body.`,"no-useless-collection-argument":`Disallow useless values or fallbacks in Set, Map, WeakSet, or WeakMap`,"no-useless-error-capture-stack-trace":"Disallows unnecessary `Error.captureStackTrace(…)` in error constructors.","no-useless-fallback-in-spread":`Disallow useless fallback when spreading in object literals.`,"no-useless-length-check":"It checks for an unnecessary array length check in a logical expression.\n\nThe cases are:\n\n- `array.length === 0 || array.every(Boolean)` (`array.every` returns `true` if array is has elements)\n- `array.length > 0 && array.some(Boolean)` (`array.some` returns `false` if array is empty)","no-useless-promise-resolve-reject":"Disallows returning values wrapped in `Promise.resolve` or `Promise.reject` in an async function or a `Promise#then`/`catch`/`finally` callback.","no-useless-spread":`Disallows using spread syntax in following, unnecessary cases:
|
|
248
|
-
|
|
249
|
-
- Spread an array literal as elements of an array literal
|
|
250
|
-
- Spread an array literal as arguments of a call or a \`new\` call
|
|
251
|
-
- Spread an object literal as properties of an object literal
|
|
252
|
-
- Use spread syntax to clone an array created inline`,"no-useless-switch-case":`Disallows useless default cases in switch statements.`,"no-useless-undefined":"Do not use useless `undefined`.","no-zero-fractions":`Prevents the use of zero fractions.`,"number-literal-case":`This rule enforces proper case for numeric literals.`,"numeric-separators-style":`Enforces a convention of grouping digits using numeric separators.`,"prefer-add-event-listener":"Enforces the use of `.addEventListener()` and `.removeEventListener()` over their `on`-function counterparts.\n\nFor example, `foo.addEventListener('click', handler);` is preferred over `foo.onclick = handler;` for HTML DOM Events.","prefer-array-find":"Encourages using `Array.prototype.find` instead of `filter(...)[0]` or\nsimilar patterns when only the first matching element is needed.","prefer-array-flat-map":"Prefers the use of `.flatMap()` when `map().flat()` are used together.","prefer-array-flat":"Prefers `Array#flat()` over legacy techniques to flatten arrays.","prefer-array-index-of":"Enforces using `indexOf` or `lastIndexOf` instead of `findIndex` or `findLastIndex`\nwhen the callback is a simple strict equality comparison.","prefer-array-some":"Prefers using `Array#some()` over `Array#find()`, `Array#findLast()` with comparing to undefined,\nor `Array#findIndex()`, `Array#findLastIndex()`\nand a non-zero length check on the result of `Array#filter()`","prefer-at":"Prefer `.at()` method for index access and `String#charAt()`.","prefer-bigint-literals":"Requires using BigInt literals (e.g. `123n`) instead of calling the `BigInt()` constructor\nwith literal arguments such as numbers or numeric strings","prefer-blob-reading-methods":"Recommends using `Blob#text()` and `Blob#arrayBuffer()` over `FileReader#readAsText()` and `FileReader#readAsArrayBuffer()`.","prefer-class-fields":"Prefers class field declarations over `this` assignments in constructors for static values.","prefer-classlist-toggle":"Prefers the use of `element.classList.toggle(className, condition)` over\nconditional add/remove patterns.","prefer-code-point":"Prefers usage of `String.prototype.codePointAt` over `String.prototype.charCodeAt`.\nPrefers usage of `String.fromCodePoint` over `String.fromCharCode`.","prefer-date-now":"Prefers use of `Date.now()` over `new Date().getTime()` or `new Date().valueOf()`.","prefer-default-parameters":"Instead of reassigning a function parameter, default parameters should be used. The `foo = foo || 123` statement evaluates to `123` when `foo` is falsy, possibly leading to confusing behavior, whereas default parameters only apply when passed an `undefined` value.\nThis rule only reports reassignments to literal values.\n\nYou should disable this rule if you want your functions to deal with `null` and other falsy values the same way as `undefined`.\nDefault parameters are exclusively applied when `undefined` is received..\nHowever, we recommend moving away from `null`.","prefer-dom-node-append":"Enforces the use of, for example, `document.body.append(div);` over `document.body.appendChild(div);` for DOM nodes.","prefer-dom-node-dataset":"Use `.dataset` on DOM elements over `getAttribute(…)`, `.setAttribute(…)`, `.removeAttribute(…)` and `.hasAttribute(…)`.","prefer-dom-node-remove":"Prefers the use of `child.remove()` over `parentNode.removeChild(child)`.","prefer-dom-node-text-content":"Enforces the use of `.textContent` over `.innerText` for DOM nodes.","prefer-event-target":"Prefers `EventTarget` over `EventEmitter`.\n\nThis rule reduces the bundle size and makes your code more cross-platform friendly.\n\nSee the differences between `EventEmitter` and `EventTarget`.","prefer-global-this":"Enforces the use of `globalThis` instead of\nenvironment‑specific global object aliases (`window`, `self`, or `global`).\nUsing the standard `globalThis` makes your code portable across browsers, Web Workers, Node.js,\nand future JavaScript runtimes.","prefer-includes":"Prefer `includes()` over `indexOf()` when checking for existence or non-existence.\nAll built-ins have `.includes()` in addition to `.indexOf()`.","prefer-keyboard-event-key":"Enforces the use of `KeyboardEvent#key` over `KeyboardEvent#keyCode` which is deprecated.\nThe `.key` property is also more semantic and readable.","prefer-logical-operator-over-ternary":`This rule finds ternary expressions that can be simplified to a logical operator.`,"prefer-math-min-max":"Prefers use of `Math.min()` and `Math.max()` instead of ternary\nexpressions when performing simple comparisons.","prefer-math-trunc":"Prefers use of `Math.trunc()` instead of bitwise operations for clarity and more reliable results.\n\nIt prevents the use of the following bitwise operations:\n\n- `x | 0` (`bitwise OR` with 0)\n- `~~x` (two `bitwise NOT`)\n- `x >> 0` (`Signed Right Shift` with 0)\n- `x << 0` (`Left Shift` with 0)\n- `x ^ 0` (`bitwise XOR Shift` with 0)","prefer-modern-dom-apis":"Enforces the use of:\n\n- `childNode.replaceWith(newNode)` over `parentNode.replaceChild(newNode, oldNode)`\n- `referenceNode.before(newNode)` over `parentNode.insertBefore(newNode, referenceNode)`\n- `referenceNode.before('text')` over `referenceNode.insertAdjacentText('beforebegin', 'text')`\n- `referenceNode.before(newNode)` over `referenceNode.insertAdjacentElement('beforebegin', newNode)`","prefer-modern-math-apis":`Checks for usage of legacy patterns for mathematical operations.`,"prefer-native-coercion-functions":`Prefers built in functions, over custom ones with the same functionality.`,"prefer-negative-index":"Prefer negative index over `.length` - index when possible","prefer-node-protocol":"Prefer using the `node:protocol` when importing Node.js builtin modules","prefer-number-properties":"Disallows use of `parseInt()`, `parseFloat()`, `isNan()`, `isFinite()`, `Nan`, `Infinity` and `-Infinity` as global variables.","prefer-object-from-entries":"Encourages using `Object.fromEntries` when converting an array of key-value pairs\ninto an object.","prefer-optional-catch-binding":`Prefers omitting the catch binding parameter if it is unused`,"prefer-prototype-methods":`This rule prefers borrowing methods from the prototype instead of the instance.`,"prefer-query-selector":"Prefer `.querySelector()` over `.getElementById()`, `.querySelectorAll()` over `.getElementsByClassName()` and `.getElementsByTagName()`.","prefer-reflect-apply":"Disallows the use of `Function.prototype.apply()` and suggests using `Reflect.apply()` instead.","prefer-regexp-test":"Prefers `RegExp#test()` over `String#match()` and `String#exec()`.","prefer-response-static-json":"Enforces the use of `Response.json()` over `new Response(JSON.stringify())`.","prefer-set-has":"Prefer `Set#has()` over `Array#includes()` when checking for existence or non-existence.","prefer-set-size":"Prefer `Set#size` over `Set#length` when the `Set` is converted to an array.","prefer-spread":"Enforces the use of the spread operator (`...`) over outdated patterns.","prefer-string-raw":`Prefers use of String.raw to avoid escaping \\.`,"prefer-string-replace-all":"Prefers `String#replaceAll()` over `String#replace()` when using a regex with the global flag.","prefer-string-slice":"Prefer `String#slice()` over `String#substr()` and `String#substring()`.","prefer-string-starts-ends-with":"Prefer `String#startsWith()` and `String#endsWith()` over using a regex with `/^foo/` or `/foo$/`.","prefer-string-trim-start-end":"`String#trimLeft()` and `String#trimRight()` are aliases of `String#trimStart()` and `String#trimEnd()`. This is to ensure consistency and use direction-independent wording.","prefer-structured-clone":`Prefer using structuredClone to create a deep clone.`,"prefer-top-level-await":`Prefer top-level await over top-level promises and async function calls.`,"prefer-type-error":"Enforce throwing a `TypeError` instead of a generic `Error` after a type checking if-statement.","require-array-join-separator":`Enforce using the separator argument with Array#join()`,"require-module-attributes":`This rule enforces non-empty attribute list in import/export statements and import() expressions.`,"require-module-specifiers":"Enforce non-empty specifier list in `import` and `export` statements.","require-number-to-fixed-digits-argument":`Enforce using the digits argument with Number.toFixed()`,"require-post-message-target-origin":`Enforce using the targetOrigin argument with window.postMessage()`,"switch-case-braces":`Requires empty switch cases to omit braces, while non-empty cases must use braces.
|
|
253
|
-
This reduces visual clutter for empty cases and enforces proper scoping for non-empty ones.`,"text-encoding-identifier-case":"This rule enforces consistent casing for text encoding identifiers, specifically:\n\n- `'utf8'` instead of `'UTF-8'` or `'utf-8'` (or `'utf-8'` if `withDash` is enabled)\n- `'ascii'` instead of `'ASCII'`","throw-new-error":"This rule makes sure you always use `new` when throwing an error."},vitest:{"consistent-each-for":"This rule ensure consistency on which method used to create parameterized test.\nThis configuration affects to different test function types (`test`, `it`, `describe`, `suite`).","consistent-test-filename":`This rule triggers an error when a file is considered a test file, but its name
|
|
254
|
-
does not match an expected filename format.`,"consistent-vitest-vi":`This rule triggers an error when an unexpected vitest accessor is used.`,"hoisted-apis-on-top":`Enforce hoisted APIs to be on top of the file.`,"no-conditional-tests":`The rule disallows the use of conditional statements within test cases to
|
|
255
|
-
ensure that tests are deterministic and clearly readable.`,"no-import-node-test":"This rule warns when `node:test` is imported (usually accidentally).\nWith `--fix`, it will replace the import with `vitest`.","no-unneeded-async-expect-function":`Disallows unnecessary async function wrapper for expected promises.`,"prefer-called-once":"Substitute `toBeCalledTimes(1)` and `toHaveBeenCalledTimes(1)` with\n`toBeCalledOnce()` and `toHaveBeenCalledOnce()` respectively.","prefer-called-times":"This rule aims to enforce the use of `toBeCalledTimes(1)` or `toHaveBeenCalledTimes(1)` over `toBeCalledOnce()` or `toHaveBeenCalledOnce()`.","prefer-describe-function-title":`When testing a specific function, this rule aims to enforce passing a named function to describe()
|
|
256
|
-
instead of an equivalent hardcoded string.`,"prefer-to-be-falsy":"This rule warns when `toBe(false)` is used with `expect` or `expectTypeOf`.\nWith `--fix`, it will be replaced with `toBeFalsy()`.","prefer-to-be-object":"This rule enforces using `toBeObject()` to check if a value is of type `Object`.","prefer-to-be-truthy":"This rule warns when `toBe(true)` is used with `expect` or `expectTypeOf`.\nWith `--fix`, it will be replaced with `toBeTruthy()`.","require-local-test-context-for-concurrent-snapshots":`The rule is intended to ensure that concurrent snapshot tests are executed
|
|
257
|
-
within a properly configured local test context.`,"warn-todo":"This rule triggers warnings when `.todo` is used in `describe`, `it`, or `test` functions.\nIt is recommended to use this with your CI pipeline to annotate PR diffs."},vue:{"define-emits-declaration":'This rule enforces `defineEmits` typing style which you should use `type-based`, strict `type-literal` (introduced in Vue 3.3), or `runtime` declaration.\nThis rule only works in setup script and `lang="ts"`.',"define-props-declaration":'This rule enforces `defineProps` typing style which you should use `type-based` or `runtime` declaration.\nThis rule only works in `<script setup>` with `lang="ts"`.',"define-props-destructuring":`This rule enforces a consistent style for handling Vue 3 Composition API props,
|
|
258
|
-
allowing you to choose between requiring destructuring or prohibiting it.`,"max-props":`Enforce maximum number of props in Vue component.`,"no-arrow-functions-in-watch":`This rule disallows using arrow functions when defining a watcher.`,"no-deprecated-destroyed-lifecycle":"Disallow using deprecated `destroyed` and `beforeDestroy` lifecycle hooks in Vue.js 3.0.0+.","no-export-in-script-setup":"Disallow `export` in `<script setup>`","no-import-compiler-macros":`Disallow importing Vue compiler macros.`,"no-lifecycle-after-await":`Disallow asynchronously registered lifecycle hooks.`,"no-multiple-slot-args":`Disallow passing multiple arguments to scoped slots.`,"no-required-prop-with-default":`Enforce props with default values to be optional.`,"no-this-in-before-route-enter":"Disallow `this` usage in a `beforeRouteEnter` method.\n\nThis rule is only relevant when using `vue-router`.","prefer-import-from-vue":"Enforce `import from 'vue'` instead of `import from '@vue/*'`.","require-default-export":`Require components to be the default export.`,"require-typed-ref":"Require `ref` and `shallowRef` functions to be strongly typed.","valid-define-emits":"This rule checks whether defineEmits compiler macro is valid.\n\nThis rule reports defineEmits compiler macros in the following cases:\n\n- `defineEmits` is referencing locally declared variables.\n- `defineEmits` has both a literal type and an argument. e.g. `defineEmits<(e: 'foo')=>void>(['bar'])`\n- `defineEmits` has been called multiple times.\n- Custom events are defined in both `defineEmits` and `export default {}`.\n- Custom events are not defined in either `defineEmits` or `export default {}`.","valid-define-props":"This rule checks whether `defineProps` compiler macro is valid.\n\nThis rule reports `defineProps` compiler macros in the following cases:\n\n- `defineProps` is referencing locally declared variables.\n- `defineProps` has both a literal type and an argument. e.g. `defineProps<{ /props/ }>({ /props/ })`\n- `defineProps` has been called multiple times.\n- Props are defined in both `defineProps` and `export default {}`.\n- Props are not defined in either `defineProps` or `export default {}`."}};l(u(import.meta.url));const v=`1.42.0`,y={k:{type:`MOVE_UP`},up:{type:`MOVE_UP`},down:{type:`MOVE_DOWN`},j:{type:`MOVE_DOWN`},left:{type:`MOVE_LEFT`},h:{type:`MOVE_LEFT`},right:{type:`MOVE_RIGHT`},l:{type:`MOVE_RIGHT`},return:{type:`OPEN_DOCS`},enter:{type:`OPEN_DOCS`},1:{type:`SET_STATUS`,value:`off`},2:{type:`SET_STATUS`,value:`warn`},3:{type:`SET_STATUS`,value:`error`},q:{type:`EXIT`},r:{type:`RUN_LINT`},x:{type:`RUN_SINGLE_RULE`}};let b={activePane:0,selectedCategoryIndex:0,selectedRuleIndex:0,categoryScroll:0,ruleScroll:0,isLintInProgress:!1,message:`oxlint-tui`,messageType:`dim`,...E()};function x(t,n){if(!(!b.configPath||!b.config))try{b.config.rules||(b.config.rules={});let r=t.value,i=t.scope===`oxc2`||t.scope===`eslint`?r:`${t.scope}/${r}`,a=b.config.rules,o=Object.keys(a).find(e=>e===i||e===r||e.endsWith(`/${r}`))||i;a[o]=n,e.writeFileSync(b.configPath,JSON.stringify(b.config,null,2),`utf8`)}catch{b.message=`Failed to write config file`,b.messageType=`error`}}function S({rule:e=null}={}){if(b.isLintInProgress)return;b.isLintInProgress=!0;let t=e?`${e.scope}/${e.value}`:null,n=e?e.type_aware:Object.values(b.rulesByCategory).flat().some(e=>e.isActive&&e.type_aware===!0);b.message=`Linting`,t&&(b.message+=` [${t}]`),n&&(b.message+=` with --type-aware`),b.message+=`...`,b.messageType=`info`,g();let i=o===`win32`?`npx.cmd`:`npx`,a=[`-q`,`--yes`,`--package`,`oxlint@${v}`];n&&a.push(`--package`,`oxlint-tsgolint@0.11.4`),a.push(`--`,`oxlint`),n&&a.push(`--type-aware`),t&&a.push(`-A`,`all`,`-D`,t);let s=r(i,a),c=``,l=``;s.stdout.on(`data`,e=>{c+=e}),s.stderr.on(`data`,e=>{l+=e}),s.on(`close`,e=>{b.isLintInProgress=!1;let n=(c+l).match(/Found (\d+) warnings? and (\d+) errors?/i);if(n){let e=parseInt(n[2]);b.message=t?`[${t}] Found ${e} issue${e===1?``:`s`}`:n[0],b.messageType=e>0?`error`:`warn`}else if(c.toLowerCase().includes(`finished`)||e===0&&c.length<200)b.message=`Linting passed! 0 issues found.`,t&&(b.message=`[${t}] ${b.message}`),b.messageType=`success`;else{let e=l.split(`
|
|
259
|
-
`).filter(e=>!e.includes(`experimental`)&&!e.includes(`Breaking changes`)&&e.trim()!==``).join(` `);b.message=e?`Error: ${e.substring(0,50)}...`:`Lint failed`,b.messageType=`error`}g()})}function C(e){if(!e)return;let{categories:t,rulesByCategory:n,selectedCategoryIndex:r,selectedRuleIndex:i,activePane:o}=b,s=t[r],l=n[s]||[],u=c.rows-8,d=u-7;switch(e.type){case`EXIT`:j(),a(0);return;case`RUN_LINT`:S();return;case`RUN_SINGLE_RULE`:{let e=l[i];e&&S({rule:e});return}case`OPEN_DOCS`:if(o===1){let e=l[i];e&&O(e.docs_url||e.url)}return;case`SET_STATUS`:{if(o!==1||!e.value)return;let t=l[i];if(!t)return;x(t,e.value);let r=[...l];r[i]={...t,configStatus:e.value,isActive:e.value===`error`||e.value===`warn`},b={...b,message:`Rule '${t.value}' set to: ${e.value}`,messageType:`info`,rulesByCategory:{...n,[s]:r}},g();return}case`MOVE_RIGHT`:o!==1&&(b={...b,activePane:o+1},g());return;case`MOVE_LEFT`:o!==0&&(b={...b,activePane:o-1},g());return;case`MOVE_UP`:if(o===0){let e=r===0?t.length-1:r-1;b={...b,selectedCategoryIndex:e,selectedRuleIndex:0,ruleScroll:0,categoryScroll:D(e,b.categoryScroll,d)}}else if(o===1){let e=i===0?l.length-1:i-1;b={...b,selectedRuleIndex:e,ruleScroll:D(e,b.ruleScroll,u)}}g();return;case`MOVE_DOWN`:if(o===0){let e=r===t.length-1?0:r+1;b={...b,selectedCategoryIndex:e,selectedRuleIndex:0,ruleScroll:0,categoryScroll:D(e,b.categoryScroll,d)}}else if(o===1){let e=i===l.length-1?0:i+1;b={...b,selectedRuleIndex:e,ruleScroll:D(e,b.ruleScroll,u)}}g();return}}function w(e,t,n){if(n.rules){let t=n.rules[e];if(t===void 0){let r=Object.keys(n.rules).find(t=>t.endsWith(`/${e}`));r&&(t=n.rules[r])}if(t!==void 0)return Array.isArray(t)?t[0]:t}return n.categories&&n.categories[t]?n.categories[t]:`off`}function T(e){return e.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g,(e,t)=>t?``:e)}function E(){let t=[],r={rules:{},categories:{}},o=null,s=_;s||(b.message=`Error: Couldn't find description.`,b.messageType=`error`);try{let e=n(`npx -q --yes oxlint@${v} --rules --format=json`,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]});t=JSON.parse(e)}catch{b.message=`Error: Couldn't run 'npx oxlint'.`,b.messageType=`error`,a(1)}let c=i[2];if(c&&e.existsSync(c)?o=c:e.existsSync(`.oxlintrc.json`)&&(o=`.oxlintrc.json`),o)try{r=JSON.parse(T(e.readFileSync(o,`utf8`)))}catch{b.message=`Error: Couldn't parse config.`,b.messageType=`error`}let l={};return t.forEach(e=>{let t=e.category||`Uncategorized`;l[t]||(l[t]=[]);let n=w(e.value,t,r),i=s[e.scope]?.[e.value];l[t].push({...e,description:i,configStatus:n,isActive:n===`error`||n===`warn`})}),{categories:Object.keys(l).toSorted(),rulesByCategory:l,config:r,configPath:o}}function D(e,t,n){return e<t?e:e>=t+n?e-n+1:t}function O(e){e&&r(o===`darwin`?`open`:o===`win32`?`explorer`:`xdg-open`,[e],{detached:!0,stdio:`ignore`}).unref()}const k=e=>c.write(e),A=()=>k(`\x1B[?1049h\x1B[?25l`),j=()=>k(`\x1B[?1049l\x1B[?25h`);t.emitKeypressEvents(s),s.isTTY&&s.setRawMode(!0),s.on(`keypress`,(e,t)=>{C(y[t.name]||(t.ctrl&&t.name===`c`?{type:`EXIT`}:y[t.sequence]||null))}),c.on(`resize`,g),A(),g();export{b as state};
|
|
2
|
+
import e from"node:fs";import t from"node:zlib";import{fileURLToPath as n}from"node:url";import r from"node:path";import i from"readline";import{execSync as a,spawn as o}from"node:child_process";import{argv as s,exit as c,platform as l,stdin as u,stdout as d}from"node:process";const f={reset:`\x1B[0m`,dim:`\x1B[38;5;242m`,highlight:`\x1B[38;5;111m`,selectedBg:`\x1B[48;5;24m\x1B[38;5;255m\x1B[1m`,borderActive:`\x1B[38;5;111m`,borderInactive:`\x1B[38;5;237m`,error:`\x1B[38;5;203m`,warn:`\x1B[38;5;215m`,success:`\x1B[38;5;114m`,info:`\x1B[38;5;75m`};function p(e,t){if(!e)return[];let n=Math.ceil(e.length/t),r=Array(n);for(let i=0;i<n;i++)r[i]=e.substring(i*t,(i+1)*t);return r}function m(e,t,n,r,i,a,o,s,c,l){let u=l?f.borderActive:f.borderInactive,d=`${u}┌─ ${a.length>r-6?a.substring(0,r-7)+`…`:a} `.padEnd(r+u.length-1,`─`);e.push(`\x1b[${n};${t}H${d}┐${f.reset}`);for(let a=1;a<i-1;a++)e.push(`\x1b[${n+a};${t}H${u}│${` `.repeat(r-2)}│${f.reset}`);e.push(`\x1b[${n+i-1};${t}H${u}└${`─`.repeat(r-2)}┘${f.reset}`);let p=i-2;o.slice(c,c+p).forEach((i,a)=>{let o=c+a,u=typeof i!=`string`,d=u?i.value:i,p=d.length>r-4?d.substring(0,r-5)+`…`:d.padEnd(r-4),m=f.dim;if(u){let e=i;e.configStatus===`error`?m=f.error:e.configStatus===`warn`?m=f.warn:e.isActive&&(m=f.success)}e.push(`\x1b[${n+1+a};${t+2}H`),o===s?e.push(l?`${f.selectedBg}${p}${f.reset}`:`${f.dim}\x1b[7m${p}${f.reset}`):e.push(`${m}${p}${f.reset}`)})}function h(e,t,n,r,i,a){let o=f.borderInactive,s=`${o}┌─ STATS `.padEnd(r+o.length-1,`─`);e.push(`\x1b[${n};${t}H${s}┐${f.reset}`);for(let a=1;a<i-1;a++)e.push(`\x1b[${n+a};${t}H${o}│${` `.repeat(r-2)}│${f.reset}`);e.push(`\x1b[${n+i-1};${t}H${o}└${`─`.repeat(r-2)}┘${f.reset}`);let c={error:0,warn:0,off:0};a.forEach(e=>{e.configStatus===`error`?c.error++:e.configStatus===`warn`?c.warn++:c.off++}),[{label:`Error`,count:c.error,color:f.error},{label:`Warn`,count:c.warn,color:f.warn},{label:`Off`,count:c.off,color:f.dim}].forEach((a,o)=>{if(o<i-2){let i=String(a.count).padStart(3),s=a.label.padEnd(r-8);e.push(`\x1b[${n+1+o};${t+2}H${a.color}${s}${i}${f.reset}`)}})}function g(e,t,n,r,i,a,o){let s=o?f.borderActive:f.borderInactive,c=`${s}┌─ DETAILS `.padEnd(r+s.length-1,`─`);e.push(`\x1b[${n};${t}H${c}┐${f.reset}`);for(let a=1;a<i-1;a++)e.push(`\x1b[${n+a};${t}H${s}│${` `.repeat(r-2)}│${f.reset}`);if(e.push(`\x1b[${n+i-1};${t}H${s}└${`─`.repeat(r-2)}┘${f.reset}`),!a)return;let l=a.configStatus.toUpperCase();l=a.configStatus===`error`?`${f.error}${l}${f.reset}`:a.configStatus===`warn`?`${f.warn}${l}${f.reset}`:`${f.dim}${l}${f.reset}`;let u=[[`Name`,a.value],[`Status`,l],[`Category`,a.category],[`Scope`,a.scope],[`Fix`,a.fix||`N/A`],[`Default`,a.default?`Yes`:`No`],[`Type-aware`,a.type_aware?`Yes`:`No`]],d=0;u.forEach(([r,a])=>{d<i-2&&(e.push(`\x1b[${n+1+d};${t+2}H${f.highlight}${r.padEnd(12)} ${f.reset}${a}`),d++)}),d<i-3&&d++,d<i-2&&(e.push(`\x1b[${n+1+d};${t+2}H${f.reset}Description:${f.reset}`),d++,p((a.description??`N/A`).replace(/\s+/g,` `).trim(),r-6).forEach(r=>{d<i-2&&(e.push(`\x1b[${n+1+d};${t+2}H${f.dim}${r}${f.reset}`),d++)}));let m=Math.max(d+1,i-3);m<i-1&&e.push(`\x1b[${n+1+m};${t+2}HHit ${f.highlight}ENTER${f.reset} to open docs`)}function _(e,t,n){return e<t?e:e>=t+n?e-n+1:t}function v(){if(!w||!w.categories)return;let{columns:e=80,rows:t=24}=d,n=w.categories[w.selectedCategoryIndex],r=w.rulesByCategory[n]||[],i=r[w.selectedRuleIndex],a=t-5,o=Math.floor(e*.2),s=Math.floor(e*.3),c=e-o-s-2,l=a-6,u=[`\x1B[H\x1B[J`];m(u,1,1,o,l,`CATEGORIES`,w.categories,w.selectedCategoryIndex,w.categoryScroll,w.activePane===0),h(u,1,1+l,o,6,r),m(u,o+1,1,s,a,`RULES (${r.length})`,r,w.selectedRuleIndex,w.ruleScroll,w.activePane===1),g(u,o+s+1,1,c,a,i,w.activePane===2);let p=f[w.messageType]||f.reset;u.push(`\x1b[${t-3};2H${p}● ${w.message}${f.reset}`);let _=w.configPath?`Config: ${w.configPath}`:`No config loaded`;u.push(`\x1b[${t-1};2H${f.dim}Arrows/HJKL: Nav | 1-3: Status | R: Lint | X: Run rule | Enter: Docs | Q: Quit | ${_}${f.reset}`),d.write(u.join(``))}const y=`1.42.0`,b={k:{type:`MOVE_UP`},up:{type:`MOVE_UP`},down:{type:`MOVE_DOWN`},j:{type:`MOVE_DOWN`},left:{type:`MOVE_LEFT`},h:{type:`MOVE_LEFT`},right:{type:`MOVE_RIGHT`},l:{type:`MOVE_RIGHT`},return:{type:`OPEN_DOCS`},enter:{type:`OPEN_DOCS`},1:{type:`SET_STATUS`,value:`off`},2:{type:`SET_STATUS`,value:`warn`},3:{type:`SET_STATUS`,value:`error`},q:{type:`EXIT`},r:{type:`RUN_LINT`},x:{type:`RUN_SINGLE_RULE`}},x=r.dirname(n(import.meta.url));function S(){let n=r.join(x,`rule-descriptions.br`);if(e.existsSync(n))return JSON.parse(t.brotliDecompressSync(e.readFileSync(n)).toString())}const C=S();let w={activePane:0,selectedCategoryIndex:0,selectedRuleIndex:0,categoryScroll:0,ruleScroll:0,isLintInProgress:!1,message:`oxlint-tui`,messageType:`dim`,...A()};function T(e,t){w.config||={rules:{}},w.config.rules||(w.config.rules={});try{let n=e.value,r=e.scope===`oxc2`||e.scope===`eslint`?n:`${e.scope}/${n}`,i=w.config.rules,a=Object.keys(i).find(e=>e===r||e===n||e.endsWith(`/${n}`))||r;i[a]=t}catch{w.message=`Failed to update internal state`,w.messageType=`error`}}function E({rule:e=null}={}){if(w.isLintInProgress)return;w.isLintInProgress=!0;let t=e?`${e.scope}/${e.value}`:null,n=e?e.type_aware:Object.values(w.rulesByCategory).flat().some(e=>e.isActive&&e.type_aware===!0);w.message=`Linting`,t&&(w.message+=` [${t}]`),n&&(w.message+=` with --type-aware`),w.message+=`...`,w.messageType=`info`,v();let r=l===`win32`?`npx.cmd`:`npx`,i=[`-q`,`--yes`,`--package`,`oxlint@${y}`];n&&i.push(`--package`,`oxlint-tsgolint@0.11.4`),i.push(`--`,`oxlint`),n&&i.push(`--type-aware`),t?i.push(`-A`,`all`,`-D`,t):w.config&&w.config.rules&&Object.entries(w.config.rules).forEach(([e,t])=>{let n=Array.isArray(t)?t[0]:t;n===`error`?i.push(`-D`,e):n===`warn`?i.push(`-W`,e):n===`off`&&i.push(`-A`,e)});let a=o(r,i),s=``,c=``;a.stdout.on(`data`,e=>{s+=e}),a.stderr.on(`data`,e=>{c+=e}),a.on(`close`,e=>{w.isLintInProgress=!1;let n=(s+c).match(/Found (\d+) warnings? and (\d+) errors?/i);if(n){let e=parseInt(n[2]);w.message=t?`[${t}] Found ${e} issue${e===1?``:`s`}`:n[0],w.messageType=e>0?`error`:`warn`}else if(s.toLowerCase().includes(`finished`)||e===0&&s.length<200)w.message=`Linting passed! 0 issues found.`,t&&(w.message=`[${t}] ${w.message}`),w.messageType=`success`;else{let e=c.split(`
|
|
3
|
+
`).filter(e=>!e.includes(`experimental`)&&!e.includes(`Breaking changes`)&&e.trim()!==``).join(` `);w.message=e?`Error: ${e.substring(0,50)}...`:`Lint failed`,w.messageType=`error`}v()})}function D(e){if(!e)return;let{categories:t,rulesByCategory:n,selectedCategoryIndex:r,selectedRuleIndex:i,activePane:a}=w,o=t[r],s=n[o]||[],l=d.rows-8,u=l-7;switch(e.type){case`EXIT`:P(),c(0);return;case`RUN_LINT`:E();return;case`RUN_SINGLE_RULE`:{let e=s[i];e&&E({rule:e});return}case`OPEN_DOCS`:if(a===1){let e=s[i];e&&j(e.docs_url||e.url)}return;case`SET_STATUS`:{if(a!==1||!e.value)return;let t=s[i];if(!t)return;T(t,e.value);let r=[...s];r[i]={...t,configStatus:e.value,isActive:e.value===`error`||e.value===`warn`},w={...w,message:`Rule '${t.value}' set to: ${e.value}`,messageType:`info`,rulesByCategory:{...n,[o]:r}},v();return}case`MOVE_RIGHT`:a!==1&&(w={...w,activePane:a+1},v());return;case`MOVE_LEFT`:a!==0&&(w={...w,activePane:a-1},v());return;case`MOVE_UP`:if(a===0){let e=r===0?t.length-1:r-1;w={...w,selectedCategoryIndex:e,selectedRuleIndex:0,ruleScroll:0,categoryScroll:_(e,w.categoryScroll,u)}}else if(a===1){let e=i===0?s.length-1:i-1;w={...w,selectedRuleIndex:e,ruleScroll:_(e,w.ruleScroll,l)}}v();return;case`MOVE_DOWN`:if(a===0){let e=r===t.length-1?0:r+1;w={...w,selectedCategoryIndex:e,selectedRuleIndex:0,ruleScroll:0,categoryScroll:_(e,w.categoryScroll,u)}}else if(a===1){let e=i===s.length-1?0:i+1;w={...w,selectedRuleIndex:e,ruleScroll:_(e,w.ruleScroll,l)}}v();return}}function O(e,t,n){if(n.rules){let t=n.rules[e];if(t===void 0){let r=Object.keys(n.rules).find(t=>t.endsWith(`/${e}`));r&&(t=n.rules[r])}if(t!==void 0)return Array.isArray(t)?t[0]:t}return n.categories&&n.categories[t]?n.categories[t]:`off`}function k(e){return e.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g,(e,t)=>t?``:e)}function A(){let t=[],n={rules:{},categories:{}},r=null,i=C;i||(w.message=`Error: Couldn't find description.`,w.messageType=`error`);try{let e=a(`npx -q --yes oxlint@${y} --rules --format=json`,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]});t=JSON.parse(e)}catch{w.message=`Error: Couldn't run 'npx oxlint'.`,w.messageType=`error`,c(1)}let o=s[2];if(o&&e.existsSync(o)?r=o:e.existsSync(`.oxlintrc.json`)&&(r=`.oxlintrc.json`),r)try{n=JSON.parse(k(e.readFileSync(r,`utf8`)))}catch{w.message=`Error: Couldn't parse config.`,w.messageType=`error`}let l={};return t.forEach(e=>{let t=e.category||`Uncategorized`;l[t]||(l[t]=[]);let r=O(e.value,t,n),a=i[e.scope]?.[e.value];l[t].push({...e,description:a,configStatus:r,isActive:r===`error`||r===`warn`})}),{categories:Object.keys(l).toSorted(),rulesByCategory:l,config:n,configPath:r}}function j(e){e&&o(l===`darwin`?`open`:l===`win32`?`explorer`:`xdg-open`,[e],{detached:!0,stdio:`ignore`}).unref()}const M=e=>d.write(e),N=()=>M(`\x1B[?1049h\x1B[?25l`),P=()=>M(`\x1B[?1049l\x1B[?25h`);i.emitKeypressEvents(u),u.isTTY&&u.setRawMode(!0),u.on(`keypress`,(e,t)=>{D(b[t.name]||(t.ctrl&&t.name===`c`?{type:`EXIT`}:b[t.sequence]||null))}),d.on(`resize`,v),N(),v();export{w as state};
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oxlint-tui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A Node TUI Oxlint rules and configuration browser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -21,21 +21,21 @@
|
|
|
21
21
|
"type": "module",
|
|
22
22
|
"scripts": {
|
|
23
23
|
"prepare": "husky",
|
|
24
|
-
"dev": "tsx src/index.ts
|
|
25
|
-
"gen": "tsx scripts/generate-rule-descriptions.ts",
|
|
24
|
+
"dev": "tsx src/index.ts",
|
|
26
25
|
"lint": "oxlint --type-aware --format=stylish",
|
|
27
26
|
"type-check": "tsgo --noEmit",
|
|
28
27
|
"format": "oxfmt",
|
|
29
28
|
"format-check": "oxfmt --check",
|
|
30
|
-
"
|
|
31
|
-
"build
|
|
29
|
+
"gen": "tsx scripts/generate-rule-descriptions.ts",
|
|
30
|
+
"build": "tsdown && cp src/rule-descriptions.br dist/",
|
|
31
|
+
"build-run": "npm run gen && npm run build && node dist/index.mjs"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/node": "25.
|
|
35
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
34
|
+
"@types/node": "25.2.0",
|
|
35
|
+
"@typescript/native-preview": "7.0.0-dev.20260202.1",
|
|
36
36
|
"husky": "9.1.7",
|
|
37
|
-
"oxfmt": "0.
|
|
38
|
-
"oxlint": "1.
|
|
37
|
+
"oxfmt": "0.28.0",
|
|
38
|
+
"oxlint": "1.43.0",
|
|
39
39
|
"oxlint-tsgolint": "0.11.4",
|
|
40
40
|
"tsdown": "0.20.1",
|
|
41
41
|
"tsx": "4.21.0",
|