createPartialStylelintResult.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. 'use strict';
  2. /** @typedef {import('stylelint').PostcssResult} PostcssResult */
  3. /** @typedef {import('stylelint').LintResult} StylelintResult */
  4. /**
  5. * @param {PostcssResult} [postcssResult]
  6. * @param {import('stylelint').CssSyntaxError} [cssSyntaxError]
  7. * @return {StylelintResult}
  8. */
  9. module.exports = function createPartialStylelintResult(postcssResult, cssSyntaxError) {
  10. /** @type {StylelintResult} */
  11. let stylelintResult;
  12. /** @type {string | undefined} */
  13. let source;
  14. if (postcssResult && postcssResult.root) {
  15. if (postcssResult.root.source) {
  16. source = postcssResult.root.source.input.file;
  17. if (!source && 'id' in postcssResult.root.source.input) {
  18. source = postcssResult.root.source.input.id;
  19. }
  20. }
  21. const deprecationMessages = postcssResult.messages.filter(
  22. (message) => message.stylelintType === 'deprecation',
  23. );
  24. const deprecations = deprecationMessages.map((deprecationMessage) => {
  25. return {
  26. text: deprecationMessage.text,
  27. reference: deprecationMessage.stylelintReference,
  28. };
  29. });
  30. const invalidOptionMessages = postcssResult.messages.filter(
  31. (message) => message.stylelintType === 'invalidOption',
  32. );
  33. const invalidOptionWarnings = invalidOptionMessages.map((invalidOptionMessage) => {
  34. return {
  35. text: invalidOptionMessage.text,
  36. };
  37. });
  38. const parseErrors = postcssResult.messages.filter(
  39. (message) => message.stylelintType === 'parseError',
  40. );
  41. // Remove deprecation warnings, invalid options, and parse errors from the messages
  42. postcssResult.messages = postcssResult.messages.filter(
  43. (message) =>
  44. message.stylelintType !== 'deprecation' &&
  45. message.stylelintType !== 'invalidOption' &&
  46. message.stylelintType !== 'parseError',
  47. );
  48. // This defines the stylelint result object that formatters receive
  49. stylelintResult = {
  50. source,
  51. deprecations,
  52. invalidOptionWarnings,
  53. // @ts-expect-error -- TS2322: Type 'Message[]' is not assignable to type '(Warning & { stylelintType: string; })[]'.
  54. parseErrors,
  55. errored: postcssResult.stylelint.stylelintError,
  56. warnings: postcssResult.messages.map((message) => {
  57. return {
  58. line: message.line,
  59. column: message.column,
  60. endLine: message.endLine,
  61. endColumn: message.endColumn,
  62. rule: message.rule,
  63. severity: message.severity,
  64. text: message.text,
  65. };
  66. }),
  67. ignored: postcssResult.stylelint.ignored,
  68. _postcssResult: postcssResult,
  69. };
  70. } else if (cssSyntaxError) {
  71. if (cssSyntaxError.name !== 'CssSyntaxError') {
  72. throw cssSyntaxError;
  73. }
  74. stylelintResult = {
  75. source: cssSyntaxError.file || '<input css 1>',
  76. deprecations: [],
  77. invalidOptionWarnings: [],
  78. parseErrors: [],
  79. errored: true,
  80. warnings: [
  81. {
  82. line: cssSyntaxError.line,
  83. column: cssSyntaxError.column,
  84. endLine: cssSyntaxError.endLine,
  85. endColumn: cssSyntaxError.endColumn,
  86. rule: cssSyntaxError.name,
  87. severity: 'error',
  88. text: `${cssSyntaxError.reason} (${cssSyntaxError.name})`,
  89. },
  90. ],
  91. };
  92. } else {
  93. throw new Error(
  94. 'createPartialStylelintResult must be called with either postcssResult or CssSyntaxError',
  95. );
  96. }
  97. return stylelintResult;
  98. };