Skip to content

Commit 4ad048d

Browse files
committed
chore: update ESLint TypeScript setup and nvm version
- Updated ESLint configuration for better TypeScript support - Add .nvmrc with LTS version (22) to ensure environment consistency This change improves linting reliability and developer setup across environments.
1 parent 4ad796e commit 4ad048d

File tree

13 files changed

+1486
-94
lines changed

13 files changed

+1486
-94
lines changed

.github/workflows/checks.yml

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ on:
77
branches:
88
- main
99

10-
env:
11-
NODE: 16
12-
1310
jobs:
1411
prep:
1512
if: github.event.pull_request.draft == false
@@ -24,10 +21,13 @@ jobs:
2421
- name: Checkout
2522
uses: actions/checkout@v2
2623

27-
- name: Use Node.js ${{ env.NODE }}
24+
- name: Read .nvmrc
25+
run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_ENV
26+
27+
- name: Use Node.js ${{ env.NVMRC }}
2828
uses: actions/setup-node@v1
2929
with:
30-
node-version: ${{ env.NODE }}
30+
node-version: ${{ env.NVMRC }}
3131

3232
- name: Cache node_modules
3333
uses: actions/cache@v2
@@ -47,10 +47,13 @@ jobs:
4747
- name: Checkout
4848
uses: actions/checkout@v2
4949

50-
- name: Use Node.js ${{ env.NODE }}
50+
- name: Read .nvmrc
51+
run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_ENV
52+
53+
- name: Use Node.js ${{ env.NVMRC }}
5154
uses: actions/setup-node@v1
5255
with:
53-
node-version: ${{ env.NODE }}
56+
node-version: ${{ env.NVMRC }}
5457

5558
- name: Cache node_modules
5659
uses: actions/cache@v2
@@ -73,10 +76,13 @@ jobs:
7376
- name: Checkout
7477
uses: actions/checkout@v2
7578

76-
- name: Use Node.js ${{ env.NODE }}
79+
- name: Read .nvmrc
80+
run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_ENV
81+
82+
- name: Use Node.js ${{ env.NVMRC }}
7783
uses: actions/setup-node@v1
7884
with:
79-
node-version: ${{ env.NODE }}
85+
node-version: ${{ env.NVMRC }}
8086

8187
- name: Cache node_modules
8288
uses: actions/cache@v2
@@ -99,10 +105,13 @@ jobs:
99105
- name: Checkout
100106
uses: actions/checkout@v2
101107

102-
- name: Use Node.js ${{ env.NODE }}
108+
- name: Read .nvmrc
109+
run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_ENV
110+
111+
- name: Use Node.js ${{ env.NVMRC }}
103112
uses: actions/setup-node@v1
104113
with:
105-
node-version: ${{ env.NODE }}
114+
node-version: ${{ env.NVMRC }}
106115

107116
- name: Cache node_modules
108117
uses: actions/cache@v2

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22

eslint.config.js

Lines changed: 85 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,102 @@
1-
import js from '@eslint/js';
21
import globals from 'globals';
2+
import js from '@eslint/js';
3+
import tseslint from 'typescript-eslint';
4+
import react from 'eslint-plugin-react';
35
import reactHooks from 'eslint-plugin-react-hooks';
46
import reactRefresh from 'eslint-plugin-react-refresh';
5-
import tseslint from 'typescript-eslint';
7+
import prettier from 'eslint-plugin-prettier/recommended';
68
import { defineConfig, globalIgnores } from 'eslint/config';
7-
import prettierPlugin from 'eslint-plugin-prettier';
8-
import prettierConfig from 'eslint-config-prettier';
9+
10+
const customRules = {
11+
// Helps with cleaning debug statements by erroring on console.
12+
'no-console': 'error',
13+
// It's no longer needed to import React, so this just prevents weird
14+
// errors when you don't.
15+
'react/react-in-jsx-scope': 'off',
16+
// Array indexes as keys should not be used. The occasional time it is
17+
// needed, an ignore can be added.
18+
'react/no-array-index-key': 'error',
19+
// Helps with enforcing rules of hooks. Very helpful to catch wrongly
20+
// placed hooks, like conditional usage.
21+
'react-hooks/rules-of-hooks': 'error',
22+
// Ensure that components are PascalCase
23+
'react/jsx-pascal-case': 'error',
24+
// Force self closing components when there are no children.
25+
// Prevents `<MyComp prop='1'></MyComp>`
26+
'react/self-closing-comp': 'error',
27+
};
928

1029
export default defineConfig([
1130
globalIgnores(['dist', 'node_modules', 'build', 'coverage']),
31+
js.configs.recommended,
32+
react.configs.flat.recommended,
33+
prettier,
34+
// JS/JSX config
1235
{
13-
files: ['**/*.{ts,tsx,js,jsx}'],
14-
extends: [
15-
js.configs.recommended,
16-
tseslint.configs.recommended,
17-
reactHooks.configs['recommended-latest'],
18-
reactRefresh.configs.vite,
19-
prettierConfig,
20-
],
36+
files: ['**/*.{js,jsx,mjs,cjs}'],
37+
languageOptions: {
38+
ecmaVersion: 2020,
39+
globals: { ...globals.browser, process: 'readonly' },
40+
},
41+
settings: { react: { version: 'detect' } },
2142
plugins: {
22-
prettier: prettierPlugin,
43+
react,
44+
'react-hooks': reactHooks,
45+
'react-refresh': reactRefresh,
2346
},
2447
rules: {
25-
...prettierPlugin.configs.recommended.rules,
48+
...customRules,
49+
'no-unused-vars': [
50+
'error',
51+
{
52+
args: 'all',
53+
argsIgnorePattern: '^_',
54+
caughtErrors: 'all',
55+
caughtErrorsIgnorePattern: '^_',
56+
destructuredArrayIgnorePattern: '^_',
57+
varsIgnorePattern: '^_',
58+
ignoreRestSiblings: true,
59+
},
60+
],
2661
},
62+
},
63+
// TS/TSX config
64+
{
65+
files: ['**/*.{ts,tsx}'],
66+
extends: [...tseslint.configs.recommendedTypeChecked],
2767
languageOptions: {
68+
parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname },
2869
ecmaVersion: 2020,
29-
globals: {
30-
...globals.browser,
31-
process: 'readonly',
32-
},
70+
globals: { ...globals.browser, process: 'readonly' },
71+
},
72+
settings: { react: { version: 'detect' } },
73+
plugins: {
74+
...tseslint.plugins,
75+
'react-hooks': reactHooks,
76+
'react-refresh': reactRefresh,
77+
},
78+
rules: {
79+
...customRules,
80+
'@typescript-eslint/no-unused-vars': [
81+
'error',
82+
{
83+
args: 'all',
84+
argsIgnorePattern: '^_',
85+
caughtErrors: 'all',
86+
caughtErrorsIgnorePattern: '^_',
87+
destructuredArrayIgnorePattern: '^_',
88+
varsIgnorePattern: '^_',
89+
ignoreRestSiblings: true,
90+
},
91+
],
92+
// TODO: Consider making these errors in the future (use recommendedTypeChecked rules!).
93+
'@typescript-eslint/no-explicit-any': 'warn',
94+
'@typescript-eslint/no-unsafe-assignment': 'warn',
95+
'@typescript-eslint/no-unsafe-call': 'warn',
96+
'@typescript-eslint/no-unsafe-member-access': 'warn',
97+
'@typescript-eslint/no-unsafe-return': 'warn',
98+
'@typescript-eslint/no-unsafe-argument': 'warn',
99+
'@typescript-eslint/no-unsafe-enum-comparison': 'warn',
33100
},
34101
},
35102
]);

example/package.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@
2323
"test": "react-scripts test",
2424
"eject": "react-scripts eject"
2525
},
26-
"eslintConfig": {
27-
"extends": [
28-
"react-app",
29-
"react-app/jest"
30-
]
31-
},
3226
"browserslist": {
3327
"production": [
3428
">0.2%",

example/src/pages/Main/Map.jsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ function Map({ className, isBboxDrawEnabled, handleDrawComplete, items }) {
7878
map.remove();
7979
}
8080
};
81-
// eslint-disable-next-line react-hooks/exhaustive-deps
8281
}, []);
8382

8483
useEffect(() => {
@@ -110,7 +109,7 @@ Map.propTypes = {
110109
className: T.string,
111110
isBboxDrawEnabled: T.bool,
112111
handleDrawComplete: T.func.isRequired,
113-
item: TItemList,
112+
items: TItemList,
114113
};
115114

116115
export default Map;

example/src/pages/Main/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { useCallback, useState } from 'react';
2-
// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars
2+
// eslint-disable-next-line no-unused-vars
33
import { useStacSearch, useCollections, useStacApi, StacApiProvider } from 'stac-react';
44

55
import ItemList from './ItemList';
66
import Map from './Map';
77
import QueryBuilder from './QueryBuilder';
88

9-
// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars
9+
// eslint-disable-next-line no-unused-vars
1010
const options = {
1111
headers: {
1212
Authorization: 'Basic ' + btoa(process.env.REACT_APP_STAC_API_TOKEN + ':'),

jest.config.cjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
21
module.exports = {
32
preset: 'ts-jest',
43
testEnvironment: 'jsdom',

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
"react-dom": "^19.2.0"
1919
},
2020
"devDependencies": {
21-
"@eslint/js": "^9.38.0",
2221
"@testing-library/dom": "^10.4.1",
2322
"@testing-library/jest-dom": "^6.9.1",
2423
"@testing-library/react": "^16.3.0",
@@ -31,7 +30,8 @@
3130
"eslint": "^9.38.0",
3231
"eslint-config-prettier": "^10.1.8",
3332
"eslint-plugin-prettier": "^5.5.4",
34-
"eslint-plugin-react-hooks": "^5.2.0",
33+
"eslint-plugin-react": "^7.37.5",
34+
"eslint-plugin-react-hooks": "^7.0.0",
3535
"eslint-plugin-react-refresh": "^0.4.24",
3636
"globals": "^16.4.0",
3737
"jest": "^30.2.0",

src/hooks/useItem.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ function useItem(url: string): ItemHook {
3232
addItem(url, r);
3333
resolve(r);
3434
})
35+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
3536
.catch((err: unknown) => reject(err));
3637
}
3738
})
@@ -56,6 +57,7 @@ function useItem(url: string): ItemHook {
5657
addItem(url, r);
5758
resolve(r);
5859
})
60+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
5961
.catch((err: unknown) => reject(err));
6062
}
6163
})

src/hooks/useStacApi.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ function useStacApi(url: string, options?: GenericObject): StacApiHook {
3333
searchMode = SearchMode.POST;
3434
}
3535
})
36-
.then(() => setStacApi(new StacApi(baseUrl, searchMode, options)));
36+
.then(() => setStacApi(new StacApi(baseUrl, searchMode, options)))
37+
.catch((e) => {
38+
// eslint-disable-next-line no-console
39+
console.error('Failed to initialize StacApi:', e);
40+
});
3741
}, [url, options]);
3842

3943
return { stacApi };

0 commit comments

Comments
 (0)