Skip to content

Commit 8e6c7dc

Browse files
committed
Upgrade to MM eslint-config-* v15 + ESLint 9
The ESLint configuration is behind for this package. Keeping up to date with our current lint rules and lint config format helps to debug issues with ESLint now and in the future, and aligns this repo with our other repos. A list of changes: - Upgrade `@metamask/eslint-config` and `@metamask/eslint-config-*` packages to 15.0.0 - Upgrade ESLint to 9.x - Upgrade TypeScript ESLint packages to 8.25.x - Upgrade other ESLint packages to fulfill peer dependencies - Fix lint violations as a result of the upgrade Note that the rules for `jsdoc/require-jsdoc` have been refined. In performing this upgrade, many violations appeared that I thought didn't help readability.
1 parent 7d5f2c8 commit 8e6c7dc

53 files changed

Lines changed: 1951 additions & 1756 deletions

Some content is hidden

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

.eslintrc.cjs

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

babel.config.cjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module.exports = {
44
env: {
55
test: {
66
presets: ['@babel/preset-env', '@babel/preset-typescript'],
7-
plugins: ['@babel/plugin-transform-modules-commonjs']
8-
}
9-
}
7+
plugins: ['@babel/plugin-transform-modules-commonjs'],
8+
},
9+
},
1010
};

bin/create-release-branch.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#!/usr/bin/env node
2-
/* eslint-disable import/extensions */
32

4-
// eslint-disable-next-line import/no-unassigned-import, import/no-unresolved
3+
// Three things:
4+
// - This file doesn't export anything, as it's a script.
5+
// - We are using a `.js` extension because that's what appears in `dist/`.
6+
// - This file will only exist after running `yarn build`. We don't want
7+
// developers or CI to receive a lint error if the script has not been run.
8+
// (A warning will appear if the script *has* been run, but that is okay.)
9+
// eslint-disable-next-line import-x/no-unassigned-import, import-x/extensions, import-x/no-unresolved
510
import '../dist/cli.js';

eslint.config.mjs

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import base, { createConfig } from '@metamask/eslint-config';
2+
import jest from '@metamask/eslint-config-jest';
3+
import nodejs from '@metamask/eslint-config-nodejs';
4+
import typescript from '@metamask/eslint-config-typescript';
5+
6+
const config = createConfig([
7+
{
8+
ignores: ['dist/', 'docs/', '.yarn/'],
9+
},
10+
11+
{
12+
extends: base,
13+
14+
languageOptions: {
15+
sourceType: 'module',
16+
parserOptions: {
17+
tsconfigRootDir: import.meta.dirname,
18+
},
19+
},
20+
21+
rules: {
22+
// Consider copying this to @metamask/eslint-config
23+
'jsdoc/require-jsdoc': [
24+
'error',
25+
{
26+
require: {
27+
// Classes
28+
ClassDeclaration: true,
29+
// Function declarations
30+
FunctionDeclaration: true,
31+
// Methods
32+
MethodDefinition: true,
33+
},
34+
contexts: [
35+
// Type interfaces that are not defined within `declare` blocks
36+
':not(TSModuleBlock) > TSInterfaceDeclaration',
37+
// Type aliases
38+
'TSTypeAliasDeclaration',
39+
// Enums
40+
'TSEnumDeclaration',
41+
// Arrow functions that are not contained within plain objects or
42+
// are not arguments to functions or methods
43+
':not(Property, NewExpression, CallExpression) > ArrowFunctionExpression',
44+
// Function expressions that are not contained within plain objects
45+
// or are not arguments to functions or methods
46+
':not(Property, NewExpression, CallExpression) > FunctionExpression',
47+
// Exported variables at the root
48+
'ExportNamedDeclaration:has(> VariableDeclaration)',
49+
],
50+
},
51+
],
52+
// Consider copying this to @metamask/eslint-config
53+
'jsdoc/no-blank-blocks': 'error',
54+
},
55+
56+
settings: {
57+
'import-x/extensions': ['.js', '.mjs'],
58+
},
59+
},
60+
61+
{
62+
files: ['**/*.ts'],
63+
extends: typescript,
64+
rules: {
65+
// Consider copying this to @metamask/eslint-config
66+
'@typescript-eslint/explicit-function-return-type': [
67+
'error',
68+
{
69+
allowExpressions: true,
70+
},
71+
],
72+
// Consider copying this to @metamask/eslint-config
73+
'jsdoc/require-jsdoc': [
74+
'error',
75+
{
76+
require: {
77+
// Classes
78+
ClassDeclaration: true,
79+
// Function declarations
80+
FunctionDeclaration: true,
81+
// Methods
82+
MethodDefinition: true,
83+
},
84+
contexts: [
85+
// Type interfaces that are not defined within `declare` blocks
86+
':not(TSModuleBlock) > TSInterfaceDeclaration',
87+
// Type aliases
88+
'TSTypeAliasDeclaration',
89+
// Enums
90+
'TSEnumDeclaration',
91+
// Arrow functions that are not contained within plain objects or
92+
// are not arguments to functions or methods
93+
':not(Property, NewExpression, CallExpression) > ArrowFunctionExpression',
94+
// Function expressions that are not contained within plain objects
95+
// or are not arguments to functions or methods
96+
':not(Property, NewExpression, CallExpression) > FunctionExpression',
97+
// Exported variables at the root
98+
'ExportNamedDeclaration:has(> VariableDeclaration)',
99+
],
100+
},
101+
],
102+
// Consider copying this to @metamask/eslint-config
103+
'jsdoc/no-blank-blocks': 'error',
104+
},
105+
},
106+
107+
{
108+
files: ['**/*.js', '**/*.cjs', '**/*.ts', '**/*.test.ts', '**/*.test.js'],
109+
ignores: ['src/ui/**'],
110+
extends: nodejs,
111+
},
112+
113+
{
114+
files: ['**/*.test.ts'],
115+
extends: jest,
116+
},
117+
118+
// List this last to override any settings inherited from plugins,
119+
// especially `eslint-config-n`, which mistakenly assumes that all `.cjs`
120+
// files are modules (since we specified `type: module` in `package.json`)
121+
{
122+
files: ['**/*.js', '**/*.cjs'],
123+
// This *is* a script, but is written using ESM.
124+
ignores: ['bin/create-release-branch.js'],
125+
languageOptions: {
126+
sourceType: 'script',
127+
},
128+
},
129+
]);
130+
131+
export default config;

package.json

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"build:ui": "vite build",
1919
"build:clean": "rimraf dist && yarn build",
2020
"lint": "yarn lint:eslint && yarn lint:misc --check",
21-
"lint:eslint": "eslint . --cache --ext js,ts",
21+
"lint:eslint": "eslint .",
2222
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
2323
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern",
2424
"prepack": "./scripts/prepack.sh",
@@ -46,10 +46,10 @@
4646
"@babel/preset-env": "^7.23.5",
4747
"@babel/preset-typescript": "^7.23.3",
4848
"@lavamoat/allow-scripts": "^3.1.0",
49-
"@metamask/eslint-config": "^10.0.0",
50-
"@metamask/eslint-config-jest": "^10.0.0",
51-
"@metamask/eslint-config-nodejs": "^10.0.0",
52-
"@metamask/eslint-config-typescript": "^10.0.0",
49+
"@metamask/eslint-config": "^15.0.0",
50+
"@metamask/eslint-config-jest": "^15.0.0",
51+
"@metamask/eslint-config-nodejs": "^15.0.0",
52+
"@metamask/eslint-config-typescript": "^15.0.0",
5353
"@tailwindcss/vite": "^4.0.9",
5454
"@types/debug": "^4.1.7",
5555
"@types/express": "^5.0.0",
@@ -63,18 +63,21 @@
6363
"@types/validate-npm-package-name": "^4.0.2",
6464
"@types/which": "^3.0.0",
6565
"@types/yargs": "^17.0.10",
66-
"@typescript-eslint/eslint-plugin": "^5.62.0",
67-
"@typescript-eslint/parser": "^5.62.0",
66+
"@typescript-eslint/eslint-plugin": "^8.25.0",
67+
"@typescript-eslint/parser": "^8.25.0",
6868
"@vitejs/plugin-react": "^4.3.4",
6969
"babel-jest": "^29.7.0",
7070
"deepmerge": "^4.2.2",
71-
"eslint": "^8.27.0",
71+
"eslint": "^9.21.0",
7272
"eslint-config-prettier": "^9.1.0",
73-
"eslint-plugin-import": "^2.26.0",
74-
"eslint-plugin-jest": "^26.9.0",
75-
"eslint-plugin-jsdoc": "^39.6.2",
73+
"eslint-import-resolver-typescript": "^3.8.3",
74+
"eslint-plugin-import-x": "^4.6.1",
75+
"eslint-plugin-jest": "^28.11.0",
76+
"eslint-plugin-jsdoc": "^50.6.3",
77+
"eslint-plugin-n": "^17.15.1",
7678
"eslint-plugin-node": "^11.1.0",
7779
"eslint-plugin-prettier": "^5.2.1",
80+
"eslint-plugin-promise": "^7.2.1",
7881
"jest": "^29.7.0",
7982
"jest-it-up": "^3.0.0",
8083
"jest-when": "^3.5.2",
@@ -89,6 +92,7 @@
8992
"tailwindcss": "^4.0.9",
9093
"tsx": "^4.6.1",
9194
"typescript": "~5.1.6",
95+
"typescript-eslint": "^8.49.0",
9296
"vite": "^6.2.0"
9397
},
9498
"peerDependencies": {
@@ -106,7 +110,8 @@
106110
"allowScripts": {
107111
"@lavamoat/preinstall-always-fail": false,
108112
"tsx>esbuild": false,
109-
"vite>esbuild": false
113+
"vite>esbuild": false,
114+
"eslint-plugin-import-x>unrs-resolver": false
110115
}
111116
}
112117
}

src/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { main } from './main.js';
33
/**
44
* The entrypoint to this tool.
55
*/
6-
async function cli() {
6+
async function cli(): Promise<void> {
77
await main({
88
argv: process.argv,
99
cwd: process.cwd(),

src/command-line-arguments.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import yargs from 'yargs/yargs';
21
import { hideBin } from 'yargs/helpers';
2+
import yargs from 'yargs/yargs';
33

4+
/**
5+
* The set of positional and named arguments that can be passed to this tool.
6+
*/
47
export type CommandLineArguments = {
58
projectDirectory: string;
69
tempDirectory: string | undefined;

src/dirname.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
import { fileURLToPath } from 'url';
21
import { dirname } from 'path';
3-
4-
const __filename = fileURLToPath(import.meta.url);
5-
const __dirname = dirname(__filename);
2+
import { fileURLToPath } from 'url';
63

74
/**
85
* Get the current directory path.
96
*
107
* @returns The current directory path.
118
*/
12-
export function getCurrentDirectoryPath() {
13-
return __dirname;
9+
export function getCurrentDirectoryPath(): string {
10+
return dirname(fileURLToPath(import.meta.url));
1411
}

src/editor.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { when } from 'jest-when';
2+
23
import { determineEditor } from './editor.js';
34
import * as envModule from './env.js';
45
import * as miscUtils from './misc-utils.js';

src/editor.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import { getErrorMessage } from '@metamask/utils';
2+
13
import { getEnvironmentVariables } from './env.js';
24
import { debug, resolveExecutable } from './misc-utils.js';
35

46
/**
57
* Information about the editor present on the user's computer.
68
*
7-
* @property path - The path to the executable representing the editor.
8-
* @property args - Command-line arguments to pass to the executable when
9-
* calling it.
9+
* Properties:
10+
*
11+
* - `path` - The path to the executable representing the editor.
12+
* - `args` - Command-line arguments to pass to the executable when calling it.
1013
*/
1114
export type Editor = {
1215
path: string;
@@ -31,7 +34,7 @@ export async function determineEditor(): Promise<Editor | null> {
3134
executablePath = await resolveExecutable(EDITOR);
3235
} catch (error) {
3336
debug(
34-
`Could not resolve executable ${EDITOR} (${error}), falling back to VSCode`,
37+
`Could not resolve executable ${EDITOR} (${getErrorMessage(error)}), falling back to VSCode`,
3538
);
3639
}
3740
}
@@ -43,7 +46,7 @@ export async function determineEditor(): Promise<Editor | null> {
4346
executableArgs.push('--wait');
4447
} catch (error) {
4548
debug(
46-
`Could not resolve path to VSCode: ${error}, continuing regardless`,
49+
`Could not resolve path to VSCode: ${getErrorMessage(error)}, continuing regardless`,
4750
);
4851
}
4952
}

0 commit comments

Comments
 (0)