A comprehensive utility library for developing ESLint plugins. This package provides a collection of helper functions for AST manipulation, node checking, code fixing, and TypeScript annotation handling.
npm install @axetroy/eslint-utils- Checker Utilities: Functions to check and validate AST nodes
- Fixer Utilities: Functions to fix and transform code
- AST Utilities: Functions to work with Abstract Syntax Trees
- Annotation Utilities: Functions to handle TypeScript annotations
Check if a node is a function call with the given target name.
Parameters:
node(Node): The AST node to checktarget(string): The function name or member expression (e.g., 'foo', 'bar.foo', '*.foo')options(object, optional):argCount(number): Exact number of argumentsminArgCount(number): Minimum number of argumentsmaxArgCount(number): Maximum number of arguments
Returns: boolean
Examples:
import { isFunctionCall } from '@axetroy/eslint-utils';
isFunctionCall(node, 'foo', { argCount: 2 }) // true if node is `foo(1, 2)`
isFunctionCall(node, 'bar.foo') // true if node is `bar.foo()`
isFunctionCall(node, 'foo', { minArgCount: 2 }) // true if node is `foo(1, 2, 3)`
isFunctionCall(node, 'foo', { maxArgCount: 2 }) // true if node is `foo(1)` or `foo(1, 2)`
isFunctionCall(node, '*.foo') // true if node is `bar.foo()` or `baz.foo()`Determine whether a node is in a control flow position (if, while, for, switch, etc.).
Parameters:
node(Node): The AST node to check
Returns: boolean
Example:
import { isInControlFlow } from '@axetroy/eslint-utils';
// Returns true for nodes in positions like:
// if (node) { ... }
// while (node) { ... }
// for (; node; ) { ... }Compare two AST nodes for equality by structure and value. Ignores location properties (loc, start, end, parent, range).
Parameters:
node1(Node): The first AST nodenode2(Node): The second AST node
Returns: boolean
Example:
import { isNodeEqual } from '@axetroy/eslint-utils';
const node1 = { type: 'Identifier', name: 'foo' };
const node2 = { type: 'Identifier', name: 'foo' };
isNodeEqual(node1, node2); // trueCheck if a node is a literal value or literal constructor call.
Parameters:
node(Node): The AST node to check
Returns: boolean
Example:
import { isLiteral } from '@axetroy/eslint-utils';
// Returns true for:
// - Literal nodes: 'string', 123, true
// - Constructor calls: Boolean(true), String('text'), Number(42)
// - New expressions: new Boolean(true), new String('text')Determine whether a node is a Boolean expression.
Parameters:
sourceCode(SourceCode): The ESLint source code objectnode(Expression): The AST node to checkdepth(number, optional): Maximum recursion depth (default: 0, max: 10)
Returns: boolean
Example:
import { isBooleanExpression } from '@axetroy/eslint-utils';
// Returns true for:
// - Boolean literals: true, false
// - Boolean expressions: age > 18, !flag, a && b
// - Boolean functions: Boolean(), Array.isArray()Determine whether a function returns a Boolean value.
Parameters:
sourceCode(SourceCode): The ESLint source code objectnode(Function): The function node to check
Returns: boolean
Replace the text of a given node with new text. Handles special cases for await and yield expressions.
Parameters:
fixer(RuleFixer): The ESLint rule fixersourceCode(SourceCode): The ESLint source code objectnode(Node): The node to replacetext(string): The replacement text
Returns: Generator
Example:
import { replaceText } from '@axetroy/eslint-utils';
context.report({
node,
message: 'Replace with true',
*fix(fixer) {
yield* replaceText(fixer, sourceCode, node, 'true');
}
});Replace a variable name and all its references. Handles exports, shorthand properties, and type annotations.
Parameters:
fixer(RuleFixer): The ESLint rule fixersourceCode(SourceCode): The ESLint source code objectscope(Scope): The scope containing the variableidentifier(Identifier): The identifier node to renamevariableName(string): The new variable name
Returns: Generator
Example:
import { replaceVariableName } from '@axetroy/eslint-utils';
context.report({
node,
message: 'Rename variable to newName',
*fix(fixer) {
yield* replaceVariableName(fixer, sourceCode, scope, identifier, 'newName');
}
});Insert or update an import declaration.
Parameters:
fixer(RuleFixer): The ESLint rule fixersourceCode(SourceCode): The ESLint source code objectspecifier(object):default(string, optional): Default import namenamespaces(string[], optional): Named imports
source(string): The module source
Returns: Generator
Example:
import { insertImportDeclaration } from '@axetroy/eslint-utils';
context.report({
node,
message: 'Add missing import',
*fix(fixer) {
yield* insertImportDeclaration(
fixer,
sourceCode,
{ default: 'React', namespaces: ['useState', 'useEffect'] },
'react'
);
}
});Get the text of a node. Handles special cases like SequenceExpression.
Parameters:
sourceCode(SourceCode): The ESLint source code objectnode(Node): The AST node
Returns: string
Example:
import { getText } from '@axetroy/eslint-utils';
const text = getText(sourceCode, node);
console.log(text); // "foo(bar, baz)"Check if a TypeScript annotation is a Boolean type.
Parameters:
annotation(Node): The type annotation node
Returns: boolean
Example:
import { isBooleanAnnotation } from '@axetroy/eslint-utils';
// Returns true for TypeScript types:
// - boolean
// - Boolean
// Supports both @typescript-eslint/parser and babel-eslint9Here's a complete example of an ESLint rule using these utilities:
import {
isFunctionCall,
isBooleanExpression,
replaceText,
getText
} from '@axetroy/eslint-utils';
module.exports = {
meta: {
type: 'suggestion',
fixable: 'code',
},
create(context) {
const sourceCode = context.getSourceCode();
return {
CallExpression(node) {
if (isFunctionCall(node, 'Boolean', { argCount: 1 })) {
const arg = node.arguments[0];
if (isBooleanExpression(sourceCode, arg)) {
context.report({
node,
message: 'Unnecessary Boolean() call',
*fix(fixer) {
const text = getText(sourceCode, arg);
yield* replaceText(fixer, sourceCode, node, text);
}
});
}
}
}
};
}
};This package includes TypeScript definitions for all exported functions.
import type { Node } from 'estree';
import type { SourceCode, Rule, Scope } from 'eslint';
import { isFunctionCall, replaceVariableName } from '@axetroy/eslint-utils';The Anti-996 License