reportUnknownRuleNames.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 = new Array(MAX_LEVENSHTEIN_DISTANCE);
  12. for (let i = 0; i < suggestions.length; i++) {
  13. suggestions[i] = [];
  14. }
  15. Object.keys(rules).forEach((existRuleName) => {
  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 (let i = 0; i < suggestions.length; i++) {
  24. if (suggestions[i].length > 0) {
  25. if (i < 3) {
  26. return suggestions[i].slice(0, MAX_SUGGESTIONS_COUNT);
  27. }
  28. result = result.concat(suggestions[i]);
  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. const warningProperties = {
  56. severity: 'error',
  57. rule: unknownRuleName,
  58. node: postcssRoot,
  59. index: 0,
  60. };
  61. cache.set(unknownRuleName, suggestions);
  62. postcssResult.warn(rejectMessage(unknownRuleName, suggestions), warningProperties);
  63. };