index.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict';
  2. const flattenArray = require('../../utils/flattenArray');
  3. const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule');
  4. const report = require('../../utils/report');
  5. const ruleMessages = require('../../utils/ruleMessages');
  6. const validateObjectWithArrayProps = require('../../utils/validateObjectWithArrayProps');
  7. const validateOptions = require('../../utils/validateOptions');
  8. const { isString } = require('../../utils/validateTypes');
  9. const ruleName = 'at-rule-property-required-list';
  10. const messages = ruleMessages(ruleName, {
  11. expected: (property, atRule) => `Expected property "${property}" for at-rule "${atRule}"`,
  12. });
  13. const meta = {
  14. url: 'https://stylelint.io/user-guide/rules/list/at-rule-property-required-list',
  15. };
  16. /** @type {import('stylelint').Rule<Record<string, string | string[]>>} */
  17. const rule = (primary) => {
  18. return (root, result) => {
  19. const validOptions = validateOptions(result, ruleName, {
  20. actual: primary,
  21. possible: [validateObjectWithArrayProps(isString)],
  22. });
  23. if (!validOptions) {
  24. return;
  25. }
  26. root.walkAtRules((atRule) => {
  27. if (!isStandardSyntaxAtRule(atRule)) {
  28. return;
  29. }
  30. const { name, nodes } = atRule;
  31. const atRuleName = name.toLowerCase();
  32. const propList = flattenArray(primary[atRuleName]);
  33. if (!propList) {
  34. return;
  35. }
  36. for (const property of propList) {
  37. const propertyName = property.toLowerCase();
  38. const hasProperty = nodes.find(
  39. (node) => node.type === 'decl' && node.prop.toLowerCase() === propertyName,
  40. );
  41. if (hasProperty) {
  42. continue;
  43. }
  44. report({
  45. message: messages.expected(propertyName, atRuleName),
  46. node: atRule,
  47. word: `@${atRule.name}`,
  48. result,
  49. ruleName,
  50. });
  51. continue;
  52. }
  53. });
  54. };
  55. };
  56. rule.ruleName = ruleName;
  57. rule.messages = messages;
  58. rule.meta = meta;
  59. module.exports = rule;