@enke.dev/lint 0.9.2 → 0.10.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 CHANGED
@@ -80,3 +80,11 @@ export default defineConfig({ cssCustomPropertyPrefix: 'your-prefix' });
80
80
  ```
81
81
 
82
82
  For now, [no TypeScript support](https://github.com/stylelint/stylelint/issues/4940) is possible.
83
+
84
+ ## Development
85
+
86
+ This repo self-tests the configuration by linting itself: `npm run lint`.\
87
+ Therefore, a `text.config.ts` is used.
88
+
89
+ And additionally, a naive test is in place to check that the linter actually finds issues: `npm run test`.\
90
+ It uses the native Node test runner against some obviously faulty code in the `test` directory.
@@ -1,2 +1,3 @@
1
- declare const _default: import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
1
+ import type { Linter } from 'eslint';
2
+ declare const _default: Linter.Config<Linter.RulesRecord>[];
2
3
  export default _default;
package/eslint.config.js CHANGED
@@ -1,45 +1,55 @@
1
1
  /// <reference types="./eslint-plugins.d.ts" />
2
+ import { readFile } from 'node:fs/promises';
2
3
  import { fixupPluginRules } from '@eslint/compat';
3
- import eslintJs from '@eslint/js';
4
- import eslintJson from '@eslint/json';
5
- import { defineConfig } from 'eslint/config';
6
- import eslintPluginHtml from 'eslint-plugin-html';
4
+ import eslintPluginJs from '@eslint/js';
5
+ import eslintPluginJson from '@eslint/json';
6
+ import eslintPluginHtml from '@html-eslint/eslint-plugin';
7
+ import eslintParserHtml from '@html-eslint/parser';
8
+ import { defineConfig, globalIgnores } from 'eslint/config';
9
+ import eslintPluginHtmlScripts from 'eslint-plugin-html';
7
10
  import eslintPluginImport from 'eslint-plugin-import';
8
11
  import eslintPluginImportExtension from 'eslint-plugin-import-extensions';
9
12
  import { configs as eslintPluginLitConfigs } from 'eslint-plugin-lit';
10
13
  import { configs as eslintPluginLitA11yConfigs } from 'eslint-plugin-lit-a11y';
11
- import { configs as eslintPluginPackageJsonConfigs } from 'eslint-plugin-package-json';
12
14
  import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
13
15
  import eslintPluginSimpleImportSort from 'eslint-plugin-simple-import-sort';
14
16
  import eslintPluginUnusedImports from 'eslint-plugin-unused-imports';
15
17
  import { configs as eslintPluginWebComponentsConfigs } from 'eslint-plugin-wc';
16
18
  import eslintTs from 'typescript-eslint';
19
+ // collect gitignore excludes
20
+ const gitIgnores = await readFile(new URL('./.gitignore', import.meta.url), 'utf-8');
21
+ const gitIgnoreLines = gitIgnores
22
+ .split('\n')
23
+ .map(line => line.trim().replace(/^\//, ''))
24
+ .filter(line => line && !line.startsWith('#'));
25
+ // shared parser options
26
+ const parserOptions = {
27
+ ecmaVersion: 'latest',
28
+ sourceType: 'module',
29
+ };
17
30
  export default defineConfig([
18
- eslintJs.configs.recommended,
19
- ...eslintTs.configs.strict,
20
- ...eslintTs.configs.stylistic,
31
+ globalIgnores([...gitIgnoreLines, 'dist/']),
21
32
  eslintPluginPrettierRecommended,
22
- eslintPluginImport.flatConfigs.recommended,
23
- {
24
- ignores: ['node_modules/', 'dist/'],
25
- },
26
33
  // Javascript and Typescript files
27
34
  {
28
- files: ['**/*.{js,ts}'],
29
- ...eslintPluginWebComponentsConfigs['flat/recommended'],
30
- ...eslintPluginLitConfigs['flat/recommended'],
31
- ...eslintPluginLitA11yConfigs.recommended,
35
+ files: ['**/*.js', '**/*.ts'],
36
+ extends: [
37
+ eslintPluginJs.configs.recommended,
38
+ ...eslintTs.configs.strict,
39
+ ...eslintTs.configs.stylistic,
40
+ eslintPluginWebComponentsConfigs['flat/recommended'],
41
+ eslintPluginLitConfigs['flat/recommended'],
42
+ eslintPluginLitA11yConfigs.recommended,
43
+ eslintPluginImport.flatConfigs.recommended,
44
+ ],
32
45
  plugins: {
33
46
  'simple-import-sort': eslintPluginSimpleImportSort,
34
47
  'unused-imports': eslintPluginUnusedImports,
35
48
  'import-extensions': fixupPluginRules(eslintPluginImportExtension),
49
+ html: eslintPluginHtml,
50
+ htmlScripts: eslintPluginHtmlScripts,
36
51
  },
37
- languageOptions: {
38
- parserOptions: {
39
- ecmaVersion: 'latest',
40
- sourceType: 'module',
41
- },
42
- },
52
+ languageOptions: { parserOptions },
43
53
  settings: {
44
54
  'import/resolver': {
45
55
  typescript: true,
@@ -57,6 +67,16 @@ export default defineConfig([
57
67
  'linebreak-style': ['error', 'unix'],
58
68
  quotes: ['error', 'single', { avoidEscape: true }],
59
69
  semi: ['error', 'always'],
70
+ 'no-console': 'error',
71
+ // inline html
72
+ 'html/require-img-alt': 'error',
73
+ 'html/no-multiple-h1': 'error',
74
+ 'html/no-extra-spacing-attrs': 'error',
75
+ 'html/no-duplicate-id': 'error',
76
+ 'html/require-li-container': 'error',
77
+ 'html/no-obsolete-tags': 'error',
78
+ 'html/require-closing-tags': 'error',
79
+ 'html/no-duplicate-attrs': 'error',
60
80
  // import sorting
61
81
  'simple-import-sort/imports': [
62
82
  'error',
@@ -108,21 +128,49 @@ export default defineConfig([
108
128
  // HTML files
109
129
  {
110
130
  files: ['**/*.html'],
111
- plugins: { html: eslintPluginHtml },
131
+ plugins: {
132
+ html: eslintPluginHtml,
133
+ htmlScripts: eslintPluginHtmlScripts,
134
+ },
135
+ extends: [eslintPluginHtml.configs['flat/recommended']],
136
+ language: 'html/html',
137
+ languageOptions: {
138
+ parser: eslintParserHtml,
139
+ parserOptions,
140
+ },
141
+ settings: {
142
+ 'html/indent': '+2',
143
+ 'html/lowercase': 'error',
144
+ 'html/no-accesskey-attrs': 'error',
145
+ 'html/no-aria-hidden-body': 'error',
146
+ 'html/no-aria-hidden-on-focusable': 'error',
147
+ 'html/no-duplicate-class': 'error',
148
+ 'html/no-duplicate-in-head': 'error',
149
+ 'html/no-empty-headings': 'error',
150
+ 'html/no-invalid-entities': 'error',
151
+ 'html/no-heading-inside-button': 'error',
152
+ 'html/no-invalid-entity': 'error',
153
+ 'html/no-invalid-role': 'error',
154
+ 'html/no-nested-interactive': 'error',
155
+ 'html/no-multiple-empty-lines': 'error',
156
+ 'html/no-target-blank': 'error',
157
+ 'html/no-trailing-spaces': 'error',
158
+ 'html/report-bad-indent': 'error',
159
+ 'html/require-input-label': 'error',
160
+ },
161
+ rules: {
162
+ 'html/indent': ['error', 2],
163
+ },
112
164
  },
113
165
  // JSON files
114
166
  {
115
- ...eslintPluginPackageJsonConfigs.recommended,
116
- ...eslintJson.configs.recommended,
117
- ignores: ['package-lock.json'],
167
+ files: ['**/*.json'],
118
168
  language: 'json/json',
169
+ ignores: ['package-lock.json'],
170
+ plugins: { json: eslintPluginJson },
171
+ extends: [eslintPluginJson.configs.recommended],
119
172
  rules: {
120
- 'no-irregular-whitespace': 'off',
121
- 'import-extensions/require-extensions': 'off',
122
- 'import-extensions/require-index': 'off',
123
- },
124
- settings: {
125
- 'html/html-extensions': ['.html'],
173
+ 'json/top-level-interop': 'error',
126
174
  },
127
175
  },
128
176
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enke.dev/lint",
3
- "version": "0.9.2",
3
+ "version": "0.10.1",
4
4
  "description": "Meta package to provide linting for web projects",
5
5
  "homepage": "https://github.com/enke-dev/lint",
6
6
  "repository": {
@@ -19,10 +19,11 @@
19
19
  "main": "eslint.config.js",
20
20
  "types": "eslint.config.d.ts",
21
21
  "scripts": {
22
- "lint": "eslint -c eslint.config.ts ./*.config.ts",
22
+ "lint": "eslint -c test.config.ts .",
23
+ "test": "node --experimental-strip-types --test test.run.ts",
23
24
  "inspect": "./node_modules/.bin/eslint-config-inspector --config eslint.config.ts",
24
- "dev": "tsc --watch",
25
- "build": "tsc"
25
+ "dev": "tsc -p tsconfig.build.json --watch",
26
+ "build": "tsc -p tsconfig.build.json"
26
27
  },
27
28
  "author": {
28
29
  "name": "David Enke",
@@ -46,21 +47,23 @@
46
47
  "typescript-eslint": "^8.43.0"
47
48
  },
48
49
  "dependencies": {
49
- "@eslint/compat": "^1.3.2",
50
- "@eslint/js": "^9.35.0",
51
- "@eslint/json": "^0.13.2",
52
- "eslint-config-prettier": "^10.1.8",
53
- "eslint-import-resolver-typescript": "^4.4.4",
54
- "eslint-plugin-html": "^8.1.3",
55
- "eslint-plugin-import": "^2.32.0",
56
- "eslint-plugin-import-extensions": "^0.1.5",
57
- "eslint-plugin-lit": "^2.1.1",
58
- "eslint-plugin-lit-a11y": "^5.1.1",
59
- "eslint-plugin-package-json": "^0.56.2",
60
- "eslint-plugin-prettier": "^5.5.4",
61
- "eslint-plugin-simple-import-sort": "^12.1.1",
62
- "eslint-plugin-unused-imports": "^4.2.0",
63
- "eslint-plugin-wc": "^3.0.1"
50
+ "@eslint/compat": "1.3.2",
51
+ "@eslint/js": "9.35.0",
52
+ "@eslint/json": "0.13.2",
53
+ "@html-eslint/eslint-plugin": "0.46.2",
54
+ "@html-eslint/parser": "0.46.2",
55
+ "eslint-config-prettier": "10.1.8",
56
+ "eslint-import-resolver-typescript": "4.4.4",
57
+ "eslint-plugin-html": "8.1.3",
58
+ "eslint-plugin-import": "2.32.0",
59
+ "eslint-plugin-import-extensions": "0.1.5",
60
+ "eslint-plugin-lit": "2.1.1",
61
+ "eslint-plugin-lit-a11y": "5.1.1",
62
+ "eslint-plugin-package-json": "0.56.2",
63
+ "eslint-plugin-prettier": "5.5.4",
64
+ "eslint-plugin-simple-import-sort": "12.1.1",
65
+ "eslint-plugin-unused-imports": "4.2.0",
66
+ "eslint-plugin-wc": "3.0.1"
64
67
  },
65
68
  "devDependencies": {
66
69
  "@eslint/config-inspector": "1.2.0",