@jeroenpol/eslint-config 2.0.2 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ 2.1.1 / 2026-02-23
2
+ ==================
3
+ - [minor] Add local smoke test (`npm run lint:smoke`) for package-consumer verification
4
+
5
+ 2.1.0 / 2026-02-23
6
+ ==================
7
+ - [minor] Make config easier to consume as a shareable flat config package
8
+ - [minor] Export `best-practices` and `stylistic` subpath entrypoints
9
+ - [minor] Improve README with current ESLint flat-config usage examples
10
+
1
11
  2.0.1 / 2025-03-03
2
12
  ==================
3
13
  - [minor] Only lint files in /src
package/README.md CHANGED
@@ -1,11 +1,62 @@
1
- # Polware eslint-config
1
+ # @jeroenpol/eslint-config
2
2
 
3
- ## Usage
3
+ Shareable ESLint flat config for TypeScript/JavaScript projects.
4
4
 
5
- Use this esLint config as a basis for you Angular projects.
5
+ ## ESLint standard this package follows
6
6
 
7
- ### Installation
7
+ - Uses the ESLint flat config format (`eslint.config.*`).
8
+ - Designed as a shareable config package imported into your project config.
9
+ - Keeps `eslint` as `peerDependencies`.
10
+ - Ships required plugins as package `dependencies` for easier consumer setup.
8
11
 
9
- 1. Install and initialize eslint running the following command:
12
+ ## Install
10
13
 
11
- npm init @eslint/config@latest -- --config @jeroenpol/eslint-config
14
+ ```bash
15
+ npm i -D eslint typescript @jeroenpol/eslint-config
16
+ ```
17
+
18
+ ## Use in another project
19
+
20
+ Create `eslint.config.mjs` in your project root:
21
+
22
+ ```js
23
+ import config from '@jeroenpol/eslint-config';
24
+
25
+ export default config;
26
+ ```
27
+
28
+ ## Override rules in your project
29
+
30
+ ```js
31
+ import config from '@jeroenpol/eslint-config';
32
+
33
+ export default [
34
+ ...config,
35
+ {
36
+ files: ['**/*.ts'],
37
+ rules: {
38
+ '@typescript-eslint/explicit-function-return-type': 'off',
39
+ },
40
+ },
41
+ ];
42
+ ```
43
+
44
+ ## Use only part of the config
45
+
46
+ ```js
47
+ import bestPractices from '@jeroenpol/eslint-config/best-practices';
48
+ import stylistic from '@jeroenpol/eslint-config/stylistic';
49
+
50
+ export default [
51
+ ...bestPractices,
52
+ ...stylistic,
53
+ ];
54
+ ```
55
+
56
+ ## Validate locally (smoke test)
57
+
58
+ Run this in this repository to verify the config can be consumed through its package export:
59
+
60
+ ```bash
61
+ npm run lint:smoke
62
+ ```
@@ -5,146 +5,146 @@ import tseslint from 'typescript-eslint';
5
5
 
6
6
  export default tseslint.config(tseslint.configs.recommendedTypeChecked,
7
7
  {
8
- files: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.js'],
8
+ files: ['**/*.{ts,tsx,js,mjs,cjs}'],
9
9
  plugins: { 'sonarjs': sonarjs, 'simple-import-sort': simpleImportSort, 'unused-imports': unusedImports, '@typescript-eslint': tseslint.plugin },
10
- languageOptions: {
11
- parserOptions: {
12
- projectService: true,
13
- tsconfigRootDir: import.meta.dirname,
10
+ languageOptions: {
11
+ parserOptions: {
12
+ projectService: true,
13
+ tsconfigRootDir: process.cwd(),
14
+ },
14
15
  },
15
- },
16
- rules: {
17
- // GENERAL
18
- 'no-unreachable': 'error',
19
- 'no-debugger': 'error',
20
- 'no-console': 'error',
21
- 'no-empty': 'error',
22
- 'unicode-bom': 'warn',
16
+ rules: {
17
+ // GENERAL
18
+ 'no-unreachable': 'error',
19
+ 'no-debugger': 'error',
20
+ 'no-console': 'error',
21
+ 'no-empty': 'error',
22
+ 'unicode-bom': 'warn',
23
23
 
24
- // NAMING CONVENTIONS
25
- '@typescript-eslint/naming-convention': [
26
- 'warn',
27
- {
28
- selector: 'enum',
29
- format: ['PascalCase'],
30
- },
31
- {
32
- selector: 'enumMember',
33
- format: ['UPPER_CASE'],
34
- },
35
- {
36
- selector: 'interface',
37
- format: ['PascalCase'],
38
- },
39
- ],
24
+ // NAMING CONVENTIONS
25
+ '@typescript-eslint/naming-convention': [
26
+ 'warn',
27
+ {
28
+ selector: 'enum',
29
+ format: ['PascalCase'],
30
+ },
31
+ {
32
+ selector: 'enumMember',
33
+ format: ['UPPER_CASE'],
34
+ },
35
+ {
36
+ selector: 'interface',
37
+ format: ['PascalCase'],
38
+ },
39
+ ],
40
40
 
41
- // CODE COMPLEXITY
42
- 'max-depth': ['error', 8],
43
- 'max-nested-callbacks': ['error', 8],
44
- 'max-statements-per-line': ['error', { max: 1 }],
45
- 'sonarjs/cognitive-complexity': ['error', 15],
41
+ // CODE COMPLEXITY
42
+ 'max-depth': ['error', 8],
43
+ 'max-nested-callbacks': ['error', 8],
44
+ 'max-statements-per-line': ['error', { max: 1 }],
45
+ 'sonarjs/cognitive-complexity': ['error', 15],
46
46
 
47
- // CLASSES
48
- '@typescript-eslint/no-require-imports': 'error',
49
- 'simple-import-sort/imports': 'error',
50
- 'simple-import-sort/exports': 'error',
51
- '@typescript-eslint/no-unused-vars': 'off',
52
- 'unused-imports/no-unused-imports': 'error',
53
- 'no-duplicate-imports': 'error',
54
- 'no-useless-constructor': 'off', // duplicate of @typescript-eslint/no-useless-constructor
55
- '@typescript-eslint/no-useless-constructor': ['error'],
56
- '@typescript-eslint/member-ordering': 'warn',
57
- '@typescript-eslint/explicit-member-accessibility': [
58
- 'error',
59
- {
60
- accessibility: 'off',
61
- overrides: {
62
- accessors: 'explicit',
63
- constructors: 'no-public',
64
- methods: 'explicit',
65
- properties: 'explicit',
66
- parameterProperties: 'explicit',
47
+ // CLASSES
48
+ '@typescript-eslint/no-require-imports': 'error',
49
+ 'simple-import-sort/imports': 'error',
50
+ 'simple-import-sort/exports': 'error',
51
+ '@typescript-eslint/no-unused-vars': 'off',
52
+ 'unused-imports/no-unused-imports': 'error',
53
+ 'no-duplicate-imports': 'error',
54
+ 'no-useless-constructor': 'off', // duplicate of @typescript-eslint/no-useless-constructor
55
+ '@typescript-eslint/no-useless-constructor': ['error'],
56
+ '@typescript-eslint/member-ordering': 'warn',
57
+ '@typescript-eslint/explicit-member-accessibility': [
58
+ 'error',
59
+ {
60
+ accessibility: 'off',
61
+ overrides: {
62
+ accessors: 'explicit',
63
+ constructors: 'no-public',
64
+ methods: 'explicit',
65
+ properties: 'explicit',
66
+ parameterProperties: 'explicit',
67
+ },
68
+ ignoredMethodNames: [
69
+ 'ngOnChanges',
70
+ 'ngOnInit',
71
+ 'ngDoCheck',
72
+ 'ngAfterContentInit',
73
+ 'ngAfterContentChecked',
74
+ 'ngAfterViewInit',
75
+ 'ngAfterViewChecked',
76
+ 'ngOnDestroy',
77
+ ],
67
78
  },
68
- ignoredMethodNames: [
69
- 'ngOnChanges',
70
- 'ngOnInit',
71
- 'ngDoCheck',
72
- 'ngAfterContentInit',
73
- 'ngAfterContentChecked',
74
- 'ngAfterViewInit',
75
- 'ngAfterViewChecked',
76
- 'ngOnDestroy',
77
- ],
78
- },
79
- ],
79
+ ],
80
80
 
81
- // FUNCTIONS
82
- 'curly': ['error', 'all'],
83
- 'max-lines-per-function': ['error', { max: 60, skipBlankLines: true, skipComments: true }],
84
- 'max-statements': ['error', 20],
85
- 'no-empty-function': ['error', { allow: ['constructors'] }],
86
- 'no-param-reassign': 'error',
87
- 'no-unexpected-multiline': 'error',
88
- 'prefer-arrow-callback': 'warn',
89
- '@typescript-eslint/explicit-function-return-type': ['error', { allowHigherOrderFunctions: true, allowExpressions: true }],
90
- 'sonarjs/no-extra-arguments': 'error',
81
+ // FUNCTIONS
82
+ 'curly': ['error', 'all'],
83
+ 'max-lines-per-function': ['error', { max: 60, skipBlankLines: true, skipComments: true }],
84
+ 'max-statements': ['error', 20],
85
+ 'no-empty-function': ['error', { allow: ['constructors'] }],
86
+ 'no-param-reassign': 'error',
87
+ 'no-unexpected-multiline': 'error',
88
+ 'prefer-arrow-callback': 'warn',
89
+ '@typescript-eslint/explicit-function-return-type': ['error', { allowHigherOrderFunctions: true, allowExpressions: true }],
90
+ 'sonarjs/no-extra-arguments': 'error',
91
91
 
92
- // VARIABLES
93
- 'unused-imports/no-unused-vars': [
94
- 'error',
95
- { vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
96
- ],
97
- 'no-shadow': 'error',
98
- 'no-multi-assign': 'error',
99
- 'prefer-const': 'error',
100
- 'no-unused-expressions': 'error',
101
- 'sonarjs/non-existent-operator': 'error',
102
- '@typescript-eslint/no-explicit-any': 'warn',
103
- '@typescript-eslint/no-non-null-assertion': 'error',
104
- '@typescript-eslint/no-inferrable-types': 'error',
105
- '@typescript-eslint/no-restricted-types': [
106
- 'error',
107
- {
108
- types: {
109
- Boolean: {
110
- message: 'Use boolean instead',
111
- fixWith: 'boolean',
112
- },
113
- Number: {
114
- message: 'Use number instead',
115
- fixWith: 'number',
116
- },
117
- String: {
118
- message: 'Use string instead',
119
- fixWith: 'string',
120
- },
121
- Symbol: {
122
- message: 'Use symbol instead',
123
- fixWith: 'symbol',
92
+ // VARIABLES
93
+ 'unused-imports/no-unused-vars': [
94
+ 'error',
95
+ { vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
96
+ ],
97
+ 'no-shadow': 'error',
98
+ 'no-multi-assign': 'error',
99
+ 'prefer-const': 'error',
100
+ 'no-unused-expressions': 'error',
101
+ 'sonarjs/non-existent-operator': 'error',
102
+ '@typescript-eslint/no-explicit-any': 'warn',
103
+ '@typescript-eslint/no-non-null-assertion': 'error',
104
+ '@typescript-eslint/no-inferrable-types': 'error',
105
+ '@typescript-eslint/no-restricted-types': [
106
+ 'error',
107
+ {
108
+ types: {
109
+ Boolean: {
110
+ message: 'Use boolean instead',
111
+ fixWith: 'boolean',
112
+ },
113
+ Number: {
114
+ message: 'Use number instead',
115
+ fixWith: 'number',
116
+ },
117
+ String: {
118
+ message: 'Use string instead',
119
+ fixWith: 'string',
120
+ },
121
+ Symbol: {
122
+ message: 'Use symbol instead',
123
+ fixWith: 'symbol',
124
+ },
124
125
  },
125
126
  },
126
- },
127
- ],
128
- '@typescript-eslint/prefer-optional-chain': 'warn',
127
+ ],
128
+ '@typescript-eslint/prefer-optional-chain': 'warn',
129
129
 
130
- // ARRAYS
131
- 'array-callback-return': 'error',
132
- '@typescript-eslint/array-type': 'error',
133
- 'no-array-constructor': 'error',
134
- '@typescript-eslint/prefer-includes': 'warn',
130
+ // ARRAYS
131
+ 'array-callback-return': 'error',
132
+ '@typescript-eslint/array-type': 'error',
133
+ 'no-array-constructor': 'error',
134
+ '@typescript-eslint/prefer-includes': 'warn',
135
135
 
136
- // SWITCH STATEMENTS
137
- 'sonarjs/max-switch-cases': ['error', 10],
138
- 'sonarjs/no-nested-switch': 'error',
139
- 'default-case': 'error',
140
- 'no-fallthrough': 'error',
136
+ // SWITCH STATEMENTS
137
+ 'sonarjs/max-switch-cases': ['error', 10],
138
+ 'sonarjs/no-nested-switch': 'error',
139
+ 'default-case': 'error',
140
+ 'no-fallthrough': 'error',
141
141
 
142
- // COMPARISON
143
- 'sonarjs/no-inverted-boolean-check': 'error',
144
- 'eqeqeq': 'error',
142
+ // COMPARISON
143
+ 'sonarjs/no-inverted-boolean-check': 'error',
144
+ 'eqeqeq': 'error',
145
145
 
146
- // ASYNCHRONOUS
147
- '@typescript-eslint/no-misused-promises': 'error',
148
- '@typescript-eslint/no-floating-promises': 'error',
149
- },
150
- });
146
+ // ASYNCHRONOUS
147
+ '@typescript-eslint/no-misused-promises': 'error',
148
+ '@typescript-eslint/no-floating-promises': 'error',
149
+ },
150
+ });
@@ -7,7 +7,7 @@ const customized = stylistic.configs.customize({
7
7
 
8
8
  export default [
9
9
  {
10
- files: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.js'],
10
+ files: ['**/*.{ts,tsx,js,mjs,cjs}'],
11
11
  plugins: {
12
12
  '@stylistic': stylistic,
13
13
  },
package/index.mjs CHANGED
@@ -2,12 +2,10 @@ import tseslint from 'typescript-eslint';
2
2
  import bestPractices from './configurations/best-practices.mjs';
3
3
  import stylistic from './configurations/stylistic.mjs';
4
4
 
5
+ export { default as bestPractices } from './configurations/best-practices.mjs';
6
+ export { default as stylistic } from './configurations/stylistic.mjs';
7
+
5
8
  export default [
6
- {
7
- ignores: [
8
- '**/*.mjs',
9
- ]
10
- },
11
9
  ...bestPractices,
12
10
  ...stylistic,
13
11
  {
package/package.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "@jeroenpol/eslint-config",
3
- "version": "2.0.2",
4
- "description": "ES Lint config made for Angular, configured by Polware",
3
+ "version": "2.1.1",
4
+ "description": "ESLint config made for Angular, configured by Polware",
5
5
  "main": "index.mjs",
6
6
  "exports": {
7
7
  ".": "./index.mjs",
8
+ "./best-practices": "./configurations/best-practices.mjs",
9
+ "./stylistic": "./configurations/stylistic.mjs",
8
10
  "./package.json": "./package.json"
9
11
  },
10
- "scripts": {},
12
+ "scripts": {
13
+ "lint:smoke": "eslint --config test/smoke/eslint.config.mjs test/smoke/sample.ts"
14
+ },
11
15
  "repository": {
12
16
  "type": "git",
13
17
  "url": "https://github.com/jeroenpol/eslint-config"
@@ -34,33 +38,24 @@
34
38
  "url": "https://github.com/jeroenpol/eslint-config"
35
39
  },
36
40
  "homepage": "https://github.com/jeroenpol/eslint-config",
37
- "devDependencies": {
38
- "@eslint/eslintrc": "^3.3.0",
39
- "@eslint/js": "^9.21.0",
41
+ "dependencies": {
40
42
  "@stylistic/eslint-plugin": "^4.2.0",
41
- "@stylistic/eslint-plugin-ts": "^4.2.0",
42
- "@typescript-eslint/eslint-plugin": "8.8.1",
43
- "@typescript-eslint/parser": "^8.8.1",
44
- "eslint": "^9.8.0",
45
43
  "eslint-plugin-simple-import-sort": "^12.1.1",
46
44
  "eslint-plugin-sonarjs": "3.0.2",
47
45
  "eslint-plugin-unused-imports": "4.1.4",
48
- "typescript": "^5.5.4",
49
46
  "typescript-eslint": "^8.8.1"
50
47
  },
48
+ "devDependencies": {
49
+ "@eslint/eslintrc": "^3.3.0",
50
+ "@eslint/js": "^9.21.0",
51
+ "eslint": "^9.8.0",
52
+ "typescript": "^5.5.4"
53
+ },
51
54
  "peerDependencies": {
52
- "@stylistic/eslint-plugin": ">=4",
53
- "@stylistic/eslint-plugin-ts": ">=4",
54
- "@typescript-eslint/eslint-plugin": ">=8",
55
- "@typescript-eslint/parser": ">=8",
56
55
  "eslint": ">=9",
57
- "eslint-plugin-simple-import-sort": ">=12",
58
- "eslint-plugin-sonarjs": ">=3",
59
- "eslint-plugin-unused-imports": ">=4",
60
- "typescript": ">=5",
61
- "typescript-eslint": ">=8"
56
+ "typescript": ">=5"
62
57
  },
63
58
  "engines": {
64
59
  "node": "20"
65
60
  }
66
- }
61
+ }