reportUnknownRuleNames.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. 'use strict';
  2. const levenshtein = require('fastest-levenshtein');
  3. const rules = require('./rules');
  4. const MAX_LEVENSHTEIN_DISTANCE = 6;
  5. const MAX_SUGGESTIONS_COUNT = 3;
  6. /**
  7. * @param {string} ruleName
  8. * @return {string[]}
  9. */
  10. function extractSuggestions(ruleName) {
  11. const suggestions = Array.from({ length: MAX_LEVENSHTEIN_DISTANCE });
  12. for (let i = 0; i < suggestions.length; i++) {
  13. suggestions[i] = [];
  14. }
  15. for (const existRuleName of Object.keys(rules)) {
  16. const distance = levenshtein.distance(existRuleName, ruleName);
  17. if (distance <= MAX_LEVENSHTEIN_DISTANCE) {
  18. suggestions[distance - 1].push(existRuleName);
  19. }
  20. }
  21. /** @type {string[]} */
  22. let result = [];
  23. for (const [i, suggestion] of suggestions.entries()) {
  24. if (suggestion.length > 0) {
  25. if (i < 3) {
  26. return suggestion.slice(0, MAX_SUGGESTIONS_COUNT);
  27. }
  28. result = result.concat(suggestion);
  29. }
  30. }
  31. return result.slice(0, MAX_SUGGESTIONS_COUNT);
  32. }
  33. /**
  34. * @param {string} ruleName
  35. * @param {string[]} [suggestions=[]]
  36. * @return {string}
  37. */
  38. function rejectMessage(ruleName, suggestions = []) {
  39. return `Unknown rule ${ruleName}.${
  40. suggestions.length > 0 ? ` Did you mean ${suggestions.join(', ')}?` : ''
  41. }`;
  42. }
  43. /** @type {Map<string, string[]>} */
  44. const cache = new Map();
  45. /**
  46. * @param {string} unknownRuleName
  47. * @param {import('postcss').Root} postcssRoot
  48. * @param {import('stylelint').PostcssResult} postcssResult
  49. * @returns {void}
  50. */
  51. module.exports = function reportUnknownRuleNames(unknownRuleName, postcssRoot, postcssResult) {
  52. const suggestions = cache.has(unknownRuleName)
  53. ? /** @type {string[]} */ (cache.get(unknownRuleName))
  54. : extractSuggestions(unknownRuleName);
  55. cache.set(unknownRuleName, suggestions);
  56. postcssResult.warn(rejectMessage(unknownRuleName, suggestions), {
  57. severity: 'error',
  58. rule: unknownRuleName,
  59. node: postcssRoot,
  60. index: 0,
  61. });
  62. };