Skip to content

Commit f762106

Browse files
feat!: ESLint v9 support
- Replaced experimental-utils with utils - Fixed prefer-composition notUnsubscribed not including name in error message - Copied over relevant eslint-etc and tsutils-etc helpers - Replaced mocha with vitest - Build with tsup - Installed ESLint v9, rewrote config, ran auto-fix - Changed all rules to a named export - Added RxJS to peerDependencies (optional) - Added code coverage requirement to PRs
1 parent d49d4b8 commit f762106

30 files changed

+2796
-2177
lines changed

.eslintrc.json

Lines changed: 0 additions & 13 deletions
This file was deleted.

.github/workflows/ci.yml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ concurrency:
88
group: '${{ github.workflow }} - ${{ github.head_ref || github.ref }}'
99
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
1010

11+
permissions:
12+
contents: read
13+
pull-requests: write
14+
1115
jobs:
1216

1317
check:
@@ -25,17 +29,28 @@ jobs:
2529
uses: actions/setup-node@v4
2630
with:
2731
node-version: ${{ matrix.node-version }}
32+
- name: Setup LCOV
33+
uses: hrishikesh-kadam/setup-lcov@v1
2834
- name: Setup Yarn
2935
run: corepack enable
3036

3137
- name: Install Packages
3238
run: yarn install
3339

3440
- name: Type Check
35-
run: yarn dist:build
41+
run: yarn typecheck
3642

3743
- name: Lint
3844
run: yarn lint
3945

40-
- name: Test
41-
run: yarn test
46+
- name: Test Coverage
47+
run: yarn coverage
48+
49+
- name: Report Coverage
50+
if: ${{ matrix.node-version == 22 && github.event_name == 'pull_request' }}
51+
uses: zgosalvez/github-actions-report-lcov@v4
52+
with:
53+
coverage-files: coverage/lcov.info
54+
minimum-coverage: 50
55+
github-token: ${{ secrets.GITHUB_TOKEN }}
56+
update-comment: true

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"editor.codeActionsOnSave": {
3+
"source.fixAll.eslint": "explicit"
4+
},
5+
}

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,20 @@
33
## Unreleased
44

55
Initial release.
6+
7+
### Breaking Changes
8+
9+
- `eslint` ^8.57.0 || 9.0.0 is required
10+
- `typescript-eslint` ^8 is required
11+
- TypeScript >=4.8.4 is required
12+
- `tslib` ^2.1.0 is required
13+
- Node.js ^18.18.0 || ^20.9.0 || >= 21.1.0 is required
14+
15+
### Chores
16+
17+
- drop dependency `eslint-etc`
18+
- drop dependency `requireindex`
19+
- drop dependency `tsutils` and `tsutils-etc`, add dependency `ts-api-utils`
20+
- add `rxjs` >= 7.2.0 as optional peer dependency
21+
- add `requiresTypeChecking` to `meta.docs` of relevant rules
22+
- switch from mocha to vitest

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ We recommend you use the VS Code plugins for ESLint.
3636

3737
### Testing
3838

39+
Use `yarn test` to run the tests in watch mode.
40+
We use [vitest](https://vitest.dev) for unit testing.
41+
3942
All unit tests must pass for a pull request to be accepted.
43+
We also enforce code coverage, which you can check with `yarn coverage --coverage.reporter text`.
4044

4145
## Pull Request
4246

eslint.config.mjs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// @ts-check
2+
import js from '@eslint/js';
3+
import stylistic from '@stylistic/eslint-plugin';
4+
import gitignore from 'eslint-config-flat-gitignore';
5+
import importX from 'eslint-plugin-import-x';
6+
import n from 'eslint-plugin-n';
7+
import tseslint from 'typescript-eslint';
8+
import vitest from '@vitest/eslint-plugin';
9+
import eslintPlugin from 'eslint-plugin-eslint-plugin';
10+
11+
/** @type {import('@typescript-eslint/utils').TSESLint.FlatConfig.Config} */
12+
// @ts-expect-error -- eslint-plugin does not provide types.
13+
const eslintPluginConfig = eslintPlugin.configs['flat/recommended'];
14+
15+
export default tseslint.config(gitignore(), {
16+
files: [
17+
'src/**/*.ts',
18+
'tests/**/*.ts',
19+
],
20+
extends: [
21+
js.configs.recommended,
22+
...tseslint.configs.strictTypeChecked,
23+
...tseslint.configs.stylisticTypeChecked,
24+
stylistic.configs['disable-legacy'],
25+
stylistic.configs.customize({
26+
flat: true,
27+
quotes: 'single',
28+
indent: 2,
29+
semi: true,
30+
jsx: false,
31+
braceStyle: '1tbs',
32+
commaDangle: 'always-multiline',
33+
}),
34+
n.configs['flat/recommended-module'],
35+
importX.flatConfigs.recommended,
36+
importX.flatConfigs.typescript,
37+
eslintPluginConfig,
38+
],
39+
languageOptions: {
40+
parserOptions: {
41+
projectService: true,
42+
},
43+
},
44+
rules: {
45+
'@stylistic/arrow-parens': 'off',
46+
'@stylistic/multiline-ternary': 'off',
47+
48+
'sort-imports': [
49+
'warn',
50+
{
51+
ignoreCase: true,
52+
ignoreDeclarationSort: true,
53+
},
54+
],
55+
'import-x/order': [
56+
'warn',
57+
{
58+
alphabetize: {
59+
order: 'asc',
60+
orderImportKind: 'asc',
61+
caseInsensitive: true,
62+
},
63+
},
64+
],
65+
66+
'import-x/no-named-as-default-member': 'off',
67+
68+
'n/no-missing-import': 'off',
69+
70+
'eslint-plugin/require-meta-docs-description': [
71+
'error',
72+
{
73+
pattern: '^(Enforce|Require|Disallow)',
74+
},
75+
],
76+
'eslint-plugin/prefer-placeholders': 'error',
77+
'eslint-plugin/require-meta-schema-description': 'error',
78+
79+
'@typescript-eslint/no-unnecessary-condition': 'off',
80+
'@typescript-eslint/restrict-template-expressions': [
81+
'error',
82+
{
83+
allowNumber: true,
84+
allowBoolean: true,
85+
allowAny: true,
86+
allowNullish: true,
87+
allowRegExp: true,
88+
allowNever: true,
89+
},
90+
],
91+
'@typescript-eslint/no-unused-vars': [
92+
'error',
93+
{
94+
vars: 'all',
95+
varsIgnorePattern: '^_',
96+
args: 'after-used',
97+
argsIgnorePattern: '^_',
98+
},
99+
],
100+
},
101+
}, {
102+
files: [
103+
'tests/**/*.ts',
104+
],
105+
extends: [
106+
vitest.configs.recommended,
107+
],
108+
});

package.json

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,52 +22,70 @@
2222
"angular"
2323
],
2424
"sideEffects": false,
25+
"exports": {
26+
".": {
27+
"import": {
28+
"types": "./dist/index.d.mts",
29+
"default": "./dist/index.mjs"
30+
},
31+
"require": {
32+
"types": "./dist/index.d.ts",
33+
"default": "./dist/index.js"
34+
}
35+
}
36+
},
2537
"main": "./dist/index.js",
38+
"module": "./dist/index.mjs",
39+
"types": "./dist/index.d.ts",
2640
"files": [
2741
"dist",
2842
"docs"
2943
],
3044
"scripts": {
31-
"dist": "yarn run lint && yarn run dist:build",
32-
"dist:build": "yarn run dist:clean && tsc -p tsconfig-dist.json",
33-
"dist:clean": "rimraf dist",
34-
"lint": "eslint src/**/*.ts tests/**/*.ts",
35-
"prepublishOnly": "yarn run test && yarn run dist",
36-
"prettier": "prettier --write \"./{src,tests}/**/*.{js,json,ts,tsx}\"",
37-
"prettier:ci": "prettier --check \"./{src,tests}/**/*.{js,json,ts,tsx}\"",
38-
"test": "yarn run test:rules",
39-
"test:debug": "mocha -r ts-node/register -t 5000 tests/rules/prefer-async-pipe.test.ts",
40-
"test:rules": "mocha -r ts-node/register -t 5000 tests/rules/*.test.ts"
45+
"build": "tsup",
46+
"lint": "yarn lint-js",
47+
"lint-js": "eslint",
48+
"test": "vitest",
49+
"coverage": "vitest run --coverage",
50+
"typecheck": "tsc --noEmit"
4151
},
4252
"dependencies": {
43-
"@typescript-eslint/experimental-utils": "^5.0.0",
53+
"@typescript-eslint/utils": "^8.19.1",
4454
"common-tags": "^1.8.0",
45-
"eslint-etc": "^5.0.0",
46-
"requireindex": "~1.2.0",
47-
"tslib": "^2.0.0"
55+
"ts-api-utils": "^2.0.0",
56+
"tslib": "^2.1.0"
4857
},
4958
"peerDependencies": {
50-
"eslint": "^8.0.0",
51-
"typescript": "^4.0.0 || ^5.0.0"
59+
"eslint": "^8.57.0 || ^9.0.0",
60+
"rxjs": ">=7.2.0",
61+
"typescript": ">=4.8.4"
62+
},
63+
"peerDependenciesMeta": {
64+
"rxjs": {
65+
"optional": true
66+
}
5267
},
5368
"devDependencies": {
54-
"@cartant/eslint-config": "^3.0.0",
55-
"@types/chai": "^4.2.0",
56-
"@types/common-tags": "^1.8.0",
57-
"@types/eslint": "^8.0.0",
58-
"@types/mocha": "^9.0.0",
59-
"@types/node": "^18.0.0",
60-
"@typescript-eslint/parser": "^5.0.0",
61-
"chai": "^4.2.0",
62-
"eslint": "^8.0.0",
63-
"lint-staged": "^13.0.0",
64-
"mocha": "^9.0.0",
65-
"prettier": "^2.0.0",
66-
"rimraf": "^3.0.0",
67-
"ts-node": "^10.0.0",
68-
"typescript": "~4.7.4"
69+
"@eslint/js": "^9.19.0",
70+
"@stylistic/eslint-plugin": "^3.0.0",
71+
"@types/common-tags": "^1.8.4",
72+
"@types/node": "~18.18.0",
73+
"@typescript-eslint/rule-tester": "^8.22.0",
74+
"@vitest/coverage-v8": "^3.0.4",
75+
"@vitest/eslint-plugin": "^1.1.25",
76+
"eslint": "^9.19.0",
77+
"eslint-config-flat-gitignore": "^1.0.0",
78+
"eslint-import-resolver-typescript": "^3.7.0",
79+
"eslint-plugin-eslint-plugin": "^6.4.0",
80+
"eslint-plugin-import-x": "^4.6.1",
81+
"eslint-plugin-n": "^17.15.1",
82+
"rxjs": "^7.8.1",
83+
"tsup": "^8.3.6",
84+
"typescript": "~5.7.3",
85+
"typescript-eslint": "^8.22.0",
86+
"vitest": "^3.0.4"
6987
},
7088
"engines": {
71-
"node": ">=18.0.0"
89+
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
7290
}
7391
}

0 commit comments

Comments
 (0)