linter-bundle 3.2.0 → 3.4.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/CHANGELOG.md CHANGED
@@ -6,7 +6,55 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.2.0...HEAD)
9
+ [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.4.0...HEAD)
10
+
11
+ ## [3.4.0] - 2023-07-20
12
+
13
+ ### Changed
14
+
15
+ - [eslint] Updated `@typescript-eslint` from `6.0.0` to `6.1.0`
16
+ - [eslint] Updated `eslint` from `8.44.0` to `8.45.0`
17
+ - [eslint] Updated `eslint-plugin-jsdoc` from `46.4.3` to `46.4.4`
18
+ - [eslint] Updated `eslint-plugin-unicorn` from `47.0.0` to `48.0.0`
19
+ - [stylelint] Updated `stylelint` from `15.10.1` to `15.10.2`
20
+ - [eslint] Moved `unicorn/import-style` configuration for `path` (unassigned: false, default: false, namespace: true, named: true) from `overrides-storybook` into the main configuration.
21
+ - [eslint/overrides-javascript] Activated [`unicorn/prefer-top-level-await`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-top-level-await.md) rule for `*.mjs` files.
22
+
23
+ ### Fixed
24
+
25
+ - [stylelint] Fixed `Cannot find module 'node_modules/stylelint/bin/stylelint.js'` issue, if the file is called `stylelint.mjs`
26
+
27
+ [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.3.0...v3.4.0)
28
+
29
+ ## [3.3.0] - 2023-07-13
30
+
31
+ ### Changed
32
+
33
+ - [general] Drop support for Node.js version v17 (v16 is still supported), as `@typescript-eslint` v6.0.0 doesn't support it anymore
34
+ - [eslint] Updated `@typescript-eslint` from `5.59.9` to `6.0.0`
35
+ - [eslint] Updated `eslint` from `8.42.0` to `8.44.0`
36
+ - [eslint] Updated `eslint-plugin-jest` from `27.2.1` to `27.2.3`
37
+ - [eslint] Updated `eslint-plugin-n` from `16.0.0` to `16.0.1`
38
+ - [eslint/overrides-jsdoc] Updated `eslint-plugin-jsdoc` from `46.2.4` to `46.4.3`
39
+ - [markdownlint] Updated `markdownlint-cli` from `0.34.0` to `0.35.0`
40
+ - [stylelint] Updated `stylelint` from `15.7.0` to `15.10.1`
41
+ - [stylelint] Updated `stylelint-scss` from `5.0.0` to `5.0.1`
42
+ - [eslint/overrides-jsdoc] Don't enforce line-breaks before `@throws` by the [`jsdoc/tag-lines`](https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-tag-lines) rule
43
+ - [stylelint] Forked [`stylelint-selector-no-empty`](https://github.com/ssivanatarajan/stylelint-selector-no-empty), because it seems not to be regularly maintained anymore
44
+
45
+ ### Added
46
+
47
+ - [stylelint] Make use of new [`media-feature-name-value-no-unknown`](https://github.com/stylelint/stylelint/blob/main/lib/rules/media-feature-name-value-no-unknown/README.md) rule
48
+ - [stylelint] Make use of new [`media-query-no-invalid`](https://github.com/stylelint/stylelint/blob/main/lib/rules/media-query-no-invalid/README.md) rule
49
+ - [eslint/overrides-javascript] Activated `@typescript-eslint/prefer-nullish-coalescing` for JavaScript file, as it is now supported in Node.js for a while.
50
+ - [eslint/overrides-javascript] Activated `@typescript-eslint/prefer-optional-chain` for JavaScript file, as it is now supported in Node.js for a while.
51
+
52
+ ### Removed
53
+
54
+ - [eslint] Remove silently removed `@typescript-eslint/no-parameter-properties` rule
55
+ - [eslint] Disabled `unicorn/no-empty-file`, because of [false-positives](https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2175) with `@typescript-eslint v6.0.0`
56
+
57
+ [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.2.0...v3.3.0)
10
58
 
11
59
  ## [3.2.0] - 2023-06-06
12
60
 
@@ -26,6 +74,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
26
74
  - [eslint] Updated `eslint` from `8.40.0` to `8.42.0`
27
75
  - [eslint] Updated `eslint-plugin-jsdoc` from `44.2.4` to `46.2.4`
28
76
  - [stylelint] Updated `stylelint` from `15.6.1` to `15.6.3`
77
+
78
+ ### Added
79
+
29
80
  - [eslint/overrides-jsdoc] Added, but disabled new [`jsdoc/imports-as-dependencies`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/imports-as-dependencies.md) rule, as it doesn't cover `peerDependencies` and Node.js modules (like `child_process`)
30
81
 
31
82
  [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.0.0...v3.1.0)
package/README.md CHANGED
@@ -46,7 +46,7 @@ Beside that, the following additional rules are part of this bundle:
46
46
  - [stylelint-high-performance-animation](https://www.npmjs.com/package/stylelint-high-performance-animation) (Forked version)
47
47
  - [stylelint-order](https://www.npmjs.com/package/stylelint-order)
48
48
  - [stylelint-scss](https://www.npmjs.com/package/stylelint-scss)
49
- - [stylelint-selector-no-empty](https://www.npmjs.com/package/stylelint-selector-no-empty)
49
+ - [stylelint-selector-no-empty](https://www.npmjs.com/package/stylelint-selector-no-empty) (Forked version)
50
50
  - [stylelint-selector-tag-no-without-class](https://www.npmjs.com/package/stylelint-selector-tag-no-without-class) (Forked version)
51
51
  - [stylelint-use-logical-spec](https://www.npmjs.com/package/stylelint-use-logical-spec)
52
52
 
package/eslint/index.js CHANGED
@@ -699,7 +699,6 @@ module.exports = {
699
699
  '@typescript-eslint/no-namespace': ['error', { allowDeclarations: true }],
700
700
  '@typescript-eslint/no-non-null-assertion': 'error',
701
701
  '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
702
- '@typescript-eslint/no-parameter-properties': 'error',
703
702
  '@typescript-eslint/no-redeclare': ['error', { ignoreDeclarationMerge: true }],
704
703
  '@typescript-eslint/no-redundant-type-constituents': 'off', // False positive with Promise<... | never>
705
704
  '@typescript-eslint/no-require-imports': 'error',
@@ -942,7 +941,16 @@ module.exports = {
942
941
  /([A-Za-z0-9]?[a-z0-9]+)*[A-Z]{2,4}([A-Za-z0-9]?[a-z0-9]+)*/u // Up to 4 Characters can be upper-case in a row (e.g. in `prepareDOM` or `SVGIcon`)
943
942
  ]
944
943
  }],
945
- 'unicorn/import-style': 'error',
944
+ 'unicorn/import-style': ['error', {
945
+ styles: {
946
+ path: {
947
+ unassigned: false,
948
+ default: false,
949
+ namespace: true,
950
+ named: true
951
+ }
952
+ }
953
+ }],
946
954
  'unicorn/new-for-builtins': 'error',
947
955
  'unicorn/no-abusive-eslint-disable': 'error',
948
956
  'unicorn/no-array-callback-reference': 'off', // If I use functions, they are the best option for this use-case
@@ -953,7 +961,7 @@ module.exports = {
953
961
  'unicorn/no-await-expression-member': 'error',
954
962
  'unicorn/no-console-spaces': 'error',
955
963
  'unicorn/no-document-cookie': 'error',
956
- 'unicorn/no-empty-file': 'error',
964
+ 'unicorn/no-empty-file': 'off', // @todo False-positives since @typescript-eslint v6.0.0. @see https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2175
957
965
  'unicorn/no-for-loop': 'off', // @typescript-eslint/prefer-for-of
958
966
  'unicorn/no-hex-escape': 'error',
959
967
  'unicorn/no-instanceof-array': 'error',
@@ -973,7 +981,6 @@ module.exports = {
973
981
  'unicorn/no-unnecessary-await': 'error',
974
982
  'unicorn/no-unreadable-array-destructuring': 'error',
975
983
  'unicorn/no-unreadable-iife': 'error',
976
- 'unicorn/no-unsafe-regex': 'off',
977
984
  'unicorn/no-unused-properties': 'error',
978
985
  'unicorn/no-useless-fallback-in-spread': 'error',
979
986
  'unicorn/no-useless-promise-resolve-reject': 'error',
@@ -1022,13 +1029,13 @@ module.exports = {
1022
1029
  'unicorn/prefer-set-has': 'error',
1023
1030
  'unicorn/prefer-set-size': 'error',
1024
1031
  'unicorn/prefer-spread': 'off', // @todo Disabled till there a solution for the warning, that `slice()` on Typed-Arrays should be replaced (which is not possible). @see https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1064
1025
- 'unicorn/prefer-string-replace-all': 'off', // @todo Available since 2020 in browsers. SHould this be preferred?
1032
+ 'unicorn/prefer-string-replace-all': 'off', // @todo Available since 2020 in browsers. Should this be preferred?
1026
1033
  'unicorn/prefer-string-slice': 'off', // @todo As of today (2020.08.24) and since the last 9 years, substr() is three times faster than slice() in Firefox.
1027
1034
  'unicorn/prefer-string-starts-ends-with': 'error',
1028
1035
  'unicorn/prefer-string-trim-start-end': 'error',
1029
1036
  'unicorn/prefer-switch': 'error',
1030
1037
  'unicorn/prefer-ternary': 'off', // We prefer readability over saving a few chars
1031
- 'unicorn/prefer-top-level-await': 'off', // @todo There should be a detection that this option is only activated on Node.js v14.8 environments and above (Check for "engine" property in package.json, and "node -v")
1038
+ 'unicorn/prefer-top-level-await': 'off', // @todo Available since 2021. Activate in 2024
1032
1039
  'unicorn/prefer-regexp-test': 'error',
1033
1040
  'unicorn/prefer-type-error': 'error',
1034
1041
  'unicorn/prevent-abbreviations': ['error', { ignore: ['args', 'i', 'j', 'i18n', 'ref', 'Ref', 'params', 'props', 'Props'] }],
@@ -7,11 +7,10 @@ const overridesJavaScript = require('./overrides-javascript');
7
7
  module.exports = {
8
8
  ...overridesJavaScript,
9
9
  overrides: [
10
+ ...overridesJavaScript.overrides,
10
11
  {
11
- ...overridesJavaScript.overrides[0],
12
+ files: ['*.js', '*.cjs', '*.mjs'],
12
13
  rules: {
13
- ...overridesJavaScript.overrides[0].rules,
14
-
15
14
  /**
16
15
  * typescript-eslint
17
16
  *
@@ -32,8 +32,6 @@ module.exports = {
32
32
  '@typescript-eslint/no-require-imports': 'off', // Requires type information
33
33
  '@typescript-eslint/no-unsafe-assignment': 'off', // @todo Reactivate after bug in @typescript-eslint is fixed (@see https://github.com/typescript-eslint/typescript-eslint/issues/1943)
34
34
  '@typescript-eslint/no-var-requires': 'off', // Requires type information
35
- '@typescript-eslint/prefer-nullish-coalescing': 'off', // @todo `??` is not yet supported by NodeJS. Remove this like, as soon as it is supported.
36
- '@typescript-eslint/prefer-optional-chain': 'off', // @todo `?.` is not yet supported by NodeJS. Remove this like, as soon as it is supported.
37
35
  '@typescript-eslint/triple-slash-reference': 'off', // Required to make use of *.d.ts files
38
36
 
39
37
  /**
@@ -105,6 +103,12 @@ module.exports = {
105
103
  'unicorn/prevent-abbreviations': ['error', { ignore: ['args', 'dev', 'env', 'i', 'j', 'i18n', 'pkg', 'ref', 'Ref', 'req', 'res', 'setupDevServerMiddleware'] }],
106
104
  'unicorn/text-encoding-identifier-case': 'off'
107
105
  }
106
+ },
107
+ {
108
+ files: ['*.mjs'],
109
+ rules: {
110
+ 'unicorn/prefer-top-level-await': 'error'
111
+ }
108
112
  }
109
113
  ]
110
114
  };
@@ -34,7 +34,7 @@ module.exports = {
34
34
  'jsdoc/check-values': 'error',
35
35
  'jsdoc/empty-tags': 'error',
36
36
  'jsdoc/implements-on-classes': 'error',
37
- 'jsdoc/imports-as-dependencies': 'off', // @todo Doesn't cover `peerDependencies` and Node.js modules (like `child_process`) yet
37
+ 'jsdoc/imports-as-dependencies': 'off', // @todo Doesn't cover `peerDependencies` yet. As of v46.2.5 it should cover Node.js modules (like `child_process`), which must be checked, before activation.
38
38
  'jsdoc/match-description': 'error',
39
39
  'jsdoc/match-name': 'off',
40
40
  'jsdoc/multiline-blocks': ['error', { noSingleLineBlocks: true, singleLineTags: ['lends', 'type', 'typedef'], noFinalLineText: false }],
@@ -75,7 +75,8 @@ module.exports = {
75
75
  param: { lines: 'never' },
76
76
  private: { lines: 'never' },
77
77
  protected: { lines: 'never' },
78
- public: { lines: 'never' }
78
+ public: { lines: 'never' },
79
+ throws: { lines: 'never' }
79
80
  },
80
81
  startLines: null,
81
82
  endLines: null,
@@ -23,23 +23,7 @@ module.exports = {
23
23
  *
24
24
  * @see https://github.com/import-js/eslint-plugin-import
25
25
  */
26
- 'import/no-nodejs-modules': 'off',
27
-
28
- /**
29
- * eslint-plugin-unicorn
30
- *
31
- * @see https://github.com/sindresorhus/eslint-plugin-unicorn
32
- */
33
- 'unicorn/import-style': ['error', {
34
- styles: {
35
- path: {
36
- unassigned: false,
37
- default: false,
38
- namespace: true,
39
- named: true
40
- }
41
- }
42
- }]
26
+ 'import/no-nodejs-modules': 'off'
43
27
  }
44
28
  },
45
29
  {
@@ -6,6 +6,7 @@
6
6
 
7
7
  const ts = require('typescript');
8
8
 
9
+ // @ts-expect-error -- TypeScript is not able to resolve the folder since @typescript-eslint v6.0.0
9
10
  const { ESLintUtils } = require('@typescript-eslint/utils');
10
11
 
11
12
  /**
@@ -28,11 +29,9 @@ module.exports = {
28
29
  return;
29
30
  }
30
31
 
31
- // @ts-expect-error -- Different type definitions for `Rule.RuleContext` in ESLint and @typescript-eslint
32
32
  const parserServices = ESLintUtils.getParserServices(context);
33
33
  const checker = parserServices.program.getTypeChecker();
34
34
 
35
- // @ts-expect-error -- ESLint `Identifier` is not recognized as `Node` by @typescript-eslint
36
35
  const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node.argument);
37
36
 
38
37
  /** @type {Type} */
@@ -5,6 +5,7 @@
5
5
  /**
6
6
  * Ensures that the input `value` is an array, otherwise an empty array is returned.
7
7
  *
8
+ * @public
8
9
  * @template T
9
10
  * @param {T} value - The value which should be checked.
10
11
  * @returns {T extends Array<any> ? T : []} Either the input array, or an empty array, if the input array is not an array.
@@ -13,6 +13,7 @@ const path = require('path');
13
13
  /**
14
14
  * Detects if installed versions of dependencies don't match to the required dependencies.
15
15
  *
16
+ * @public
16
17
  * @returns {Dependency[]} An array of missing overrides (=wrong versions).
17
18
  */
18
19
  function findMissingOverrides () {
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @file Returns the path to the Stylelint CLI script.
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+
8
+ /**
9
+ * Returns if the project is using npm or yarn.
10
+ *
11
+ * @public
12
+ * @returns {string | null} Return the path to the Stylelint CLI script, or `null` if it can't be found.
13
+ */
14
+ function getStylelintPath () {
15
+ const stylelintLibPath = path.dirname(require.resolve('stylelint'));
16
+
17
+ for (const stylelintBinPath of [
18
+ path.join(stylelintLibPath, '../bin/stylelint.mjs'),
19
+ path.join(stylelintLibPath, '../bin/stylelint.js')
20
+ ]) {
21
+ if (fs.existsSync(stylelintBinPath)) {
22
+ return stylelintBinPath;
23
+ }
24
+ }
25
+
26
+ return null;
27
+ }
28
+
29
+ module.exports = {
30
+ getStylelintPath
31
+ };
32
+
@@ -8,6 +8,7 @@ const path = require('path');
8
8
  /**
9
9
  * Returns if the project is using npm or yarn.
10
10
  *
11
+ * @public
11
12
  * @returns {'none' | 'npm' | 'yarn' | 'both'} Returns which package manager name.
12
13
  */
13
14
  function isNpmOrYarn () {
@@ -9,6 +9,7 @@ const childProcess = require('child_process');
9
9
  /**
10
10
  * Executes a process asynchronously.
11
11
  *
12
+ * @public
12
13
  * @param {string} command - The process to execute.
13
14
  * @param {childProcess.ExecOptions | undefined} [options] - The options of the `childProcess.exec()` method.
14
15
  * @returns {Promise<ProcessResult>} An object containing the result of the process execution
@@ -13,6 +13,7 @@ const path = require('path');
13
13
  /**
14
14
  * Detects outdated "overrides"/"resolutions" dependencies.
15
15
  *
16
+ * @public
16
17
  * @returns {{ overrides: Dependency[]; resolutions: Dependency[]; }} Either the input array, or an empty array, if the input array is not an array.
17
18
  */
18
19
  function validatePackageOverrides () {
package/lint.js CHANGED
@@ -10,6 +10,7 @@ const tty = require('tty');
10
10
  const micromatch = require('micromatch');
11
11
 
12
12
  const { findMissingOverrides } = require('./helper/find-missing-overrides.js');
13
+ const { getStylelintPath } = require('./helper/get-stylelint-path.js');
13
14
  const { isNpmOrYarn } = require('./helper/is-npm-or-yarn.js');
14
15
  const { runProcess } = require('./helper/run-process.js');
15
16
  const { validatePackageOverrides } = require('./helper/validate-package-overrides.js');
@@ -115,10 +116,18 @@ void (async () => {
115
116
  });
116
117
  }
117
118
 
119
+ const stylelintBinPath = getStylelintPath();
120
+
121
+ if (stylelintBinPath === null) {
122
+ return generateDummyJobOutput(taskName, config, {
123
+ stderr: 'Stylelint CLI script not found.'
124
+ });
125
+ }
126
+
118
127
  return runTask({
119
128
  taskName,
120
129
  config,
121
- command: `node "${require.resolve('stylelint/bin/stylelint.js')}" ${includes} --formatter unix`
130
+ command: `node "${stylelintBinPath}" ${includes} --formatter unix`
122
131
  });
123
132
  }
124
133
 
@@ -280,7 +289,7 @@ function validateEnvironment (npmOrYarn) {
280
289
  propertyName = 'resolutions';
281
290
  }
282
291
  else {
283
- installCommand = 'npm install';
292
+ installCommand = 'npm install --no-package-lock';
284
293
  propertyName = 'overrides';
285
294
  }
286
295
 
@@ -288,7 +297,7 @@ function validateEnvironment (npmOrYarn) {
288
297
  process.stderr.write(`- ${missingOverrides.map((dependency) => `${dependency.name}: ${dependency.configuredVersion} is installed, but ${dependency.expectedVersion} is expected`).join('\n- ')}\n\n`);
289
298
  process.stderr.write(`This could be caused by forgetting to execute \`${installCommand}\` after changing a version number in the package.json, or by some other package shipping outdated versions of the ${missingOverrides.length === 1 ? 'dependency' : 'dependencies'}.\n`);
290
299
  process.stderr.write('If another package is causing this problem, you can fix it by adding the following entry to your package.json:\n');
291
- process.stderr.write(`{\n "${propertyName}: {\n ${missingOverrides.map((dependency) => `"${dependency.name}": "${dependency.expectedVersion}"`).join(',\n ')}\n }\n}\n\n`);
300
+ process.stderr.write(`{\n "${propertyName}": {\n ${missingOverrides.map((dependency) => `"${dependency.name}": "${dependency.expectedVersion}"`).join(',\n ')}\n }\n}\n\n`);
292
301
 
293
302
  process.exitCode = 1;
294
303
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linter-bundle",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "Ready-to use bundle of linting tools, containing configurations for ESLint, stylelint and markdownlint.",
5
5
  "keywords": [
6
6
  "eslint",
@@ -22,7 +22,7 @@
22
22
  "lint": "lint.js"
23
23
  },
24
24
  "engines": {
25
- "node": ">=16.0.0"
25
+ "node": "^16.0.0 || >=18.0.0"
26
26
  },
27
27
  "repository": {
28
28
  "type": "git",
@@ -36,35 +36,34 @@
36
36
  "preversion": "npm run check-outdated && npm run lint",
37
37
  "postversion": "git push && git push --tags && npm publish",
38
38
  "stylelint-find-rules": "stylelint-find-new-rules ./stylelint/index.js",
39
- "validate-stylelint-options": "node ./validate-stylelint-options",
39
+ "validate-stylelint-options": "node ./validate-stylelint-options.mjs",
40
40
  "check-outdated": "npx --yes -- check-outdated --ignore-pre-releases"
41
41
  },
42
42
  "dependencies": {
43
- "@typescript-eslint/eslint-plugin": "5.59.9",
44
- "@typescript-eslint/parser": "5.59.9",
45
- "@typescript-eslint/utils": "5.59.9",
46
- "eslint": "8.42.0",
43
+ "@typescript-eslint/eslint-plugin": "6.1.0",
44
+ "@typescript-eslint/parser": "6.1.0",
45
+ "@typescript-eslint/utils": "6.1.0",
46
+ "eslint": "8.45.0",
47
47
  "eslint-import-resolver-typescript": "3.5.5",
48
48
  "eslint-import-resolver-webpack": "0.13.2",
49
49
  "eslint-plugin-eslint-comments": "3.2.0",
50
50
  "eslint-plugin-functional": "5.0.8",
51
51
  "eslint-plugin-import": "2.27.5",
52
- "eslint-plugin-jest": "27.2.1",
53
- "eslint-plugin-jsdoc": "46.2.4",
52
+ "eslint-plugin-jest": "27.2.3",
53
+ "eslint-plugin-jsdoc": "46.4.4",
54
54
  "eslint-plugin-jsx-a11y": "6.7.1",
55
- "eslint-plugin-n": "16.0.0",
55
+ "eslint-plugin-n": "16.0.1",
56
56
  "eslint-plugin-promise": "6.1.1",
57
57
  "eslint-plugin-react": "7.32.2",
58
58
  "eslint-plugin-react-hooks": "4.6.0",
59
- "eslint-plugin-unicorn": "47.0.0",
60
- "markdownlint-cli": "0.34.0",
59
+ "eslint-plugin-unicorn": "48.0.0",
60
+ "markdownlint-cli": "0.35.0",
61
61
  "micromatch": "4.0.5",
62
62
  "postcss-scss": "4.0.6",
63
- "stylelint": "15.7.0",
63
+ "stylelint": "15.10.2",
64
64
  "stylelint-declaration-block-no-ignored-properties": "2.7.0",
65
65
  "stylelint-order": "6.0.3",
66
- "stylelint-scss": "5.0.0",
67
- "stylelint-selector-no-empty": "1.0.9",
66
+ "stylelint-scss": "5.0.1",
68
67
  "stylelint-use-logical-spec": "5.0.0"
69
68
  },
70
69
  "peerDependencies": {
@@ -72,10 +71,10 @@
72
71
  "typescript": "^4.0.0"
73
72
  },
74
73
  "devDependencies": {
75
- "@types/eslint": "8.40.0",
74
+ "@types/eslint": "8.44.0",
76
75
  "@types/micromatch": "4.0.2",
77
- "@types/node": "20.2.5",
76
+ "@types/node": "20.4.2",
78
77
  "stylelint-find-new-rules": "4.1.0",
79
- "typescript": "5.1.3"
78
+ "typescript": "5.1.6"
80
79
  }
81
80
  }
@@ -15,9 +15,9 @@ module.exports = {
15
15
  'stylelint-declaration-block-no-ignored-properties',
16
16
  'stylelint-order',
17
17
  'stylelint-scss',
18
- 'stylelint-selector-no-empty',
19
18
  'stylelint-use-logical-spec',
20
19
  path.join(__dirname, '/plugins/stylelint-high-performance-animation.js'),
20
+ path.join(__dirname, '/plugins/stylelint-selector-no-empty.js'),
21
21
  path.join(__dirname, '/plugins/stylelint-selector-tag-no-without-class.js'),
22
22
  path.join(__dirname, '/plugins/stylelint-stylistic.js')
23
23
  ],
@@ -187,7 +187,9 @@ module.exports = {
187
187
  'media-feature-name-no-vendor-prefix': null, // For Safari, we still need "-webkit-min-device-pixel-ratio": https://caniuse.com/css-media-resolution
188
188
  'media-feature-name-unit-allowed-list': null,
189
189
  'media-feature-name-value-allowed-list': null,
190
+ 'media-feature-name-value-no-unknown': true,
190
191
  'media-feature-range-notation': 'prefix',
192
+ 'media-query-no-invalid': true,
191
193
  'named-grid-areas-no-invalid': true,
192
194
  'no-descending-specificity': null, // doesn't work in many cases (e.g. while using the SCSS :global()-pseudo-class)
193
195
  'no-duplicate-at-import-rules': true,
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @file Fork of `stylelint-selector-no-empty` rule.
3
+ *
4
+ * @license MIT
5
+ *
6
+ * @see https://www.npmjs.com/package/stylelint-selector-no-empty
7
+ */
8
+
9
+ const stylelint = require('stylelint');
10
+
11
+ const ruleName = 'plugin/stylelint-selector-no-empty';
12
+
13
+ let nearestSelector = '';
14
+
15
+ const messages = stylelint.utils.ruleMessages(ruleName, {
16
+ expected (selector) {
17
+ if (typeof selector === 'string' && selector.length > 0) {
18
+ return `Unexpected empty selector near '${selector}'`;
19
+ }
20
+
21
+ return 'Unexpected empty selector';
22
+ }
23
+ });
24
+
25
+ // @ts-expect-error -- Parameter 'enabled' implicitly has an 'any' type.
26
+ module.exports = stylelint.createPlugin(ruleName, (enabled) => {
27
+ if (!enabled) {
28
+ return;
29
+ }
30
+
31
+ return (root, result) => {
32
+ root.walkRules((rule) => {
33
+ try {
34
+ nearestSelector = '';
35
+
36
+ for (const selector of rule.selector.split(',')) {
37
+ if (selector.length === 0) {
38
+ reportError(rule, result);
39
+ continue;
40
+ }
41
+ nearestSelector = selector;
42
+
43
+ const tabSplittedSelectors = getSplittedSelectors(selector.split('\n'), '\t');
44
+ const spaceSplittedSelectors = getSplittedSelectors(tabSplittedSelectors, ' ');
45
+ checkEmptySelector(spaceSplittedSelectors, result, rule);
46
+ }
47
+ }
48
+ catch { /* Do nothing */ }
49
+ });
50
+ };
51
+ });
52
+
53
+ /**
54
+ * Splits the selectors based on a specified delimiter and filters out empty selectors.
55
+ *
56
+ * @param {string[]} splittedSelectors - The selectors to be split.
57
+ * @param {string} splitBy - The delimiter to split the selectors.
58
+ * @returns {string[]} The split and filtered selectors.
59
+ */
60
+ function getSplittedSelectors (splittedSelectors, splitBy) {
61
+ const res = [];
62
+
63
+ for (const splittedSelector of splittedSelectors) {
64
+ try {
65
+ for (const selector of splittedSelector.split(splitBy)) {
66
+ if (selector.trim().length > 0) {
67
+ res.push(selector);
68
+ }
69
+ }
70
+ }
71
+ catch { /* Do nothing */ }
72
+ }
73
+
74
+ return res;
75
+ }
76
+
77
+ /**
78
+ * Checks for empty selectors within the space-split selectors.
79
+ *
80
+ * @param {string[]} spaceSplittedSelectors - The space-split selectors.
81
+ * @param {stylelint.PostcssResult} result - The result object.
82
+ * @param {import('postcss').Rule} rule - The current rule.
83
+ */
84
+ function checkEmptySelector (spaceSplittedSelectors, result, rule) {
85
+ for (let sp of spaceSplittedSelectors) {
86
+ if ((sp.startsWith('.') || sp.startsWith('#')) && sp.trim().length > 1) {
87
+ sp = sp.slice(1);
88
+ }
89
+
90
+ for (const classSelectorsWithoutDot of sp.split('.')) {
91
+ for (const selector of classSelectorsWithoutDot.split('#')) {
92
+ if (selector.trim().length === 0) {
93
+ reportError(rule, result);
94
+ return;
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Reports an error for an empty selector.
103
+ *
104
+ * @param {import('postcss').Rule} rule - The current rule.
105
+ * @param {stylelint.PostcssResult} result - The result object.
106
+ */
107
+ function reportError (rule, result) {
108
+ stylelint.utils.report({
109
+ result,
110
+ ruleName,
111
+ message: messages.expected(nearestSelector),
112
+ node: rule
113
+ });
114
+ }
package/.gitattributes DELETED
@@ -1,16 +0,0 @@
1
- * text=auto
2
-
3
- *.css text eol=lf
4
- *.html text eol=lf
5
- *.js text eol=lf
6
- *.json text eol=lf
7
- *.log text eol=lf
8
- *.md text eol=lf
9
- *.scss text eol=lf
10
- *.svg text eol=lf
11
- *.ts text eol=lf
12
- *.tsx text eol=lf
13
- *.txt text eol=lf
14
- *.xml text eol=lf
15
- *.yaml text eol=lf
16
- *.yml text eol=lf
@@ -1,52 +0,0 @@
1
- /**
2
- * @file Ensures that stylelint options are valid by checking the `invalidOptionWarnings` property of the JSON response.
3
- */
4
-
5
- const fs = require('fs');
6
- const os = require('os');
7
- const path = require('path');
8
-
9
- const { runProcess } = require('./helper/run-process.js');
10
-
11
- void (async () => {
12
- const temporaryPath = path.join(os.tmpdir(), 'linter-bundle-');
13
-
14
- const folder = fs.mkdtempSync(temporaryPath);
15
-
16
- const tempFilePath = path.join(folder, 'tmp.scss');
17
-
18
- fs.writeFileSync(tempFilePath, '@property --color {\n\tsyntax: "<color>";\n\tinherits: false;\n\tinitial-value: #f00; // stylelint-disable-line color-no-hex -- The initial value must be a hex-color\n}\n\n* {\n\tborder: 1px solid var(--color);\n\n\tcolor: var(--color);\n}\n', 'utf8');
19
-
20
- const result = await runProcess(`stylelint -f json "${tempFilePath}"`);
21
-
22
- fs.unlinkSync(tempFilePath);
23
-
24
- if (result.stderr) {
25
- process.stderr.write(result.stderr);
26
-
27
- process.exitCode = 1;
28
-
29
- return;
30
- }
31
-
32
- /**
33
- * @type {import('stylelint').LintResult}
34
- */
35
- const { invalidOptionWarnings, warnings } = JSON.parse(result.stdout)[0];
36
-
37
- if (warnings.length > 0) {
38
- process.stderr.write(`Warnings:\n\n- ${warnings.map(({ text }) => text).join('\n- ')}\n`);
39
-
40
- process.exitCode = 1;
41
-
42
- return;
43
- }
44
-
45
- if (invalidOptionWarnings.length > 0) {
46
- process.stderr.write(`Invalid stylelint configuration:\n\n- ${invalidOptionWarnings.map(({ text }) => text).join('\n- ')}\n`);
47
-
48
- process.exitCode = 1;
49
-
50
- return;
51
- }
52
- })();