index.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. 'use strict';
  2. const hasBlock = require('../../utils/hasBlock');
  3. const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule');
  4. const nextNonCommentNode = require('../../utils/nextNonCommentNode');
  5. const rawNodeString = require('../../utils/rawNodeString');
  6. const report = require('../../utils/report');
  7. const ruleMessages = require('../../utils/ruleMessages');
  8. const validateOptions = require('../../utils/validateOptions');
  9. const whitespaceChecker = require('../../utils/whitespaceChecker');
  10. const ruleName = 'at-rule-semicolon-newline-after';
  11. const messages = ruleMessages(ruleName, {
  12. expectedAfter: () => 'Expected newline after ";"',
  13. });
  14. const meta = {
  15. url: 'https://stylelint.io/user-guide/rules/at-rule-semicolon-newline-after',
  16. fixable: true,
  17. };
  18. /** @type {import('stylelint').Rule} */
  19. const rule = (primary, _secondary, context) => {
  20. const checker = whitespaceChecker('newline', primary, messages);
  21. return (root, result) => {
  22. const validOptions = validateOptions(result, ruleName, {
  23. actual: primary,
  24. possible: ['always'],
  25. });
  26. if (!validOptions) {
  27. return;
  28. }
  29. root.walkAtRules((atRule) => {
  30. const nextNode = atRule.next();
  31. if (!nextNode) {
  32. return;
  33. }
  34. if (hasBlock(atRule)) {
  35. return;
  36. }
  37. if (!isStandardSyntaxAtRule(atRule)) {
  38. return;
  39. }
  40. // Allow an end-of-line comment
  41. const nodeToCheck = nextNonCommentNode(nextNode);
  42. if (!nodeToCheck) {
  43. return;
  44. }
  45. checker.afterOneOnly({
  46. source: rawNodeString(nodeToCheck),
  47. index: -1,
  48. err: (msg) => {
  49. if (context.fix) {
  50. nodeToCheck.raws.before = context.newline + nodeToCheck.raws.before;
  51. } else {
  52. report({
  53. message: msg,
  54. node: atRule,
  55. index: atRule.toString().length + 1,
  56. result,
  57. ruleName,
  58. });
  59. }
  60. },
  61. });
  62. });
  63. };
  64. };
  65. rule.ruleName = ruleName;
  66. rule.messages = messages;
  67. rule.meta = meta;
  68. module.exports = rule;