Skip to content

Commit 0aaf686

Browse files
committed
v6.1.6 - disable no-unpublished-import, fix tsconfig, fix package.json config
1 parent 1f32bfc commit 0aaf686

File tree

5 files changed

+95
-52
lines changed

5 files changed

+95
-52
lines changed

HISTORY.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
# History
22

3-
## v6.1.5 2025 August 8
3+
## v6.1.6 2025 August 13
4+
5+
- Disable `n/no-unpublished-import` completely, as it is broken in general, not just in TypeScript environments
6+
- Fix loading of your `tsconfig` files
7+
- Fix loading of your `package.json` eslint configuration
8+
- Updated dependencies, [base files](https://github.com/bevry/base), and [editions](https://editions.bevry.me) using [boundation](https://github.com/bevry/boundation)
9+
- Thank you to the sponsors: [Andrew Nesbitt](https://nesbitt.io), [Divinci ™](https://divinci.ai), [Mr. Henry](https://mrhenry.be), [Poonacha Medappa](https://poonachamedappa.com), [Roboflow](https://roboflow.com), [Square](https://github.com/square)
10+
11+
## v6.1.5 2025 August 12
412

513
- Renamed the rule extensions for brevity and clarity
614
- Add `eslint-config-bevry/typescript/es5` configuration for TypeScript ES5 targets, which ignores the `@typescript-eslint/prefer-for-of` rule, as it is not supported in ES5
715
- Updated dependencies, [base files](https://github.com/bevry/base), and [editions](https://editions.bevry.me) using [boundation](https://github.com/bevry/boundation)
816
- Thank you to the sponsors: [Andrew Nesbitt](https://nesbitt.io), [Divinci ™](https://divinci.ai), [Mr. Henry](https://mrhenry.be), [Poonacha Medappa](https://poonachamedappa.com), [Roboflow](https://roboflow.com), [Square](https://github.com/square)
917

10-
## v6.1.4 2025 August 8
18+
## v6.1.4 2025 August 12
1119

1220
- Disable potentially useful but broken `n/no-unsupported-features/es-syntax` rule, as it does not respect the `ecmaVersion` setting, and instead prefers to use the Node.js engine version, which is not what we want when using a transpiler, and is disrespectful as our configuration knows better, hence why there is even an `ecmaVersion` setting in the first place, they should rename this rule to `n/no-unsupported-features/node-syntax` as that it what it actually is
1321
- In a future version, we could use [editions](https://editions.bevry.me) to get the highest compatible Node.js version, and configure it for that, as a workaround for this silly behaviour
1422
- Thank you to the sponsors: [Andrew Nesbitt](https://nesbitt.io), [Divinci ™](https://divinci.ai), [Mr. Henry](https://mrhenry.be), [Poonacha Medappa](https://poonachamedappa.com), [Roboflow](https://roboflow.com), [Square](https://github.com/square)
1523

16-
## v6.1.3 2025 August 8
24+
## v6.1.3 2025 August 12
1725

1826
- ECMAScript version handling is now more robust, handling both target and source ecmascript versions
1927
- Our rule customisations are now extensions themselves injected at the appropriate time to better avoid conflicts and redundancies with other plugin rules

package-lock.json

Lines changed: 12 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "eslint-config-bevry",
3-
"version": "6.1.5",
3+
"version": "6.1.6",
44
"license": "Artistic-2.0",
55
"description": "Intelligent, self-configuring ESLint configuration that automatically analyzes your project structure, dependencies, and metadata to apply optimal linting rules for JavaScript, TypeScript, React, Node.js, and more.",
66
"homepage": "https://github.com/bevry/eslint-config-bevry",

source/index.js

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,70 @@ import eslintJSDoc from 'eslint-plugin-jsdoc'
1414
import babelParser from '@babel/eslint-parser'
1515
import babelPlugin from '@babel/eslint-plugin'
1616

17-
// @ts-ignore
17+
// Our dependencies
1818
import versionClean from 'version-clean'
19+
20+
// Node.js dependencies
1921
import { join } from 'node:path'
2022
import { cwd } from 'node:process'
21-
import { readJSON } from '@bevry/json'
2223

24+
// Local imports
25+
import * as rules from './rules.js'
26+
27+
// Local paths
28+
import { readJSON } from '@bevry/json'
2329
import filedirname from 'filedirname'
2430
const [, dirname] = filedirname()
25-
const root = dirname.endsWith('source') ? join(dirname, '..') : dirname // on CI dirname is: /home/runner/work/eslint-config-bevry/eslint-config-bevry/source
26-
const pwd = cwd()
27-
28-
import * as rules from './rules.js'
29-
const { IGNORE } = rules
31+
const bevryRootPath = join(dirname, '..')
32+
const userRootPath = cwd()
33+
const bevryPackagePath = join(bevryRootPath, 'package.json')
34+
const userPackagePath = join(userRootPath, 'package.json')
3035

3136
// ------------------------------------
3237
// Prepare
3338

39+
/**
40+
* Error thrown when a dependency that should be inlined is found in the user's package.json
41+
*/
3442
class InlinedError extends Error {
43+
/**
44+
* Creates an InlinedError instance
45+
* @param {string} dependency - The name of the dependency that is now inlined
46+
*/
3547
constructor(dependency) {
3648
super(
3749
`the development dependency ${dependency} is now inlined within eslint-config-bevry\nrun: npm uninstall --save-dev ${dependency}`,
3850
)
3951
}
4052
}
4153

42-
const bevryPackage = await readJSON(join(root, 'package.json'))
43-
const pkg = {}
44-
try {
45-
Object.assign(pkg, await readJSON(join(pwd, 'package.json')))
46-
} catch (err) {} // eslint-disable-line
54+
/**
55+
* Reads a JSON file, returning an empty object if reading failed.
56+
* @param {string} path - The path to the JSON file to read
57+
* @param {object} [fallback] - The fallback value to return if reading fails
58+
* @returns {Promise<object>} The parsed JSON object or the fallback value
59+
*/
60+
function readJSONFallback(path, fallback = {}) {
61+
return readJSON(path).catch(() => fallback)
62+
}
63+
64+
const bevryPackage = await readJSON(bevryPackagePath)
65+
const userPackage = await readJSONFallback(userPackagePath)
4766

4867
// https://eslint.org/docs/latest/use/configure/configuration-files#configuration-objects
4968
/** @type {import('eslint').Linter.Config} */
5069
const config = {
5170
name: bevryPackage.name,
5271
// version: bevryPackage.version,
53-
files: pkg.eslintConfig?.files || [],
72+
files: userPackage.eslintConfig?.files || [],
5473
// don't use ignores, as it doesn't help us with matched patterns from extended configurations, instead use globalIgnores
5574
extends: [
5675
globalIgnores([
5776
// '**/*.d.ts', <-- now that we fixed the rules that conflict with typescript with v6.1.1, ignoring these isn't necessary anymore
5877
'**/vendor/',
5978
'**/node_modules/',
6079
'**/edition-*/',
61-
...(pkg.eslintConfig?.ignores || []),
80+
...(userPackage.eslintConfig?.ignores || []),
6281
]),
6382
rules.jsBefore,
6483
eslintJS.configs.recommended,
@@ -107,7 +126,7 @@ function hasDep(name) {
107126
* @throws {InlinedError} if any of the specified dependencies are present
108127
*/
109128
function inlinedDeps(...names) {
110-
if (pkg.name === 'eslint-config-bevry') return
129+
if (userPackage.name === 'eslint-config-bevry') return
111130
for (const name of names) {
112131
if (hasDep(name)) {
113132
throw new InlinedError(name)
@@ -116,15 +135,19 @@ function inlinedDeps(...names) {
116135
}
117136

118137
// Load the dependencies and versions
119-
Object.assign(deps, pkg.dependencies || {}, pkg.devDependencies || {})
138+
Object.assign(
139+
deps,
140+
userPackage.dependencies || {},
141+
userPackage.devDependencies || {},
142+
)
120143
Object.keys(deps).forEach((name) => {
121144
const range = deps[name]
122145
const version = versionClean(range) || null // resolve to null in case of github references
123146
versions[name] = version
124147
})
125148

126149
// extract some common items
127-
const keywords = pkg.keywords || []
150+
const keywords = userPackage.keywords || []
128151

129152
// ------------------------------------
130153
// Deprecations
@@ -188,9 +211,9 @@ let sourceType = 'script',
188211
typescript = hasDep('typescript'),
189212
babel = hasDep('@babel/core'),
190213
jsx = false
191-
const prettier = Boolean(pkg.prettier) || hasDep('prettier'),
192-
browser = Boolean(pkg.browser) || keywords.includes('browser'),
193-
node = Boolean(pkg.engines?.node) || keywords.includes('node'),
214+
const prettier = Boolean(userPackage.prettier) || hasDep('prettier'),
215+
browser = Boolean(userPackage.browser) || keywords.includes('browser'),
216+
node = Boolean(userPackage.engines?.node) || keywords.includes('node'),
194217
worker =
195218
keywords.includes('worker') ||
196219
keywords.includes('workers') ||
@@ -201,7 +224,8 @@ const prettier = Boolean(pkg.prettier) || hasDep('prettier'),
201224

202225
/**
203226
* Ensure the ecmascript version is coerced to an eslint valid ecmascript version
204-
* @param version
227+
* @param {string} [version] - The version string to coerce (e.g., 'esnext', 'latest', '2020')
228+
* @returns {string|number} The coerced version as a string or number, or empty string if invalid
205229
*/
206230
function coerceEcmascriptVersion(version = '') {
207231
if (version === 'esnext' || version === 'latest' || version === 'next') {
@@ -221,14 +245,14 @@ function coerceEcmascriptVersion(version = '') {
221245
}
222246

223247
// editions
224-
if (pkg.editions) {
225-
const sourceEdition = pkg.editions[0]
248+
if (userPackage.editions) {
249+
const sourceEdition = userPackage.editions[0]
226250
const sourceEditionTags = sourceEdition.tags || sourceEdition.syntaxes || []
227251
const ecmascriptVersionTag = coerceEcmascriptVersion(
228252
sourceEditionTags.find((tag) => tag.startsWith('es')),
229253
)
230254
const ecmascriptVersionEngine = coerceEcmascriptVersion(
231-
pkg.engines?.ecmascript,
255+
userPackage.engines?.ecmascript,
232256
)
233257
ecmascriptVersionSource =
234258
ecmascriptVersionTag || ecmascriptVersionEngine || ecmascriptNextVersion
@@ -323,12 +347,6 @@ if (node) {
323347
// https://github.com/eslint-community/eslint-plugin-n#-configs
324348
if (sourceType === 'module') {
325349
config.extends.push(eslintNode.configs['flat/recommended-module'])
326-
if (typescript) {
327-
Object.assign(config.rules, {
328-
// This result is broken for TypeScript projects, as in TypeScript you do `import thing from file.js` instead of `file.ts`, as it is about the resultant file, not the source file; TypeScript handles this correctly, however this rule does not
329-
'n/no-unpublished-import': IGNORE,
330-
})
331-
}
332350
} else {
333351
config.extends.push(eslintNode.configs['flat/recommended-script'])
334352
}
@@ -370,7 +388,7 @@ if (babel) {
370388
if (typescript) {
371389
Object.assign(config.languageOptions.parserOptions, {
372390
projectService: true,
373-
tsconfigRootDir: root,
391+
tsconfigRootDir: userRootPath,
374392
})
375393
config.extends.push(
376394
// https://typescript-eslint.io/users/configs
@@ -422,10 +440,10 @@ if (ecmascriptVersionSource <= 5) {
422440
}
423441

424442
// user rules overrides
425-
if (pkg.eslintConfig?.rules) {
426-
Object.extends.push({
443+
if (userPackage.eslintConfig?.rules) {
444+
config.extends.push({
427445
name: 'eslint-config-bevry/package-json',
428-
rules: pkg.eslintConfig.rules,
446+
rules: userPackage.eslintConfig.rules,
429447
})
430448
}
431449

source/rules.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
/** ESLint rule severity level for ignoring/disabling a rule */
12
export const IGNORE = 0
3+
/** ESLint rule severity level for warnings */
24
export const WARN = 1
5+
/** ESLint rule severity level for errors */
36
export const ERROR = 2
7+
/** Maximum number of parameters allowed in functions */
48
export const MAX_PARAMS = 4
59

610
// ============================================================================
711
// Rules intended to be overwrote by ESLint Recommended
812
// https://unpkg.com/@eslint/js@9/src/configs/eslint-recommended.js
913

14+
/** ESLint configuration for JavaScript rules that will be overridden by ESLint recommended */
1015
export const jsBefore = {
1116
name: 'eslint-config-bevry/js/before',
1217
rules: {
@@ -200,6 +205,7 @@ export const jsBefore = {
200205
// Rules intended to overwrite ESLint Recommended
201206
// https://unpkg.com/@eslint/js@9/src/configs/eslint-recommended.js
202207

208+
/** ESLint configuration for JavaScript rules that override ESLint recommended */
203209
export const jsAfter = {
204210
name: 'eslint-config-bevry/js/after',
205211
rules: {
@@ -1070,7 +1076,7 @@ export const jsAfter = {
10701076
// ============================================================================
10711077
// Adjustments
10721078

1073-
// These are adjustments based on the source ecmascript version, as the transpiler handles them
1079+
/** ESLint configuration adjustments for ES5 compatibility - transpiler handles these features */
10741080
export const es5 = {
10751081
name: 'eslint-config-bevry/es5',
10761082
rules: {
@@ -1082,6 +1088,7 @@ export const es5 = {
10821088
},
10831089
}
10841090

1091+
/** ESLint configuration for import plugin rules */
10851092
export const importAfter = {
10861093
name: 'eslint-config-bevry/import/after',
10871094
rules: {
@@ -1095,6 +1102,7 @@ export const importAfter = {
10951102
// https://github.com/eslint-community/eslint-plugin-n?tab=readme-ov-file#-rules
10961103
// https://github.com/eslint-community/eslint-plugin-n/blob/master/lib/all-rules.js
10971104
// None of these should be set by the recommended configs
1105+
/** ESLint configuration for Node.js plugin rules */
10981106
export const nodeAfter = {
10991107
name: 'eslint-config-bevry/node/after',
11001108
rules: {
@@ -1142,9 +1150,15 @@ export const nodeAfter = {
11421150
// https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-sync.md
11431151
// Sometimes sync methods are useful, so warn but don't error
11441152
'n/no-sync': WARN,
1153+
1154+
// https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-unpublished-import.md
1155+
// This result is broken for TypeScript projects, as in TypeScript you do `import thing from file.js` instead of `file.ts`, as it is about the resultant file, not the source file; TypeScript handles this correctly, however this rule does not
1156+
// However, it is also broken for this very project too, which is a JavaScript only project, so it is just broken in general...
1157+
'n/no-unpublished-import': IGNORE,
11451158
},
11461159
}
11471160

1161+
/** ESLint configuration for Node.js projects that use compilation/transpilation */
11481162
export const nodeCompiled = {
11491163
name: 'eslint-config-bevry/node/compiled',
11501164
rules: {
@@ -1154,6 +1168,7 @@ export const nodeCompiled = {
11541168
},
11551169
}
11561170

1171+
/** ESLint configuration for TypeScript projects - rules that override default configs */
11571172
export const typescriptAfter = {
11581173
name: 'eslint-config-bevry/typescript/after',
11591174
rules: {
@@ -1185,21 +1200,22 @@ export const typescriptAfter = {
11851200
},
11861201
}
11871202

1188-
// These are adjustments based on the target ecmascript version, as the transpiler does not handle them
1203+
/** ESLint configuration for TypeScript projects targeting ES5 - transpiler limitations */
11891204
export const typescriptEs5 = {
11901205
name: 'eslint-config-bevry/typescript/es5',
11911206
rules: {
11921207
'@typescript-eslint/prefer-for-of': IGNORE, // came in ES2015
11931208
},
11941209
}
1210+
/** ESLint configuration for TypeScript projects targeting ES2015 - transpiler limitations */
11951211
export const typescriptEs2015 = {
11961212
name: 'eslint-config-bevry/typescript/es2015',
11971213
rules: {
11981214
'@typescript-eslint/prefer-includes': IGNORE, // came in ES2016
11991215
},
12001216
}
12011217

1202-
// allow unsafe types in our test files, as how else are we meant to test that unsafe inputs will be handled correctly?
1218+
/** ESLint configuration for TypeScript test files - allows unsafe types for testing */
12031219
export const typescriptTests = {
12041220
name: 'eslint-config-bevry/typescript/tests',
12051221
files: ['**/test.{js,cjs,mjs,jsx,mjsx,ts,cts,mts,tsx,mtsx}'],

0 commit comments

Comments
 (0)