@alexlit/lint-kit 214.4.0 → 215.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.
Files changed (155) hide show
  1. package/README.md +27 -22
  2. package/eslint.config.js +23 -56
  3. package/lint-staged.config.js +2 -2
  4. package/linthtml.config.js +2 -2
  5. package/package.json +3 -2
  6. package/packages/config-eslint/README.md +156 -106
  7. package/packages/config-eslint/base.js +5 -3
  8. package/packages/config-eslint/index.d.ts +112 -0
  9. package/packages/config-eslint/index.js +79 -23
  10. package/packages/config-eslint/package.json +19 -16
  11. package/packages/config-eslint/plugins/de-morgan.js +9 -4
  12. package/packages/config-eslint/plugins/import-x.js +50 -37
  13. package/packages/config-eslint/plugins/javascript.js +96 -85
  14. package/packages/config-eslint/plugins/jsdoc.js +24 -17
  15. package/packages/config-eslint/plugins/json.js +31 -24
  16. package/packages/config-eslint/plugins/perfectionist.js +108 -95
  17. package/packages/config-eslint/plugins/pinia.js +17 -10
  18. package/packages/config-eslint/plugins/prettier.js +24 -10
  19. package/packages/config-eslint/plugins/regexp.js +16 -9
  20. package/packages/config-eslint/plugins/sonar.js +19 -12
  21. package/packages/config-eslint/plugins/stylistic.js +107 -100
  22. package/packages/config-eslint/plugins/tailwindcss.js +17 -6
  23. package/packages/config-eslint/plugins/tanstack-query.js +16 -9
  24. package/packages/config-eslint/plugins/typescript-type-checked.js +38 -33
  25. package/packages/config-eslint/plugins/typescript.js +23 -14
  26. package/packages/config-eslint/plugins/unicorn.js +73 -64
  27. package/packages/config-eslint/plugins/unocss.js +12 -5
  28. package/packages/config-eslint/plugins/vitest.js +20 -13
  29. package/packages/config-eslint/plugins/vue-accessibility.js +22 -13
  30. package/packages/config-eslint/plugins/vue-i18n.js +38 -31
  31. package/packages/config-eslint/plugins/vue.js +255 -242
  32. package/packages/config-eslint/plugins/zod.js +17 -10
  33. package/packages/config-eslint/rules/typescript.js +1 -1
  34. package/packages/config-hooks/README.md +119 -37
  35. package/packages/config-hooks/index.d.ts +19 -0
  36. package/packages/config-hooks/lint-staged.js +8 -6
  37. package/packages/config-hooks/package.json +3 -1
  38. package/packages/config-htmllint/README.md +50 -22
  39. package/packages/config-htmllint/index.d.ts +13 -0
  40. package/packages/config-htmllint/index.js +15 -7
  41. package/packages/config-htmllint/package.json +4 -2
  42. package/packages/config-markdownlint/README.md +40 -5
  43. package/packages/config-markdownlint/index.json +0 -2
  44. package/packages/config-markdownlint/package.json +1 -1
  45. package/packages/config-npmlint/README.md +48 -5
  46. package/packages/config-npmlint/package.json +3 -3
  47. package/packages/config-prettier/README.md +106 -23
  48. package/packages/config-prettier/index.d.ts +92 -0
  49. package/packages/config-prettier/index.js +60 -74
  50. package/packages/config-prettier/package.json +4 -3
  51. package/packages/config-prettier/plugins/jsdoc.js +12 -3
  52. package/packages/config-prettier/plugins/mdc.js +12 -3
  53. package/packages/config-prettier/plugins/packagejson.js +12 -3
  54. package/packages/config-prettier/plugins/php.js +12 -3
  55. package/packages/config-prettier/plugins/pug.js +12 -3
  56. package/packages/config-prettier/plugins/ruby.js +10 -10
  57. package/packages/config-prettier/plugins/sh.js +12 -3
  58. package/packages/config-prettier/plugins/solidity.js +12 -3
  59. package/packages/config-prettier/plugins/sort-json.js +12 -3
  60. package/packages/config-prettier/plugins/sql.js +12 -3
  61. package/packages/config-prettier/plugins/tailwindcss.js +12 -3
  62. package/packages/config-prettier/plugins/xml.js +12 -3
  63. package/packages/config-stylelint/README.md +131 -44
  64. package/packages/config-stylelint/index.d.ts +52 -0
  65. package/packages/config-stylelint/index.js +169 -165
  66. package/packages/config-stylelint/package.json +3 -1
  67. package/packages/config-stylelint/plugins/a11y.js +24 -11
  68. package/packages/config-stylelint/plugins/bem.js +10 -3
  69. package/packages/config-stylelint/plugins/color-format.js +14 -4
  70. package/packages/config-stylelint/plugins/declaration-block-no-ignored-properties.js +15 -4
  71. package/packages/config-stylelint/plugins/gamut.js +12 -4
  72. package/packages/config-stylelint/plugins/high-performance-animation.js +12 -3
  73. package/packages/config-stylelint/plugins/logical-css.js +10 -3
  74. package/packages/config-stylelint/plugins/media-use-custom-media.js +12 -4
  75. package/packages/config-stylelint/plugins/no-indistinguishable-colors.js +15 -4
  76. package/packages/config-stylelint/plugins/no-nested-media.js +12 -4
  77. package/packages/config-stylelint/plugins/no-unresolved-module.js +12 -3
  78. package/packages/config-stylelint/plugins/no-unsupported-browser-features.js +12 -3
  79. package/packages/config-stylelint/plugins/order.js +13 -3
  80. package/packages/config-stylelint/plugins/prettier.js +12 -4
  81. package/packages/config-stylelint/plugins/scss.js +13 -3
  82. package/packages/config-stylelint/plugins/selector-no-empty.js +12 -4
  83. package/packages/config-stylelint/plugins/use-nesting.js +15 -4
  84. package/packages/config-stylelint/plugins/vue.js +11 -2
  85. package/prettier.config.js +15 -7
  86. package/scripts/semver.sh +3 -3
  87. package/stylelint.config.js +25 -11
  88. package/packages/config-eslint/_legacy/LICENSE +0 -20
  89. package/packages/config-eslint/_legacy/README.md +0 -48
  90. package/packages/config-eslint/_legacy/constants/allow-boolean-property-list.js +0 -38
  91. package/packages/config-eslint/_legacy/constants/boolean-prefixes.js +0 -11
  92. package/packages/config-eslint/_legacy/constants/english-verbs.js +0 -3368
  93. package/packages/config-eslint/_legacy/dictionaries/index.js +0 -467
  94. package/packages/config-eslint/_legacy/dictionaries/programming/bash.js +0 -25
  95. package/packages/config-eslint/_legacy/dictionaries/programming/django.js +0 -2345
  96. package/packages/config-eslint/_legacy/dictionaries/programming/elixir.js +0 -64
  97. package/packages/config-eslint/_legacy/dictionaries/programming/go.js +0 -7748
  98. package/packages/config-eslint/_legacy/dictionaries/programming/java.js +0 -33527
  99. package/packages/config-eslint/_legacy/dictionaries/programming/latex.js +0 -675
  100. package/packages/config-eslint/_legacy/dictionaries/programming/lua.js +0 -394
  101. package/packages/config-eslint/_legacy/dictionaries/programming/php.js +0 -9788
  102. package/packages/config-eslint/_legacy/dictionaries/programming/python.js +0 -367
  103. package/packages/config-eslint/_legacy/dictionaries/programming/ruby.js +0 -357
  104. package/packages/config-eslint/_legacy/dictionaries/programming/rust.js +0 -115
  105. package/packages/config-eslint/_legacy/dictionaries/programming/scala.js +0 -2755
  106. package/packages/config-eslint/_legacy/dictionaries/specialized/html-symbol-entities.js +0 -1118
  107. package/packages/config-eslint/_legacy/dictionaries/specialized/lorem-ipsum.js +0 -359
  108. package/packages/config-eslint/_legacy/index.js +0 -12
  109. package/packages/config-eslint/_legacy/legacy.js +0 -3
  110. package/packages/config-eslint/_legacy/package.json +0 -97
  111. package/packages/config-eslint/_legacy/plugins/array-func.js +0 -20
  112. package/packages/config-eslint/_legacy/plugins/compat.js +0 -7
  113. package/packages/config-eslint/_legacy/plugins/decorator-position.js +0 -15
  114. package/packages/config-eslint/_legacy/plugins/eslint-comments.js +0 -9
  115. package/packages/config-eslint/_legacy/plugins/etc.js +0 -13
  116. package/packages/config-eslint/_legacy/plugins/ext.js +0 -12
  117. package/packages/config-eslint/_legacy/plugins/filenames.js +0 -38
  118. package/packages/config-eslint/_legacy/plugins/import.js +0 -133
  119. package/packages/config-eslint/_legacy/plugins/jsdoc.js +0 -32
  120. package/packages/config-eslint/_legacy/plugins/jsx-a11y.js +0 -5
  121. package/packages/config-eslint/_legacy/plugins/lit-a11y.js +0 -5
  122. package/packages/config-eslint/_legacy/plugins/lit.js +0 -9
  123. package/packages/config-eslint/_legacy/plugins/more.js +0 -17
  124. package/packages/config-eslint/_legacy/plugins/no-await-in-promise.js +0 -5
  125. package/packages/config-eslint/_legacy/plugins/no-constructor-bind.js +0 -8
  126. package/packages/config-eslint/_legacy/plugins/no-explicit-type-exports.js +0 -7
  127. package/packages/config-eslint/_legacy/plugins/no-loops.js +0 -7
  128. package/packages/config-eslint/_legacy/plugins/no-secrets.js +0 -12
  129. package/packages/config-eslint/_legacy/plugins/no-use-extend-native.js +0 -5
  130. package/packages/config-eslint/_legacy/plugins/node.js +0 -5
  131. package/packages/config-eslint/_legacy/plugins/prettier.js +0 -24
  132. package/packages/config-eslint/_legacy/plugins/promise.js +0 -10
  133. package/packages/config-eslint/_legacy/plugins/regexp.js +0 -7
  134. package/packages/config-eslint/_legacy/plugins/security.js +0 -10
  135. package/packages/config-eslint/_legacy/plugins/simple-import-sort.js +0 -7
  136. package/packages/config-eslint/_legacy/plugins/sonar.js +0 -5
  137. package/packages/config-eslint/_legacy/plugins/sort-class-members.js +0 -298
  138. package/packages/config-eslint/_legacy/plugins/sort-destructure-keys.js +0 -10
  139. package/packages/config-eslint/_legacy/plugins/sort-keys-fix.js +0 -7
  140. package/packages/config-eslint/_legacy/plugins/spellcheck.js +0 -9
  141. package/packages/config-eslint/_legacy/plugins/sql.js +0 -26
  142. package/packages/config-eslint/_legacy/plugins/tanstack-query.js +0 -4
  143. package/packages/config-eslint/_legacy/plugins/testing-library.js +0 -9
  144. package/packages/config-eslint/_legacy/plugins/typescript-sort-keys.js +0 -5
  145. package/packages/config-eslint/_legacy/plugins/typescript.js +0 -157
  146. package/packages/config-eslint/_legacy/plugins/unicorn.js +0 -70
  147. package/packages/config-eslint/_legacy/plugins/unused-imports.js +0 -17
  148. package/packages/config-eslint/_legacy/plugins/vitest.js +0 -16
  149. package/packages/config-eslint/_legacy/plugins/vue-i18n.js +0 -34
  150. package/packages/config-eslint/_legacy/plugins/vue.js +0 -291
  151. package/packages/config-eslint/_legacy/plugins/vuejs-accessibility.js +0 -20
  152. package/packages/config-eslint/_legacy/plugins/wc.js +0 -5
  153. package/packages/config-eslint/_legacy/plugins/write-good-comments.js +0 -7
  154. package/packages/config-eslint/_legacy/utils/create-config.js +0 -377
  155. package/packages/config-eslint/_legacy/utils/extend-spell-checker.js +0 -23
@@ -1,62 +1,149 @@
1
- # StyleLint Configuration
1
+ [![version](https://npmx.dev/api/registry/badge/version/@alexlit/config-stylelint)](https://www.npmjs.com/package/@alexlit/config-stylelint)
2
+ [![downloads](https://npmx.dev/api/registry/badge/downloads/@alexlit/config-stylelint)](https://npmx.dev/package/@alexlit/config-stylelint)
3
+ [![license](https://npmx.dev/api/registry/badge/license/@alexlit/config-stylelint)](LICENSE)
2
4
 
3
- ## Installation
5
+ # Stylelint Configuration
4
6
 
5
- ```sh
7
+ Готовая конфигурация [Stylelint](https://stylelint.io/) для проверки CSS, SCSS и
8
+ Vue-файлов: настроенные правила из популярных stylelint-плагинов - порядок и
9
+ синтаксис свойств, доступность, БЭМ, поддержка SCSS и т.д. Вместо того чтобы
10
+ подключать и настраивать каждый плагин вручную, соберите конфигурацию из готовых
11
+ проверок.
12
+
13
+ Проверки модульные: по умолчанию ничего не включено - вы сами перечисляете
14
+ нужные в `defineConfig`.
15
+
16
+ ## Установка
17
+
18
+ ```bash
6
19
  npm i @alexlit/config-stylelint -D
7
20
  ```
8
21
 
9
- ## Connection
22
+ ## Быстрый старт
10
23
 
11
- - Default
12
- ([see plugins enabled by default](https://github.com/alex-lit/lint-kit/blob/master/packages/config-stylelint/index.js))
24
+ ```js
25
+ // stylelint.config.js
26
+ import { defineConfig, plugins } from '@alexlit/config-stylelint';
13
27
 
14
- ```js
15
- // stylelint.config.js
16
- import { createConfig } from '@alexlit/config-stylelint';
28
+ export default defineConfig([
29
+ plugins.scss(),
30
+ plugins.vue(),
31
+ plugins.prettier(),
32
+ ]);
33
+ ```
17
34
 
18
- export default createConfig();
19
- ```
35
+ Каждый вызов `plugins.*()` - отдельная проверка. Добавьте только то, что нужно
36
+ проекту; полный список - в разделе [Проверки](#проверки).
20
37
 
21
- - Custom
22
-
23
- ```js
24
- // stylelint.config.js
25
- import { createConfig } from '@alexlit/config-stylelint';
26
-
27
- export default createConfig(
28
- {
29
- // disable some default plugins
30
- 'no-nested-media': false,
31
-
32
- // enable some optional plugins
33
- 'gamut': true,
34
- 'logical-css': true,
35
- },
36
- {
37
- // add custom rules
38
- rules: {
39
- 'custom-property-empty-line-before': [
40
- 'always',
41
- {
42
- except: ['after-comment', 'after-custom-property', 'first-nested'],
43
- },
44
- ],
45
- },
46
- },
47
- );
48
- ```
38
+ Больше проверок - просто допишите их в массив:
39
+
40
+ ```js
41
+ // stylelint.config.js
42
+ import { defineConfig, plugins } from '@alexlit/config-stylelint';
43
+
44
+ export default defineConfig([
45
+ plugins.colorFormat(),
46
+ plugins.declarationBlockNoIgnoredProperties(),
47
+ plugins.highPerformanceAnimation(),
48
+ plugins.noNestedMedia(),
49
+ plugins.order(),
50
+ plugins.scss(),
51
+ plugins.selectorNoEmpty(),
52
+ plugins.useNesting(),
53
+ plugins.vue(),
54
+ plugins.a11y(),
55
+ plugins.bem(),
56
+ plugins.gamut(),
57
+ plugins.logicalCss(),
58
+ plugins.mediaUseCustomMedia(),
59
+ plugins.noUnresolvedModule(),
60
+ plugins.noUnsupportedBrowserFeatures(),
61
+ plugins.prettier(),
62
+ ]);
63
+ ```
64
+
65
+ ## Настройка
66
+
67
+ ### Правила конкретной проверки
68
+
69
+ Чтобы переопределить правила одной проверки, передайте объект в её вызов:
70
+
71
+ ```js
72
+ // stylelint.config.js
73
+ import { defineConfig, plugins } from '@alexlit/config-stylelint';
74
+
75
+ export default defineConfig([
76
+ plugins.useNesting({ rules: { 'csstools/use-nesting': 'never' } }),
77
+ plugins.noUnresolvedModule({
78
+ rules: { 'plugin/no-unresolved-module': { alias: { '~': 'src' } } },
79
+ }),
80
+ ]);
81
+ ```
82
+
83
+ ### Общие настройки Stylelint
84
+
85
+ Второй аргумент `defineConfig` - общие опции: собственные правила, файлы для
86
+ игнора и т.д. Он перебивает настройки всех проверок:
87
+
88
+ ```js
89
+ // stylelint.config.js
90
+ import { defineConfig, plugins } from '@alexlit/config-stylelint';
91
+
92
+ export default defineConfig([plugins.scss(), plugins.vue()], {
93
+ ignoreFiles: ['fixtures/**'],
94
+ rules: { 'max-nesting-depth': 3 },
95
+ });
96
+ ```
97
+
98
+ ## Проверки
99
+
100
+ | Проверка | Что делает | Плагин |
101
+ | ----------------------------------------------- | ---------------------------------------------------- | --------------------------------------------------- |
102
+ | `plugins.a11y()` | Проверяет типичные ошибки доступности | `@double-great/stylelint-a11y` |
103
+ | `plugins.bem()` | Настраивает линтинг по методологии БЭМ | `@morev/stylelint-plugin` |
104
+ | `plugins.colorFormat()` | Нормализует формат цветов (hex → rgb/hsl) | встроенное правило `color-format/format` |
105
+ | `plugins.declarationBlockNoIgnoredProperties()` | Запрещает бесполезные свойства в блоке объявлений | `stylelint-declaration-block-no-ignored-properties` |
106
+ | `plugins.gamut()` | Проверяет цвета на выход за пределы цветового охвата | `stylelint-gamut` |
107
+ | `plugins.highPerformanceAnimation()` | Запрещает анимации, нагружающие рендеринг | `stylelint-high-performance-animation` |
108
+ | `plugins.logicalCss()` | Проверяет использование логических CSS-свойств | `stylelint-plugin-logical-css` |
109
+ | `plugins.mediaUseCustomMedia()` | Требует использования кастомных медиа-запросов | `stylelint-media-use-custom-media` |
110
+ | `plugins.noIndistinguishableColors()` | Запрещает неразличимые цвета | `stylelint-no-indistinguishable-colors` |
111
+ | `plugins.noNestedMedia()` | Запрещает вложенные медиа-запросы | `stylelint-no-nested-media` |
112
+ | `plugins.noUnresolvedModule()` | Проверяет разрешение импортов | `stylelint-no-unresolved-module` |
113
+ | `plugins.noUnsupportedBrowserFeatures()` | Проверяет поддержку CSS-функций целевыми браузерами | `stylelint-no-unsupported-browser-features` |
114
+ | `plugins.order()` | Настраивает порядок свойств и селекторов | `stylelint-order` |
115
+ | `plugins.prettier()` | Интегрирует Prettier | `stylelint-prettier` |
116
+ | `plugins.scss()` | Настраивает линтинг SCSS | `stylelint-scss` |
117
+ | `plugins.selectorNoEmpty()` | Запрещает пустые селекторы | `stylelint-selector-no-empty` |
118
+ | `plugins.useNesting()` | Требует использования CSS-вложенности | `stylelint-use-nesting` |
119
+ | `plugins.vue()` | Подключает поддержку Vue.js SFC | `stylelint-config-recommended-vue` |
120
+
121
+ ## Миграция с v61
122
+
123
+ v62 - breaking-релиз: проверок по умолчанию больше нет, всё подключается явно.
124
+
125
+ | v61 | v62 |
126
+ | ------------------------------- | ---------------------------------------------- |
127
+ | `createConfig()` | перечислите нужные проверки явно |
128
+ | `createConfig({ gamut: true })` | `defineConfig([plugins.gamut()])` |
129
+ | `createConfig({ scss: false })` | просто не добавляйте `plugins.scss()` в список |
130
+ | `createConfig({}, options)` | `defineConfig([...], options)` |
131
+
132
+ Проверки, включённые по умолчанию в v61: `color-format`,
133
+ `declaration-block-no-ignored-properties`, `high-performance-animation`,
134
+ `no-nested-media`, `order`, `scss`, `selector-no-empty`, `use-nesting`, `vue`, а
135
+ также `prettier`.
49
136
 
50
- ## Development
137
+ ## Разработка
51
138
 
52
- - Check rules
139
+ - Проверка актуальности правил:
53
140
 
54
- ```sh
141
+ ```bash
55
142
  npx stylelint-find-new-rules
56
143
  ```
57
144
 
58
- ## Useful links
145
+ ## Полезные ссылки
59
146
 
60
- - [Awesome StyleLint](https://github.com/stylelint/awesome-stylelint)
147
+ - [awesome-stylelint](https://github.com/stylelint/awesome-stylelint)
61
148
  - [stylelint-scales](https://github.com/jeddy3/stylelint-scales)
62
149
  - [stylelint-value-no-unknown-custom-properties](https://github.com/csstools/stylelint-value-no-unknown-custom-properties)
@@ -0,0 +1,52 @@
1
+ import type { Config } from 'stylelint';
2
+
3
+ /**
4
+ * Опции фабрики плагина - частичный конфиг Stylelint, накладываемый поверх
5
+ * значений по умолчанию.
6
+ */
7
+ type PluginOptions = Partial<Config>;
8
+
9
+ /**
10
+ * Пространство имён фабрик конфигов плагинов. Дефолтных плагинов нет -
11
+ * подключайте нужные явно.
12
+ */
13
+ interface Plugins {
14
+ a11y: (options?: PluginOptions) => Config;
15
+ bem: (options?: PluginOptions) => Config;
16
+ colorFormat: (options?: PluginOptions) => Config;
17
+ declarationBlockNoIgnoredProperties: (options?: PluginOptions) => Config;
18
+ gamut: (options?: PluginOptions) => Config;
19
+ highPerformanceAnimation: (options?: PluginOptions) => Config;
20
+ logicalCss: (options?: PluginOptions) => Config;
21
+ mediaUseCustomMedia: (options?: PluginOptions) => Config;
22
+ noIndistinguishableColors: (options?: PluginOptions) => Config;
23
+ noNestedMedia: (options?: PluginOptions) => Config;
24
+ noUnresolvedModule: (options?: PluginOptions) => Config;
25
+ noUnsupportedBrowserFeatures: (options?: PluginOptions) => Config;
26
+ order: (options?: PluginOptions) => Config;
27
+ prettier: (options?: PluginOptions) => Config;
28
+ scss: (options?: PluginOptions) => Config;
29
+ selectorNoEmpty: (options?: PluginOptions) => Config;
30
+ useNesting: (options?: PluginOptions) => Config;
31
+ vue: (options?: PluginOptions) => Config;
32
+ }
33
+
34
+ /** Пространство имён фабрик конфигов плагинов. */
35
+ declare const plugins: Plugins;
36
+
37
+ /**
38
+ * Создать конфиг Stylelint.
39
+ *
40
+ * Приоритет (от низкого к высокому): база → конфиги плагинов по порядку →
41
+ * `options`. `extends`, `ignoreFiles`, `overrides` и `plugins` конкатенируются
42
+ * (дубли `plugins` убираются), `rules` - shallow merge.
43
+ *
44
+ * @param pluginConfigs - Конфиги плагинов (например, `[plugins.scss()]`)
45
+ * @param options - Базовые опции Stylelint, наивысший приоритет
46
+ */
47
+ declare function defineConfig(
48
+ pluginConfigs?: Config[],
49
+ options?: Config,
50
+ ): Config;
51
+
52
+ export { defineConfig, plugins };
@@ -1,178 +1,182 @@
1
1
  /* eslint-disable unicorn/no-null */
2
+ import { a11y } from './plugins/a11y.js';
3
+ import { bem } from './plugins/bem.js';
4
+ import { colorFormat } from './plugins/color-format.js';
5
+ import { declarationBlockNoIgnoredProperties } from './plugins/declaration-block-no-ignored-properties.js';
6
+ import { gamut } from './plugins/gamut.js';
7
+ import { highPerformanceAnimation } from './plugins/high-performance-animation.js';
8
+ import { logicalCss } from './plugins/logical-css.js';
9
+ import { mediaUseCustomMedia } from './plugins/media-use-custom-media.js';
10
+ import { noIndistinguishableColors } from './plugins/no-indistinguishable-colors.js';
11
+ import { noNestedMedia } from './plugins/no-nested-media.js';
12
+ import { noUnresolvedModule } from './plugins/no-unresolved-module.js';
13
+ import { noUnsupportedBrowserFeatures } from './plugins/no-unsupported-browser-features.js';
14
+ import { order } from './plugins/order.js';
15
+ import { prettier } from './plugins/prettier.js';
16
+ import { scss } from './plugins/scss.js';
17
+ import { selectorNoEmpty } from './plugins/selector-no-empty.js';
18
+ import { useNesting } from './plugins/use-nesting.js';
19
+ import { vue } from './plugins/vue.js';
2
20
 
3
- const DEFAULT_PLUGINS = {
4
- 'color-format': true,
5
- 'declaration-block-no-ignored-properties': true,
6
- 'high-performance-animation': true,
7
- 'no-nested-media': true,
8
- 'order': true,
9
- 'scss': true,
10
- 'selector-no-empty': true,
11
- 'use-nesting': true,
12
- 'vue': true,
21
+ /** Плагины. Дефолтных плагинов нет - подключайте нужные явно в `defineConfig`. */
22
+ const plugins = {
23
+ a11y,
24
+ bem,
25
+ colorFormat,
26
+ declarationBlockNoIgnoredProperties,
27
+ gamut,
28
+ highPerformanceAnimation,
29
+ logicalCss,
30
+ mediaUseCustomMedia,
31
+ noIndistinguishableColors,
32
+ noNestedMedia,
33
+ noUnresolvedModule,
34
+ noUnsupportedBrowserFeatures,
35
+ order,
36
+ prettier,
37
+ scss,
38
+ selectorNoEmpty,
39
+ useNesting,
40
+ vue,
13
41
  };
14
42
 
15
- const OPTIONAL_PLUGINS = {
16
- 'a11y': false,
17
- 'bem': false,
18
- 'gamut': false,
19
- 'logical-css': false,
20
- 'media-use-custom-media': false,
21
- 'no-indistinguishable-colors': false,
22
- 'no-unresolved-module': false,
23
- 'no-unsupported-browser-features': false,
24
- };
25
-
26
- const CODESTYLE_PLUGINS = { prettier: true };
27
-
28
- const PLUGINS = {
29
- ...DEFAULT_PLUGINS,
30
- ...OPTIONAL_PLUGINS,
31
- ...CODESTYLE_PLUGINS,
43
+ /** Базовые правила, применяются всегда (ниже опций плагинов и `options`). */
44
+ const BASE_RULES = {
45
+ 'alpha-value-notation': 'number',
46
+ 'annotation-no-unknown': [true, { ignoreAnnotations: ['default'] }],
47
+ 'at-rule-disallowed-list': ['debug'],
48
+ 'at-rule-empty-line-before': [
49
+ 'always',
50
+ {
51
+ except: ['blockless-after-same-name-blockless', 'first-nested'],
52
+ ignoreAtRules: ['else'],
53
+ },
54
+ ],
55
+ 'at-rule-no-deprecated': [true, { ignoreAtRules: ['apply', 'tailwind'] }],
56
+ 'at-rule-no-unknown': null,
57
+ 'at-rule-no-vendor-prefix': true,
58
+ 'block-no-empty': null,
59
+ 'color-function-notation': 'modern',
60
+ 'color-hex-length': 'short',
61
+ 'color-no-hex': true,
62
+ 'color-no-invalid-hex': true,
63
+ 'custom-property-empty-line-before': [
64
+ 'always',
65
+ { except: ['after-comment', 'after-custom-property', 'first-nested'] },
66
+ ],
67
+ 'custom-property-pattern': '^_?[a-z]+([a-z0-9-]+[a-z0-9]+)?$',
68
+ 'declaration-block-no-redundant-longhand-properties': null,
69
+ 'declaration-property-value-no-unknown': [
70
+ true,
71
+ {
72
+ ignoreProperties: {
73
+ '/.+/': /(v-(bind|deep|global|slotted)|calc-size|rgb|theme|view)|\$/,
74
+ },
75
+ },
76
+ ],
77
+ 'font-family-name-quotes': 'always-unless-keyword',
78
+ 'function-no-unknown': null, // delegate to scss/function-no-unknown
79
+ 'function-url-quotes': 'always',
80
+ 'function-url-scheme-disallowed-list': ['/^data/', 'ftp', '/^http/'],
81
+ 'hue-degree-notation': 'angle',
82
+ 'keyframes-name-pattern': '^[a-z]+(-[a-z]+)*$',
83
+ 'max-nesting-depth': [
84
+ 6,
85
+ { ignoreAtRules: ['each', 'media', 'supports', 'include'] },
86
+ ],
87
+ 'media-feature-name-no-unknown': [
88
+ true,
89
+ { ignoreMediaFeatureNames: ['screen'] },
90
+ ],
91
+ 'media-feature-name-no-vendor-prefix': true,
92
+ 'no-descending-specificity': null,
93
+ 'no-empty-source': null,
94
+ 'no-unknown-animations': true,
95
+ 'number-max-precision': 3,
96
+ 'property-no-unknown': [
97
+ true,
98
+ {
99
+ ignoreProperties: [
100
+ 'align-tracks',
101
+ 'animation-timeline',
102
+ 'interpolate-size',
103
+ 'text-stroke',
104
+ ],
105
+ },
106
+ ],
107
+ 'property-no-vendor-prefix': true,
108
+ 'rule-empty-line-before': [
109
+ 'always',
110
+ { except: ['after-single-line-comment', 'first-nested'], ignore: [] },
111
+ ],
112
+ 'selector-class-pattern': [
113
+ '^[a-z]([a-z0-9-]+)?(__([a-z0-9]+-?)+)?(--([a-z0-9]+-?)+){0,2}$',
114
+ {
115
+ message:
116
+ 'Selector should be written as BEM "block__element--modifier--value" (selector-class-pattern)',
117
+ },
118
+ ],
119
+ 'selector-combinator-disallowed-list': ['>>>', '/deep/'],
120
+ 'selector-max-compound-selectors': 6,
121
+ 'selector-max-id': 0,
122
+ 'selector-no-qualifying-type': null,
123
+ 'selector-no-vendor-prefix': true,
124
+ 'selector-pseudo-element-disallowed-list': ['shadow'],
125
+ 'selector-pseudo-element-no-unknown': [
126
+ true,
127
+ { ignorePseudoElements: ['v-deep', 'file-selector-button'] },
128
+ ],
129
+ 'selector-type-no-unknown': [true, { ignoreTypes: ['ymaps'] }],
130
+ 'shorthand-property-no-redundant-values': true,
131
+ 'string-no-newline': null,
132
+ 'time-min-milliseconds': 16,
133
+ 'value-keyword-case': [
134
+ 'lower',
135
+ { camelCaseSvgKeywords: true, ignoreFunctions: ['v-bind'] },
136
+ ],
137
+ 'value-no-vendor-prefix': true,
32
138
  };
33
139
 
34
140
  /**
35
- * Create "extends" field
141
+ * Создать конфиг Stylelint.
36
142
  *
37
- * @param {PLUGINS} plugins Enabled/disabled plugins list
38
- */
39
- const createPluginsList = (plugins = {}) => {
40
- const pluginsList = [];
41
-
42
- Object.entries({ ...PLUGINS, ...plugins })?.forEach(([name, isActive]) => {
43
- if (isActive) {
44
- pluginsList.push(`@alexlit/config-stylelint/plugins/${name}`);
45
- }
46
- });
47
-
48
- return pluginsList;
49
- };
50
-
51
- /**
52
- * Create stylelint config
143
+ * Приоритет (от низкого к высокому): база → конфиги плагинов по порядку →
144
+ * `options`. `extends`, `ignoreFiles`, `overrides` и `plugins` конкатенируются
145
+ * (дубли `plugins` убираются), `rules` - shallow merge.
146
+ *
147
+ * @param {import('stylelint').Config[]} [pluginConfigs] - Конфиги плагинов
148
+ * (например, `[plugins.scss(), plugins.vue()]`)
149
+ * @param {import('stylelint').Config} [options] - Базовые опции Stylelint,
150
+ * наивысший приоритет
53
151
  *
54
- * @param {PLUGINS} plugins Enabled/disabled plugins list
55
- * @param {import('stylelint').Config} options Stylelint options
152
+ * @returns {import('stylelint').Config}
56
153
  */
57
- const createConfig = (plugins = {}, options = {}) => ({
58
- ...options,
59
-
60
- extends: [
61
- 'stylelint-config-standard',
62
-
63
- ...createPluginsList(plugins),
64
-
65
- ...(options.extends ?? []),
66
- ],
67
- ignoreFiles: [
68
- '.*',
69
- '.*/**',
70
- 'build/**',
71
- 'dist/**',
72
- 'docs/**',
73
- 'node_modules/**',
74
- 'storybook-*/**',
75
-
76
- ...(options.ignoreFiles ?? []),
77
- ],
78
- plugins: options.plugins ?? [],
79
- rules: {
80
- 'alpha-value-notation': 'number',
81
- 'annotation-no-unknown': [true, { ignoreAnnotations: ['default'] }],
82
- 'at-rule-disallowed-list': ['debug'],
83
- 'at-rule-empty-line-before': [
84
- 'always',
85
- {
86
- except: ['blockless-after-same-name-blockless', 'first-nested'],
87
- ignoreAtRules: ['else'],
88
- },
89
- ],
90
- 'at-rule-no-deprecated': [true, { ignoreAtRules: ['apply', 'tailwind'] }],
91
- 'at-rule-no-unknown': null,
92
- 'at-rule-no-vendor-prefix': true,
93
- 'block-no-empty': null,
94
- 'color-function-notation': 'modern',
95
- 'color-hex-length': 'short',
96
- 'color-no-hex': true,
97
- 'color-no-invalid-hex': true,
98
- 'custom-property-empty-line-before': [
99
- 'always',
100
- { except: ['after-comment', 'after-custom-property', 'first-nested'] },
101
- ],
102
- 'custom-property-pattern': '^_?[a-z]+([a-z0-9-]+[a-z0-9]+)?$',
103
- 'declaration-block-no-redundant-longhand-properties': null,
104
- 'declaration-property-value-no-unknown': [
105
- true,
106
- {
107
- ignoreProperties: {
108
- '/.+/': /(v-(bind|deep|global|slotted)|calc-size|rgb|theme|view)|\$/,
109
- },
110
- },
111
- ],
112
- 'font-family-name-quotes': 'always-unless-keyword',
113
- 'function-no-unknown': null, // delegate to scss/function-no-unknown
114
- 'function-url-quotes': 'always',
115
- 'function-url-scheme-disallowed-list': ['/^data/', 'ftp', '/^http/'],
116
- 'hue-degree-notation': 'angle',
117
- 'keyframes-name-pattern': '^[a-z]+(-[a-z]+)*$',
118
- 'max-nesting-depth': [
119
- 6,
120
- { ignoreAtRules: ['each', 'media', 'supports', 'include'] },
154
+ const defineConfig = (pluginConfigs = [], options = {}) => {
155
+ const baseConfig = {
156
+ extends: ['stylelint-config-standard'],
157
+ ignoreFiles: [
158
+ '.*',
159
+ '.*/**',
160
+ 'build/**',
161
+ 'dist/**',
162
+ 'docs/**',
163
+ 'node_modules/**',
164
+ 'storybook-*/**',
121
165
  ],
122
- 'media-feature-name-no-unknown': [
123
- true,
124
- { ignoreMediaFeatureNames: ['screen'] },
125
- ],
126
- 'media-feature-name-no-vendor-prefix': true,
127
- 'no-descending-specificity': null,
128
- 'no-empty-source': null,
129
- 'no-unknown-animations': true,
130
- 'number-max-precision': 3,
131
- 'property-no-unknown': [
132
- true,
133
- {
134
- ignoreProperties: [
135
- 'align-tracks',
136
- 'animation-timeline',
137
- 'interpolate-size',
138
- 'text-stroke',
139
- ],
140
- },
141
- ],
142
- 'property-no-vendor-prefix': true,
143
- 'rule-empty-line-before': [
144
- 'always',
145
- { except: ['after-single-line-comment', 'first-nested'], ignore: [] },
146
- ],
147
- 'selector-class-pattern': [
148
- '^[a-z]([a-z0-9-]+)?(__([a-z0-9]+-?)+)?(--([a-z0-9]+-?)+){0,2}$',
149
- {
150
- message:
151
- 'Selector should be written as BEM "block__element--modifier--value" (selector-class-pattern)',
152
- },
153
- ],
154
- 'selector-combinator-disallowed-list': ['>>>', '/deep/'],
155
- 'selector-max-compound-selectors': 6,
156
- 'selector-max-id': 0,
157
- 'selector-no-qualifying-type': null,
158
- 'selector-no-vendor-prefix': true,
159
- 'selector-pseudo-element-disallowed-list': ['shadow'],
160
- 'selector-pseudo-element-no-unknown': [
161
- true,
162
- { ignorePseudoElements: ['v-deep', 'file-selector-button'] },
163
- ],
164
- 'selector-type-no-unknown': [true, { ignoreTypes: ['ymaps'] }],
165
- 'shorthand-property-no-redundant-values': true,
166
- 'string-no-newline': null,
167
- 'time-min-milliseconds': 16,
168
- 'value-keyword-case': [
169
- 'lower',
170
- { camelCaseSvgKeywords: true, ignoreFunctions: ['v-bind'] },
171
- ],
172
- 'value-no-vendor-prefix': true,
166
+ plugins: [],
167
+ rules: BASE_RULES,
168
+ };
173
169
 
174
- ...options.rules,
175
- },
176
- });
170
+ const sources = [baseConfig, ...pluginConfigs, options];
171
+
172
+ return {
173
+ ...Object.assign({}, ...sources),
174
+ extends: sources.flatMap((source) => source.extends ?? []),
175
+ ignoreFiles: sources.flatMap((source) => source.ignoreFiles ?? []),
176
+ overrides: sources.flatMap((source) => source.overrides ?? []),
177
+ plugins: [...new Set(sources.flatMap((source) => source.plugins ?? []))],
178
+ rules: Object.assign({}, ...sources.map((source) => source.rules ?? {})),
179
+ };
180
+ };
177
181
 
178
- export { createConfig };
182
+ export { defineConfig, plugins };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexlit/config-stylelint",
3
- "version": "61.5.2",
3
+ "version": "63.0.1",
4
4
  "private": false,
5
5
  "description": "Stylelint config",
6
6
  "keywords": [
@@ -23,9 +23,11 @@
23
23
  ],
24
24
  "type": "module",
25
25
  "main": "index.js",
26
+ "types": "index.d.ts",
26
27
  "files": [
27
28
  "README.md",
28
29
  "index.js",
30
+ "index.d.ts",
29
31
  "plugins"
30
32
  ],
31
33
  "scripts": {
@@ -1,18 +1,31 @@
1
1
  /* eslint-disable unicorn/no-null */
2
2
 
3
3
  /**
4
- * @type {import('stylelint').Config}
4
+ * Проверяет типичные ошибки доступности.
5
+ *
6
+ * @param {Partial<import('stylelint').Config>} [options] - Опции, накладываемые
7
+ * поверх значений по умолчанию (shallow merge)
8
+ *
9
+ * @returns {import('stylelint').Config}
5
10
  *
6
11
  * @see [stylelint-a11y](https://github.com/double-great/stylelint-a11y)
7
12
  */
8
- export default {
9
- plugins: ['@double-great/stylelint-a11y'],
10
- rules: {
11
- 'a11y/media-prefers-reduced-motion': null,
12
- 'a11y/no-obsolete-attribute': true,
13
- 'a11y/no-obsolete-element': true,
14
- 'a11y/no-outline-none': true,
15
- 'a11y/no-text-align-justify': true,
16
- 'a11y/selector-pseudo-class-focus': true,
17
- },
13
+ export const a11y = (options = {}) => {
14
+ const baseConfig = {
15
+ plugins: ['@double-great/stylelint-a11y'],
16
+ rules: {
17
+ 'a11y/media-prefers-reduced-motion': null,
18
+ 'a11y/no-obsolete-attribute': true,
19
+ 'a11y/no-obsolete-element': true,
20
+ 'a11y/no-outline-none': true,
21
+ 'a11y/no-text-align-justify': true,
22
+ 'a11y/selector-pseudo-class-focus': true,
23
+ },
24
+ };
25
+
26
+ return {
27
+ ...baseConfig,
28
+ ...options,
29
+ rules: { ...baseConfig.rules, ...options.rules },
30
+ };
18
31
  };