Skip to content

Commit 0c55843

Browse files
committed
feat: target ESLint v9
1 parent c10b2ae commit 0c55843

24 files changed

+173
-88
lines changed

.eslintignore

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

eslint.config.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
const HapiPlugin = require('@hapi/eslint-plugin');
4+
5+
module.exports = [
6+
{
7+
ignores: [
8+
'node_modules/',
9+
'test_runner/',
10+
'test/coverage/',
11+
'test/cli/',
12+
'test/cli_*/',
13+
'test/lint/',
14+
'test/override/',
15+
'test/plan/',
16+
'test/transform/'
17+
]
18+
},
19+
...HapiPlugin.configs.module
20+
];

lib/linter/.eslintrc.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
22

3-
module.exports = {
4-
extends: 'plugin:@hapi/module'
5-
};
3+
const HapiPlugin = require('@hapi/eslint-plugin');
4+
5+
module.exports = [...HapiPlugin.configs.module];

lib/linter/index.js

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const Fs = require('fs');
4-
const Path = require('path');
54

65
const Eslint = require('eslint');
76
const Hoek = require('@hapi/hoek');
@@ -18,31 +17,47 @@ exports.lint = async function () {
1817

1918
const options = process.argv[2] ? JSON.parse(process.argv[2]) : undefined;
2019

21-
if (!Fs.existsSync('.eslintrc.js') &&
22-
!Fs.existsSync('.eslintrc.cjs') && // Needed for projects with "type": "module"
23-
!Fs.existsSync('.eslintrc.yaml') &&
24-
!Fs.existsSync('.eslintrc.yml') &&
25-
!Fs.existsSync('.eslintrc.json') &&
26-
!Fs.existsSync('.eslintrc')) {
27-
configuration.overrideConfigFile = Path.join(__dirname, '.eslintrc.js');
20+
let usingDefault = false;
21+
22+
if (!Fs.existsSync('eslint.config.js') &&
23+
!Fs.existsSync('eslint.config.cjs') &&
24+
!Fs.existsSync('eslint.config.mjs')) {
25+
// No configuration file found, using the default one
26+
usingDefault = true;
27+
configuration.baseConfig = require('./.eslintrc.js');
28+
configuration.overrideConfigFile = true;
2829
}
2930

3031
if (options) {
3132
Hoek.merge(configuration, options, true, false);
3233
}
3334

34-
if (!configuration.extensions) {
35-
configuration.extensions = ['.js', '.cjs', '.mjs'];
35+
// Only the default configuration should be altered, otherwise the user's configuration should be used as is
36+
if (usingDefault) {
37+
if (!configuration.extensions) {
38+
const extensions = ['js', 'cjs', 'mjs'];
39+
40+
if (configuration.typescript) {
41+
extensions.push('ts');
42+
}
3643

37-
if (configuration.typescript) {
38-
configuration.extensions.push('.ts');
44+
configuration.baseConfig.unshift({
45+
files: extensions.map((ext) => `**/*.${ext}`)
46+
});
3947
}
40-
}
4148

42-
if (configuration.typescript) {
43-
delete configuration.typescript;
49+
if (configuration.ignores) {
50+
configuration.baseConfig.unshift({
51+
ignores: configuration.ignores
52+
});
53+
}
4454
}
4555

56+
delete configuration.extensions;
57+
delete configuration.typescript;
58+
delete configuration.ignores;
59+
60+
4661
let results;
4762
try {
4863
const eslint = new Eslint.ESLint(configuration);
@@ -66,6 +81,13 @@ exports.lint = async function () {
6681

6782
transformed.errors = result.messages.map((err) => {
6883

84+
if (err.messageTemplate === 'all-matched-files-ignored') {
85+
return {
86+
severity: 'ERROR',
87+
message: err.message
88+
};
89+
}
90+
6991
return {
7092
line: err.line,
7193
severity: err.severity === 1 ? 'WARNING' : 'ERROR',

lib/modules/coverage.js

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ const SourceMap = require('../source-map');
1616
const Transform = require('./transform');
1717

1818
const internals = {
19-
_state: Symbol.for('@hapi/lab/coverage/_state'),
20-
eslint: new ESLint.ESLint({ baseConfig: Eslintrc })
19+
_state: Symbol.for('@hapi/lab/coverage/_state')
2120
};
2221

2322

@@ -111,7 +110,7 @@ internals.prime = function (extension, ctx) {
111110
require.extensions[extension] = function (localModule, filename) {
112111

113112
// We never want to instrument eslint configs in order to avoid infinite recursion
114-
if (Path.basename(filename, extension) !== '.eslintrc') {
113+
if (!['.eslintrc', 'eslint.config'].includes(Path.basename(filename, extension))) {
115114
for (let i = 0; i < internals.state.patterns.length; ++i) {
116115
if (internals.state.patterns[i].test(filename.replace(/\\/g, '/'))) {
117116
return localModule._compile(internals.instrument(filename, ctx), filename);
@@ -761,11 +760,40 @@ internals.file = async function (filename, data, options) {
761760

762761
internals.context = async (options) => {
763762

763+
const filePath = Path.join(options.coveragePath || '', 'x.js');
764+
let calculated;
765+
764766
// The parserOptions are shared by all files for coverage purposes, based on
765767
// the effective eslint config for a hypothetical file {coveragePath}/x.js
766-
const { parserOptions } = await internals.eslint.calculateConfigForFile(
767-
Path.join(options.coveragePath || '', 'x.js')
768-
);
768+
try {
769+
// Let's try first with eslint's native configuration detection
770+
const eslint = new ESLint.ESLint({
771+
ignore: false
772+
});
773+
774+
calculated = await eslint.calculateConfigForFile(filePath);
775+
}
776+
catch (err) {
777+
/* $lab:coverage:off$ */
778+
if (err.messageTemplate !== 'config-file-missing') {
779+
throw err;
780+
}
781+
782+
// If the eslint config file is missing, we'll use the one provided by lab
783+
const eslint = new ESLint.ESLint({
784+
overrideConfig: Eslintrc,
785+
overrideConfigFile: true,
786+
ignore: false
787+
});
788+
789+
calculated = await eslint.calculateConfigForFile(filePath);
790+
/* $lab:coverage:on$ */
791+
}
792+
793+
const parserOptions = {
794+
...calculated.languageOptions,
795+
...calculated.languageOptions?.parserOptions
796+
};
769797

770798
return { parserOptions };
771799
};

lib/modules/lint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ exports.lint = function (settings) {
2020
try {
2121
linterOptions = JSON.parse(settings['lint-options'] || '{}');
2222
}
23-
catch (err) {
23+
catch {
2424
return reject(new Error('lint-options could not be parsed'));
2525
}
2626

lib/modules/transform.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ exports.retrieveFile = function (path) {
7373
try {
7474
contents = Fs.readFileSync(path, 'utf8');
7575
}
76-
catch (e) {
76+
catch {
7777
contents = null;
7878
}
7979

lib/modules/typescript.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internals.transform = function (content, fileName) {
1414
try {
1515
var { config, error } = Typescript.readConfigFile(configFile, Typescript.sys.readFile);
1616
}
17-
catch (err) {
17+
catch {
1818
throw new Error(`Cannot find a tsconfig file for ${fileName}`);
1919
}
2020

lib/runner.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ const internals = {};
1313

1414
// Prevent libraries like Sinon from clobbering global time functions
1515

16+
/* eslint-disable no-redeclare */
1617
const Date = global.Date;
1718
const setTimeout = global.setTimeout;
1819
const clearTimeout = global.clearTimeout;
1920
const setImmediate = global.setImmediate;
21+
/* eslint-enable no-redeclare */
2022

2123

2224
Error.stackTraceLimit = Infinity; // Set Error stack size

package.json

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,14 @@
1313
"bin/lab",
1414
"lib"
1515
],
16-
"eslintConfig": {
17-
"extends": [
18-
"plugin:@hapi/module"
19-
]
20-
},
2116
"dependencies": {
2217
"@babel/core": "^7.16.0",
23-
"@babel/eslint-parser": "^7.16.0",
18+
"@babel/eslint-parser": "^7.25.1",
2419
"@hapi/bossy": "^6.0.0",
25-
"@hapi/eslint-plugin": "^6.0.0",
20+
"@hapi/eslint-plugin": "^7.0.0",
2621
"@hapi/hoek": "^11.0.2",
2722
"diff": "^5.0.0",
28-
"eslint": "8.x.x",
23+
"eslint": "9.x.x",
2924
"find-rc": "4.x.x",
3025
"globby": "^11.1.0",
3126
"handlebars": "4.x.x",
@@ -37,7 +32,7 @@
3732
"will-call": "1.x.x"
3833
},
3934
"peerDependencies": {
40-
"@hapi/eslint-plugin": "^6.0.0",
35+
"@hapi/eslint-plugin": "^7.0.0",
4136
"typescript": ">=3.6.5"
4237
},
4338
"peerDependenciesMeta": {
@@ -48,13 +43,14 @@
4843
"devDependencies": {
4944
"@hapi/code": "^9.0.0",
5045
"@hapi/somever": "^4.0.0",
46+
"@types/eslint": "^9.6.0",
5147
"@types/node": "^18.11.17",
52-
"@typescript-eslint/parser": "^5.62.0",
5348
"cpr": "3.x.x",
5449
"lab-event-reporter": "1.x.x",
5550
"semver": "7.x.x",
5651
"tsconfig-paths": "^4.0.0",
57-
"typescript": "^4.5.4"
52+
"typescript": "^4.5.4",
53+
"typescript-eslint": "^8.1.0"
5854
},
5955
"bin": {
6056
"lab": "./bin/lab"

0 commit comments

Comments
 (0)