stylelint-find-new-rules 3.0.4 → 4.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/lib/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const chalk = require('chalk');
3
+ const colors = require('picocolors');
4
4
  const yargs = require('yargs');
5
5
  const standalone = require('./index');
6
6
  const { print, printRules } = require('./utils/print');
@@ -21,7 +21,7 @@ const handleError = (err) => {
21
21
  errMsg = err.message || err.error || JSON.stringify(err);
22
22
  }
23
23
 
24
- print(chalk.red(`Error: ${errMsg}`));
24
+ print(colors.red(`Error: ${errMsg}`));
25
25
  process.exit(1);
26
26
  };
27
27
 
@@ -37,7 +37,7 @@ const { argv } = yargs
37
37
  alias: 'unused',
38
38
  describe: (
39
39
  `Find available rules that are not configured.\n` +
40
- `To disable, set to ${chalk.blue('false')} or use ${chalk.blue('--no-u')}`
40
+ `To disable, set to ${colors.blue('false')} or use ${colors.blue('--no-u')}`
41
41
  ),
42
42
  default: DEFAULT_OPTIONS.unused,
43
43
  })
@@ -46,7 +46,7 @@ const { argv } = yargs
46
46
  alias: 'deprecated',
47
47
  describe: (
48
48
  `Find deprecated configured rules.\n` +
49
- `To disable, set to ${chalk.blue('false')} or use ${chalk.blue('--no-d')}`
49
+ `To disable, set to ${colors.blue('false')} or use ${colors.blue('--no-d')}`
50
50
  ),
51
51
  default: DEFAULT_OPTIONS.deprecated,
52
52
  })
@@ -55,7 +55,7 @@ const { argv } = yargs
55
55
  alias: 'invalid',
56
56
  describe: (
57
57
  `Find configured rules that are no longer available.\n` +
58
- `To disable, set to ${chalk.blue('false')} or use ${chalk.blue('--no-i')}`
58
+ `To disable, set to ${colors.blue('false')} or use ${colors.blue('--no-i')}`
59
59
  ),
60
60
  default: DEFAULT_OPTIONS.invalid,
61
61
  })
@@ -85,7 +85,7 @@ const options = Object.entries(DEFAULT_OPTIONS).reduce(
85
85
  );
86
86
 
87
87
  if (!options.unused && !options.deprecated && !options.current && !options.available) {
88
- print(chalk.red(`Oops, one of the command line Options must be set...`));
88
+ print(colors.red(`Oops, one of the command line Options must be set...`));
89
89
  yargs.showHelp();
90
90
  process.exit(1);
91
91
  }
@@ -123,7 +123,7 @@ const printResults = (rules) => {
123
123
  }
124
124
 
125
125
  if (!hasOutdatedRules) {
126
- print(chalk.green(`All rules are up-to-date!`));
126
+ print(colors.green(`All rules are up-to-date!`));
127
127
  }
128
128
  process.exit(hasOutdatedRules ? 1 : 0);
129
129
  };
package/lib/index.js CHANGED
@@ -1,30 +1,13 @@
1
1
  'use strict';
2
2
 
3
- const { cosmiconfig } = require('cosmiconfig');
3
+ const { resolveConfig } = require('stylelint');
4
4
  const { getAllRules, getUsedRules } = require('./utils/rules');
5
5
 
6
- const getConfig = async (configFile = null) => {
7
- const explorer = cosmiconfig('stylelint');
6
+ module.exports = async (configFile = null) => {
7
+ const config = await resolveConfig(process.cwd(), { configFile });
8
8
 
9
- let _cosmiConfig;
10
- if (configFile) {
11
- _cosmiConfig = await explorer.load(configFile);
12
- } else {
13
- _cosmiConfig = await explorer.search();
14
- }
15
-
16
- if (!_cosmiConfig) {
17
- throw new Error(`No stylelint configuration found.`);
18
- }
19
-
20
- return _cosmiConfig.config;
21
- };
22
-
23
- module.exports = async (file = null) => {
24
- const userConfig = await getConfig(file);
25
-
26
- const all = getAllRules(userConfig);
27
- const used = getUsedRules(userConfig, all);
9
+ const all = getAllRules(config);
10
+ const used = getUsedRules(config, all);
28
11
  const deprecated = used.filter(({ isDeprecated }) => isDeprecated);
29
12
 
30
13
  const unused = all.filter(
@@ -37,6 +20,5 @@ module.exports = async (file = null) => {
37
20
  ({ name }) => !all.find((_rule) => _rule.name === name),
38
21
  );
39
22
 
40
- // eslint-disable-next-line object-curly-newline
41
23
  return { all, used, unused, invalid, deprecated };
42
24
  };
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+
3
+ const PLUGINS_URL_RESOLVER = {
4
+ 'stylelint': (rule) => (
5
+ `https://stylelint.io/user-guide/rules/list/${rule}`
6
+ ),
7
+ 'stylelint-scss': (rule) => (
8
+ `https://github.com/kristerkari/stylelint-scss/blob/master/src/rules/${rule}/README.md`
9
+ ),
10
+ 'stylelint-order': (rule) => (
11
+ `https://github.com/hudochenkov/stylelint-order/blob/master/rules/${rule}/README.md`
12
+ ),
13
+ 'stylelint-declaration-block-no-ignored-properties': () => (
14
+ 'https://github.com/kristerkari/stylelint-declaration-block-no-ignored-properties'
15
+ ),
16
+ 'stylelint-prettier': () => 'https://github.com/prettier/stylelint-prettier',
17
+ };
18
+
19
+ // @see https://regex101.com/r/4d3Jpl/2
20
+ const DEPRECATED_REGEX = /result\.warn\(\s*.+,\s*{\s*.*\s*['"]?stylelintType['"]?\s*:\s*['"]deprecation['"],/i;
21
+
22
+ const extractRuleMeta = (name, rule, isPlugin) => {
23
+ const meta = rule.meta || {};
24
+
25
+ const deprecated = meta.deprecated === 'undefined'
26
+ // - Hacky solution to find if the rule is deprecated since
27
+ // stylelint do not provide metadata for rules.
28
+ // @see https://github.com/stylelint/stylelint/issues/2622
29
+ ? DEPRECATED_REGEX.test(rule().toString())
30
+ : !!meta.deprecated;
31
+
32
+ const url = (() => {
33
+ if (typeof meta.url === 'string') {
34
+ return meta.url;
35
+ }
36
+
37
+ if (!isPlugin) {
38
+ return PLUGINS_URL_RESOLVER.stylelint(name);
39
+ }
40
+
41
+ if (!name.includes('/')) {
42
+ return null;
43
+ }
44
+
45
+ // @see https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/String/split#description
46
+ // eslint-disable-next-line prefer-named-capture-group -- See above (about capturing groups in split's regex).
47
+ const [plugin, baseName] = name.split(/\/(.+)/);
48
+
49
+ return `stylelint-${plugin}` in PLUGINS_URL_RESOLVER
50
+ ? PLUGINS_URL_RESOLVER[`stylelint-${plugin}`](baseName)
51
+ : null;
52
+ })();
53
+
54
+ return { name, isDeprecated: deprecated, url };
55
+ };
56
+
57
+ module.exports = extractRuleMeta;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const columnify = require('columnify');
4
- const chalk = require('chalk');
4
+ const colors = require('picocolors');
5
5
  const os = require('os');
6
6
 
7
7
  const print = (output) => {
@@ -20,18 +20,18 @@ const printRules = (heading, rules, options = {}) => {
20
20
  const outRule = { rule: name };
21
21
 
22
22
  if (color) {
23
- outRule.rule = chalk[`${color}Bright`](outRule.rule);
23
+ outRule.rule = colors.bold(colors[color](outRule.rule));
24
24
  }
25
25
 
26
26
  if (showLink) {
27
- outRule.url = url ? chalk.cyan(url) : null;
27
+ outRule.url = url ? colors.cyan(url) : null;
28
28
  }
29
29
 
30
30
  return outRule;
31
31
  },
32
32
  );
33
33
 
34
- print(chalk[color || 'blue'].underline(heading));
34
+ print(colors.underline(colors[color || 'blue'](heading)));
35
35
  print(columnify(rulesToPrint, {}));
36
36
  };
37
37
 
@@ -1,73 +1,30 @@
1
1
  'use strict';
2
2
 
3
- const path = require('path');
4
- const requireRelative = require('require-relative');
5
- const ruleBuilder = require('./ruleBuilder');
6
-
7
- const requireResolveRelative = (moduleName, relativePath = null) => (
8
- path.dirname(requireRelative.resolve(moduleName, relativePath))
9
- );
10
-
11
- const getStylelintRules = () => {
12
- const stylelint = requireRelative('stylelint');
13
- const _buildRule = ruleBuilder('stylelint');
14
-
15
- // @see https://regex101.com/r/4d3Jpl/2
16
- const DEPRECATED_REGEX = /result\.warn\(\s*.+,\s*{\s*.*\s*['"]?stylelintType['"]?\s*:\s*['"]deprecation['"],/i;
17
-
18
- return Object.entries(stylelint.rules).map(([name, rule]) => {
19
- let { meta } = rule;
20
-
21
- // - Hacky solution to find if the rule is deprecated since
22
- // stylelint do not provide metadata for rules.
23
- // @see https://github.com/stylelint/stylelint/issues/2622
24
- if (!meta) {
25
- const deprecated = DEPRECATED_REGEX.test(rule().toString());
26
- meta = { deprecated };
27
- }
28
-
29
- return _buildRule(name, { meta });
30
- });
31
- };
3
+ const coreRules = require('stylelint').rules;
4
+ const extractRuleMeta = require('./extractRuleMeta');
32
5
 
33
6
  const getAllRules = (config) => {
34
- const _gatherPluginsRules = (_config, relativePath = null) => {
35
- const _rules = [];
36
-
37
- if (_config.plugins) {
38
- const _plugins = Array.isArray(_config.plugins) ? _config.plugins : [_config.plugins];
39
- _plugins.forEach((plugin) => {
40
- const isPathPlugin = path.isAbsolute(plugin) || plugin.startsWith('.');
41
- const _buildRule = ruleBuilder(isPathPlugin ? '[UNKNOWN]' : plugin);
42
-
43
- let pluginRules;
44
- pluginRules = requireRelative(plugin, relativePath);
45
- pluginRules = pluginRules.default || pluginRules; // - ES6 or CommonJS modules
46
- pluginRules = Array.isArray(pluginRules) ? pluginRules : [pluginRules];
47
-
48
- pluginRules.forEach(({ ruleName: name, rule }) => {
49
- if (!name || !name.includes('/')) {
50
- return;
51
- }
52
- _rules.push(_buildRule(name, rule));
53
- });
7
+ const rules = Object.entries(coreRules).map(([name, rule]) => (
8
+ extractRuleMeta(name, rule, false)
9
+ ));
10
+
11
+ if (config.plugins) {
12
+ [config.plugins].flat().forEach((plugin) => {
13
+ let pluginRules;
14
+ pluginRules = require(plugin); // eslint-disable-line import/no-dynamic-require, global-require
15
+ pluginRules = pluginRules.default || pluginRules; // - ES6 or CommonJS modules
16
+ pluginRules = [pluginRules].flat();
17
+
18
+ pluginRules.forEach(({ ruleName: name, rule }) => {
19
+ if (!name || !name.includes('/')) {
20
+ return;
21
+ }
22
+ rules.push(extractRuleMeta(name, rule, true));
54
23
  });
55
- }
56
-
57
- if (_config.extends) {
58
- const _extends = Array.isArray(_config.extends) ? _config.extends : [_config.extends];
59
- _extends.forEach((extendName) => {
60
- const extendedConfigPath = requireResolveRelative(extendName, relativePath);
61
- const extendedConfig = requireRelative(extendName, relativePath);
62
- _rules.push(..._gatherPluginsRules(extendedConfig, extendedConfigPath));
63
- });
64
- }
65
-
66
- return _rules;
67
- };
24
+ });
25
+ }
68
26
 
69
- const pluginsRules = _gatherPluginsRules(config);
70
- return getStylelintRules().concat(pluginsRules);
27
+ return rules;
71
28
  };
72
29
 
73
30
  const getUsedRules = (config, allRules = null) => {
@@ -75,24 +32,7 @@ const getUsedRules = (config, allRules = null) => {
75
32
  allRules = getAllRules(config);
76
33
  }
77
34
 
78
- const _gatherRules = (_config, relativePath = null) => {
79
- const rulesNames = Object.keys(_config.rules || {});
80
-
81
- // - Extends
82
- if (_config.extends) {
83
- const _extends = Array.isArray(_config.extends) ? _config.extends : [_config.extends];
84
-
85
- _extends.forEach((extendName) => {
86
- const extendedConfigPath = requireResolveRelative(extendName, relativePath);
87
- const extendedConfig = requireRelative(extendName, relativePath);
88
- rulesNames.push(..._gatherRules(extendedConfig, extendedConfigPath));
89
- });
90
- }
91
-
92
- return rulesNames;
93
- };
94
-
95
- const rules = _gatherRules(config)
35
+ const rules = Object.keys(config.rules || {})
96
36
  .filter((value, index, self) => self.indexOf(value) === index)
97
37
  .map((name) => {
98
38
  const rule = allRules.find((_rule) => _rule.name === name);
@@ -102,4 +42,4 @@ const getUsedRules = (config, allRules = null) => {
102
42
  return rules;
103
43
  };
104
44
 
105
- module.exports = { getUsedRules, getAllRules, getStylelintRules };
45
+ module.exports = { getUsedRules, getAllRules };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stylelint-find-new-rules",
3
- "version": "3.0.4",
3
+ "version": "4.0.0",
4
4
  "description": "Find stylelint rules that you don't have in your config",
5
5
  "homepage": "https://github.com/Donov4n/stylelint-find-new-rules",
6
6
  "license": "MIT",
@@ -17,18 +17,17 @@
17
17
  "lint": "eslint --ext .js lib"
18
18
  },
19
19
  "dependencies": {
20
- "chalk": "~4.1.2",
21
- "columnify": "~1.5.4",
22
- "cosmiconfig": "~7.0.1",
23
- "require-relative": "~0.8.7",
24
- "yargs": "~17.2.1"
20
+ "columnify": "~1.6.0",
21
+ "picocolors": "^1.0.0",
22
+ "yargs": "~17.3.1"
25
23
  },
26
24
  "devDependencies": {
27
- "@pulsanova/eslint-config-base": "~1.3.2",
28
- "eslint": "^7.32.0"
25
+ "@pulsanova/eslint-config-base": "~2.1.2",
26
+ "eslint": "^8.11.0",
27
+ "stylelint": "^14"
29
28
  },
30
29
  "peerDependencies": {
31
- "stylelint": "^13 || ^14"
30
+ "stylelint": "^14"
32
31
  },
33
32
  "engines": {
34
33
  "node": ">=10"
@@ -1,39 +0,0 @@
1
- 'use strict';
2
-
3
- const PLUGINS_URL_RESOLVER = {
4
- 'stylelint': (rule) => (
5
- `https://stylelint.io/user-guide/rules/list/${rule}`
6
- ),
7
- 'stylelint-scss': (rule) => (
8
- `https://github.com/kristerkari/stylelint-scss/blob/master/src/rules/${rule}/README.md`
9
- ),
10
- 'stylelint-order': (rule) => (
11
- `https://github.com/hudochenkov/stylelint-order/blob/master/rules/${rule}/README.md`
12
- ),
13
- 'stylelint-declaration-block-no-ignored-properties': () => (
14
- 'https://github.com/kristerkari/stylelint-declaration-block-no-ignored-properties'
15
- ),
16
- 'stylelint-prettier': () => 'https://github.com/prettier/stylelint-prettier',
17
- };
18
-
19
- const ruleBuilder = (resolverName) => {
20
- const resolver = PLUGINS_URL_RESOLVER[resolverName];
21
-
22
- return (name, rule) => {
23
- const meta = rule.meta || {};
24
- const isDeprecated = meta.deprecated || false;
25
-
26
- let baseName = name;
27
- if (resolverName !== 'stylelint') {
28
- const namespacePos = name.indexOf('/');
29
- if (namespacePos !== -1) {
30
- baseName = name.substr(namespacePos + 1);
31
- }
32
- }
33
-
34
- const url = resolver ? resolver(baseName) : null;
35
- return { name, isDeprecated, url };
36
- };
37
- };
38
-
39
- module.exports = ruleBuilder;