Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion configs/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ export const reactConfig = {
'react/sort-default-props': 'off',
'react/checked-requires-onchange-or-readonly': 'off',
'react/jsx-props-no-spread-multi': 'error',
'react/forward-ref-uses-ref': 'error',
// Disabled: rule calls removed `context.getSourceCode()` and crashes on ESLint 10.
// Tracked upstream in jsx-eslint/eslint-plugin-react#3977; fix PR #3979 stalled.
// Low cost to leave off — React 19 deprecates `forwardRef` itself.
'react/forward-ref-uses-ref': 'off',

'react-hooks/automatic-effect-dependencies': 'off',
'react-hooks/capitalized-calls': 'off',
Expand Down
25 changes: 14 additions & 11 deletions configs/typescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,24 +370,23 @@ export const typescriptConfig = {
replace: 'readonly $1'
},
{
pattern: '^(Array|Map|Set)<(.+)>$',
replace: 'Readonly$1<$2>'
pattern: '^(\\[.+\\])$',
replace: 'readonly $1'
},
{
pattern: '^(.+)$',
replace: 'Readonly<$1>'
pattern: '^(Map|Set)<(.+)>$',
replace: 'Readonly$1<$2>'
}
]
},
parameters: {
enforcement: 'ReadonlyShallow'
},
returnTypes: {
enforcement: 'ReadonlyShallow'
enforcement: 'None'
},
variables: {
enforcement: 'ReadonlyShallow',
ignoreInFunctions: true
enforcement: 'None'
}
}
],
Expand All @@ -404,12 +403,16 @@ export const typescriptConfig = {
comparator: 'AtLeast',
fixer: [
{
pattern: '^(Array|Map|Set)<(.+)>$',
replace: 'Readonly$1<$2>'
pattern: '^([_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*\\[\\])$',
replace: 'readonly $1'
},
{
pattern: '^(\\[.+\\])$',
replace: 'readonly $1'
},
{
pattern: '^(.+)$',
replace: 'Readonly<$1>'
pattern: '^(Map|Set)<(.+)>$',
replace: 'Readonly$1<$2>'
}
]
}
Expand Down
3 changes: 3 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const codeSpellCheckerRules = {
};

export default [
{
ignores: ['test/fixtures/**']
},
baseConfig,
nodeConfig,
{
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/base-node/clean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function greet(recipient) {
return `Hello, ${recipient}`;
}
200 changes: 200 additions & 0 deletions test/fixtures/base-node/violations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
// TODO: implement properly

import { readFileSync } from 'fs';
import fsDefault from 'fs';
import { readFileSync as readAgain } from 'fs';

var declaredWithVar = 1;
var laterAssigned;
laterAssigned = 2;
console.log(declaredWithVar, laterAssigned, readFileSync, fsDefault, readAgain);

const concatenated = 'hello' + ' ' + 'world';
const big = 10000000;
const ternary = 1 > 0 ? true : false;
const nested = 1 > 0 ? (1 < 2 ? 'a' : 'b') : 'c';
console.log(concatenated, big, ternary, nested);

function looseCheck(value) {
if (value == null) {
return 'null';
}
if (value) {
return 'truthy';
}
return '';
}
looseCheck('');

function compute(n) {
let total = 0;
total = total + n * 7;
total = total | 0;
total++;
return total;
}
compute(2);

function summarize(values) {
let sum = 0;
for (let index = 0; index < values.length; index = index + 1) {
sum = sum + values[index];
}
return sum;
}
summarize([1, 2, 3]);

function tooManyArgs(alpha, beta, gamma, delta, epsilon) {
return alpha + beta + gamma + delta + epsilon;
}
tooManyArgs(1, 2, 3, 4, 5);

function defaultFirst(first = 1, second) {
return first + second;
}
defaultFirst(1, 2);

function noop() {}
noop();

function classify(value) {
switch (value) {
case 'a':
return 'A';
}
return '';
}
classify('a');

function fail() {
throw 'oops';
}

function fetchSomething() {
return Promise.resolve('done');
}
fetchSomething().then(function (value) {
return console.log(value);
});

async function awaiter() {
return (await fetchSomething()).toUpperCase();
}
awaiter();

function risky() {
try {
fail();
} catch (err) {
throw err;
}
}

debugger;

function showUser(name) {
const greeting = 'Hello ' + name + '!';
const hasPrefix = greeting.indexOf('H') !== -1;
const startsWithHello = greeting.substr(0, 5) === 'Hello';
return greeting + (hasPrefix && startsWithHello ? 'yes' : 'no');
}
showUser('world');

function emptyError() {
throw new Error();
}
try {
emptyError();
} catch (err) {
console.log(err);
}

function shadowOuter() {
const value = 1;
function inner() {
const value = 2;
console.log(value);
}
inner();
console.log(value);
}
shadowOuter();

function reassignParam(input) {
input.count = input.count + 1;
}
reassignParam({ count: 0 });

function uselessRename() {
const data = { foo: 'a' };
const { foo: foo } = data;
console.log(foo);
}
uselessRename();

function templateInString() {
return 'value is ${count}';
}
templateInString();

function buildArr() {
return Array.from(new Set([1, 2, 3])).sort();
}
buildArr();

function manyStatements() {
let result = 0;
result = result + 1;
result = result + 1;
result = result + 1;
result = result + 1;
result = result + 1;
result = result + 1;
result = result + 1;
result = result + 1;
result = result + 1;
result = result + 1;
return result;
}
manyStatements();

function deeplyNested(values) {
if (values.length > 0) {
if (values[0] > 0) {
if (values[0] > 1) {
if (values[0] > 2) {
if (values[0] > 3) {
if (values[0] > 4) {
return values[0];
}
}
}
}
}
}
return 0;
}
deeplyNested([5]);

function readEnv() {
return process.env.HOME;
}
readEnv();

function pathJoin() {
return __dirname + '/sub';
}
pathJoin();

function callbackHandler(err, data) {
console.log(data);
return err;
}
callbackHandler(null, 'x');

function legacyBuffer() {
return new Buffer('hello');
}
legacyBuffer();

process.exit(0);
7 changes: 7 additions & 0 deletions test/fixtures/base-typescript-node/clean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type Greeting = {
readonly recipient: string;
};

export function greet(greeting: Greeting): string {
return `Hello, ${greeting.recipient}`;
}
11 changes: 11 additions & 0 deletions test/fixtures/base-typescript-node/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
"noEmit": true
},
"include": ["./**/*.ts"]
}
Loading