@swissgeo/config-eslint 1.0.0-beta.4 → 1.0.0

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,129 @@
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
+ ### Granular Configurations
48
+
49
+ You can also import specific configurations if you don't want the full default set:
50
+
51
+ - `vueConfig`: Vue 3 specific rules
52
+ - `unitTestsConfig`: Mocha/Chai rules for `*.spec.{js,ts}`
53
+ - `markdownConfig`: Markdown linting rules
54
+ - `jsConfig`: Standard JavaScript rules
55
+
56
+ ```typescript
57
+ import { jsConfig, vueConfig } from '@swissgeo/config-eslint'
58
+
59
+ export default [
60
+ ...jsConfig,
61
+ ...vueConfig,
62
+ ]
63
+ ```
64
+
65
+ ### Custom Configuration
66
+
67
+ You can extend or override the default configuration:
68
+
69
+ ```typescript
70
+ import eslintConfig from '@swissgeo/config-eslint'
71
+
72
+ export default [
73
+ ...eslintConfig,
74
+ {
75
+ rules: {
76
+ // Your custom rules
77
+ },
78
+ },
79
+ ]
80
+ ```
81
+
82
+ ## Features
83
+
84
+ ### TypeScript Support
85
+
86
+ - Full TypeScript linting with `@typescript-eslint`
87
+ - Consistent type exports enforcement
88
+ - No import type side-effects
89
+
90
+ ### Vue 3 Support
91
+
92
+ - Vue 3 ESLint rules with TypeScript integration
93
+ - 4-space HTML indentation
94
+ - Alphabetical import sorting
95
+
96
+ ### Import Sorting
97
+
98
+ Automatic alphabetical import sorting with `eslint-plugin-perfectionist`, treating `@/*` imports as internal.
99
+
100
+ ### Code Style
101
+
102
+ - Enforced curly braces for all control statements
103
+ - Consistent brace style (1tbs)
104
+ - No console statements in production code (except tests)
105
+
106
+ ### Test Support
107
+
108
+ - **Unit Tests**: Mocha and Chai-friendly rules for `*.spec.{js,ts}` files
109
+ - **Cypress Tests**: Cypress-recommended rules with custom configuration
110
+
111
+ ### Markdown Linting
112
+
113
+ Support for linting code blocks in Markdown files.
114
+
115
+ ## Peer Dependencies
116
+
117
+ This package requires:
118
+
119
+ - `eslint`
120
+ - `@swissgeo/config-prettier`
121
+ - `@swissgeo/config-stylelint`
122
+
123
+ ## License
124
+
125
+ BSD-3-Clause
126
+
127
+ ## Repository
128
+
129
+ [https://github.com/geoadmin/web-mapviewer](https://github.com/geoadmin/web-mapviewer)
package/dist/index.d.ts CHANGED
@@ -1,15 +1,23 @@
1
- import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
2
- /**
3
- * Generates a set of ESLint rules for Cypress tests. The root directory of the Cypress tests can be
4
- * specified (the default value is 'tests/cypress/').
5
- *
6
- * @param cypressRootDir The root directory of the Cypress tests.
7
- * @returns The set of ESLint rules for Cypress tests.
8
- */
9
- export declare function cypressConfig(cypressRootDir?: string): FlatConfig.ConfigArray;
10
- export declare const vueConfig: FlatConfig.ConfigArray;
11
- export declare const unitTestsConfig: FlatConfig.ConfigArray;
12
- export declare const markdownConfig: FlatConfig.ConfigArray;
13
- export declare const jsConfig: FlatConfig.ConfigArray;
14
- declare const defaultConfig: FlatConfig.ConfigArray;
15
- export default defaultConfig;
1
+ import { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
2
+
3
+ /**
4
+ * Generates a set of ESLint rules for Cypress tests. The root directory of the Cypress tests can be
5
+ * specified (the default value is 'tests/cypress/').
6
+ *
7
+ * @param cypressRootDir The root directory of the Cypress tests.
8
+ * @returns The set of ESLint rules for Cypress tests.
9
+ */
10
+ export declare function cypressConfig(cypressRootDir?: string): FlatConfig.ConfigArray;
11
+
12
+ declare const defaultConfig: FlatConfig.ConfigArray;
13
+ export default defaultConfig;
14
+
15
+ export declare const jsConfig: FlatConfig.ConfigArray;
16
+
17
+ export declare const markdownConfig: FlatConfig.ConfigArray;
18
+
19
+ export declare const unitTestsConfig: FlatConfig.ConfigArray;
20
+
21
+ export declare const vueConfig: FlatConfig.ConfigArray;
22
+
23
+ export { }
package/dist/index.js CHANGED
@@ -1,211 +1,223 @@
1
- import jsESLint from '@eslint/js';
2
- import markdown from '@eslint/markdown';
3
- import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';
4
- import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript';
5
- import pluginChaiFriendly from 'eslint-plugin-chai-friendly';
6
- import pluginCypress from 'eslint-plugin-cypress/flat';
7
- import mocha from 'eslint-plugin-mocha';
8
- import perfectionist from 'eslint-plugin-perfectionist';
9
- import pluginVue from 'eslint-plugin-vue';
10
- import globals from 'globals';
11
- import tsESLint, { plugin as tsESLintPlugin } from 'typescript-eslint';
12
- const noUnusedVarsRules = {
13
- 'no-unused-vars': [
14
- 'error',
15
- {
16
- argsIgnorePattern: '^_',
17
- caughtErrorsIgnorePattern: '^_',
18
- destructuredArrayIgnorePattern: '^_',
19
- },
20
- ],
21
- '@typescript-eslint/no-unused-vars': [
22
- 'error',
23
- {
24
- argsIgnorePattern: '^_',
25
- caughtErrorsIgnorePattern: '^_',
26
- destructuredArrayIgnorePattern: '^_',
27
- },
28
- ],
29
- };
30
- const standardTSRules = {
31
- 'no-unused-vars': 'off',
32
- '@typescript-eslint/no-unused-vars': [
33
- 'error',
34
- {
35
- // as we are adding dispatcher reference in all our store action, but won't be using
36
- // them directly in the action, we must ignore these unused variables too
37
- argsIgnorePattern: '^(_|dispatcher)',
38
- caughtErrorsIgnorePattern: '^_',
39
- destructuredArrayIgnorePattern: '^_',
40
- },
41
- ],
42
- '@typescript-eslint/consistent-type-exports': 'error',
43
- '@typescript-eslint/no-import-type-side-effects': 'error',
1
+ import g from "@eslint/js";
2
+ import d from "@eslint/markdown";
3
+ import y from "@vue/eslint-config-prettier/skip-formatting";
4
+ import { defineConfigWithVueTs as _, vueTsConfigs as I } from "@vue/eslint-config-typescript";
5
+ import p from "eslint-plugin-chai-friendly";
6
+ import C from "eslint-plugin-cypress";
7
+ import e from "eslint-plugin-import";
8
+ import h from "eslint-plugin-mocha";
9
+ import s from "eslint-plugin-perfectionist";
10
+ import v from "eslint-plugin-vue";
11
+ import o from "globals";
12
+ import r from "typescript-eslint";
13
+ const t = {
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: !1 }],
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
+ }, n = {
32
+ "no-unused-vars": [
33
+ "error",
34
+ {
35
+ argsIgnorePattern: "^_",
36
+ caughtErrorsIgnorePattern: "^_",
37
+ destructuredArrayIgnorePattern: "^_"
38
+ }
39
+ ],
40
+ "@typescript-eslint/no-unused-vars": [
41
+ "error",
42
+ {
43
+ argsIgnorePattern: "^_",
44
+ caughtErrorsIgnorePattern: "^_",
45
+ destructuredArrayIgnorePattern: "^_"
46
+ }
47
+ ]
48
+ }, l = {
49
+ "no-unused-vars": "off",
50
+ "@typescript-eslint/no-unused-vars": [
51
+ "error",
52
+ {
53
+ // as we are adding dispatcher reference in all our store action, but won't be using
54
+ // them directly in the action, we must ignore these unused variables too
55
+ argsIgnorePattern: "^(_|dispatcher)",
56
+ caughtErrorsIgnorePattern: "^_",
57
+ destructuredArrayIgnorePattern: "^_"
58
+ }
59
+ ],
60
+ "@typescript-eslint/consistent-type-exports": "error",
61
+ "@typescript-eslint/no-import-type-side-effects": "error",
62
+ "@typescript-eslint/consistent-type-imports": [
63
+ "error",
64
+ {
65
+ prefer: "type-imports",
66
+ fixStyle: "separate-type-imports"
67
+ }
68
+ ]
69
+ }, a = {
70
+ plugins: {
71
+ "chai-friendly": p
72
+ },
73
+ rules: {
74
+ "no-console": "off",
75
+ "no-prototype-builtins": "off",
76
+ // see https://github.com/ihordiachenko/eslint-plugin-chai-friendly?tab=readme-ov-file#usage
77
+ "no-unused-expressions": "off",
78
+ // disable original rule for JS
79
+ "@typescript-eslint/no-unused-expressions": "off",
80
+ // disable original rule for TS
81
+ "chai-friendly/no-unused-expressions": "error",
82
+ ...n
83
+ }
44
84
  };
45
- const chaiFriendlyRules = {
85
+ function N(i = "tests/cypress/") {
86
+ return r.config([
87
+ {
88
+ files: [`${i}**/*.ts`, `${i}**/*.js`],
89
+ languageOptions: {
90
+ parserOptions: {
91
+ projectService: !0,
92
+ tsconfigRootDir: import.meta.dirname
93
+ }
94
+ },
95
+ rules: l,
96
+ ...C.configs.recommended,
97
+ ...a
98
+ }
99
+ ]);
100
+ }
101
+ const f = [
102
+ ".gitignore",
103
+ "**/node_modules",
104
+ "**/.github",
105
+ "**/dist",
106
+ "tsconfig.json",
107
+ "**/*.md",
108
+ "**/eslint.config.mts"
109
+ ], c = _(
110
+ e.flatConfigs.recommended,
111
+ e.flatConfigs.typescript,
112
+ v.configs["flat/essential"],
113
+ r.configs.recommended,
114
+ I.recommendedTypeCheckedOnly,
115
+ {
116
+ files: ["**/*.vue"],
46
117
  plugins: {
47
- 'chai-friendly': pluginChaiFriendly,
118
+ perfectionist: s
48
119
  },
49
120
  rules: {
50
- 'no-console': 'off',
51
- 'no-prototype-builtins': 'off',
52
- // see https://github.com/ihordiachenko/eslint-plugin-chai-friendly?tab=readme-ov-file#usage
53
- 'no-unused-expressions': 'off', // disable original rule for JS
54
- '@typescript-eslint/no-unused-expressions': 'off', // disable original rule for TS
55
- 'chai-friendly/no-unused-expressions': 'error',
56
- ...noUnusedVarsRules,
57
- },
58
- };
59
- /**
60
- * Generates a set of ESLint rules for Cypress tests. The root directory of the Cypress tests can be
61
- * specified (the default value is 'tests/cypress/').
62
- *
63
- * @param cypressRootDir The root directory of the Cypress tests.
64
- * @returns The set of ESLint rules for Cypress tests.
65
- */
66
- export function cypressConfig(cypressRootDir = 'tests/cypress/') {
67
- return tsESLint.config([
68
- {
69
- files: [`${cypressRootDir}**/*.ts`, `${cypressRootDir}**/*.js`],
70
- languageOptions: {
71
- parserOptions: {
72
- projectService: true,
73
- tsconfigRootDir: import.meta.dirname,
74
- },
75
- },
76
- rules: standardTSRules,
77
- ...pluginCypress.configs.recommended,
78
- ...chaiFriendlyRules,
79
- },
80
- ]);
81
- }
82
- const allIgnores = [
83
- '.gitignore',
84
- '**/node_modules',
85
- '**/.github',
86
- '**/dist',
87
- 'tsconfig.json',
88
- '**/*.md',
89
- '**/eslint.config.mts',
90
- ];
91
- export const vueConfig = defineConfigWithVueTs(pluginVue.configs['flat/essential'], vueTsConfigs.recommendedTypeCheckedOnly, {
92
- files: ['**/*.vue'],
121
+ ...t,
122
+ "vue/html-indent": ["error", 4],
123
+ "vue/block-lang": "error",
124
+ ...n
125
+ }
126
+ }
127
+ ), u = [
128
+ {
129
+ files: ["**/*.spec.{js,ts}", "scripts/**.{js,ts}"],
130
+ ...a
131
+ }
132
+ ], m = [
133
+ {
134
+ files: ["**/*.md"],
93
135
  plugins: {
94
- '@typescript-eslint': tsESLintPlugin,
95
- perfectionist,
136
+ markdown: d
96
137
  },
138
+ processor: "markdown/markdown",
97
139
  rules: {
98
- '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 }],
109
- ...noUnusedVarsRules,
110
- },
111
- });
112
- export const unitTestsConfig = [
113
- {
114
- files: ['**/*.spec.{js,ts}', 'scripts/**.{js,ts}'],
115
- ...chaiFriendlyRules,
116
- },
117
- ];
118
- export const markdownConfig = [
119
- {
120
- files: ['**/*.md'],
121
- plugins: {
122
- markdown: markdown,
123
- },
124
- processor: 'markdown/markdown',
125
- rules: {
126
- 'no-irregular-whitespace': 'off',
127
- 'no-undef': 'off',
128
- },
129
- },
130
- ];
131
- export const jsConfig = [
132
- jsESLint.configs.recommended,
133
- {
134
- ignores: allIgnores,
140
+ "no-irregular-whitespace": "off",
141
+ "no-undef": "off"
142
+ }
143
+ }
144
+ ], T = [
145
+ g.configs.recommended,
146
+ {
147
+ ignores: f
148
+ },
149
+ {
150
+ files: ["**/*.js", "**/*.jsx"],
151
+ // no need to check our snippets
152
+ ignores: ["**/*.md"],
153
+ plugins: {
154
+ mocha: h,
155
+ "chai-friendly": p,
156
+ perfectionist: s
135
157
  },
136
- {
137
- files: ['**/*.js', '**/*.jsx'],
138
- // no need to check our snippets
139
- ignores: ['**/*.md'],
140
- plugins: {
141
- mocha,
142
- 'chai-friendly': pluginChaiFriendly,
143
- perfectionist,
144
- '@typescript-eslint': tsESLintPlugin,
145
- },
146
- languageOptions: {
147
- ecmaVersion: 'latest',
148
- globals: {
149
- ...globals.browser,
150
- ...globals.vitest,
151
- ...globals.node,
152
- defineModel: 'readonly',
153
- __APP_VERSION__: true,
154
- __VITE_ENVIRONMENT__: true,
155
- __CESIUM_STATIC_PATH__: true,
156
- __IS_TESTING_WITH_CYPRESS__: true,
157
- },
158
- sourceType: 'module',
159
- },
160
- rules: {
161
- eqeqeq: ['error', 'always'],
162
- '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
- ...noUnusedVarsRules,
174
- },
158
+ languageOptions: {
159
+ ecmaVersion: "latest",
160
+ globals: {
161
+ ...o.browser,
162
+ ...o.vitest,
163
+ ...o.node,
164
+ defineModel: "readonly",
165
+ __APP_VERSION__: !0,
166
+ __VITE_ENVIRONMENT__: !0,
167
+ __CESIUM_STATIC_PATH__: !0,
168
+ __IS_TESTING_WITH_CYPRESS__: !0
169
+ },
170
+ sourceType: "module"
175
171
  },
176
- ...markdownConfig,
177
- ...unitTestsConfig,
178
- ...vueConfig,
179
- // skip the formatting in the linting process
180
- skipFormatting,
181
- ];
182
- const defaultConfig = tsESLint.config(...jsConfig, tsESLint.configs.recommended, ...markdownConfig, ...vueConfig, {
183
- ignores: allIgnores,
184
- }, {
185
- files: ['**/*.ts', '**/*.tsx'],
172
+ rules: {
173
+ ...t,
174
+ "mocha/no-exclusive-tests": "error",
175
+ ...n
176
+ }
177
+ },
178
+ ...m,
179
+ ...u,
180
+ ...c,
181
+ // skip the formatting in the linting process
182
+ y
183
+ ], q = r.config(
184
+ e.flatConfigs.recommended,
185
+ e.flatConfigs.typescript,
186
+ ...T,
187
+ r.configs.recommended,
188
+ ...m,
189
+ ...c,
190
+ {
191
+ ignores: f
192
+ },
193
+ {
194
+ files: ["**/*.ts", "**/*.tsx"],
186
195
  // no need to check our snippets
187
- ignores: ['**/*.md'],
188
- plugins: { perfectionist },
196
+ ignores: ["**/*.md"],
197
+ plugins: {
198
+ perfectionist: s
199
+ },
189
200
  languageOptions: {
190
- parserOptions: {
191
- projectService: true,
192
- tsconfigRootDir: import.meta.dirname,
193
- },
201
+ parserOptions: {
202
+ projectService: !0,
203
+ tsconfigRootDir: import.meta.dirname
204
+ }
194
205
  },
195
206
  // switching to TypeScript unused var rule (instead of JS rule), so that no error is raised
196
207
  // on unused param from abstract function arguments
197
208
  rules: {
198
- ...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 }],
207
- },
208
- },
209
- // 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)
210
- unitTestsConfig);
211
- export default defaultConfig;
209
+ ...l,
210
+ ...t
211
+ }
212
+ },
213
+ // 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)
214
+ u
215
+ );
216
+ export {
217
+ N as cypressConfig,
218
+ q as default,
219
+ T as jsConfig,
220
+ m as markdownConfig,
221
+ u as unitTestsConfig,
222
+ c as vueConfig
223
+ };
@@ -0,0 +1 @@
1
+ (function(e,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("@eslint/js"),require("@eslint/markdown"),require("@vue/eslint-config-prettier/skip-formatting"),require("@vue/eslint-config-typescript"),require("eslint-plugin-chai-friendly"),require("eslint-plugin-cypress"),require("eslint-plugin-import"),require("eslint-plugin-mocha"),require("eslint-plugin-perfectionist"),require("eslint-plugin-vue"),require("globals"),require("typescript-eslint")):typeof define=="function"&&define.amd?define(["exports","@eslint/js","@eslint/markdown","@vue/eslint-config-prettier/skip-formatting","@vue/eslint-config-typescript","eslint-plugin-chai-friendly","eslint-plugin-cypress","eslint-plugin-import","eslint-plugin-mocha","eslint-plugin-perfectionist","eslint-plugin-vue","globals","typescript-eslint"],r):(e=typeof globalThis<"u"?globalThis:e||self,r(e["@swissgeo/config-eslint"]={},e.jsESLint,e.markdown,e.skipFormatting,e.eslintConfigTypescript,e.pluginChaiFriendly,e.pluginCypress,e.pluginImport,e.mocha,e.perfectionist,e.pluginVue,e.globals,e.tsESLint))})(this,function(e,r,v,h,f,d,C,n,T,i,I,t,s){"use strict";const o={eqeqeq:["error","always"],"no-console":"error","no-var":"error",curly:["error","all"],"brace-style":["error","1tbs",{allowSingleLine:!1}],"perfectionist/sort-imports":["error",{type:"alphabetical",internalPattern:["^@/.*"]}],"import/consistent-type-specifier-style":["error","prefer-top-level"],"import/no-unresolved":"off"},u={"no-unused-vars":["error",{argsIgnorePattern:"^_",caughtErrorsIgnorePattern:"^_",destructuredArrayIgnorePattern:"^_"}],"@typescript-eslint/no-unused-vars":["error",{argsIgnorePattern:"^_",caughtErrorsIgnorePattern:"^_",destructuredArrayIgnorePattern:"^_"}]},g={"no-unused-vars":"off","@typescript-eslint/no-unused-vars":["error",{argsIgnorePattern:"^(_|dispatcher)",caughtErrorsIgnorePattern:"^_",destructuredArrayIgnorePattern:"^_"}],"@typescript-eslint/consistent-type-exports":"error","@typescript-eslint/no-import-type-side-effects":"error","@typescript-eslint/consistent-type-imports":["error",{prefer:"type-imports",fixStyle:"separate-type-imports"}]},a={plugins:{"chai-friendly":d},rules:{"no-console":"off","no-prototype-builtins":"off","no-unused-expressions":"off","@typescript-eslint/no-unused-expressions":"off","chai-friendly/no-unused-expressions":"error",...u}};function j(_="tests/cypress/"){return s.config([{files:[`${_}**/*.ts`,`${_}**/*.js`],languageOptions:{parserOptions:{projectService:!0,tsconfigRootDir:void 0}},rules:g,...C.configs.recommended,...a}])}const m=[".gitignore","**/node_modules","**/.github","**/dist","tsconfig.json","**/*.md","**/eslint.config.mts"],l=f.defineConfigWithVueTs(n.flatConfigs.recommended,n.flatConfigs.typescript,I.configs["flat/essential"],s.configs.recommended,f.vueTsConfigs.recommendedTypeCheckedOnly,{files:["**/*.vue"],plugins:{perfectionist:i},rules:{...o,"vue/html-indent":["error",4],"vue/block-lang":"error",...u}}),c=[{files:["**/*.spec.{js,ts}","scripts/**.{js,ts}"],...a}],p=[{files:["**/*.md"],plugins:{markdown:v},processor:"markdown/markdown",rules:{"no-irregular-whitespace":"off","no-undef":"off"}}],y=[r.configs.recommended,{ignores:m},{files:["**/*.js","**/*.jsx"],ignores:["**/*.md"],plugins:{mocha:T,"chai-friendly":d,perfectionist:i},languageOptions:{ecmaVersion:"latest",globals:{...t.browser,...t.vitest,...t.node,defineModel:"readonly",__APP_VERSION__:!0,__VITE_ENVIRONMENT__:!0,__CESIUM_STATIC_PATH__:!0,__IS_TESTING_WITH_CYPRESS__:!0},sourceType:"module"},rules:{...o,"mocha/no-exclusive-tests":"error",...u}},...p,...c,...l,h],q=s.config(n.flatConfigs.recommended,n.flatConfigs.typescript,...y,s.configs.recommended,...p,...l,{ignores:m},{files:["**/*.ts","**/*.tsx"],ignores:["**/*.md"],plugins:{perfectionist:i},languageOptions:{parserOptions:{projectService:!0,tsconfigRootDir:void 0}},rules:{...g,...o}},c);e.cypressConfig=j,e.default=q,e.jsConfig=y,e.markdownConfig=p,e.unitTestsConfig=c,e.vueConfig=l,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
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",
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": {
@@ -12,33 +17,35 @@
12
17
  }
13
18
  },
14
19
  "dependencies": {
15
- "@eslint/js": "^9.39.1",
20
+ "@eslint/js": "^9.39.2",
16
21
  "@eslint/markdown": "^7.5.1",
17
- "@typescript-eslint/utils": "^8.46.4",
22
+ "@typescript-eslint/utils": "^8.52.0",
18
23
  "@vue/eslint-config-prettier": "^10.2.0",
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
- "eslint-plugin-perfectionist": "^4.15.1",
29
+ "eslint-plugin-perfectionist": "^5.2.0",
24
30
  "eslint-plugin-prettier": "^5.5.4",
25
- "eslint-plugin-vue": "^10.5.1",
26
- "typescript-eslint": "^8.46.4"
31
+ "eslint-plugin-vue": "^10.6.2",
32
+ "typescript-eslint": "^8.52.0"
27
33
  },
28
34
  "devDependencies": {
29
- "@microsoft/api-extractor": "^7.55.0",
30
- "@types/node": "^24.10.1",
31
- "globals": "^16.5.0",
35
+ "@microsoft/api-extractor": "^7.55.2",
36
+ "@types/node": "ts5.9",
37
+ "globals": "^17.0.0",
32
38
  "typescript": "^5.9.3",
33
- "@swissgeo/config-typescript": "1.0.0-beta.3"
39
+ "unplugin-dts": "1.0.0-beta.6",
40
+ "vite": "7.2.2",
41
+ "@swissgeo/config-typescript": "1.0.0"
34
42
  },
35
43
  "peerDependencies": {
36
- "eslint": "^9.39.1",
37
- "@swissgeo/config-prettier": "1.0.0-beta.6",
38
- "@swissgeo/config-stylelint": "1.0.0-beta.3"
44
+ "eslint": "^9.39.2",
45
+ "@swissgeo/config-stylelint": "1.0.0"
39
46
  },
40
47
  "scripts": {
41
- "build": "pnpm run type-check && pnpm run generate-types",
48
+ "build": "pnpm run type-check && pnpm run generate-types && vite build",
42
49
  "generate-types": "tsc --declaration",
43
50
  "lint": "eslint --fix",
44
51
  "lint:no-fix": "eslint",
package/tsconfig.json CHANGED
@@ -1,11 +1,4 @@
1
1
  {
2
- "files": ["index.ts"],
3
- "compilerOptions": {
4
- "target": "ESNext",
5
- "module": "ESNext",
6
- "moduleResolution": "bundler",
7
- "noEmitOnError": false,
8
- "outDir": "dist",
9
- "types": ["node"]
10
- }
2
+ "extends": "@swissgeo/config-typescript/tsconfig.base.json",
3
+ "include": ["**/*.ts"]
11
4
  }
@@ -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
 
package/vite.config.ts ADDED
@@ -0,0 +1,38 @@
1
+ import type { UserConfig } from 'vite'
2
+
3
+ import { resolve } from 'path'
4
+ import dts from 'unplugin-dts/vite'
5
+
6
+ const config: UserConfig = {
7
+ build: {
8
+ lib: {
9
+ entry: {
10
+ index: resolve(__dirname, 'index.ts'),
11
+ },
12
+ name: '@swissgeo/config-eslint',
13
+ },
14
+ rollupOptions: {
15
+ // Mark ESLint-related packages as external so Vite doesn't try to bundle them.
16
+ // These packages use Node.js built-ins and can't be bundled for browser use.
17
+ // This is safe because the config is only used in Node.js during linting.
18
+ external: [
19
+ /^@eslint\/.*/,
20
+ /^@typescript-eslint\/.*/,
21
+ /^@vue\/.*/,
22
+ /^eslint.*/,
23
+ /^typescript-eslint/,
24
+ 'globals',
25
+ ],
26
+ output: {
27
+ exports: 'named',
28
+ },
29
+ },
30
+ },
31
+ plugins: [
32
+ dts({
33
+ bundleTypes: true,
34
+ }),
35
+ ],
36
+ }
37
+
38
+ export default config
@@ -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
- }