stylelint-find-new-rules 3.0.2 → 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,18 +1,18 @@
1
1
  'use strict';
2
2
 
3
- const chalk = require('chalk');
4
- const yargs = require('yargs');
3
+ const colors = require('picocolors');
4
+ const yargs = require('yargs');
5
5
  const standalone = require('./index');
6
6
  const { print, printRules } = require('./utils/print');
7
7
 
8
8
  const pkg = require('../package.json');
9
9
 
10
10
  const DEFAULT_OPTIONS = {
11
- unused : true,
12
- deprecated : true,
13
- invalid : true,
14
- current : false,
15
- available : false
11
+ unused: true,
12
+ deprecated: true,
13
+ invalid: true,
14
+ current: false,
15
+ available: false,
16
16
  };
17
17
 
18
18
  const handleError = (err) => {
@@ -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
 
@@ -33,43 +33,43 @@ const { argv } = yargs
33
33
  .example('stylelint-find-new-rules --no-d --no-i')
34
34
  .example('stylelint-find-new-rules path/to/custom.config.js')
35
35
  .option('u', {
36
- type : 'boolean',
37
- alias : 'unused',
38
- describe : (
36
+ type: 'boolean',
37
+ alias: 'unused',
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
- default: DEFAULT_OPTIONS.unused
42
+ default: DEFAULT_OPTIONS.unused,
43
43
  })
44
44
  .option('d', {
45
- type : 'boolean',
46
- alias : 'deprecated',
47
- describe : (
45
+ type: 'boolean',
46
+ alias: 'deprecated',
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
- default: DEFAULT_OPTIONS.deprecated
51
+ default: DEFAULT_OPTIONS.deprecated,
52
52
  })
53
53
  .option('i', {
54
- type : 'boolean',
55
- alias : 'invalid',
56
- describe : (
54
+ type: 'boolean',
55
+ alias: 'invalid',
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
- default: DEFAULT_OPTIONS.invalid
60
+ default: DEFAULT_OPTIONS.invalid,
61
61
  })
62
62
  .option('c', {
63
- type : 'boolean',
64
- alias : 'current',
65
- describe : 'Find all currently configured rules.',
66
- default : DEFAULT_OPTIONS.current
63
+ type: 'boolean',
64
+ alias: 'current',
65
+ describe: 'Find all currently configured rules.',
66
+ default: DEFAULT_OPTIONS.current,
67
67
  })
68
68
  .option('a', {
69
- type : 'boolean',
70
- alias : 'available',
71
- describe : 'Find all available stylelint rules.',
72
- default : DEFAULT_OPTIONS.available
69
+ type: 'boolean',
70
+ alias: 'available',
71
+ describe: 'Find all available stylelint rules.',
72
+ default: DEFAULT_OPTIONS.available,
73
73
  })
74
74
  .help('h')
75
75
  .alias('h', 'help')
@@ -81,11 +81,11 @@ const options = Object.entries(DEFAULT_OPTIONS).reduce(
81
81
  const value = name in argv ? argv[name] : defaultValue;
82
82
  return { ...acc, [name]: value };
83
83
  },
84
- {}
84
+ {},
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
  }
@@ -110,20 +110,20 @@ const printResults = (rules) => {
110
110
  if (options.deprecated && rules.deprecated.length) {
111
111
  hasOutdatedRules = true;
112
112
  printRules(`[DEPRECATED] Configured rules that are deprecated:`, rules.deprecated, {
113
- color: 'red'
113
+ color: 'red',
114
114
  });
115
115
  }
116
116
 
117
117
  if (options.invalid && rules.invalid.length) {
118
118
  hasOutdatedRules = true;
119
119
  printRules(`[INVALID] Configured rules that are no longer available:`, rules.invalid, {
120
- color : 'red',
121
- showLink : false
120
+ color: 'red',
121
+ showLink: false,
122
122
  });
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,42 +1,24 @@
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 function (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 function (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(
31
14
  ({ name, isDeprecated }) => (
32
- !isDeprecated && !used.find(_rule => _rule.name === name)
33
- )
15
+ !isDeprecated && !used.find((_rule) => _rule.name === name)
16
+ ),
34
17
  );
35
18
 
36
19
  const invalid = used.filter(
37
- ({ name }) => !all.find(_rule => _rule.name === name)
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,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const columnify = require('columnify');
4
- const chalk = require('chalk');
5
- const os = require('os');
4
+ const colors = require('picocolors');
5
+ const os = require('os');
6
6
 
7
7
  const print = (output) => {
8
8
  process.stdout.write(output);
@@ -11,7 +11,7 @@ const print = (output) => {
11
11
 
12
12
  const printRules = (heading, rules, options = {}) => {
13
13
  const defaults = { color: null, showLink: true };
14
- const { color, showLink } = Object.assign({}, defaults, options);
14
+ const { color, showLink } = { ...defaults, ...options };
15
15
 
16
16
  const rulesToPrint = [...rules]
17
17
  .sort((a, b) => a.name.localeCompare(b.name))
@@ -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,31 +32,14 @@ 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
- const rule = allRules.find(_rule => _rule.name === name);
38
+ const rule = allRules.find((_rule) => _rule.name === name);
99
39
  return rule || { name, url: null };
100
40
  });
101
41
 
102
42
  return rules;
103
43
  };
104
44
 
105
- module.exports = { getUsedRules, getAllRules, getStylelintRules };
45
+ module.exports = { getUsedRules, getAllRules };
package/package.json CHANGED
@@ -1,33 +1,33 @@
1
1
  {
2
- "name" : "stylelint-find-new-rules",
3
- "version" : "3.0.2",
4
- "description" : "Find stylelint rules that you don't have in your config",
5
- "homepage" : "https://github.com/Donov4n/stylelint-find-new-rules",
6
- "license" : "MIT",
7
- "repository" : "Donov4n/stylelint-find-new-rules",
8
- "author" : "Donovan Lambert <d.lambert@cirize.com>",
9
- "contributors" : ["Alex Ilyaev"],
10
- "main" : "lib/index.js",
11
- "bin" : {
2
+ "name": "stylelint-find-new-rules",
3
+ "version": "4.0.0",
4
+ "description": "Find stylelint rules that you don't have in your config",
5
+ "homepage": "https://github.com/Donov4n/stylelint-find-new-rules",
6
+ "license": "MIT",
7
+ "repository": "Donov4n/stylelint-find-new-rules",
8
+ "author": "Donovan Lambert <d.lambert@cirize.com>",
9
+ "contributors": [
10
+ "Alex Ilyaev"
11
+ ],
12
+ "main": "lib/index.js",
13
+ "bin": {
12
14
  "stylelint-find-new-rules": "bin/stylelint-find-new-rules.js"
13
15
  },
14
16
  "scripts": {
15
17
  "lint": "eslint --ext .js lib"
16
18
  },
17
19
  "dependencies": {
18
- "chalk": "~4.1.2",
19
- "columnify": "~1.5.4",
20
- "cosmiconfig": "~7.0.0",
21
- "require-relative": "~0.8.7",
22
- "yargs": "~17.1.1"
20
+ "columnify": "~1.6.0",
21
+ "picocolors": "^1.0.0",
22
+ "yargs": "~17.3.1"
23
23
  },
24
24
  "devDependencies": {
25
- "eslint": "^7.32.0",
26
- "eslint-config-airbnb-base": "^14.2.1",
27
- "eslint-plugin-import": "^2.24.0"
25
+ "@pulsanova/eslint-config-base": "~2.1.2",
26
+ "eslint": "^8.11.0",
27
+ "stylelint": "^14"
28
28
  },
29
29
  "peerDependencies": {
30
- "stylelint": "^13"
30
+ "stylelint": "^14"
31
31
  },
32
32
  "engines": {
33
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/${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;