Skip to content

Commit ddf8db7

Browse files
davidkpianowith-heartAndarist
authored
Add eslint (#5097)
* add eslint (#5041) * remove tslint.json * install and configure eslint * resolve lint errors * add eslint to ci-checks * enable eslint type-checked rules * fix type-check errors * add eslint fix commits to .git-blame-ignore-revs * allow empty object types * disable no-unnecessary-type-constraints on specific lines * revert removal of non-conforming type check in actions * resolve lint errors * Update packages/core/src/types.ts Co-authored-by: Mateusz Burzyński <[email protected]> * Update packages/core/src/types.ts Co-authored-by: Mateusz Burzyński <[email protected]> * Update packages/xstate-inspect/src/server.ts Co-authored-by: Mateusz Burzyński <[email protected]> --------- Co-authored-by: David Khourshid <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> * Fix lint issues --------- Co-authored-by: with-heart <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]>
1 parent 7b8a100 commit ddf8db7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1119
-588
lines changed

.git-blame-ignore-revs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
71183da18ae6b0b6b2e8f0c52ea9976232e54f41
33
94037fe9c429839f0508ddcd287718b659276e3b
44
f51bf4d8907307ace083a0decb34668176c7fad3
5+
6+
# lint fixes
7+
8bff3b8ad57516e9816278b77ff5e0fffafd85ca
8+
aeec38a6ef56bb534ff8bc968b95107ff54959cc

.github/actions/ci-checks/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ runs:
66
run: pnpm build
77
shell: bash
88

9+
- name: ESLint
10+
run: pnpm lint --no-cache
11+
shell: bash
12+
913
- name: Typecheck
1014
run: pnpm typecheck
1115
shell: bash

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# eslint
2+
.eslintcache
3+
14
# Logs
25
logs
36
*.log

babel.config.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
const { NODE_ENV } = process.env;
2-
const isTest = NODE_ENV === 'test';
3-
41
module.exports = {
52
assumptions: {
63
constantReexports: true, // only matters for tests (since only there we transpile to CJS using Babel), it makes debugging easier

eslint.config.mjs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// @ts-check
2+
import globals from 'globals';
3+
import js from '@eslint/js';
4+
import ts from 'typescript-eslint';
5+
6+
export default ts.config(
7+
// plugins
8+
js.configs.recommended,
9+
...ts.configs.recommendedTypeChecked,
10+
11+
// global ignore
12+
{
13+
ignores: [
14+
'{docs,examples,templates}/',
15+
'**/dist',
16+
'**/*.test.*',
17+
'scripts/jest-utils/'
18+
]
19+
},
20+
21+
// global language and linter options
22+
{
23+
languageOptions: {
24+
globals: { ...globals.browser, ...globals.node },
25+
parserOptions: {
26+
projectService: true,
27+
tsconfigRootDir: import.meta.dirname
28+
}
29+
},
30+
linterOptions: {
31+
reportUnusedDisableDirectives: 'error'
32+
}
33+
},
34+
35+
// global rule overrides
36+
{
37+
rules: {
38+
'@typescript-eslint/no-empty-object-type': [
39+
'error',
40+
{
41+
allowInterfaces: 'with-single-extends',
42+
allowObjectTypes: 'always'
43+
}
44+
],
45+
'@typescript-eslint/no-explicit-any': 'off',
46+
'@typescript-eslint/no-unsafe-argument': 'off',
47+
'@typescript-eslint/no-unsafe-assignment': 'off',
48+
'@typescript-eslint/no-unsafe-call': 'off',
49+
'@typescript-eslint/no-unsafe-member-access': 'off',
50+
'@typescript-eslint/no-unsafe-return': 'off',
51+
'@typescript-eslint/no-unused-vars': [
52+
'error',
53+
{
54+
args: 'all',
55+
argsIgnorePattern: '^_',
56+
caughtErrors: 'all',
57+
caughtErrorsIgnorePattern: '^_',
58+
destructuredArrayIgnorePattern: '^_',
59+
varsIgnorePattern: '^_',
60+
ignoreRestSiblings: true
61+
}
62+
],
63+
'@typescript-eslint/unbound-method': 'off',
64+
'@typescript-eslint/no-redundant-type-constituents': 'off',
65+
'prefer-const': [
66+
'error',
67+
{
68+
destructuring: 'all'
69+
}
70+
]
71+
}
72+
},
73+
74+
// disable type-checking for js files
75+
{
76+
files: ['**/*.{js,cjs,mjs}'],
77+
...ts.configs.disableTypeChecked
78+
},
79+
80+
// js-specific config and rules
81+
{
82+
files: ['**/*.{js,cjs}'],
83+
languageOptions: {
84+
sourceType: 'commonjs'
85+
},
86+
rules: {
87+
'@typescript-eslint/no-require-imports': 'off'
88+
}
89+
}
90+
);

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"postinstall": "manypkg check && preconstruct dev",
2828
"build": "preconstruct build",
2929
"fix": "manypkg fix",
30+
"lint": "eslint --cache --quiet",
3031
"typecheck": "tsc",
3132
"test": "jest",
3233
"test:core": "jest packages/core",
@@ -52,6 +53,7 @@
5253
"@babel/preset-typescript": "^7.23.3",
5354
"@changesets/changelog-github": "^0.4.8",
5455
"@changesets/cli": "^2.26.2",
56+
"@eslint/js": "^9.7.0",
5557
"@jest/types": "^29.6.3",
5658
"@manypkg/cli": "^0.21.4",
5759
"@preconstruct/cli": "^2.8.1",
@@ -62,6 +64,8 @@
6264
"@vue/vue3-jest": "^29.2.6",
6365
"babel-jest": "^29.7.0",
6466
"babel-preset-solid": "^1.8.4",
67+
"eslint": "^9.7.0",
68+
"globals": "^15.8.0",
6569
"husky": "^3.1.0",
6670
"jest": "^29.7.0",
6771
"jest-config": "^29.7.0",
@@ -76,6 +80,7 @@
7680
"svelte-jester": "^2.3.2",
7781
"synckit": "^0.8.5",
7882
"typescript": "^5.6.2",
83+
"typescript-eslint": "^8.0.1",
7984
"vue": "^3.0.11"
8085
},
8186
"husky": {

packages/core/src/SimulatedClock.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Clock } from './system.ts';
22

3+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
34
export interface SimulatedClock extends Clock {
45
start(speed: number): void;
56
increment(ms: number): void;
@@ -11,6 +12,7 @@ interface SimulatedTimeout {
1112
timeout: number;
1213
fn: (...args: any[]) => void;
1314
}
15+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1416
export class SimulatedClock implements SimulatedClock {
1517
private timeouts: Map<number, SimulatedTimeout> = new Map();
1618
private _now: number = 0;

packages/core/src/State.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ import type {
1919
MetaObject,
2020
StateSchema,
2121
StateId,
22-
SnapshotStatus,
23-
SnapshotFrom
22+
SnapshotStatus
2423
} from './types.ts';
2524
import { matchesState } from './utils.ts';
2625

@@ -37,10 +36,7 @@ type ToTestStateValue<TStateValue extends StateValue> =
3736
>;
3837
};
3938

40-
export function isMachineSnapshot<
41-
TContext extends MachineContext,
42-
TEvent extends EventObject
43-
>(value: unknown): value is AnyMachineSnapshot {
39+
export function isMachineSnapshot(value: unknown): value is AnyMachineSnapshot {
4440
return (
4541
!!value &&
4642
typeof value === 'object' &&

packages/core/src/StateMachine.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export class StateMachine<
9595
public implementations: MachineImplementationsSimplified<TContext, TEvent>;
9696

9797
/** @internal */
98-
public __xstatenode: true = true;
98+
public __xstatenode = true as const;
9999

100100
/** @internal */
101101
public idMap: Map<string, StateNode<TContext, TEvent>> = new Map();
@@ -559,8 +559,7 @@ export class StateMachine<
559559
> = (snapshot as any).children;
560560

561561
Object.keys(snapshotChildren).forEach((actorId) => {
562-
const actorData =
563-
snapshotChildren[actorId as keyof typeof snapshotChildren];
562+
const actorData = snapshotChildren[actorId];
564563
const childState = actorData.snapshot;
565564
const src = actorData.src;
566565

@@ -603,7 +602,7 @@ export class StateMachine<
603602
TConfig
604603
>;
605604

606-
let seen = new Set();
605+
const seen = new Set();
607606

608607
function reviveContext(
609608
contextPart: Record<string, unknown>,
@@ -613,7 +612,7 @@ export class StateMachine<
613612
return;
614613
}
615614
seen.add(contextPart);
616-
for (let key in contextPart) {
615+
for (const key in contextPart) {
617616
const value: unknown = contextPart[key];
618617

619618
if (value && typeof value === 'object') {

packages/core/src/StateNode.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export class StateNode<
186186
(stateConfig: AnyStateNodeConfig, key) => {
187187
const stateNode = new StateNode(stateConfig, {
188188
_parent: this,
189-
_key: key as string,
189+
_key: key,
190190
_machine: this.machine
191191
});
192192
return stateNode;
@@ -247,9 +247,9 @@ export class StateNode<
247247
eventType: null as any,
248248
reenter: false,
249249
toJSON: () => ({
250-
target: this.initial!.target!.map((t) => `#${t.id}`),
250+
target: this.initial.target.map((t) => `#${t.id}`),
251251
source: `#${this.id}`,
252-
actions: this.initial!.actions.map(toSerializableAction),
252+
actions: this.initial.actions.map(toSerializableAction),
253253
eventType: null as any
254254
})
255255
}

0 commit comments

Comments
 (0)