@alexlit/lint-kit 200.1.0 → 201.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexlit/lint-kit",
3
- "version": "200.1.0",
3
+ "version": "201.0.0",
4
4
  "private": false,
5
5
  "description": "Preset of configuration files and dependencies for linting web applications (designed for Vue.js with TypeScript)",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexlit/config-eslint",
3
- "version": "152.1.0",
3
+ "version": "153.0.1",
4
4
  "private": false,
5
5
  "description": "Sharable ESLint configuration",
6
6
  "keywords": [
@@ -45,10 +45,10 @@
45
45
  "@stylistic/eslint-plugin": "^5.10.0",
46
46
  "@tanstack/eslint-plugin-query": "^5.101.4",
47
47
  "@unocss/eslint-config": "^66.7.5",
48
- "@vitest/eslint-plugin": "^1.6.26",
49
- "eslint": "^10.8.0",
48
+ "@vitest/eslint-plugin": "^1.6.27",
49
+ "eslint": "^10.8.1",
50
50
  "eslint-config-prettier": "^10.1.8",
51
- "eslint-plugin-jsdoc": "^63.3.3",
51
+ "eslint-plugin-jsdoc": "^64.1.0",
52
52
  "eslint-plugin-perfectionist": "^5.10.1",
53
53
  "eslint-plugin-pinia": "^0.4.2",
54
54
  "eslint-plugin-prettier": "^5.5.6",
@@ -57,12 +57,12 @@
57
57
  "eslint-plugin-tailwindcss": "^4.2.0",
58
58
  "eslint-plugin-unicorn": "^73.0.0",
59
59
  "eslint-plugin-vue": "^10.10.0",
60
- "eslint-plugin-vuejs-accessibility": "^2.5.0",
61
- "eslint-plugin-zod": "^4.9.0",
60
+ "eslint-plugin-vuejs-accessibility": "^2.6.0",
61
+ "eslint-plugin-zod": "^4.9.1",
62
62
  "globals": "^17.9.0",
63
- "jsonc-eslint-parser": "^3.2.0",
63
+ "jsonc-eslint-parser": "^3.3.0",
64
64
  "typescript": "^6.0.3",
65
- "typescript-eslint": "^8.66.0",
65
+ "typescript-eslint": "^8.67.0",
66
66
  "yaml-eslint-parser": "^2.1.0"
67
67
  },
68
68
  "publishConfig": {
@@ -44,6 +44,20 @@ export const javascript = defineConfig([
44
44
  "Не используйте префикс 'handle' для обработчиков событий. Переименуйте метод, заменив 'handle' на 'on' (например, 'onClick' вместо 'handleClick').",
45
45
  selector: 'Identifier[name=/^handle[A-Z]/]',
46
46
  },
47
+ {
48
+ message:
49
+ "Использование классического цикла 'for' запрещено. Используйте методы массивов (.forEach, .map и т.д.).",
50
+ selector: 'ForStatement',
51
+ },
52
+ {
53
+ message:
54
+ "Цикл 'for...in' запрещен. Используйте Object.keys() или Object.entries().",
55
+ selector: 'ForInStatement',
56
+ },
57
+ {
58
+ message: "Цикл 'for...of' запрещен. Используйте методы массивов.",
59
+ selector: 'ForOfStatement',
60
+ },
47
61
  ],
48
62
  'prefer-arrow-callback': [
49
63
  'error',
@@ -1,7 +1,7 @@
1
- // import plugin from '@tanstack/eslint-plugin-query';
1
+ import plugin from '@tanstack/eslint-plugin-query';
2
2
  import { defineConfig } from 'eslint/config';
3
3
 
4
4
  /** @see [@tanstack/query](https://tanstack.com/query/latest/docs/eslint/eslint-plugin-query) */
5
5
  export const tanstackQuery = defineConfig([
6
- // ...plugin.configs['flat/recommended'], // TODO: update plugin
6
+ ...plugin.configs['flat/recommended'],
7
7
  ]);
@@ -8,7 +8,6 @@ export const zod = defineConfig([
8
8
  {
9
9
  ...plugin.configs.recommended,
10
10
  files: FILES,
11
-
12
11
  rules: {
13
12
  ...plugin.configs.recommended.rules,
14
13
  'zod/consistent-import': ['error', { syntax: 'named' }],
@@ -27,23 +27,29 @@ const PLUGINS = { ...DEFAULT_PLUGINS, ...OPTIONAL_PLUGINS };
27
27
  * @returns {import('prettier').Config} Prettier configuration
28
28
  */
29
29
  const createPluginsConfig = async (plugins = {}) => {
30
- let pluginsConfig = { plugins: [] };
31
-
32
30
  const pluginEntries = Object.entries({ ...PLUGINS, ...plugins });
33
31
 
34
- for (const [name, isActive] of pluginEntries) {
35
- if (isActive) {
36
- const { default: config } = await import(
37
- `@alexlit/config-prettier/plugins/${name}.js`
38
- );
32
+ const configs = await Promise.all(
33
+ pluginEntries
34
+ .filter(([, isActive]) => isActive)
35
+ .map(async ([name]) => {
36
+ const { default: config } = await import(
37
+ `@alexlit/config-prettier/plugins/${name}.js`
38
+ );
39
39
 
40
- if (config.plugins?.length > 0) {
41
- pluginsConfig.plugins.push(...config.plugins);
42
- }
40
+ return config;
41
+ }),
42
+ );
43
43
 
44
- pluginsConfig = { ...pluginsConfig, ...omit(config, ['plugins']) };
44
+ let pluginsConfig = { plugins: [] };
45
+
46
+ configs.forEach((config) => {
47
+ if (config.plugins?.length > 0) {
48
+ pluginsConfig.plugins.push(...config.plugins);
45
49
  }
46
- }
50
+
51
+ pluginsConfig = { ...pluginsConfig, ...omit(config, ['plugins']) };
52
+ });
47
53
 
48
54
  return pluginsConfig;
49
55
  };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexlit/config-prettier",
3
- "version": "22.7.0",
3
+ "version": "22.7.2",
4
4
  "private": false,
5
5
  "description": "prettier config",
6
6
  "keywords": [
@@ -44,7 +44,7 @@
44
44
  "prettier-plugin-jsdoc": "^1.8.1",
45
45
  "prettier-plugin-packagejson": "^3.0.2",
46
46
  "prettier-plugin-sh": "^0.19.0",
47
- "prettier-plugin-solidity": "^2.4.0",
47
+ "prettier-plugin-solidity": "^2.4.1",
48
48
  "prettier-plugin-sort-json": "^4.2.0",
49
49
  "prettier-plugin-sql": "^0.20.0",
50
50
  "prettier-plugin-tailwindcss": "^0.8.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexlit/config-stylelint",
3
- "version": "61.0.0",
3
+ "version": "61.0.2",
4
4
  "private": false,
5
5
  "description": "Stylelint config",
6
6
  "keywords": [
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "@double-great/stylelint-a11y": "^3.5.1",
40
40
  "@morev/stylelint-plugin": "^0.6.1",
41
- "postcss": "^8.5.25",
41
+ "postcss": "^8.5.26",
42
42
  "postcss-html": "^2.0.0",
43
43
  "prettier": "^3.9.6",
44
44
  "stylelint": "17.14.1",
@@ -13,15 +13,15 @@ const hexToRgb = (hex) => {
13
13
  const b = number & 255;
14
14
 
15
15
  if (value.length === 3 || value.length === 6) {
16
- return { r, g, b, a: 1 };
16
+ return { a: 1, b, g, r };
17
17
  }
18
18
 
19
- const a = Number.parseFloat((((number >> 24) & 255) / 255).toFixed(2));
19
+ const a = Number((((number >> 24) & 255) / 255).toFixed(2));
20
20
 
21
- return { r, g, b, a };
21
+ return { a, b, g, r };
22
22
  };
23
23
 
24
- const rgbToHsl = ({ r, g, b }) => {
24
+ const rgbToHsl = ({ b, g, r }) => {
25
25
  const rN = r / 255;
26
26
  const gN = g / 255;
27
27
  const bN = b / 255;
@@ -33,24 +33,22 @@ const rgbToHsl = ({ r, g, b }) => {
33
33
  const lightness = (max + min) / 2;
34
34
 
35
35
  if (delta === 0) {
36
- return { h: 0, s: 0, l: Math.round(lightness * 100) };
36
+ return { h: 0, l: Math.round(lightness * 100), s: 0 };
37
37
  }
38
38
 
39
- const saturation = lightness > 0.5
40
- ? delta / (2 - max - min)
41
- : delta / (max + min);
39
+ const saturation = delta / (lightness > 0.5 ? 2 - max - min : max + min);
42
40
 
43
41
  let hue;
44
42
 
45
43
  switch (max) {
46
- case rN: {
47
- hue = ((gN - bN) / delta + (gN < bN ? 6 : 0)) / 6;
44
+ case gN: {
45
+ hue = ((bN - rN) / delta + 2) / 6;
48
46
 
49
47
  break;
50
48
  }
51
49
 
52
- case gN: {
53
- hue = ((bN - rN) / delta + 2) / 6;
50
+ case rN: {
51
+ hue = ((gN - bN) / delta + (gN < bN ? 6 : 0)) / 6;
54
52
 
55
53
  break;
56
54
  }
@@ -62,13 +60,13 @@ const rgbToHsl = ({ r, g, b }) => {
62
60
 
63
61
  return {
64
62
  h: Math.round(hue * 360),
65
- s: Math.round(saturation * 100),
66
63
  l: Math.round(lightness * 100),
64
+ s: Math.round(saturation * 100),
67
65
  };
68
66
  };
69
67
 
70
68
  const formatColor = (hex, format) => {
71
- const { r, g, b, a } = hexToRgb(hex);
69
+ const { a, b, g, r } = hexToRgb(hex);
72
70
 
73
71
  if (format === 'rgb' || format === 'rgba') {
74
72
  if (a < 1) {
@@ -78,7 +76,7 @@ const formatColor = (hex, format) => {
78
76
  return `rgb(${r}, ${g}, ${b})`;
79
77
  }
80
78
 
81
- const { h, s, l } = rgbToHsl({ r, g, b });
79
+ const { h, l, s } = rgbToHsl({ b, g, r });
82
80
 
83
81
  if (a < 1) {
84
82
  return `hsla(${h}, ${s}%, ${l}%, ${a})`;
@@ -97,12 +95,15 @@ const styleSearch = (source, target, callback) => {
97
95
  break;
98
96
  }
99
97
 
100
- callback({ startIndex: index, endIndex: index + target.length });
98
+ callback({ endIndex: index + target.length, startIndex: index });
101
99
 
102
100
  startIndex = index + 1;
103
101
  }
104
102
  };
105
103
 
104
+ const replaceHexes = (value, fixTo) =>
105
+ value.replaceAll(/#[0-9A-Z]+/gi, (hex) => formatColor(hex, fixTo));
106
+
106
107
  const messages = ruleMessages(ruleName, {
107
108
  custom: (message) => message,
108
109
  rejected: (hex) => `Unexpected hex color "${hex}"`,
@@ -112,9 +113,7 @@ const rule = function (actual, options, context) {
112
113
  return (root, result) => {
113
114
  const validOptions = validateOptions(result, ruleName, {
114
115
  actual,
115
- possible: {
116
- format: ['rgb', 'rgba', 'hsl', 'hsla'],
117
- },
116
+ possible: { format: ['rgb', 'rgba', 'hsl', 'hsla'] },
118
117
  });
119
118
 
120
119
  if (!validOptions) {
@@ -150,9 +149,10 @@ const rule = function (actual, options, context) {
150
149
  return;
151
150
  }
152
151
 
153
- const message = actual && actual.message
154
- ? messages.custom(actual.message)
155
- : messages.rejected(hexValue);
152
+ const message =
153
+ actual && actual.message
154
+ ? messages.custom(actual.message)
155
+ : messages.rejected(hexValue);
156
156
 
157
157
  report({
158
158
  endIndex: match.endIndex,
@@ -165,16 +165,9 @@ const rule = function (actual, options, context) {
165
165
  });
166
166
 
167
167
  if (fixPositions.length > 0) {
168
- for (const fixPosition of fixPositions) {
169
- const hexes = [...decl.value.matchAll(/#[0-9A-Z]+/gi)];
170
-
171
- for (const hexMatch of hexes) {
172
- decl.value = decl.value.replace(
173
- hexMatch[0],
174
- formatColor(hexMatch[0], fixPosition.fixTo),
175
- );
176
- }
177
- }
168
+ fixPositions.forEach((fixPosition) => {
169
+ decl.value = replaceHexes(decl.value, fixPosition.fixTo);
170
+ });
178
171
  }
179
172
  });
180
173
  };
@@ -68,47 +68,38 @@ const AT_RULES = [
68
68
  'viewport',
69
69
  ];
70
70
 
71
- function buildAttributeRules() {
72
- return [
73
- ...LETTERS.map((letter) => ({
74
- selector: new RegExp(String.raw`\[${letter}`),
75
- type: 'rule',
76
- })),
77
- { selector: /\[/, type: 'rule' },
78
- ];
79
- }
80
-
81
- function buildLetterRules(prefix) {
82
- return [
83
- ...LETTERS.map((letter) => ({
84
- selector: new RegExp(`${prefix}${letter}`),
85
- type: 'rule',
86
- })),
87
- { selector: new RegExp(prefix), type: 'rule' },
88
- ];
89
- }
90
-
91
- function buildMediaFeatureRules() {
92
- return MEDIA_FEATURES.map((parameter) => ({
71
+ const buildAttributeRules = () => [
72
+ ...LETTERS.map((letter) => ({
73
+ selector: new RegExp(String.raw`\[${letter}`),
74
+ type: 'rule',
75
+ })),
76
+ { selector: /\[/, type: 'rule' },
77
+ ];
78
+
79
+ const buildLetterRules = (prefix) => [
80
+ ...LETTERS.map((letter) => ({
81
+ selector: new RegExp(`${prefix}${letter}`),
82
+ type: 'rule',
83
+ })),
84
+ { selector: new RegExp(prefix), type: 'rule' },
85
+ ];
86
+
87
+ const buildMediaFeatureRules = () =>
88
+ MEDIA_FEATURES.map((parameter) => ({
93
89
  name: 'media',
94
90
  parameter,
95
91
  type: 'at-rule',
96
92
  }));
97
- }
98
-
99
- function buildPseudoClassRules() {
100
- return [
101
- ...LETTERS.map((letter) => ({ selector: `:${letter}`, type: 'rule' })),
102
- { selector: ':', type: 'rule' },
103
- ];
104
- }
105
-
106
- function buildPseudoElementRules() {
107
- return [
108
- ...LETTERS.map((letter) => ({ selector: `::${letter}`, type: 'rule' })),
109
- { selector: '::', type: 'rule' },
110
- ];
111
- }
93
+
94
+ const buildPseudoClassRules = () => [
95
+ ...LETTERS.map((letter) => ({ selector: `:${letter}`, type: 'rule' })),
96
+ { selector: ':', type: 'rule' },
97
+ ];
98
+
99
+ const buildPseudoElementRules = () => [
100
+ ...LETTERS.map((letter) => ({ selector: `::${letter}`, type: 'rule' })),
101
+ { selector: '::', type: 'rule' },
102
+ ];
112
103
 
113
104
  /**
114
105
  * @type {import('stylelint').Config}