{"version":3,"file":"_rule.mjs","sources":["../../../../../src/rules/css/grouped-declarations/_rule.ts"],"sourcesContent":["import { RuleCreator } from \"@typescript-eslint/utils/eslint-utils\";\nimport rootPostcss from \"postcss\";\n\nimport { resolveDocsRoute } from \"../../../utils\";\nimport { isIdentifier } from \"../../../utils/ast/guards\";\n\nimport { rewriteToExpectedAST } from \"./fixer.rewrite-to-expected-ast\";\nimport { astToKeySegments } from \"./util.ast-to-key-segments\";\nimport { makeDeclarationScopeAnalyzer } from \"./util.declaration-scope-analyzer\";\nimport { extractDeclarationScope } from \"./util.extract-declaration-scopes\";\nimport { restoreExpressions } from \"./util.restore-expressions\";\nimport { stringifyExpressions } from \"./util.stringify-expressions\";\n\nconst postcss = rootPostcss();\n\nexport type Options = [];\n\nexport enum MessageIds {\n  INVALID_GROUP_ORDER = \"invalid-group-order\",\n  INVALID_DECLARATION_ORDER = \"invalid-declaration-order\",\n  INVALID_GROUPING = \"invalid-grouping\",\n  FIXABLE_REPORT = \"fixable-report\",\n  PARSING_FAILED = \"parsing-failed\",\n}\n\nconst createRule = RuleCreator(resolveDocsRoute);\n\n/**\n * Identifies @linaria/core CSS-in-JS tags and ensures that a standardised\n * grouping of declarations is enforced. A \"group\" is identified as a logical\n * set of declarations separated by either an empty line or a comment.\n *\n * Issues will, whereever possible, be reported inline at violating CSS lines\n * to allow developers to easily digest issues. However, in some cases such\n * reports have not been implemented.\n *\n * In practice the reports exist simply to improve DX-experience. The actual\n * auto-fix relies upon comparing the original AST with an AST that fully\n * respects the configured ordering, prioritised as follows:\n *\n * 1) Declaration grouping will be considered in scopes. AtRule and Rule\n * creates new scopes.\n *\n * 2) The root scope will be positioned before other scopes. Then Rule scopes\n * will follow and finally AtRules.\n *\n * 3) Inside each scope declarations will be sorted based on the provided\n * grouping.\n *\n * 4) In case a group of declarations begins with a comment, then these will be\n * taken out of the ordering flow and positioned at the end of the scope.\n * Ordering will not be performed for this group.\n *\n * 5) If a declaration does not match any provided grouping then it will be\n * added to a final group after all other groups. Inside declarations will be\n * sorted alphabetically.\n */\nexport const groupedDeclarationsRule = createRule<Options, MessageIds>({\n  name: \"css/grouped-declarations\",\n  defaultOptions: [],\n  meta: {\n    type: \"problem\",\n    fixable: \"code\",\n    messages: {\n      [MessageIds.INVALID_GROUP_ORDER]: `\"{{currentGroup}}\" (priority {{currentGroupIndex}}) should be placed before \"{{prevGroup}}\" (priority {{prevGroupIndex}})`,\n      [MessageIds.INVALID_DECLARATION_ORDER]: `\"{{property}}\" is not ordered correctly with respect to the ordering \"{{order}}\"`,\n      [MessageIds.INVALID_GROUPING]: `\"{{property}}\" does not belong to the current group ordering \"{{order}}\"`,\n      [MessageIds.FIXABLE_REPORT]:\n        \"Issues have been identified with the current CSS structuring, please use this error to automatically re-format\",\n      [MessageIds.PARSING_FAILED]:\n        \"CSS parsing failed. This is likely a bug in the plugin. Please inspect terminal output, and report a bug.\",\n    },\n    docs: {\n      description:\n        \"Identifies @linaria/core CSS-in-JS tags and ensures that a standardised grouping of declarations is enforced\",\n    },\n    hasSuggestions: true,\n    schema: [],\n  },\n  create: (context) => {\n    const sourceCode = context.sourceCode;\n\n    return {\n      TaggedTemplateExpression: (node) => {\n        // Bail out early in case we're not considering a @linaria/core css\n        // literal\n        if (!isIdentifier(node.tag) || node.tag.name !== \"css\") {\n          return;\n        }\n\n        const cssString = stringifyExpressions(\n          node.quasi.quasis,\n          node.quasi.expressions.map((expression) =>\n            sourceCode.getText(expression),\n          ),\n        );\n\n        try {\n          const cssAST = postcss.process(cssString).root;\n\n          if (cssAST.type === \"document\") {\n            throw new Error(\"AST of type document is not supported currently.\");\n            return;\n          }\n\n          const orginalKey = astToKeySegments(cssAST).join(\"\");\n\n          const declarationRootScope = extractDeclarationScope(cssAST);\n          const analyzeDeclarationScope = makeDeclarationScopeAnalyzer(\n            context,\n            node,\n          );\n          analyzeDeclarationScope(declarationRootScope);\n\n          const fixedAst = rewriteToExpectedAST(cssAST, declarationRootScope);\n          const fixedKey = astToKeySegments(fixedAst).join(\"\");\n\n          if (orginalKey !== fixedKey) {\n            context.report({\n              node: node.tag,\n              messageId: MessageIds.FIXABLE_REPORT,\n              fix(fixer) {\n                return fixer.replaceText(\n                  node.quasi,\n                  `\\`${restoreExpressions(fixedAst.toString())}\\``,\n                );\n              },\n            });\n          }\n        } catch (err) {\n          console.warn(context.filename, err);\n          context.report({\n            node: node.tag,\n            messageId: MessageIds.PARSING_FAILED,\n          });\n        }\n      },\n    };\n  },\n});\n"],"names":["MessageIds"],"mappings":"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"}