@swissgeo/config-eslint 1.0.0-beta.4 → 1.0.0-rc.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/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @swissgeo/config-eslint
2
+
3
+ Shared ESLint configuration for SWISSGEO projects.
4
+
5
+ ## Overview
6
+
7
+ This package provides a comprehensive ESLint flat config setup for SWISSGEO projects, with built-in support for:
8
+
9
+ - TypeScript
10
+ - Vue 3
11
+ - JavaScript (ES6+)
12
+ - Markdown files
13
+ - Unit tests (Mocha, Chai)
14
+ - Cypress E2E tests
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install --save-dev @swissgeo/config-eslint eslint
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic Configuration
25
+
26
+ Create an `eslint.config.mts` file in your project root:
27
+
28
+ ```typescript
29
+ import eslintConfig from '@swissgeo/config-eslint'
30
+
31
+ export default eslintConfig
32
+ ```
33
+
34
+ ### With Cypress Tests
35
+
36
+ If your project includes Cypress tests, use the `cypressConfig` function:
37
+
38
+ ```typescript
39
+ import eslintConfig, { cypressConfig } from '@swissgeo/config-eslint'
40
+
41
+ export default [
42
+ ...eslintConfig,
43
+ ...cypressConfig('tests/cypress/'), // Specify your Cypress root directory
44
+ ]
45
+ ```
46
+
47
+ ### Custom Configuration
48
+
49
+ You can extend or override the default configuration:
50
+
51
+ ```typescript
52
+ import eslintConfig from '@swissgeo/config-eslint'
53
+
54
+ export default [
55
+ ...eslintConfig,
56
+ {
57
+ rules: {
58
+ // Your custom rules
59
+ },
60
+ },
61
+ ]
62
+ ```
63
+
64
+ ## Features
65
+
66
+ ### TypeScript Support
67
+
68
+ - Full TypeScript linting with `@typescript-eslint`
69
+ - Consistent type exports enforcement
70
+ - No import type side-effects
71
+
72
+ ### Vue 3 Support
73
+
74
+ - Vue 3 ESLint rules with TypeScript integration
75
+ - 4-space HTML indentation
76
+ - Alphabetical import sorting
77
+
78
+ ### Import Sorting
79
+
80
+ Automatic alphabetical import sorting with `eslint-plugin-perfectionist`, treating `@/*` imports as internal.
81
+
82
+ ### Code Style
83
+
84
+ - Enforced curly braces for all control statements
85
+ - Consistent brace style (1tbs)
86
+ - No console statements in production code (except tests)
87
+
88
+ ### Test Support
89
+
90
+ - **Unit Tests**: Mocha and Chai-friendly rules for `*.spec.{js,ts}` files
91
+ - **Cypress Tests**: Cypress-recommended rules with custom configuration
92
+
93
+ ### Markdown Linting
94
+
95
+ Support for linting code blocks in Markdown files.
96
+
97
+ ## Peer Dependencies
98
+
99
+ This package requires:
100
+
101
+ - `eslint`
102
+ - `@swissgeo/config-prettier`
103
+ - `@swissgeo/config-stylelint`
104
+
105
+ ## License
106
+
107
+ BSD-3-Clause
108
+
109
+ ## Repository
110
+
111
+ [https://github.com/geoadmin/web-mapviewer](https://github.com/geoadmin/web-mapviewer)
package/dist/index.js CHANGED
@@ -3,12 +3,32 @@ import markdown from '@eslint/markdown';
3
3
  import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';
4
4
  import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript';
5
5
  import pluginChaiFriendly from 'eslint-plugin-chai-friendly';
6
- import pluginCypress from 'eslint-plugin-cypress/flat';
6
+ import pluginCypress from 'eslint-plugin-cypress';
7
+ import pluginImport from 'eslint-plugin-import';
7
8
  import mocha from 'eslint-plugin-mocha';
8
9
  import perfectionist from 'eslint-plugin-perfectionist';
9
10
  import pluginVue from 'eslint-plugin-vue';
10
11
  import globals from 'globals';
11
- import tsESLint, { plugin as tsESLintPlugin } from 'typescript-eslint';
12
+ import tsESLint from 'typescript-eslint';
13
+ const commonTsAndJsRules = {
14
+ eqeqeq: ['error', 'always'],
15
+ 'no-console': 'error',
16
+ 'no-var': 'error',
17
+ // Enforce a consistent brace style for all control statements
18
+ curly: ['error', 'all'],
19
+ // Enforce opening braces on the same line and closing brace on a new line
20
+ 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
21
+ 'perfectionist/sort-imports': [
22
+ 'error',
23
+ {
24
+ type: 'alphabetical',
25
+ internalPattern: ['^@/.*'],
26
+ },
27
+ ],
28
+ 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
29
+ // has some issue (with typescript-eslint for instance), so we disable it (TS does already a good job at detecting unresolved imports)
30
+ 'import/no-unresolved': 'off',
31
+ };
12
32
  const noUnusedVarsRules = {
13
33
  'no-unused-vars': [
14
34
  'error',
@@ -41,6 +61,13 @@ const standardTSRules = {
41
61
  ],
42
62
  '@typescript-eslint/consistent-type-exports': 'error',
43
63
  '@typescript-eslint/no-import-type-side-effects': 'error',
64
+ '@typescript-eslint/consistent-type-imports': [
65
+ 'error',
66
+ {
67
+ prefer: 'type-imports',
68
+ fixStyle: 'separate-type-imports',
69
+ },
70
+ ],
44
71
  };
45
72
  const chaiFriendlyRules = {
46
73
  plugins: {
@@ -88,24 +115,15 @@ const allIgnores = [
88
115
  '**/*.md',
89
116
  '**/eslint.config.mts',
90
117
  ];
91
- export const vueConfig = defineConfigWithVueTs(pluginVue.configs['flat/essential'], vueTsConfigs.recommendedTypeCheckedOnly, {
118
+ export const vueConfig = defineConfigWithVueTs(pluginImport.flatConfigs.recommended, pluginImport.flatConfigs.typescript, pluginVue.configs['flat/essential'], tsESLint.configs.recommended, vueTsConfigs.recommendedTypeCheckedOnly, {
92
119
  files: ['**/*.vue'],
93
120
  plugins: {
94
- '@typescript-eslint': tsESLintPlugin,
95
121
  perfectionist,
96
122
  },
97
123
  rules: {
124
+ ...commonTsAndJsRules,
98
125
  'vue/html-indent': ['error', 4],
99
- // TODO: switch to 'error' (or remove this line) after complete TS migration
100
- 'vue/block-lang': 'off',
101
- 'perfectionist/sort-imports': [
102
- 'error',
103
- { type: 'alphabetical', internalPattern: ['^@/.*'] },
104
- ],
105
- // Enforce consistent brace style for all control statements
106
- curly: ['error', 'all'],
107
- // Enforce opening brace on same line and closing brace on new line
108
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
126
+ 'vue/block-lang': 'error',
109
127
  ...noUnusedVarsRules,
110
128
  },
111
129
  });
@@ -141,7 +159,6 @@ export const jsConfig = [
141
159
  mocha,
142
160
  'chai-friendly': pluginChaiFriendly,
143
161
  perfectionist,
144
- '@typescript-eslint': tsESLintPlugin,
145
162
  },
146
163
  languageOptions: {
147
164
  ecmaVersion: 'latest',
@@ -158,18 +175,8 @@ export const jsConfig = [
158
175
  sourceType: 'module',
159
176
  },
160
177
  rules: {
161
- eqeqeq: ['error', 'always'],
178
+ ...commonTsAndJsRules,
162
179
  'mocha/no-exclusive-tests': 'error',
163
- 'no-console': 'error',
164
- 'no-var': 'error',
165
- 'perfectionist/sort-imports': [
166
- 'error',
167
- { type: 'alphabetical', internalPattern: ['^@/.*'] },
168
- ],
169
- // Enforce consistent brace style for all control statements
170
- curly: ['error', 'all'],
171
- // Enforce opening brace on same line and closing brace on new line
172
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
173
180
  ...noUnusedVarsRules,
174
181
  },
175
182
  },
@@ -179,13 +186,15 @@ export const jsConfig = [
179
186
  // skip the formatting in the linting process
180
187
  skipFormatting,
181
188
  ];
182
- const defaultConfig = tsESLint.config(...jsConfig, tsESLint.configs.recommended, ...markdownConfig, ...vueConfig, {
189
+ const defaultConfig = tsESLint.config(pluginImport.flatConfigs.recommended, pluginImport.flatConfigs.typescript, ...jsConfig, tsESLint.configs.recommended, ...markdownConfig, ...vueConfig, {
183
190
  ignores: allIgnores,
184
191
  }, {
185
192
  files: ['**/*.ts', '**/*.tsx'],
186
193
  // no need to check our snippets
187
194
  ignores: ['**/*.md'],
188
- plugins: { perfectionist },
195
+ plugins: {
196
+ perfectionist,
197
+ },
189
198
  languageOptions: {
190
199
  parserOptions: {
191
200
  projectService: true,
@@ -196,14 +205,7 @@ const defaultConfig = tsESLint.config(...jsConfig, tsESLint.configs.recommended,
196
205
  // on unused param from abstract function arguments
197
206
  rules: {
198
207
  ...standardTSRules,
199
- 'perfectionist/sort-imports': [
200
- 'error',
201
- { type: 'alphabetical', internalPattern: ['^@/.*'] },
202
- ],
203
- // Enforce consistent brace style for all control statements
204
- curly: ['error', 'all'],
205
- // Enforce opening brace on same line and closing brace on new line
206
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
208
+ ...commonTsAndJsRules,
207
209
  },
208
210
  },
209
211
  // we have to declare that AFTER the TS specifics, our unit test rules from the JS config are otherwise ignored (when the tests are written in TS)
package/index.ts CHANGED
@@ -5,16 +5,37 @@ import markdown from '@eslint/markdown'
5
5
  import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
6
6
  import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
7
7
  import pluginChaiFriendly from 'eslint-plugin-chai-friendly'
8
- import pluginCypress from 'eslint-plugin-cypress/flat'
8
+ import pluginCypress from 'eslint-plugin-cypress'
9
+ import pluginImport from 'eslint-plugin-import'
9
10
  import mocha from 'eslint-plugin-mocha'
10
11
  import perfectionist from 'eslint-plugin-perfectionist'
11
12
  import pluginVue from 'eslint-plugin-vue'
12
13
  import globals from 'globals'
13
- import tsESLint, { plugin as tsESLintPlugin } from 'typescript-eslint'
14
+ import tsESLint from 'typescript-eslint'
14
15
 
15
16
  type PartialRules = Partial<Record<string, FlatConfig.RuleEntry>>
16
17
  type PartialConfig = Partial<FlatConfig.Config>
17
18
 
19
+ const commonTsAndJsRules: PartialRules = {
20
+ eqeqeq: ['error', 'always'],
21
+ 'no-console': 'error',
22
+ 'no-var': 'error',
23
+ // Enforce a consistent brace style for all control statements
24
+ curly: ['error', 'all'],
25
+ // Enforce opening braces on the same line and closing brace on a new line
26
+ 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
27
+ 'perfectionist/sort-imports': [
28
+ 'error',
29
+ {
30
+ type: 'alphabetical',
31
+ internalPattern: ['^@/.*'],
32
+ },
33
+ ],
34
+ 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
35
+ // has some issue (with typescript-eslint for instance), so we disable it (TS does already a good job at detecting unresolved imports)
36
+ 'import/no-unresolved': 'off',
37
+ }
38
+
18
39
  const noUnusedVarsRules: PartialRules = {
19
40
  'no-unused-vars': [
20
41
  'error',
@@ -48,6 +69,13 @@ const standardTSRules: PartialRules = {
48
69
  ],
49
70
  '@typescript-eslint/consistent-type-exports': 'error',
50
71
  '@typescript-eslint/no-import-type-side-effects': 'error',
72
+ '@typescript-eslint/consistent-type-imports': [
73
+ 'error',
74
+ {
75
+ prefer: 'type-imports',
76
+ fixStyle: 'separate-type-imports',
77
+ },
78
+ ],
51
79
  }
52
80
 
53
81
  const chaiFriendlyRules: PartialConfig = {
@@ -100,26 +128,20 @@ const allIgnores: string[] = [
100
128
  ]
101
129
 
102
130
  export const vueConfig: FlatConfig.ConfigArray = defineConfigWithVueTs(
131
+ pluginImport.flatConfigs.recommended,
132
+ pluginImport.flatConfigs.typescript,
103
133
  pluginVue.configs['flat/essential'],
134
+ tsESLint.configs.recommended,
104
135
  vueTsConfigs.recommendedTypeCheckedOnly,
105
136
  {
106
137
  files: ['**/*.vue'],
107
138
  plugins: {
108
- '@typescript-eslint': tsESLintPlugin,
109
139
  perfectionist,
110
140
  },
111
141
  rules: {
142
+ ...commonTsAndJsRules,
112
143
  'vue/html-indent': ['error', 4],
113
- // TODO: switch to 'error' (or remove this line) after complete TS migration
114
- 'vue/block-lang': 'off',
115
- 'perfectionist/sort-imports': [
116
- 'error',
117
- { type: 'alphabetical', internalPattern: ['^@/.*'] },
118
- ],
119
- // Enforce consistent brace style for all control statements
120
- curly: ['error', 'all'],
121
- // Enforce opening brace on same line and closing brace on new line
122
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
144
+ 'vue/block-lang': 'error',
123
145
  ...noUnusedVarsRules,
124
146
  },
125
147
  }
@@ -159,7 +181,6 @@ export const jsConfig: FlatConfig.ConfigArray = [
159
181
  mocha,
160
182
  'chai-friendly': pluginChaiFriendly,
161
183
  perfectionist,
162
- '@typescript-eslint': tsESLintPlugin,
163
184
  },
164
185
  languageOptions: {
165
186
  ecmaVersion: 'latest',
@@ -178,18 +199,8 @@ export const jsConfig: FlatConfig.ConfigArray = [
178
199
  sourceType: 'module',
179
200
  },
180
201
  rules: {
181
- eqeqeq: ['error', 'always'],
202
+ ...commonTsAndJsRules,
182
203
  'mocha/no-exclusive-tests': 'error',
183
- 'no-console': 'error',
184
- 'no-var': 'error',
185
- 'perfectionist/sort-imports': [
186
- 'error',
187
- { type: 'alphabetical', internalPattern: ['^@/.*'] },
188
- ],
189
- // Enforce consistent brace style for all control statements
190
- curly: ['error', 'all'],
191
- // Enforce opening brace on same line and closing brace on new line
192
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
193
204
  ...noUnusedVarsRules,
194
205
  },
195
206
  },
@@ -201,6 +212,8 @@ export const jsConfig: FlatConfig.ConfigArray = [
201
212
  ]
202
213
 
203
214
  const defaultConfig: FlatConfig.ConfigArray = tsESLint.config(
215
+ pluginImport.flatConfigs.recommended,
216
+ pluginImport.flatConfigs.typescript,
204
217
  ...jsConfig,
205
218
  tsESLint.configs.recommended,
206
219
  ...markdownConfig,
@@ -212,7 +225,9 @@ const defaultConfig: FlatConfig.ConfigArray = tsESLint.config(
212
225
  files: ['**/*.ts', '**/*.tsx'],
213
226
  // no need to check our snippets
214
227
  ignores: ['**/*.md'],
215
- plugins: { perfectionist },
228
+ plugins: {
229
+ perfectionist,
230
+ },
216
231
  languageOptions: {
217
232
  parserOptions: {
218
233
  projectService: true,
@@ -223,14 +238,7 @@ const defaultConfig: FlatConfig.ConfigArray = tsESLint.config(
223
238
  // on unused param from abstract function arguments
224
239
  rules: {
225
240
  ...standardTSRules,
226
- 'perfectionist/sort-imports': [
227
- 'error',
228
- { type: 'alphabetical', internalPattern: ['^@/.*'] },
229
- ],
230
- // Enforce consistent brace style for all control statements
231
- curly: ['error', 'all'],
232
- // Enforce opening brace on same line and closing brace on new line
233
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
241
+ ...commonTsAndJsRules,
234
242
  },
235
243
  },
236
244
  // we have to declare that AFTER the TS specifics, our unit test rules from the JS config are otherwise ignored (when the tests are written in TS)
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@swissgeo/config-eslint",
3
- "version": "1.0.0-beta.4",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "Shared ESLint config for SWISSGEO projects.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/geoadmin/web-mapviewer.git",
8
+ "directory": "packages/config/eslint"
9
+ },
5
10
  "license": "BSD-3-Clause",
6
11
  "type": "module",
7
12
  "exports": {
@@ -19,23 +24,23 @@
19
24
  "@vue/eslint-config-typescript": "^14.6.0",
20
25
  "eslint-plugin-chai-friendly": "^1.1.0",
21
26
  "eslint-plugin-cypress": "^5.2.0",
27
+ "eslint-plugin-import": "^2.32.0",
22
28
  "eslint-plugin-mocha": "^11.2.0",
23
29
  "eslint-plugin-perfectionist": "^4.15.1",
24
30
  "eslint-plugin-prettier": "^5.5.4",
25
31
  "eslint-plugin-vue": "^10.5.1",
26
- "typescript-eslint": "^8.46.4"
32
+ "typescript-eslint": "^8.49.0"
27
33
  },
28
34
  "devDependencies": {
29
35
  "@microsoft/api-extractor": "^7.55.0",
30
36
  "@types/node": "^24.10.1",
31
37
  "globals": "^16.5.0",
32
38
  "typescript": "^5.9.3",
33
- "@swissgeo/config-typescript": "1.0.0-beta.3"
39
+ "@swissgeo/config-typescript": "1.0.0-rc.1"
34
40
  },
35
41
  "peerDependencies": {
36
42
  "eslint": "^9.39.1",
37
- "@swissgeo/config-prettier": "1.0.0-beta.6",
38
- "@swissgeo/config-stylelint": "1.0.0-beta.3"
43
+ "@swissgeo/config-stylelint": "1.0.0-rc.1"
39
44
  },
40
45
  "scripts": {
41
46
  "build": "pnpm run type-check && pnpm run generate-types",
package/tsconfig.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "files": ["index.ts"],
3
+ "include": ["types/*.ts"],
3
4
  "compilerOptions": {
4
5
  "target": "ESNext",
5
6
  "module": "ESNext",
@@ -1,5 +1,5 @@
1
1
  declare module 'eslint-plugin-chai-friendly' {
2
- import { FlatConfig } from '@typescript-eslint/utils/ts-eslint'
2
+ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'
3
3
 
4
4
  const plugin: FlatConfig.Plugin
5
5
 
@@ -1,11 +0,0 @@
1
- import type { Linter } from 'eslint'
2
-
3
- declare module 'eslint-plugin-cypress/lib' {
4
- const plugin: {
5
- configs: {
6
- recommended: Linter.Config
7
- [key: string]: Linter.Config | undefined
8
- }
9
- }
10
- export default plugin
11
- }