lint-suite 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"no-unused-classes.d.ts","sourceRoot":"","sources":["../../../../../../../packages/lint-suite/src/lib/rules/no-unused-classes/no-unused-classes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAoC,MAAM,WAAW,CAAC;AAwB1E,eAAO,MAAM,QAAQ,iCAAiC,CAAC;AAOvD,eAAO,MAAM,QAAQ;qBALG,MAAM,KAAG,MAAM;CAK2B,CAAC;AAuInE,QAAA,MAAM,MAAM,EAAE,MAAgD,CAAC;AAE/D,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"no-unused-classes.d.ts","sourceRoot":"","sources":["../../../../../../../packages/lint-suite/src/lib/rules/no-unused-classes/no-unused-classes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAoC,MAAM,WAAW,CAAC;AAyB1E,eAAO,MAAM,QAAQ,iCAAiC,CAAC;AAOvD,eAAO,MAAM,QAAQ;qBALG,MAAM,KAAG,MAAM;CAK2B,CAAC;AAqKnE,QAAA,MAAM,MAAM,EAAE,MAAgD,CAAC;AAE/D,eAAe,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"template-usage.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/lint-suite/src/lib/rules/no-unused-classes/template/template-usage.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACd,MAAM,qCAAqC,CAAC;AAwH7C,eAAO,MAAM,aAAa,GAAI,SAAS,cAAc,EAAE,KAAG,aAuBzD,CAAC"}
1
+ {"version":3,"file":"template-usage.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/lint-suite/src/lib/rules/no-unused-classes/template/template-usage.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACd,MAAM,qCAAqC,CAAC;AA+G7C,eAAO,MAAM,aAAa,GAAI,SAAS,cAAc,EAAE,KAAG,aAuBzD,CAAC"}
@@ -1,3 +1,5 @@
1
+ import type { TmplAstBoundAttribute } from '@angular/compiler';
1
2
  import type { ClassAttributeHost, TemplateClass } from '../common/class-usage.type.ts';
3
+ export declare const isClassExpression: (input: TmplAstBoundAttribute) => boolean;
2
4
  export declare const templateClasses: (node: ClassAttributeHost) => TemplateClass[];
3
5
  //# sourceMappingURL=template-classes.util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"template-classes.util.d.ts","sourceRoot":"","sources":["../../../../../../../packages/lint-suite/src/lib/rules/utils/template-classes.util.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACd,MAAM,+BAA+B,CAAC;AAuFvC,eAAO,MAAM,eAAe,GAAI,MAAM,kBAAkB,KAAG,aAAa,EAoBvE,CAAC"}
1
+ {"version":3,"file":"template-classes.util.d.ts","sourceRoot":"","sources":["../../../../../../../packages/lint-suite/src/lib/rules/utils/template-classes.util.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACd,MAAM,+BAA+B,CAAC;AAiDvC,eAAO,MAAM,iBAAiB,GAAI,OAAO,qBAAqB,KAAG,OAUhE,CAAC;AAiCF,eAAO,MAAM,eAAe,GAAI,MAAM,kBAAkB,KAAG,aAAa,EAoBvE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"typescript-safety.d.ts","sourceRoot":"","sources":["../../../../../packages/lint-suite/src/lib/typescript-safety.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,gBAAgB,wCAwJ3B,CAAC"}
1
+ {"version":3,"file":"typescript-safety.d.ts","sourceRoot":"","sources":["../../../../../packages/lint-suite/src/lib/typescript-safety.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,gBAAgB,wCAgK3B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lint-suite",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Reusable ESLint, Stylelint, and Prettier configurations",
5
5
  "repository": {
6
6
  "type": "git",
package/stylelint.cjs CHANGED
@@ -630,7 +630,12 @@ var classExpressionUsage = (source) => {
630
630
 
631
631
  // packages/lint-suite/src/lib/rules/utils/template-classes.util.ts
632
632
  var import_compiler2 = require("@angular/compiler");
633
- var CLASS_ATTRIBUTE = "class";
633
+ var CLASS_ATTRIBUTES = [
634
+ "class",
635
+ "routerLinkActive",
636
+ "animate.enter",
637
+ "animate.leave"
638
+ ];
634
639
  var CLASS_BINDING_PREFIX = "class.";
635
640
  var TOKEN = /\S+/gu;
636
641
  var expressionSource = (value) => {
@@ -659,11 +664,11 @@ var boundClassName = (input) => {
659
664
  return input.name;
660
665
  };
661
666
  var isClassExpression = (input) => {
662
- const isClassName = input.name === CLASS_ATTRIBUTE;
667
+ const isClassName = CLASS_ATTRIBUTES.includes(input.name);
663
668
  if (!isClassName) return false;
664
669
  const { details } = input.keySpan;
665
670
  if (details === null) return true;
666
- return details === CLASS_ATTRIBUTE;
671
+ return details === input.name;
667
672
  };
668
673
  var expressionClasses = (input) => {
669
674
  const source = expressionSource(input.value);
@@ -688,7 +693,7 @@ var inputClasses = (input) => {
688
693
  var templateClasses = (node) => {
689
694
  const classes = [];
690
695
  for (const attribute of node.attributes) {
691
- const isClassName = attribute.name === CLASS_ATTRIBUTE;
696
+ const isClassName = CLASS_ATTRIBUTES.includes(attribute.name);
692
697
  if (isClassName) {
693
698
  const found = staticClasses(attribute);
694
699
  classes.push(...found);
@@ -705,7 +710,6 @@ var templateClasses = (node) => {
705
710
  var toRegExp = (pattern) => new RegExp(pattern, "u");
706
711
 
707
712
  // packages/lint-suite/src/lib/rules/no-unused-classes/template/template-usage.ts
708
- var CLASS_ATTRIBUTE2 = "class";
709
713
  var NG_CLASS_ATTRIBUTE = "ngClass";
710
714
  var matchesNone = () => false;
711
715
  var UNKNOWN_USAGE2 = {
@@ -722,11 +726,7 @@ var expressionSource2 = (value) => {
722
726
  var isClassInput = (input) => {
723
727
  const isNgClass = input.name === NG_CLASS_ATTRIBUTE;
724
728
  if (isNgClass) return true;
725
- const isClass = input.name === CLASS_ATTRIBUTE2;
726
- if (!isClass) return false;
727
- const { details } = input.keySpan;
728
- if (details === null) return true;
729
- return details === CLASS_ATTRIBUTE2;
729
+ return isClassExpression(input);
730
730
  };
731
731
  var ClassUsageVisitor = class extends import_compiler3.TmplAstRecursiveVisitor {
732
732
  names = /* @__PURE__ */ new Set();
@@ -844,6 +844,23 @@ var extendedClasses = (root) => {
844
844
  root.walkAtRules("extend", collect2);
845
845
  return names;
846
846
  };
847
+ var isEmittingRule = (rule) => {
848
+ const isEmittingNode = (node) => {
849
+ return node.type === "decl" || node.type === "atrule";
850
+ };
851
+ const children = rule.nodes;
852
+ return children.some(isEmittingNode);
853
+ };
854
+ var emittedClasses = (root) => {
855
+ const names = /* @__PURE__ */ new Set();
856
+ const visit = (rule, resolved) => {
857
+ const isEmitting = isEmittingRule(rule);
858
+ if (!isEmitting) return;
859
+ for (const selector of resolved) addNames2(selector, names);
860
+ };
861
+ walkResolvedRules(root, visit);
862
+ return names;
863
+ };
847
864
  var ruleClasses = (resolved, parents) => {
848
865
  const inherited = /* @__PURE__ */ new Set();
849
866
  for (const parent of parents) addNames2(parent, inherited);
@@ -858,6 +875,8 @@ var ruleClasses = (resolved, parents) => {
858
875
  return [...own];
859
876
  };
860
877
  var reportUnused = (context, rule, name) => {
878
+ const isEmitted = context.emitted.has(name);
879
+ if (!isEmitted) return;
861
880
  const matchesIgnored = (pattern) => pattern.test(name);
862
881
  const isIgnored = context.ignored.some(matchesIgnored);
863
882
  if (isIgnored) return;
@@ -889,10 +908,12 @@ var noUnusedClasses = (primary, secondary) => {
889
908
  const patterns = secondary?.ignoreClassPatterns ?? DEFAULT_IGNORE_PATTERNS;
890
909
  const ignored = patterns.map(toRegExp);
891
910
  const extended = extendedClasses(root);
911
+ const emitted = emittedClasses(root);
892
912
  const context = {
893
913
  result,
894
914
  ignored,
895
915
  extended,
916
+ emitted,
896
917
  isUsed: usage.has
897
918
  };
898
919
  const visit = (rule, resolved, parents) => {
package/stylelint.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../packages/lint-suite/src/stylelint.ts", "../../../../packages/lint-suite/src/lib/rules/no-unused-classes/no-unused-classes.ts", "../../../../packages/lint-suite/src/lib/rules/no-unused-classes/styles/stylesheet-components.ts", "../../../../packages/lint-suite/src/lib/rules/no-unused-classes/styles/linked-templates.ts", "../../../../packages/lint-suite/src/lib/rules/file-cache.ts", "../../../../packages/lint-suite/src/lib/rules/utils/template-links.util.ts", "../../../../packages/lint-suite/src/lib/rules/component-metadata.ts", "../../../../packages/lint-suite/src/lib/rules/no-unused-classes/template/template-usage.ts", "../../../../packages/lint-suite/src/lib/rules/selector-classes.ts", "../../../../packages/lint-suite/src/lib/rules/utils/class-expression-literals.util.ts", "../../../../packages/lint-suite/src/lib/rules/utils/template-classes.util.ts", "../../../../packages/lint-suite/src/lib/rules/utils/to-regexp.util.ts", "../../../../packages/lint-suite/src/lib/rules/utils/resolved-rules.util.ts"],
4
- "sourcesContent": ["import type { Config } from 'stylelint';\nimport stylelintScss from 'stylelint-scss';\nimport bemPattern from 'stylelint-selector-bem-pattern';\n\nimport noUnusedClasses from './lib/rules/no-unused-classes/no-unused-classes.ts';\n\nexport const stylelint: Config = {\n // Stylelint resolves config for cwd when picking a formatter; without a\n // top-level `rules` an overrides-only config fails with \"No rules found\".\n rules: {},\n overrides: [\n {\n files: ['**/*.scss', '**/*.css'],\n extends: [\n 'stylelint-config-standard',\n 'stylelint-config-standard-scss',\n 'stylelint-config-recess-order'\n ],\n plugins: [...stylelintScss, bemPattern, noUnusedClasses],\n rules: {\n 'selector-class-pattern':\n '^(?:(?:o|c|u|t|s|is|has|_|js|qa)-)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*(?:__[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:--[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:\\\\[.+\\\\])?$',\n 'plugin/selector-bem-pattern': {\n preset: 'bem',\n implicitComponents: ['**/*.component.scss', '**/*.component.css'],\n ignoreCustomProperties: ['^--mdc', '^--sys']\n },\n 'no-descending-specificity': null,\n // A stylesheet class no linked template uses is reported.\n // Bad: .ghost {} used by no template\n // Good: delete it, or use it in a template\n 'lint-suite/no-unused-classes': true\n }\n }\n ]\n};\n", "import type { AtRule, Root, Rule } from 'postcss';\nimport stylelint from 'stylelint';\nimport type { Plugin, PostcssResult, Problem, RuleMeta } from 'stylelint';\n\nimport type { RuleOptions } from './common/no-unused-classes.type.ts';\nimport { stylesheetTemplates } from './styles/stylesheet-components.ts';\nimport { templateUsage } from './template/template-usage.ts';\nimport type { ClassMatcher } from '../common/class-usage.type.ts';\nimport { selectorTemplateClasses } from '../selector-classes.ts';\nimport { walkResolvedRules } from '../utils/resolved-rules.util.ts';\nimport { toRegExp } from '../utils/to-regexp.util.ts';\n\ntype StylesheetWalker = (root: Root, result: PostcssResult) => void;\n\ntype UnusedContext = {\n readonly result: PostcssResult;\n readonly ignored: RegExp[];\n readonly extended: Set<string>;\n readonly isUsed: ClassMatcher;\n};\n\nconst { createPlugin, utils } = stylelint;\n\nconst DEFAULT_IGNORE_PATTERNS = ['^(js|qa|mat|cdk|mdc)-'];\n\n// eslint-disable-next-line local/no-unused-exports -- read by no-unused-classes.spec.ts\nexport const ruleName = 'lint-suite/no-unused-classes';\n\nconst rejected = (name: string): string => {\n return `Unexpected class \".${name}\" not used by any template of this stylesheet`;\n};\n\n// eslint-disable-next-line local/no-unused-exports -- read by no-unused-classes.spec.ts\nexport const messages = utils.ruleMessages(ruleName, { rejected });\n\nconst meta: RuleMeta = {\n url: 'https://github.com/F0rty-Tw0/lint-suite#no-unused-classes'\n};\n\nconst isString = (value: unknown): boolean => typeof value === 'string';\n\nconst validate = (\n result: PostcssResult,\n primary: true,\n secondary: RuleOptions | undefined\n): boolean => {\n const primaryOptions = { actual: primary, possible: [true] };\n const possible = { ignoreClassPatterns: [isString] };\n const secondaryOptions = { actual: secondary, possible, optional: true };\n\n return utils.validateOptions(\n result,\n ruleName,\n primaryOptions,\n secondaryOptions\n );\n};\n\nconst addNames = (selector: string, names: Set<string>): void => {\n for (const name of selectorTemplateClasses(selector)) names.add(name);\n};\n\nconst extendedClasses = (root: Root): Set<string> => {\n const names = new Set<string>();\n const collect = (atRule: AtRule): void => addNames(atRule.params, names);\n\n root.walkAtRules('extend', collect);\n\n return names;\n};\n\nconst ruleClasses = (resolved: string[], parents: string[]): string[] => {\n const inherited = new Set<string>();\n\n for (const parent of parents) addNames(parent, inherited);\n\n const own = new Set<string>();\n\n for (const selector of resolved) {\n for (const name of selectorTemplateClasses(selector)) {\n const isInherited = inherited.has(name);\n\n if (isInherited) continue;\n\n own.add(name);\n }\n }\n\n return [...own];\n};\n\nconst reportUnused = (\n context: UnusedContext,\n rule: Rule,\n name: string\n): void => {\n const matchesIgnored = (pattern: RegExp): boolean => pattern.test(name);\n const isIgnored = context.ignored.some(matchesIgnored);\n\n if (isIgnored) return;\n\n const isUsed = context.isUsed(name);\n\n if (isUsed) return;\n\n const isExtended = context.extended.has(name);\n\n if (isExtended) return;\n\n const message = messages.rejected(name);\n const word = `.${name}`;\n const problem: Problem = {\n ruleName,\n result: context.result,\n node: rule,\n message,\n word\n };\n\n utils.report(problem);\n};\n\nconst noUnusedClasses = (\n primary: true,\n secondary: RuleOptions | undefined\n): StylesheetWalker => {\n const walk = (root: Root, result: PostcssResult): void => {\n const isValid = validate(result, primary, secondary);\n\n if (!isValid) return;\n\n const file = root.source?.input.file;\n\n if (file === undefined) return;\n\n const templates = stylesheetTemplates(file);\n\n if (templates.length === 0) return;\n\n const usage = templateUsage(templates);\n\n if (usage.isDynamic) return;\n\n const patterns = secondary?.ignoreClassPatterns ?? DEFAULT_IGNORE_PATTERNS;\n const ignored = patterns.map(toRegExp);\n const extended = extendedClasses(root);\n const context: UnusedContext = {\n result,\n ignored,\n extended,\n isUsed: usage.has\n };\n const visit = (rule: Rule, resolved: string[], parents: string[]): void => {\n for (const name of ruleClasses(resolved, parents)) {\n reportUnused(context, rule, name);\n }\n };\n\n walkResolvedRules(root, visit);\n };\n\n return walk;\n};\n\nnoUnusedClasses.ruleName = ruleName;\nnoUnusedClasses.messages = messages;\nnoUnusedClasses.meta = meta;\n\nconst plugin: Plugin = createPlugin(ruleName, noUnusedClasses);\n\nexport default plugin;\n", "import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { linkedTemplates } from './linked-templates.ts';\nimport type { ComponentDescriptor } from '../../common/class-usage.type.ts';\nimport { componentMetadata } from '../../component-metadata.ts';\nimport type { TemplateSource } from '../common/no-unused-classes.type.ts';\n\nconst MODULE_EXTENSION = /\\.ts$/iu;\nconst STYLE_EXTENSION = /\\.(?:scss|sass|css)$/iu;\n\nconst UNKNOWN_TEMPLATE: TemplateSource = { kind: 'unknown' };\n\nconst listings = new Map<string, DirectoryListing>();\n\ntype DirectoryListing = {\n readonly files: string[];\n readonly version: string;\n};\n\nconst directoryListing = (directory: string): string[] => {\n const stats = statSync(directory, { bigint: true });\n const version = `${stats.mtimeNs}`;\n const cached = listings.get(directory);\n\n if (cached?.version === version) return cached.files;\n\n const files = readdirSync(directory);\n const fresh: DirectoryListing = { files, version };\n\n listings.set(directory, fresh);\n\n return files;\n};\n\nconst declaredStylesheets = (\n descriptor: ComponentDescriptor,\n directory: string\n): string[] => {\n const resolveUrl = (url: string): string => resolve(directory, url);\n\n return descriptor.styleUrls.map(resolveUrl);\n};\n\nconst fileTemplate = (\n descriptor: ComponentDescriptor,\n directory: string\n): TemplateSource | null => {\n if (descriptor.templateUrl === null) return null;\n\n const path = resolve(directory, descriptor.templateUrl);\n const isPresent = existsSync(path);\n\n if (!isPresent) return null;\n\n const source: TemplateSource = { kind: 'file', path };\n\n return source;\n};\n\nconst inlineTemplate = (\n descriptor: ComponentDescriptor,\n componentPath: string\n): TemplateSource | null => {\n if (descriptor.template === null) return null;\n\n const source: TemplateSource = {\n kind: 'inline',\n source: descriptor.template,\n path: componentPath\n };\n\n return source;\n};\n\nconst componentTemplate = (\n descriptor: ComponentDescriptor,\n componentPath: string\n): TemplateSource => {\n const directory = dirname(componentPath);\n const file = fileTemplate(descriptor, directory);\n\n if (file !== null) return file;\n\n const inline = inlineTemplate(descriptor, componentPath);\n\n return inline ?? UNKNOWN_TEMPLATE;\n};\n\nconst matchedTemplates = (\n componentPath: string,\n stylesheetPath: string\n): TemplateSource[] => {\n const directory = dirname(componentPath);\n const sources: TemplateSource[] = [];\n\n for (const descriptor of componentMetadata(componentPath)) {\n const declared = declaredStylesheets(descriptor, directory);\n const isMatch = declared.includes(stylesheetPath);\n\n if (!isMatch) continue;\n\n sources.push(componentTemplate(descriptor, componentPath));\n }\n\n return sources;\n};\n\nconst directoryFiles = (directory: string, extension: RegExp): string[] => {\n try {\n return directoryListing(directory).filter((file) => extension.test(file));\n } catch {\n return [];\n }\n};\n\nconst fallbackTemplates = (stylesheetPath: string): TemplateSource[] => {\n const sibling = stylesheetPath.replace(STYLE_EXTENSION, '.html');\n const paths = new Set<string>();\n\n const hasSibling = existsSync(sibling);\n\n if (hasSibling) paths.add(sibling);\n\n for (const path of linkedTemplates(stylesheetPath)) paths.add(path);\n\n const toSource = (path: string): TemplateSource => {\n const source: TemplateSource = { kind: 'file', path };\n\n return source;\n };\n\n const pathList = [...paths];\n\n return pathList.map(toSource);\n};\n\nexport const stylesheetTemplates = (\n stylesheetPath: string\n): TemplateSource[] => {\n const resolved = resolve(stylesheetPath);\n const directory = dirname(resolved);\n const sources: TemplateSource[] = [];\n\n for (const file of directoryFiles(directory, MODULE_EXTENSION)) {\n const componentPath = join(directory, file);\n const matched = matchedTemplates(componentPath, resolved);\n\n sources.push(...matched);\n }\n\n if (sources.length > 0) return sources;\n\n return fallbackTemplates(resolved);\n};\n", "import { readdirSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { createFileCache, readCached } from '../../file-cache.ts';\nimport { linkedStylesheetHrefs } from '../../utils/template-links.util.ts';\n\ntype LinkIndex = {\n readonly builtAt: number;\n readonly buildDuration: number;\n readonly templates: ReadonlyMap<string, string[]>;\n};\n\nconst TEMPLATE_EXTENSION = /\\.html$/iu;\nconst SKIPPED_DIRECTORIES = new Set(['node_modules', 'dist', 'coverage']);\n\nconst links = createFileCache<string[]>('template-links');\n\nlet linkIndex: LinkIndex | null = null;\n\n/** Relative stylesheet hrefs a template links, cached by the template's mtime. */\n// eslint-disable-next-line local/no-unused-exports -- read by linked-templates.spec.ts\nexport const templateLinks = (templatePath: string): string[] => {\n return readCached(links, templatePath, linkedStylesheetHrefs) ?? [];\n};\n\nconst isWalkable = (name: string): boolean => {\n const isDotfile = name.startsWith('.');\n\n if (isDotfile) return false;\n\n return !SKIPPED_DIRECTORIES.has(name);\n};\n\nconst walkTemplates = (root: string): string[] => {\n const found: string[] = [];\n const pending = [root];\n\n while (pending.length > 0) {\n const directory = pending.pop();\n\n if (directory === undefined) break;\n\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n const path = join(directory, entry.name);\n const isDirectory = entry.isDirectory();\n\n if (isDirectory) {\n const canWalk = isWalkable(entry.name);\n\n if (canWalk) pending.push(path);\n\n continue;\n }\n\n const isTemplate = TEMPLATE_EXTENSION.test(entry.name);\n\n if (isTemplate) found.push(path);\n }\n }\n\n return found;\n};\n\nconst templatesUnder = (root: string): string[] => {\n try {\n return walkTemplates(root);\n } catch {\n return [];\n }\n};\n\nconst templatesByStylesheet = (root: string): Map<string, string[]> => {\n const byStylesheet = new Map<string, string[]>();\n\n for (const template of templatesUnder(root)) {\n const directory = dirname(template);\n\n for (const href of templateLinks(template)) {\n const stylesheet = resolve(directory, href);\n const linked = byStylesheet.get(stylesheet) ?? [];\n\n linked.push(template);\n byStylesheet.set(stylesheet, linked);\n }\n }\n\n return byStylesheet;\n};\n\nconst currentLinkIndex = (): LinkIndex => {\n const now = performance.now();\n const cached = linkIndex;\n const isFresh =\n cached !== null && now - cached.builtAt < cached.buildDuration * 100;\n\n if (isFresh) return cached;\n\n const templates = templatesByStylesheet(process.cwd());\n const fresh: LinkIndex = {\n builtAt: now,\n buildDuration: performance.now() - now,\n templates\n };\n\n linkIndex = fresh;\n\n return fresh;\n};\n\n/**\n * Every template under the working directory that links the stylesheet.\n * The walk is rebuilt at most every 100x its own duration, so a link added\n * elsewhere in the project shows up on a later lint.\n */\nexport const linkedTemplates = (stylesheetPath: string): string[] => {\n return currentLinkIndex().templates.get(stylesheetPath) ?? [];\n};\n", "import {\n mkdirSync,\n readFileSync,\n renameSync,\n statSync,\n writeFileSync\n} from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport type { CachedFile, FileCache } from './common/file-cache.type.ts';\n\ntype FileParser<T> = (text: string, path: string) => T;\n\nconst CACHE_FORMAT_VERSION = 1;\n\nconst caches = new Set<FileCache<unknown>>();\n\nlet isFlushRegistered = false;\n\nconst cacheDirectory = (): string | null => {\n const { LINT_SUITE_CACHE, LINT_SUITE_CACHE_DIR } = process.env;\n const isDisabled = LINT_SUITE_CACHE === '0';\n\n if (isDisabled) return null;\n\n if (LINT_SUITE_CACHE_DIR) return LINT_SUITE_CACHE_DIR;\n\n return join(process.cwd(), 'node_modules', '.cache', 'lint-suite');\n};\n\nconst cacheFile = (name: string): string | null => {\n const directory = cacheDirectory();\n\n if (directory === null) return null;\n\n return join(directory, `${name}.v${CACHE_FORMAT_VERSION}.json`);\n};\n\nconst isCachedFile = <T>(value: unknown): value is CachedFile<T> => {\n const isObject = typeof value === 'object' && value !== null;\n\n if (!isObject) return false;\n\n const hasVersion = 'version' in value && typeof value.version === 'string';\n\n return hasVersion && 'value' in value;\n};\n\nconst storedEntries = <T>(text: string): Map<string, CachedFile<T>> => {\n const entries = new Map<string, CachedFile<T>>();\n const parsed: unknown = JSON.parse(text);\n const isRecord = typeof parsed === 'object' && parsed !== null;\n\n if (!isRecord) return entries;\n\n for (const [path, entry] of Object.entries(parsed)) {\n if (isCachedFile<T>(entry)) entries.set(path, entry);\n }\n\n return entries;\n};\n\nconst load = <T>(cache: FileCache<T>): void => {\n cache.loaded = true;\n\n const file = cacheFile(cache.name);\n\n if (file === null) return;\n\n try {\n const stored = storedEntries<T>(readFileSync(file, 'utf8'));\n\n for (const [path, entry] of stored) cache.entries.set(path, entry);\n } catch {\n return;\n }\n};\n\nconst write = (cache: FileCache<unknown>): void => {\n const file = cacheFile(cache.name);\n\n if (file === null) return;\n\n try {\n mkdirSync(dirname(file), { recursive: true });\n\n const temporary = `${file}.${process.pid}.tmp`;\n const stored = Object.fromEntries(cache.entries);\n\n writeFileSync(temporary, JSON.stringify(stored));\n renameSync(temporary, file);\n } catch {\n return;\n }\n};\n\n/** Writes every cache that parsed something this run; runs at process exit. */\n// eslint-disable-next-line local/no-unused-exports -- read by file-cache.spec.ts\nexport const flushFileCaches = (): void => {\n for (const cache of caches) {\n if (!cache.dirty) continue;\n\n write(cache);\n cache.dirty = false;\n }\n};\n\nconst registerFlush = (): void => {\n if (isFlushRegistered) return;\n\n isFlushRegistered = true;\n process.once('exit', flushFileCaches);\n};\n\n/**\n * A cache of parsed files keyed by path and mtime, mirrored to\n * `node_modules/.cache/lint-suite/<name>.v<format>.json` (or\n * `LINT_SUITE_CACHE_DIR`; `LINT_SUITE_CACHE=0` disables the disk copy).\n * Values must survive JSON.\n */\nexport const createFileCache = <T>(name: string): FileCache<T> => {\n const cache: FileCache<T> = {\n name,\n entries: new Map(),\n loaded: false,\n dirty: false\n };\n\n caches.add(cache);\n registerFlush();\n\n return cache;\n};\n\nexport const readCached = <T>(\n cache: FileCache<T>,\n path: string,\n parse: FileParser<T>\n): T | null => {\n if (!cache.loaded) load(cache);\n\n try {\n const stats = statSync(path, { bigint: true });\n const version = `${stats.mtimeNs}:${stats.size}`;\n const cached = cache.entries.get(path);\n\n if (cached?.version === version) return cached.value;\n\n const value = parse(readFileSync(path, 'utf8'), path);\n const fresh: CachedFile<T> = { value, version };\n\n cache.entries.set(path, fresh);\n cache.dirty = true;\n\n return value;\n } catch {\n return null;\n }\n};\n", "const LINK_TAG = /<link\\b[^>]*>/giu;\nconst STYLESHEET_REL = /\\brel\\s*=\\s*[\"']stylesheet[\"']/iu;\nconst HREF = /\\bhref\\s*=\\s*[\"']([^\"']*)[\"']/iu;\nconst UNRESOLVABLE = /^(?:\\/|[^:/?#]+:)/u;\n\nconst hrefOf = (tag: string): string | null => {\n const isStylesheet = STYLESHEET_REL.test(tag);\n\n if (!isStylesheet) return null;\n\n const href = HREF.exec(tag)?.[1] ?? '';\n const isUnresolvable = UNRESOLVABLE.test(href);\n const isLocal = href.length > 0 && !isUnresolvable;\n\n return isLocal ? href : null;\n};\n\nexport const linkedStylesheetHrefs = (template: string): string[] => {\n const tags = template.match(LINK_TAG) ?? [];\n\n return tags.map(hrefOf).filter((href) => href !== null);\n};\n", "import {\n ScriptTarget,\n canHaveDecorators,\n createSourceFile,\n forEachChild,\n getDecorators,\n isArrayLiteralExpression,\n isCallExpression,\n isIdentifier,\n isObjectLiteralExpression,\n isPropertyAssignment,\n isStringLiteralLike\n} from 'typescript';\nimport type {\n Decorator,\n Expression,\n Node,\n ObjectLiteralExpression\n} from 'typescript';\n\nimport type { ComponentDescriptor } from './common/class-usage.type.ts';\nimport { createFileCache, readCached } from './file-cache.ts';\n\nconst COMPONENT_MARKER = '@Component';\n\nconst cache = createFileCache<ComponentDescriptor[]>('component-metadata');\n\nconst componentArgument = (\n decorator: Decorator\n): ObjectLiteralExpression | null => {\n const { expression } = decorator;\n\n if (!isCallExpression(expression)) return null;\n\n if (!isIdentifier(expression.expression)) return null;\n\n const isComponent = expression.expression.text === 'Component';\n\n if (!isComponent) return null;\n\n const [argument] = expression.arguments;\n\n if (argument === undefined) return null;\n\n if (!isObjectLiteralExpression(argument)) return null;\n\n return argument;\n};\n\nconst decoratedMetadata = (node: Node): ObjectLiteralExpression | null => {\n if (!canHaveDecorators(node)) return null;\n\n const decorators = getDecorators(node) ?? [];\n\n for (const decorator of decorators) {\n const metadata = componentArgument(decorator);\n\n if (metadata !== null) return metadata;\n }\n\n return null;\n};\n\nconst literalText = (node: Expression): string | null => {\n if (!isStringLiteralLike(node)) return null;\n\n return node.text;\n};\n\nconst literalTexts = (node: Expression): string[] => {\n const single = literalText(node);\n\n if (single !== null) return [single];\n\n if (!isArrayLiteralExpression(node)) return [];\n\n const texts: string[] = [];\n\n for (const element of node.elements) {\n const text = literalText(element);\n\n if (text !== null) texts.push(text);\n }\n\n return texts;\n};\n\nconst metadataValue = (\n metadata: ObjectLiteralExpression,\n name: string\n): Expression | null => {\n for (const property of metadata.properties) {\n if (!isPropertyAssignment(property)) continue;\n\n if (!isIdentifier(property.name)) continue;\n\n const isMatch = property.name.text === name;\n\n if (isMatch) return property.initializer;\n }\n\n return null;\n};\n\nconst metadataTexts = (\n metadata: ObjectLiteralExpression,\n name: string\n): string[] => {\n const value = metadataValue(metadata, name);\n\n if (value === null) return [];\n\n return literalTexts(value);\n};\n\nconst toDescriptor = (\n metadata: ObjectLiteralExpression\n): ComponentDescriptor => {\n const [templateUrl] = metadataTexts(metadata, 'templateUrl');\n const [template] = metadataTexts(metadata, 'template');\n const styleUrl = metadataTexts(metadata, 'styleUrl');\n const listedStyleUrls = metadataTexts(metadata, 'styleUrls');\n const styleUrls = [...styleUrl, ...listedStyleUrls];\n const styles = metadataTexts(metadata, 'styles');\n const descriptor: ComponentDescriptor = {\n templateUrl: templateUrl ?? null,\n template: template ?? null,\n styleUrls,\n styles\n };\n\n return descriptor;\n};\n\nconst parseComponentMetadata = (\n text: string,\n path: string\n): ComponentDescriptor[] => {\n const found: ComponentDescriptor[] = [];\n const hasComponent = text.includes(COMPONENT_MARKER);\n\n if (!hasComponent) return found;\n\n const visit = (node: Node): void => {\n const metadata = decoratedMetadata(node);\n\n if (metadata !== null) found.push(toDescriptor(metadata));\n\n forEachChild(node, visit);\n };\n\n const source = createSourceFile(path, text, ScriptTarget.Latest, true);\n\n forEachChild(source, visit);\n\n return found;\n};\n\nexport const componentMetadata = (path: string): ComponentDescriptor[] => {\n return readCached(cache, path, parseComponentMetadata) ?? [];\n};\n", "import {\n ASTWithSource,\n TmplAstRecursiveVisitor,\n parseTemplate,\n tmplAstVisitAll\n} from '@angular/compiler';\nimport type {\n AST,\n TmplAstBoundAttribute,\n TmplAstComponent,\n TmplAstElement,\n TmplAstTemplate\n} from '@angular/compiler';\n\nimport type {\n ClassAttributeHost,\n ClassMatcher\n} from '../../common/class-usage.type.ts';\nimport { createFileCache, readCached } from '../../file-cache.ts';\nimport { classMatcher } from '../../selector-classes.ts';\nimport { classExpressionUsage } from '../../utils/class-expression-literals.util.ts';\nimport { templateClasses } from '../../utils/template-classes.util.ts';\nimport { toRegExp } from '../../utils/to-regexp.util.ts';\nimport type {\n TemplateSource,\n TemplateUsage\n} from '../common/no-unused-classes.type.ts';\n\ntype UsageEntry = {\n readonly names: string[];\n readonly patterns: string[];\n readonly isDynamic: boolean;\n};\n\nconst CLASS_ATTRIBUTE = 'class';\nconst NG_CLASS_ATTRIBUTE = 'ngClass';\n\nconst matchesNone: ClassMatcher = () => false;\n\nconst UNKNOWN_USAGE: TemplateUsage = {\n has: matchesNone,\n isDynamic: true,\n size: 0\n};\n\nconst templates = createFileCache<UsageEntry | null>('template-usage');\n\nconst expressionSource = (value: AST): string | null => {\n const isWithSource = value instanceof ASTWithSource;\n\n if (!isWithSource) return null;\n\n return value.source;\n};\n\nconst isClassInput = (input: TmplAstBoundAttribute): boolean => {\n const isNgClass = input.name === NG_CLASS_ATTRIBUTE;\n\n if (isNgClass) return true;\n\n const isClass = input.name === CLASS_ATTRIBUTE;\n\n if (!isClass) return false;\n\n const { details } = input.keySpan;\n\n if (details === null) return true;\n\n return details === CLASS_ATTRIBUTE;\n};\n\nclass ClassUsageVisitor extends TmplAstRecursiveVisitor {\n public readonly names = new Set<string>();\n\n public readonly patterns = new Set<string>();\n\n public isDynamic = false;\n\n public override visitElement(element: TmplAstElement): void {\n this.collect(element);\n super.visitElement(element);\n }\n\n public override visitTemplate(template: TmplAstTemplate): void {\n this.collect(template);\n super.visitTemplate(template);\n }\n\n public override visitComponent(component: TmplAstComponent): void {\n this.collect(component);\n super.visitComponent(component);\n }\n\n private collect(node: ClassAttributeHost): void {\n for (const { name } of templateClasses(node)) this.names.add(name);\n\n for (const input of node.inputs) this.collectInput(input);\n }\n\n private collectInput(input: TmplAstBoundAttribute): void {\n const isClass = isClassInput(input);\n\n if (!isClass) return;\n\n const source = expressionSource(input.value);\n\n if (source === null) {\n this.isDynamic = true;\n\n return;\n }\n\n const usage = classExpressionUsage(source);\n\n for (const name of usage.names) this.names.add(name);\n\n for (const pattern of usage.patterns) this.patterns.add(pattern);\n\n if (usage.isDynamic) this.isDynamic = true;\n }\n}\n\nconst parseUsage = (text: string, path: string): UsageEntry | null => {\n const parsed = parseTemplate(text, path);\n\n if (parsed.errors !== null) return null;\n\n const visitor = new ClassUsageVisitor();\n\n tmplAstVisitAll(visitor, parsed.nodes);\n\n const names = [...visitor.names];\n const patterns = [...visitor.patterns];\n const entry: UsageEntry = { names, patterns, isDynamic: visitor.isDynamic };\n\n return entry;\n};\n\nconst sourceUsage = (source: TemplateSource): UsageEntry | null => {\n if (source.kind === 'unknown') return null;\n\n if (source.kind === 'inline') return parseUsage(source.source, source.path);\n\n return readCached(templates, source.path, parseUsage) ?? null;\n};\n\nexport const templateUsage = (sources: TemplateSource[]): TemplateUsage => {\n const names = new Set<string>();\n const patterns = new Set<string>();\n\n for (const source of sources) {\n const entry = sourceUsage(source);\n\n if (entry === null) return UNKNOWN_USAGE;\n\n if (entry.isDynamic) return UNKNOWN_USAGE;\n\n for (const name of entry.names) names.add(name);\n\n for (const pattern of entry.patterns) patterns.add(pattern);\n }\n\n const patternList = [...patterns];\n const compiled = patternList.map(toRegExp);\n const has = classMatcher(names, compiled);\n const size = names.size;\n const usage: TemplateUsage = { has, isDynamic: false, size };\n\n return usage;\n};\n", "import selectorParser from 'postcss-selector-parser';\nimport type { Node } from 'postcss-selector-parser';\n\nimport type { ClassMatcher, SelectorClasses } from './common/class-usage.type.ts';\n\ntype SelectorClassNode = { readonly value: string };\n\nconst INTERPOLATION_TOKEN = 'zzinterpzz';\nconst PARENT_TOKEN = 'zzparentzz';\nconst UNKNOWN_PARENT_SELECTOR = `.${PARENT_TOKEN}`;\nconst UNKNOWN_PARTS = new RegExp(\n `${INTERPOLATION_TOKEN}|${PARENT_TOKEN}`,\n 'gu'\n);\nconst INTERPOLATION = /#\\{[^}]*\\}/gu;\nconst DEEP_COMBINATORS = new Set(['/deep/', '>>>']);\nconst HOST_PSEUDOS = new Set([':host', ':host-context']);\nconst NG_DEEP_PSEUDO = '::ng-deep';\nconst REGEXP_META = /[.*+?^${}()|[\\]\\\\]/gu;\n\nconst escapeRegExp = (part: string): string => {\n return part.replaceAll(REGEXP_META, '\\\\$&');\n};\n\nexport const classNamePattern = (value: string): string => {\n const literals = value.split(UNKNOWN_PARTS).map(escapeRegExp);\n const joined = literals.join('.*');\n\n return `^${joined}$`;\n};\n\nconst withoutParent = (selector: string): string => {\n return selector.replaceAll('&', UNKNOWN_PARENT_SELECTOR);\n};\n\nconst withParent = (selector: string, parent: string): string => {\n const hasNesting = selector.includes('&');\n\n if (hasNesting) return selector.replaceAll('&', parent);\n\n return `${parent} ${selector}`;\n};\n\nexport const resolveSelectors = (\n selectors: string[],\n parents: string[]\n): string[] => {\n const hasParents = parents.length > 0;\n\n if (!hasParents) return selectors.map(withoutParent);\n\n const resolved: string[] = [];\n\n for (const parent of parents) {\n for (const selector of selectors) {\n resolved.push(withParent(selector, parent));\n }\n }\n\n return resolved;\n};\n\nexport const selectorClasses = (selector: string): SelectorClasses => {\n const exact: string[] = [];\n const patterns: string[] = [];\n const normalized = selector.replaceAll(INTERPOLATION, INTERPOLATION_TOKEN);\n\n const collect = (node: SelectorClassNode): void => {\n const isBareParent = node.value === PARENT_TOKEN;\n\n if (isBareParent) return;\n\n const hasInterpolation = node.value.includes(INTERPOLATION_TOKEN);\n const hasUnknownParent = node.value.includes(PARENT_TOKEN);\n const isDynamic = hasInterpolation || hasUnknownParent;\n\n if (isDynamic) {\n patterns.push(classNamePattern(node.value));\n\n return;\n }\n\n exact.push(node.value);\n };\n\n try {\n const root = selectorParser().astSync(normalized);\n\n root.walkClasses(collect);\n } catch {\n const empty: SelectorClasses = { exact: [], patterns: [] };\n\n return empty;\n }\n\n const classes: SelectorClasses = { exact, patterns };\n\n return classes;\n};\n\nconst isBoundaryNode = (node: Node): boolean => {\n if (node.type === 'combinator') return DEEP_COMBINATORS.has(node.value);\n\n if (node.type !== 'pseudo') return false;\n\n return node.value === NG_DEEP_PSEUDO;\n};\n\nconst addTemplateClass = (value: string, names: string[]): void => {\n const hasInterpolation = value.includes(INTERPOLATION_TOKEN);\n const hasUnknownParent = value.includes(PARENT_TOKEN);\n const isDynamic = hasInterpolation || hasUnknownParent;\n\n if (isDynamic) return;\n\n names.push(value);\n};\n\nconst collectTemplateClasses = (nodes: Node[], names: string[]): boolean => {\n for (const node of nodes) {\n const isBoundary = isBoundaryNode(node);\n\n if (isBoundary) return true;\n\n if (node.type === 'class') {\n addTemplateClass(node.value, names);\n continue;\n }\n\n if (node.type !== 'pseudo') continue;\n\n const isHost = HOST_PSEUDOS.has(node.value);\n\n if (isHost) continue;\n\n for (const argument of node.nodes) {\n const isStopped = collectTemplateClasses(argument.nodes, names);\n\n if (isStopped) return true;\n }\n }\n\n return false;\n};\n\nexport const selectorTemplateClasses = (selector: string): string[] => {\n const names: string[] = [];\n const normalized = selector.replaceAll(INTERPOLATION, INTERPOLATION_TOKEN);\n\n try {\n const root = selectorParser().astSync(normalized);\n\n for (const each of root.nodes) collectTemplateClasses(each.nodes, names);\n } catch {\n return [];\n }\n\n const uniqueNames = new Set(names);\n\n return [...uniqueNames];\n};\n\nexport const classMatcher = (\n exact: Set<string>,\n patterns: RegExp[]\n): ClassMatcher => {\n const matches = (name: string): boolean => {\n const isExact = exact.has(name);\n\n if (isExact) return true;\n\n return patterns.some((pattern) => pattern.test(name));\n };\n\n return matches;\n};\n", "import {\n Conditional,\n Interpolation,\n Lexer,\n LiteralArray,\n LiteralMap,\n LiteralPrimitive,\n ParseLocation,\n ParseSourceFile,\n ParseSourceSpan,\n Parser\n} from '@angular/compiler';\nimport type { AST, ASTWithSource, LiteralMapKey } from '@angular/compiler';\n\nimport type { ClassExpressionUsage } from '../common/class-usage.type.ts';\nimport { classNamePattern } from '../selector-classes.ts';\n\nconst WHITESPACE = /\\s+/u;\nconst EXPRESSION_FILE = 'class-expression';\nconst INTERPOLATION_TOKEN = 'zzinterpzz';\n\nconst parser = new Parser(new Lexer());\n\nconst spanOf = (source: string): ParseSourceSpan => {\n const file = new ParseSourceFile(source, EXPRESSION_FILE);\n const start = new ParseLocation(file, 0, 0, 0);\n const span = new ParseSourceSpan(start, start.moveBy(source.length));\n\n return span;\n};\n\nconst astOf = (parsed: ASTWithSource): AST | null => {\n const hasErrors = parsed.errors.length > 0;\n\n if (hasErrors) return null;\n\n return parsed.ast;\n};\n\nconst parseClassExpression = (source: string): AST | null => {\n try {\n const span = spanOf(source);\n const interpolation = parser.parseInterpolation(source, span, 0, null);\n\n if (interpolation) return astOf(interpolation);\n\n const binding = parser.parseBinding(source, span, 0);\n\n return astOf(binding);\n } catch {\n return null;\n }\n};\n\nconst addNames = (value: string, names: string[]): void => {\n for (const token of value.split(WHITESPACE)) {\n if (token) names.push(token);\n }\n};\n\nconst addPrimitive = (ast: LiteralPrimitive, names: string[]): void => {\n if (typeof ast.value === 'string') addNames(ast.value, names);\n};\n\nconst addMapKeys = (ast: LiteralMap, names: string[]): void => {\n for (const key of ast.keys) {\n if (key.kind !== 'spread') addNames(key.key, names);\n }\n};\n\nconst addInterpolation = (ast: Interpolation, names: string[]): void => {\n for (const text of ast.strings) addNames(text, names);\n};\n\nconst collect = (ast: AST, names: string[]): void => {\n if (ast instanceof LiteralPrimitive) {\n addPrimitive(ast, names);\n\n return;\n }\n\n if (ast instanceof LiteralMap) {\n addMapKeys(ast, names);\n\n return;\n }\n\n if (ast instanceof Interpolation) {\n addInterpolation(ast, names);\n\n return;\n }\n\n if (ast instanceof LiteralArray) {\n for (const expression of ast.expressions) collect(expression, names);\n\n return;\n }\n\n if (ast instanceof Conditional) {\n collect(ast.trueExp, names);\n collect(ast.falseExp, names);\n }\n};\n\nexport const classExpressionLiterals = (source: string): string[] => {\n const ast = parseClassExpression(source);\n\n if (ast === null) return [];\n\n const names: string[] = [];\n\n collect(ast, names);\n\n const uniqueNames = new Set(names);\n\n return [...uniqueNames];\n};\n\nconst isSpreadKey = (key: LiteralMapKey): boolean => key.kind === 'spread';\n\nconst isDynamicAst = (ast: AST): boolean => {\n if (ast instanceof LiteralPrimitive) return false;\n\n if (ast instanceof LiteralMap) return ast.keys.some(isSpreadKey);\n\n if (ast instanceof LiteralArray) return ast.expressions.some(isDynamicAst);\n\n if (ast instanceof Conditional) {\n const isTrueDynamic = isDynamicAst(ast.trueExp);\n const isFalseDynamic = isDynamicAst(ast.falseExp);\n\n return isTrueDynamic || isFalseDynamic;\n }\n\n return true;\n};\n\nconst isNamedToken = (token: string): boolean => token !== INTERPOLATION_TOKEN;\n\nconst isPatternToken = (token: string): boolean => {\n return token.includes(INTERPOLATION_TOKEN);\n};\n\nconst isPlainToken = (token: string): boolean => !isPatternToken(token);\n\nconst interpolationUsage = (ast: Interpolation): ClassExpressionUsage => {\n const joined = ast.strings.join(INTERPOLATION_TOKEN);\n const tokens = joined.split(WHITESPACE).filter(Boolean);\n const named = tokens.filter(isNamedToken);\n const patterns = named.filter(isPatternToken).map(classNamePattern);\n const names = named.filter(isPlainToken);\n const uniqueNames = new Set(names);\n const uniquePatterns = new Set(patterns);\n const usage: ClassExpressionUsage = {\n names: [...uniqueNames],\n patterns: [...uniquePatterns],\n isDynamic: named.length < tokens.length\n };\n\n return usage;\n};\n\nconst UNKNOWN_USAGE: ClassExpressionUsage = {\n names: [],\n patterns: [],\n isDynamic: true\n};\n\nexport const classExpressionUsage = (source: string): ClassExpressionUsage => {\n const ast = parseClassExpression(source);\n\n if (ast === null) return UNKNOWN_USAGE;\n\n if (ast instanceof Interpolation) return interpolationUsage(ast);\n\n const names: string[] = [];\n\n collect(ast, names);\n\n const isDynamic = isDynamicAst(ast);\n const uniqueNames = new Set(names);\n const usage: ClassExpressionUsage = {\n names: [...uniqueNames],\n patterns: [],\n isDynamic\n };\n\n return usage;\n};\n", "import { ParseSourceSpan } from '@angular/compiler';\nimport type {\n TmplAstBoundAttribute,\n TmplAstTextAttribute\n} from '@angular/compiler';\n\nimport { classExpressionLiterals } from './class-expression-literals.util.ts';\nimport type {\n ClassAttributeHost,\n TemplateClass\n} from '../common/class-usage.type.ts';\n\nconst CLASS_ATTRIBUTE = 'class';\nconst CLASS_BINDING_PREFIX = 'class.';\nconst TOKEN = /\\S+/gu;\n\nconst expressionSource = (value: object): string | null => {\n if (!('source' in value)) return null;\n\n const { source } = value;\n\n if (typeof source !== 'string') return null;\n\n return source;\n};\n\nconst staticClasses = (attribute: TmplAstTextAttribute): TemplateClass[] => {\n const classes: TemplateClass[] = [];\n const valueSpan = attribute.valueSpan ?? attribute.sourceSpan;\n\n for (const token of attribute.value.matchAll(TOKEN)) {\n const start = valueSpan.start.moveBy(token.index);\n const end = valueSpan.start.moveBy(token.index + token[0].length);\n const span = new ParseSourceSpan(start, end);\n const templateClass: TemplateClass = { name: token[0], span };\n\n classes.push(templateClass);\n }\n\n return classes;\n};\n\nconst boundClassName = (input: TmplAstBoundAttribute): string | null => {\n const { details } = input.keySpan;\n\n if (details === null) return null;\n\n const isClassBinding = details.startsWith(CLASS_BINDING_PREFIX);\n\n if (!isClassBinding) return null;\n\n return input.name;\n};\n\nconst isClassExpression = (input: TmplAstBoundAttribute): boolean => {\n const isClassName = input.name === CLASS_ATTRIBUTE;\n\n if (!isClassName) return false;\n\n const { details } = input.keySpan;\n\n if (details === null) return true;\n\n return details === CLASS_ATTRIBUTE;\n};\n\nconst expressionClasses = (input: TmplAstBoundAttribute): TemplateClass[] => {\n const source = expressionSource(input.value);\n\n if (source === null) return [];\n\n const names = classExpressionLiterals(source);\n const templateClassOf = (name: string): TemplateClass => {\n const templateClass: TemplateClass = { name, span: input.sourceSpan };\n\n return templateClass;\n };\n\n return names.map(templateClassOf);\n};\n\nconst inputClasses = (input: TmplAstBoundAttribute): TemplateClass[] => {\n const bound = boundClassName(input);\n\n if (bound !== null) {\n const templateClass: TemplateClass = { name: bound, span: input.keySpan };\n\n return [templateClass];\n }\n\n const isExpression = isClassExpression(input);\n\n if (!isExpression) return [];\n\n return expressionClasses(input);\n};\n\nexport const templateClasses = (node: ClassAttributeHost): TemplateClass[] => {\n const classes: TemplateClass[] = [];\n\n for (const attribute of node.attributes) {\n const isClassName = attribute.name === CLASS_ATTRIBUTE;\n\n if (isClassName) {\n const found = staticClasses(attribute);\n\n classes.push(...found);\n }\n }\n\n for (const input of node.inputs) {\n const found = inputClasses(input);\n\n classes.push(...found);\n }\n\n return classes;\n};\n", "export const toRegExp = (pattern: string): RegExp => new RegExp(pattern, 'u');\n", "import type { ChildNode, Container, Root, Rule } from 'postcss';\n\nimport { resolveSelectors } from '../selector-classes.ts';\n\ntype ResolvedRuleVisitor = (\n rule: Rule,\n resolved: string[],\n parents: string[]\n) => void;\n\nconst walkContainer = (\n container: Container<ChildNode>,\n parents: string[],\n visit: ResolvedRuleVisitor\n): void => {\n for (const node of container.nodes ?? []) {\n if (node.type === 'rule') {\n const resolved = resolveSelectors(node.selectors, parents);\n\n visit(node, resolved, parents);\n walkContainer(node, resolved, visit);\n continue;\n }\n\n if (node.type !== 'atrule') continue;\n\n walkContainer(node, parents, visit);\n }\n};\n\nexport const walkResolvedRules = (\n root: Root,\n visit: ResolvedRuleVisitor\n): void => {\n walkContainer(root, [], visit);\n};\n"],
5
- "mappings": "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",
6
- "names": ["stylelint", "import_node_fs", "import_node_path", "import_node_fs", "import_node_path", "cache", "templates", "import_compiler", "selectorParser", "INTERPOLATION_TOKEN", "import_compiler", "CLASS_ATTRIBUTE", "UNKNOWN_USAGE", "expressionSource", "stylelint", "addNames", "collect", "templates", "stylelint", "stylelintScss", "bemPattern"]
4
+ "sourcesContent": ["import type { Config } from 'stylelint';\nimport stylelintScss from 'stylelint-scss';\nimport bemPattern from 'stylelint-selector-bem-pattern';\n\nimport noUnusedClasses from './lib/rules/no-unused-classes/no-unused-classes.ts';\n\nexport const stylelint: Config = {\n // Stylelint resolves config for cwd when picking a formatter; without a\n // top-level `rules` an overrides-only config fails with \"No rules found\".\n rules: {},\n overrides: [\n {\n files: ['**/*.scss', '**/*.css'],\n extends: [\n 'stylelint-config-standard',\n 'stylelint-config-standard-scss',\n 'stylelint-config-recess-order'\n ],\n plugins: [...stylelintScss, bemPattern, noUnusedClasses],\n rules: {\n 'selector-class-pattern':\n '^(?:(?:o|c|u|t|s|is|has|_|js|qa)-)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*(?:__[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:--[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:\\\\[.+\\\\])?$',\n 'plugin/selector-bem-pattern': {\n preset: 'bem',\n implicitComponents: ['**/*.component.scss', '**/*.component.css'],\n ignoreCustomProperties: ['^--mdc', '^--sys']\n },\n 'no-descending-specificity': null,\n // A stylesheet class no linked template uses is reported.\n // Bad: .ghost {} used by no template\n // Good: delete it, or use it in a template\n 'lint-suite/no-unused-classes': true\n }\n }\n ]\n};\n", "import type { AtRule, ChildNode, Root, Rule } from 'postcss';\nimport stylelint from 'stylelint';\nimport type { Plugin, PostcssResult, Problem, RuleMeta } from 'stylelint';\n\nimport type { RuleOptions } from './common/no-unused-classes.type.ts';\nimport { stylesheetTemplates } from './styles/stylesheet-components.ts';\nimport { templateUsage } from './template/template-usage.ts';\nimport type { ClassMatcher } from '../common/class-usage.type.ts';\nimport { selectorTemplateClasses } from '../selector-classes.ts';\nimport { walkResolvedRules } from '../utils/resolved-rules.util.ts';\nimport { toRegExp } from '../utils/to-regexp.util.ts';\n\ntype StylesheetWalker = (root: Root, result: PostcssResult) => void;\n\ntype UnusedContext = {\n readonly result: PostcssResult;\n readonly ignored: RegExp[];\n readonly extended: Set<string>;\n readonly emitted: Set<string>;\n readonly isUsed: ClassMatcher;\n};\n\nconst { createPlugin, utils } = stylelint;\n\nconst DEFAULT_IGNORE_PATTERNS = ['^(js|qa|mat|cdk|mdc)-'];\n\n// eslint-disable-next-line local/no-unused-exports -- read by no-unused-classes.spec.ts\nexport const ruleName = 'lint-suite/no-unused-classes';\n\nconst rejected = (name: string): string => {\n return `Unexpected class \".${name}\" not used by any template of this stylesheet`;\n};\n\n// eslint-disable-next-line local/no-unused-exports -- read by no-unused-classes.spec.ts\nexport const messages = utils.ruleMessages(ruleName, { rejected });\n\nconst meta: RuleMeta = {\n url: 'https://github.com/F0rty-Tw0/lint-suite#no-unused-classes'\n};\n\nconst isString = (value: unknown): boolean => typeof value === 'string';\n\nconst validate = (\n result: PostcssResult,\n primary: true,\n secondary: RuleOptions | undefined\n): boolean => {\n const primaryOptions = { actual: primary, possible: [true] };\n const possible = { ignoreClassPatterns: [isString] };\n const secondaryOptions = { actual: secondary, possible, optional: true };\n\n return utils.validateOptions(\n result,\n ruleName,\n primaryOptions,\n secondaryOptions\n );\n};\n\nconst addNames = (selector: string, names: Set<string>): void => {\n for (const name of selectorTemplateClasses(selector)) names.add(name);\n};\n\nconst extendedClasses = (root: Root): Set<string> => {\n const names = new Set<string>();\n const collect = (atRule: AtRule): void => addNames(atRule.params, names);\n\n root.walkAtRules('extend', collect);\n\n return names;\n};\n\nconst isEmittingRule = (rule: Rule): boolean => {\n const isEmittingNode = (node: ChildNode): boolean => {\n return node.type === 'decl' || node.type === 'atrule';\n };\n const children = rule.nodes;\n\n return children.some(isEmittingNode);\n};\n\nconst emittedClasses = (root: Root): Set<string> => {\n const names = new Set<string>();\n const visit = (rule: Rule, resolved: string[]): void => {\n const isEmitting = isEmittingRule(rule);\n\n if (!isEmitting) return;\n\n for (const selector of resolved) addNames(selector, names);\n };\n\n walkResolvedRules(root, visit);\n\n return names;\n};\n\nconst ruleClasses = (resolved: string[], parents: string[]): string[] => {\n const inherited = new Set<string>();\n\n for (const parent of parents) addNames(parent, inherited);\n\n const own = new Set<string>();\n\n for (const selector of resolved) {\n for (const name of selectorTemplateClasses(selector)) {\n const isInherited = inherited.has(name);\n\n if (isInherited) continue;\n\n own.add(name);\n }\n }\n\n return [...own];\n};\n\nconst reportUnused = (\n context: UnusedContext,\n rule: Rule,\n name: string\n): void => {\n const isEmitted = context.emitted.has(name);\n\n if (!isEmitted) return;\n\n const matchesIgnored = (pattern: RegExp): boolean => pattern.test(name);\n const isIgnored = context.ignored.some(matchesIgnored);\n\n if (isIgnored) return;\n\n const isUsed = context.isUsed(name);\n\n if (isUsed) return;\n\n const isExtended = context.extended.has(name);\n\n if (isExtended) return;\n\n const message = messages.rejected(name);\n const word = `.${name}`;\n const problem: Problem = {\n ruleName,\n result: context.result,\n node: rule,\n message,\n word\n };\n\n utils.report(problem);\n};\n\nconst noUnusedClasses = (\n primary: true,\n secondary: RuleOptions | undefined\n): StylesheetWalker => {\n const walk = (root: Root, result: PostcssResult): void => {\n const isValid = validate(result, primary, secondary);\n\n if (!isValid) return;\n\n const file = root.source?.input.file;\n\n if (file === undefined) return;\n\n const templates = stylesheetTemplates(file);\n\n if (templates.length === 0) return;\n\n const usage = templateUsage(templates);\n\n if (usage.isDynamic) return;\n\n const patterns = secondary?.ignoreClassPatterns ?? DEFAULT_IGNORE_PATTERNS;\n const ignored = patterns.map(toRegExp);\n const extended = extendedClasses(root);\n const emitted = emittedClasses(root);\n const context: UnusedContext = {\n result,\n ignored,\n extended,\n emitted,\n isUsed: usage.has\n };\n const visit = (rule: Rule, resolved: string[], parents: string[]): void => {\n for (const name of ruleClasses(resolved, parents)) {\n reportUnused(context, rule, name);\n }\n };\n\n walkResolvedRules(root, visit);\n };\n\n return walk;\n};\n\nnoUnusedClasses.ruleName = ruleName;\nnoUnusedClasses.messages = messages;\nnoUnusedClasses.meta = meta;\n\nconst plugin: Plugin = createPlugin(ruleName, noUnusedClasses);\n\nexport default plugin;\n", "import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { linkedTemplates } from './linked-templates.ts';\nimport type { ComponentDescriptor } from '../../common/class-usage.type.ts';\nimport { componentMetadata } from '../../component-metadata.ts';\nimport type { TemplateSource } from '../common/no-unused-classes.type.ts';\n\nconst MODULE_EXTENSION = /\\.ts$/iu;\nconst STYLE_EXTENSION = /\\.(?:scss|sass|css)$/iu;\n\nconst UNKNOWN_TEMPLATE: TemplateSource = { kind: 'unknown' };\n\nconst listings = new Map<string, DirectoryListing>();\n\ntype DirectoryListing = {\n readonly files: string[];\n readonly version: string;\n};\n\nconst directoryListing = (directory: string): string[] => {\n const stats = statSync(directory, { bigint: true });\n const version = `${stats.mtimeNs}`;\n const cached = listings.get(directory);\n\n if (cached?.version === version) return cached.files;\n\n const files = readdirSync(directory);\n const fresh: DirectoryListing = { files, version };\n\n listings.set(directory, fresh);\n\n return files;\n};\n\nconst declaredStylesheets = (\n descriptor: ComponentDescriptor,\n directory: string\n): string[] => {\n const resolveUrl = (url: string): string => resolve(directory, url);\n\n return descriptor.styleUrls.map(resolveUrl);\n};\n\nconst fileTemplate = (\n descriptor: ComponentDescriptor,\n directory: string\n): TemplateSource | null => {\n if (descriptor.templateUrl === null) return null;\n\n const path = resolve(directory, descriptor.templateUrl);\n const isPresent = existsSync(path);\n\n if (!isPresent) return null;\n\n const source: TemplateSource = { kind: 'file', path };\n\n return source;\n};\n\nconst inlineTemplate = (\n descriptor: ComponentDescriptor,\n componentPath: string\n): TemplateSource | null => {\n if (descriptor.template === null) return null;\n\n const source: TemplateSource = {\n kind: 'inline',\n source: descriptor.template,\n path: componentPath\n };\n\n return source;\n};\n\nconst componentTemplate = (\n descriptor: ComponentDescriptor,\n componentPath: string\n): TemplateSource => {\n const directory = dirname(componentPath);\n const file = fileTemplate(descriptor, directory);\n\n if (file !== null) return file;\n\n const inline = inlineTemplate(descriptor, componentPath);\n\n return inline ?? UNKNOWN_TEMPLATE;\n};\n\nconst matchedTemplates = (\n componentPath: string,\n stylesheetPath: string\n): TemplateSource[] => {\n const directory = dirname(componentPath);\n const sources: TemplateSource[] = [];\n\n for (const descriptor of componentMetadata(componentPath)) {\n const declared = declaredStylesheets(descriptor, directory);\n const isMatch = declared.includes(stylesheetPath);\n\n if (!isMatch) continue;\n\n sources.push(componentTemplate(descriptor, componentPath));\n }\n\n return sources;\n};\n\nconst directoryFiles = (directory: string, extension: RegExp): string[] => {\n try {\n return directoryListing(directory).filter((file) => extension.test(file));\n } catch {\n return [];\n }\n};\n\nconst fallbackTemplates = (stylesheetPath: string): TemplateSource[] => {\n const sibling = stylesheetPath.replace(STYLE_EXTENSION, '.html');\n const paths = new Set<string>();\n\n const hasSibling = existsSync(sibling);\n\n if (hasSibling) paths.add(sibling);\n\n for (const path of linkedTemplates(stylesheetPath)) paths.add(path);\n\n const toSource = (path: string): TemplateSource => {\n const source: TemplateSource = { kind: 'file', path };\n\n return source;\n };\n\n const pathList = [...paths];\n\n return pathList.map(toSource);\n};\n\nexport const stylesheetTemplates = (\n stylesheetPath: string\n): TemplateSource[] => {\n const resolved = resolve(stylesheetPath);\n const directory = dirname(resolved);\n const sources: TemplateSource[] = [];\n\n for (const file of directoryFiles(directory, MODULE_EXTENSION)) {\n const componentPath = join(directory, file);\n const matched = matchedTemplates(componentPath, resolved);\n\n sources.push(...matched);\n }\n\n if (sources.length > 0) return sources;\n\n return fallbackTemplates(resolved);\n};\n", "import { readdirSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { createFileCache, readCached } from '../../file-cache.ts';\nimport { linkedStylesheetHrefs } from '../../utils/template-links.util.ts';\n\ntype LinkIndex = {\n readonly builtAt: number;\n readonly buildDuration: number;\n readonly templates: ReadonlyMap<string, string[]>;\n};\n\nconst TEMPLATE_EXTENSION = /\\.html$/iu;\nconst SKIPPED_DIRECTORIES = new Set(['node_modules', 'dist', 'coverage']);\n\nconst links = createFileCache<string[]>('template-links');\n\nlet linkIndex: LinkIndex | null = null;\n\n/** Relative stylesheet hrefs a template links, cached by the template's mtime. */\n// eslint-disable-next-line local/no-unused-exports -- read by linked-templates.spec.ts\nexport const templateLinks = (templatePath: string): string[] => {\n return readCached(links, templatePath, linkedStylesheetHrefs) ?? [];\n};\n\nconst isWalkable = (name: string): boolean => {\n const isDotfile = name.startsWith('.');\n\n if (isDotfile) return false;\n\n return !SKIPPED_DIRECTORIES.has(name);\n};\n\nconst walkTemplates = (root: string): string[] => {\n const found: string[] = [];\n const pending = [root];\n\n while (pending.length > 0) {\n const directory = pending.pop();\n\n if (directory === undefined) break;\n\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n const path = join(directory, entry.name);\n const isDirectory = entry.isDirectory();\n\n if (isDirectory) {\n const canWalk = isWalkable(entry.name);\n\n if (canWalk) pending.push(path);\n\n continue;\n }\n\n const isTemplate = TEMPLATE_EXTENSION.test(entry.name);\n\n if (isTemplate) found.push(path);\n }\n }\n\n return found;\n};\n\nconst templatesUnder = (root: string): string[] => {\n try {\n return walkTemplates(root);\n } catch {\n return [];\n }\n};\n\nconst templatesByStylesheet = (root: string): Map<string, string[]> => {\n const byStylesheet = new Map<string, string[]>();\n\n for (const template of templatesUnder(root)) {\n const directory = dirname(template);\n\n for (const href of templateLinks(template)) {\n const stylesheet = resolve(directory, href);\n const linked = byStylesheet.get(stylesheet) ?? [];\n\n linked.push(template);\n byStylesheet.set(stylesheet, linked);\n }\n }\n\n return byStylesheet;\n};\n\nconst currentLinkIndex = (): LinkIndex => {\n const now = performance.now();\n const cached = linkIndex;\n const isFresh =\n cached !== null && now - cached.builtAt < cached.buildDuration * 100;\n\n if (isFresh) return cached;\n\n const templates = templatesByStylesheet(process.cwd());\n const fresh: LinkIndex = {\n builtAt: now,\n buildDuration: performance.now() - now,\n templates\n };\n\n linkIndex = fresh;\n\n return fresh;\n};\n\n/**\n * Every template under the working directory that links the stylesheet.\n * The walk is rebuilt at most every 100x its own duration, so a link added\n * elsewhere in the project shows up on a later lint.\n */\nexport const linkedTemplates = (stylesheetPath: string): string[] => {\n return currentLinkIndex().templates.get(stylesheetPath) ?? [];\n};\n", "import {\n mkdirSync,\n readFileSync,\n renameSync,\n statSync,\n writeFileSync\n} from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport type { CachedFile, FileCache } from './common/file-cache.type.ts';\n\ntype FileParser<T> = (text: string, path: string) => T;\n\nconst CACHE_FORMAT_VERSION = 1;\n\nconst caches = new Set<FileCache<unknown>>();\n\nlet isFlushRegistered = false;\n\nconst cacheDirectory = (): string | null => {\n const { LINT_SUITE_CACHE, LINT_SUITE_CACHE_DIR } = process.env;\n const isDisabled = LINT_SUITE_CACHE === '0';\n\n if (isDisabled) return null;\n\n if (LINT_SUITE_CACHE_DIR) return LINT_SUITE_CACHE_DIR;\n\n return join(process.cwd(), 'node_modules', '.cache', 'lint-suite');\n};\n\nconst cacheFile = (name: string): string | null => {\n const directory = cacheDirectory();\n\n if (directory === null) return null;\n\n return join(directory, `${name}.v${CACHE_FORMAT_VERSION}.json`);\n};\n\nconst isCachedFile = <T>(value: unknown): value is CachedFile<T> => {\n const isObject = typeof value === 'object' && value !== null;\n\n if (!isObject) return false;\n\n const hasVersion = 'version' in value && typeof value.version === 'string';\n\n return hasVersion && 'value' in value;\n};\n\nconst storedEntries = <T>(text: string): Map<string, CachedFile<T>> => {\n const entries = new Map<string, CachedFile<T>>();\n const parsed: unknown = JSON.parse(text);\n const isRecord = typeof parsed === 'object' && parsed !== null;\n\n if (!isRecord) return entries;\n\n for (const [path, entry] of Object.entries(parsed)) {\n if (isCachedFile<T>(entry)) entries.set(path, entry);\n }\n\n return entries;\n};\n\nconst load = <T>(cache: FileCache<T>): void => {\n cache.loaded = true;\n\n const file = cacheFile(cache.name);\n\n if (file === null) return;\n\n try {\n const stored = storedEntries<T>(readFileSync(file, 'utf8'));\n\n for (const [path, entry] of stored) cache.entries.set(path, entry);\n } catch {\n return;\n }\n};\n\nconst write = (cache: FileCache<unknown>): void => {\n const file = cacheFile(cache.name);\n\n if (file === null) return;\n\n try {\n mkdirSync(dirname(file), { recursive: true });\n\n const temporary = `${file}.${process.pid}.tmp`;\n const stored = Object.fromEntries(cache.entries);\n\n writeFileSync(temporary, JSON.stringify(stored));\n renameSync(temporary, file);\n } catch {\n return;\n }\n};\n\n/** Writes every cache that parsed something this run; runs at process exit. */\n// eslint-disable-next-line local/no-unused-exports -- read by file-cache.spec.ts\nexport const flushFileCaches = (): void => {\n for (const cache of caches) {\n if (!cache.dirty) continue;\n\n write(cache);\n cache.dirty = false;\n }\n};\n\nconst registerFlush = (): void => {\n if (isFlushRegistered) return;\n\n isFlushRegistered = true;\n process.once('exit', flushFileCaches);\n};\n\n/**\n * A cache of parsed files keyed by path and mtime, mirrored to\n * `node_modules/.cache/lint-suite/<name>.v<format>.json` (or\n * `LINT_SUITE_CACHE_DIR`; `LINT_SUITE_CACHE=0` disables the disk copy).\n * Values must survive JSON.\n */\nexport const createFileCache = <T>(name: string): FileCache<T> => {\n const cache: FileCache<T> = {\n name,\n entries: new Map(),\n loaded: false,\n dirty: false\n };\n\n caches.add(cache);\n registerFlush();\n\n return cache;\n};\n\nexport const readCached = <T>(\n cache: FileCache<T>,\n path: string,\n parse: FileParser<T>\n): T | null => {\n if (!cache.loaded) load(cache);\n\n try {\n const stats = statSync(path, { bigint: true });\n const version = `${stats.mtimeNs}:${stats.size}`;\n const cached = cache.entries.get(path);\n\n if (cached?.version === version) return cached.value;\n\n const value = parse(readFileSync(path, 'utf8'), path);\n const fresh: CachedFile<T> = { value, version };\n\n cache.entries.set(path, fresh);\n cache.dirty = true;\n\n return value;\n } catch {\n return null;\n }\n};\n", "const LINK_TAG = /<link\\b[^>]*>/giu;\nconst STYLESHEET_REL = /\\brel\\s*=\\s*[\"']stylesheet[\"']/iu;\nconst HREF = /\\bhref\\s*=\\s*[\"']([^\"']*)[\"']/iu;\nconst UNRESOLVABLE = /^(?:\\/|[^:/?#]+:)/u;\n\nconst hrefOf = (tag: string): string | null => {\n const isStylesheet = STYLESHEET_REL.test(tag);\n\n if (!isStylesheet) return null;\n\n const href = HREF.exec(tag)?.[1] ?? '';\n const isUnresolvable = UNRESOLVABLE.test(href);\n const isLocal = href.length > 0 && !isUnresolvable;\n\n return isLocal ? href : null;\n};\n\nexport const linkedStylesheetHrefs = (template: string): string[] => {\n const tags = template.match(LINK_TAG) ?? [];\n\n return tags.map(hrefOf).filter((href) => href !== null);\n};\n", "import {\n ScriptTarget,\n canHaveDecorators,\n createSourceFile,\n forEachChild,\n getDecorators,\n isArrayLiteralExpression,\n isCallExpression,\n isIdentifier,\n isObjectLiteralExpression,\n isPropertyAssignment,\n isStringLiteralLike\n} from 'typescript';\nimport type {\n Decorator,\n Expression,\n Node,\n ObjectLiteralExpression\n} from 'typescript';\n\nimport type { ComponentDescriptor } from './common/class-usage.type.ts';\nimport { createFileCache, readCached } from './file-cache.ts';\n\nconst COMPONENT_MARKER = '@Component';\n\nconst cache = createFileCache<ComponentDescriptor[]>('component-metadata');\n\nconst componentArgument = (\n decorator: Decorator\n): ObjectLiteralExpression | null => {\n const { expression } = decorator;\n\n if (!isCallExpression(expression)) return null;\n\n if (!isIdentifier(expression.expression)) return null;\n\n const isComponent = expression.expression.text === 'Component';\n\n if (!isComponent) return null;\n\n const [argument] = expression.arguments;\n\n if (argument === undefined) return null;\n\n if (!isObjectLiteralExpression(argument)) return null;\n\n return argument;\n};\n\nconst decoratedMetadata = (node: Node): ObjectLiteralExpression | null => {\n if (!canHaveDecorators(node)) return null;\n\n const decorators = getDecorators(node) ?? [];\n\n for (const decorator of decorators) {\n const metadata = componentArgument(decorator);\n\n if (metadata !== null) return metadata;\n }\n\n return null;\n};\n\nconst literalText = (node: Expression): string | null => {\n if (!isStringLiteralLike(node)) return null;\n\n return node.text;\n};\n\nconst literalTexts = (node: Expression): string[] => {\n const single = literalText(node);\n\n if (single !== null) return [single];\n\n if (!isArrayLiteralExpression(node)) return [];\n\n const texts: string[] = [];\n\n for (const element of node.elements) {\n const text = literalText(element);\n\n if (text !== null) texts.push(text);\n }\n\n return texts;\n};\n\nconst metadataValue = (\n metadata: ObjectLiteralExpression,\n name: string\n): Expression | null => {\n for (const property of metadata.properties) {\n if (!isPropertyAssignment(property)) continue;\n\n if (!isIdentifier(property.name)) continue;\n\n const isMatch = property.name.text === name;\n\n if (isMatch) return property.initializer;\n }\n\n return null;\n};\n\nconst metadataTexts = (\n metadata: ObjectLiteralExpression,\n name: string\n): string[] => {\n const value = metadataValue(metadata, name);\n\n if (value === null) return [];\n\n return literalTexts(value);\n};\n\nconst toDescriptor = (\n metadata: ObjectLiteralExpression\n): ComponentDescriptor => {\n const [templateUrl] = metadataTexts(metadata, 'templateUrl');\n const [template] = metadataTexts(metadata, 'template');\n const styleUrl = metadataTexts(metadata, 'styleUrl');\n const listedStyleUrls = metadataTexts(metadata, 'styleUrls');\n const styleUrls = [...styleUrl, ...listedStyleUrls];\n const styles = metadataTexts(metadata, 'styles');\n const descriptor: ComponentDescriptor = {\n templateUrl: templateUrl ?? null,\n template: template ?? null,\n styleUrls,\n styles\n };\n\n return descriptor;\n};\n\nconst parseComponentMetadata = (\n text: string,\n path: string\n): ComponentDescriptor[] => {\n const found: ComponentDescriptor[] = [];\n const hasComponent = text.includes(COMPONENT_MARKER);\n\n if (!hasComponent) return found;\n\n const visit = (node: Node): void => {\n const metadata = decoratedMetadata(node);\n\n if (metadata !== null) found.push(toDescriptor(metadata));\n\n forEachChild(node, visit);\n };\n\n const source = createSourceFile(path, text, ScriptTarget.Latest, true);\n\n forEachChild(source, visit);\n\n return found;\n};\n\nexport const componentMetadata = (path: string): ComponentDescriptor[] => {\n return readCached(cache, path, parseComponentMetadata) ?? [];\n};\n", "import {\n ASTWithSource,\n TmplAstRecursiveVisitor,\n parseTemplate,\n tmplAstVisitAll\n} from '@angular/compiler';\nimport type {\n AST,\n TmplAstBoundAttribute,\n TmplAstComponent,\n TmplAstElement,\n TmplAstTemplate\n} from '@angular/compiler';\n\nimport type {\n ClassAttributeHost,\n ClassMatcher\n} from '../../common/class-usage.type.ts';\nimport { createFileCache, readCached } from '../../file-cache.ts';\nimport { classMatcher } from '../../selector-classes.ts';\nimport { classExpressionUsage } from '../../utils/class-expression-literals.util.ts';\nimport {\n isClassExpression,\n templateClasses\n} from '../../utils/template-classes.util.ts';\nimport { toRegExp } from '../../utils/to-regexp.util.ts';\nimport type {\n TemplateSource,\n TemplateUsage\n} from '../common/no-unused-classes.type.ts';\n\ntype UsageEntry = {\n readonly names: string[];\n readonly patterns: string[];\n readonly isDynamic: boolean;\n};\n\nconst NG_CLASS_ATTRIBUTE = 'ngClass';\n\nconst matchesNone: ClassMatcher = () => false;\n\nconst UNKNOWN_USAGE: TemplateUsage = {\n has: matchesNone,\n isDynamic: true,\n size: 0\n};\n\nconst templates = createFileCache<UsageEntry | null>('template-usage');\n\nconst expressionSource = (value: AST): string | null => {\n const isWithSource = value instanceof ASTWithSource;\n\n if (!isWithSource) return null;\n\n return value.source;\n};\n\nconst isClassInput = (input: TmplAstBoundAttribute): boolean => {\n const isNgClass = input.name === NG_CLASS_ATTRIBUTE;\n\n if (isNgClass) return true;\n\n return isClassExpression(input);\n};\n\nclass ClassUsageVisitor extends TmplAstRecursiveVisitor {\n public readonly names = new Set<string>();\n\n public readonly patterns = new Set<string>();\n\n public isDynamic = false;\n\n public override visitElement(element: TmplAstElement): void {\n this.collect(element);\n super.visitElement(element);\n }\n\n public override visitTemplate(template: TmplAstTemplate): void {\n this.collect(template);\n super.visitTemplate(template);\n }\n\n public override visitComponent(component: TmplAstComponent): void {\n this.collect(component);\n super.visitComponent(component);\n }\n\n private collect(node: ClassAttributeHost): void {\n for (const { name } of templateClasses(node)) this.names.add(name);\n\n for (const input of node.inputs) this.collectInput(input);\n }\n\n private collectInput(input: TmplAstBoundAttribute): void {\n const isClass = isClassInput(input);\n\n if (!isClass) return;\n\n const source = expressionSource(input.value);\n\n if (source === null) {\n this.isDynamic = true;\n\n return;\n }\n\n const usage = classExpressionUsage(source);\n\n for (const name of usage.names) this.names.add(name);\n\n for (const pattern of usage.patterns) this.patterns.add(pattern);\n\n if (usage.isDynamic) this.isDynamic = true;\n }\n}\n\nconst parseUsage = (text: string, path: string): UsageEntry | null => {\n const parsed = parseTemplate(text, path);\n\n if (parsed.errors !== null) return null;\n\n const visitor = new ClassUsageVisitor();\n\n tmplAstVisitAll(visitor, parsed.nodes);\n\n const names = [...visitor.names];\n const patterns = [...visitor.patterns];\n const entry: UsageEntry = { names, patterns, isDynamic: visitor.isDynamic };\n\n return entry;\n};\n\nconst sourceUsage = (source: TemplateSource): UsageEntry | null => {\n if (source.kind === 'unknown') return null;\n\n if (source.kind === 'inline') return parseUsage(source.source, source.path);\n\n return readCached(templates, source.path, parseUsage) ?? null;\n};\n\nexport const templateUsage = (sources: TemplateSource[]): TemplateUsage => {\n const names = new Set<string>();\n const patterns = new Set<string>();\n\n for (const source of sources) {\n const entry = sourceUsage(source);\n\n if (entry === null) return UNKNOWN_USAGE;\n\n if (entry.isDynamic) return UNKNOWN_USAGE;\n\n for (const name of entry.names) names.add(name);\n\n for (const pattern of entry.patterns) patterns.add(pattern);\n }\n\n const patternList = [...patterns];\n const compiled = patternList.map(toRegExp);\n const has = classMatcher(names, compiled);\n const size = names.size;\n const usage: TemplateUsage = { has, isDynamic: false, size };\n\n return usage;\n};\n", "import selectorParser from 'postcss-selector-parser';\nimport type { Node } from 'postcss-selector-parser';\n\nimport type { ClassMatcher, SelectorClasses } from './common/class-usage.type.ts';\n\ntype SelectorClassNode = { readonly value: string };\n\nconst INTERPOLATION_TOKEN = 'zzinterpzz';\nconst PARENT_TOKEN = 'zzparentzz';\nconst UNKNOWN_PARENT_SELECTOR = `.${PARENT_TOKEN}`;\nconst UNKNOWN_PARTS = new RegExp(\n `${INTERPOLATION_TOKEN}|${PARENT_TOKEN}`,\n 'gu'\n);\nconst INTERPOLATION = /#\\{[^}]*\\}/gu;\nconst DEEP_COMBINATORS = new Set(['/deep/', '>>>']);\nconst HOST_PSEUDOS = new Set([':host', ':host-context']);\nconst NG_DEEP_PSEUDO = '::ng-deep';\nconst REGEXP_META = /[.*+?^${}()|[\\]\\\\]/gu;\n\nconst escapeRegExp = (part: string): string => {\n return part.replaceAll(REGEXP_META, '\\\\$&');\n};\n\nexport const classNamePattern = (value: string): string => {\n const literals = value.split(UNKNOWN_PARTS).map(escapeRegExp);\n const joined = literals.join('.*');\n\n return `^${joined}$`;\n};\n\nconst withoutParent = (selector: string): string => {\n return selector.replaceAll('&', UNKNOWN_PARENT_SELECTOR);\n};\n\nconst withParent = (selector: string, parent: string): string => {\n const hasNesting = selector.includes('&');\n\n if (hasNesting) return selector.replaceAll('&', parent);\n\n return `${parent} ${selector}`;\n};\n\nexport const resolveSelectors = (\n selectors: string[],\n parents: string[]\n): string[] => {\n const hasParents = parents.length > 0;\n\n if (!hasParents) return selectors.map(withoutParent);\n\n const resolved: string[] = [];\n\n for (const parent of parents) {\n for (const selector of selectors) {\n resolved.push(withParent(selector, parent));\n }\n }\n\n return resolved;\n};\n\nexport const selectorClasses = (selector: string): SelectorClasses => {\n const exact: string[] = [];\n const patterns: string[] = [];\n const normalized = selector.replaceAll(INTERPOLATION, INTERPOLATION_TOKEN);\n\n const collect = (node: SelectorClassNode): void => {\n const isBareParent = node.value === PARENT_TOKEN;\n\n if (isBareParent) return;\n\n const hasInterpolation = node.value.includes(INTERPOLATION_TOKEN);\n const hasUnknownParent = node.value.includes(PARENT_TOKEN);\n const isDynamic = hasInterpolation || hasUnknownParent;\n\n if (isDynamic) {\n patterns.push(classNamePattern(node.value));\n\n return;\n }\n\n exact.push(node.value);\n };\n\n try {\n const root = selectorParser().astSync(normalized);\n\n root.walkClasses(collect);\n } catch {\n const empty: SelectorClasses = { exact: [], patterns: [] };\n\n return empty;\n }\n\n const classes: SelectorClasses = { exact, patterns };\n\n return classes;\n};\n\nconst isBoundaryNode = (node: Node): boolean => {\n if (node.type === 'combinator') return DEEP_COMBINATORS.has(node.value);\n\n if (node.type !== 'pseudo') return false;\n\n return node.value === NG_DEEP_PSEUDO;\n};\n\nconst addTemplateClass = (value: string, names: string[]): void => {\n const hasInterpolation = value.includes(INTERPOLATION_TOKEN);\n const hasUnknownParent = value.includes(PARENT_TOKEN);\n const isDynamic = hasInterpolation || hasUnknownParent;\n\n if (isDynamic) return;\n\n names.push(value);\n};\n\nconst collectTemplateClasses = (nodes: Node[], names: string[]): boolean => {\n for (const node of nodes) {\n const isBoundary = isBoundaryNode(node);\n\n if (isBoundary) return true;\n\n if (node.type === 'class') {\n addTemplateClass(node.value, names);\n continue;\n }\n\n if (node.type !== 'pseudo') continue;\n\n const isHost = HOST_PSEUDOS.has(node.value);\n\n if (isHost) continue;\n\n for (const argument of node.nodes) {\n const isStopped = collectTemplateClasses(argument.nodes, names);\n\n if (isStopped) return true;\n }\n }\n\n return false;\n};\n\nexport const selectorTemplateClasses = (selector: string): string[] => {\n const names: string[] = [];\n const normalized = selector.replaceAll(INTERPOLATION, INTERPOLATION_TOKEN);\n\n try {\n const root = selectorParser().astSync(normalized);\n\n for (const each of root.nodes) collectTemplateClasses(each.nodes, names);\n } catch {\n return [];\n }\n\n const uniqueNames = new Set(names);\n\n return [...uniqueNames];\n};\n\nexport const classMatcher = (\n exact: Set<string>,\n patterns: RegExp[]\n): ClassMatcher => {\n const matches = (name: string): boolean => {\n const isExact = exact.has(name);\n\n if (isExact) return true;\n\n return patterns.some((pattern) => pattern.test(name));\n };\n\n return matches;\n};\n", "import {\n Conditional,\n Interpolation,\n Lexer,\n LiteralArray,\n LiteralMap,\n LiteralPrimitive,\n ParseLocation,\n ParseSourceFile,\n ParseSourceSpan,\n Parser\n} from '@angular/compiler';\nimport type { AST, ASTWithSource, LiteralMapKey } from '@angular/compiler';\n\nimport type { ClassExpressionUsage } from '../common/class-usage.type.ts';\nimport { classNamePattern } from '../selector-classes.ts';\n\nconst WHITESPACE = /\\s+/u;\nconst EXPRESSION_FILE = 'class-expression';\nconst INTERPOLATION_TOKEN = 'zzinterpzz';\n\nconst parser = new Parser(new Lexer());\n\nconst spanOf = (source: string): ParseSourceSpan => {\n const file = new ParseSourceFile(source, EXPRESSION_FILE);\n const start = new ParseLocation(file, 0, 0, 0);\n const span = new ParseSourceSpan(start, start.moveBy(source.length));\n\n return span;\n};\n\nconst astOf = (parsed: ASTWithSource): AST | null => {\n const hasErrors = parsed.errors.length > 0;\n\n if (hasErrors) return null;\n\n return parsed.ast;\n};\n\nconst parseClassExpression = (source: string): AST | null => {\n try {\n const span = spanOf(source);\n const interpolation = parser.parseInterpolation(source, span, 0, null);\n\n if (interpolation) return astOf(interpolation);\n\n const binding = parser.parseBinding(source, span, 0);\n\n return astOf(binding);\n } catch {\n return null;\n }\n};\n\nconst addNames = (value: string, names: string[]): void => {\n for (const token of value.split(WHITESPACE)) {\n if (token) names.push(token);\n }\n};\n\nconst addPrimitive = (ast: LiteralPrimitive, names: string[]): void => {\n if (typeof ast.value === 'string') addNames(ast.value, names);\n};\n\nconst addMapKeys = (ast: LiteralMap, names: string[]): void => {\n for (const key of ast.keys) {\n if (key.kind !== 'spread') addNames(key.key, names);\n }\n};\n\nconst addInterpolation = (ast: Interpolation, names: string[]): void => {\n for (const text of ast.strings) addNames(text, names);\n};\n\nconst collect = (ast: AST, names: string[]): void => {\n if (ast instanceof LiteralPrimitive) {\n addPrimitive(ast, names);\n\n return;\n }\n\n if (ast instanceof LiteralMap) {\n addMapKeys(ast, names);\n\n return;\n }\n\n if (ast instanceof Interpolation) {\n addInterpolation(ast, names);\n\n return;\n }\n\n if (ast instanceof LiteralArray) {\n for (const expression of ast.expressions) collect(expression, names);\n\n return;\n }\n\n if (ast instanceof Conditional) {\n collect(ast.trueExp, names);\n collect(ast.falseExp, names);\n }\n};\n\nexport const classExpressionLiterals = (source: string): string[] => {\n const ast = parseClassExpression(source);\n\n if (ast === null) return [];\n\n const names: string[] = [];\n\n collect(ast, names);\n\n const uniqueNames = new Set(names);\n\n return [...uniqueNames];\n};\n\nconst isSpreadKey = (key: LiteralMapKey): boolean => key.kind === 'spread';\n\nconst isDynamicAst = (ast: AST): boolean => {\n if (ast instanceof LiteralPrimitive) return false;\n\n if (ast instanceof LiteralMap) return ast.keys.some(isSpreadKey);\n\n if (ast instanceof LiteralArray) return ast.expressions.some(isDynamicAst);\n\n if (ast instanceof Conditional) {\n const isTrueDynamic = isDynamicAst(ast.trueExp);\n const isFalseDynamic = isDynamicAst(ast.falseExp);\n\n return isTrueDynamic || isFalseDynamic;\n }\n\n return true;\n};\n\nconst isNamedToken = (token: string): boolean => token !== INTERPOLATION_TOKEN;\n\nconst isPatternToken = (token: string): boolean => {\n return token.includes(INTERPOLATION_TOKEN);\n};\n\nconst isPlainToken = (token: string): boolean => !isPatternToken(token);\n\nconst interpolationUsage = (ast: Interpolation): ClassExpressionUsage => {\n const joined = ast.strings.join(INTERPOLATION_TOKEN);\n const tokens = joined.split(WHITESPACE).filter(Boolean);\n const named = tokens.filter(isNamedToken);\n const patterns = named.filter(isPatternToken).map(classNamePattern);\n const names = named.filter(isPlainToken);\n const uniqueNames = new Set(names);\n const uniquePatterns = new Set(patterns);\n const usage: ClassExpressionUsage = {\n names: [...uniqueNames],\n patterns: [...uniquePatterns],\n isDynamic: named.length < tokens.length\n };\n\n return usage;\n};\n\nconst UNKNOWN_USAGE: ClassExpressionUsage = {\n names: [],\n patterns: [],\n isDynamic: true\n};\n\nexport const classExpressionUsage = (source: string): ClassExpressionUsage => {\n const ast = parseClassExpression(source);\n\n if (ast === null) return UNKNOWN_USAGE;\n\n if (ast instanceof Interpolation) return interpolationUsage(ast);\n\n const names: string[] = [];\n\n collect(ast, names);\n\n const isDynamic = isDynamicAst(ast);\n const uniqueNames = new Set(names);\n const usage: ClassExpressionUsage = {\n names: [...uniqueNames],\n patterns: [],\n isDynamic\n };\n\n return usage;\n};\n", "import { ParseSourceSpan } from '@angular/compiler';\nimport type {\n TmplAstBoundAttribute,\n TmplAstTextAttribute\n} from '@angular/compiler';\n\nimport { classExpressionLiterals } from './class-expression-literals.util.ts';\nimport type {\n ClassAttributeHost,\n TemplateClass\n} from '../common/class-usage.type.ts';\n\nconst CLASS_ATTRIBUTES = [\n 'class',\n 'routerLinkActive',\n 'animate.enter',\n 'animate.leave'\n];\nconst CLASS_BINDING_PREFIX = 'class.';\nconst TOKEN = /\\S+/gu;\n\nconst expressionSource = (value: object): string | null => {\n if (!('source' in value)) return null;\n\n const { source } = value;\n\n if (typeof source !== 'string') return null;\n\n return source;\n};\n\nconst staticClasses = (attribute: TmplAstTextAttribute): TemplateClass[] => {\n const classes: TemplateClass[] = [];\n const valueSpan = attribute.valueSpan ?? attribute.sourceSpan;\n\n for (const token of attribute.value.matchAll(TOKEN)) {\n const start = valueSpan.start.moveBy(token.index);\n const end = valueSpan.start.moveBy(token.index + token[0].length);\n const span = new ParseSourceSpan(start, end);\n const templateClass: TemplateClass = { name: token[0], span };\n\n classes.push(templateClass);\n }\n\n return classes;\n};\n\nconst boundClassName = (input: TmplAstBoundAttribute): string | null => {\n const { details } = input.keySpan;\n\n if (details === null) return null;\n\n const isClassBinding = details.startsWith(CLASS_BINDING_PREFIX);\n\n if (!isClassBinding) return null;\n\n return input.name;\n};\n\nexport const isClassExpression = (input: TmplAstBoundAttribute): boolean => {\n const isClassName = CLASS_ATTRIBUTES.includes(input.name);\n\n if (!isClassName) return false;\n\n const { details } = input.keySpan;\n\n if (details === null) return true;\n\n return details === input.name;\n};\n\nconst expressionClasses = (input: TmplAstBoundAttribute): TemplateClass[] => {\n const source = expressionSource(input.value);\n\n if (source === null) return [];\n\n const names = classExpressionLiterals(source);\n const templateClassOf = (name: string): TemplateClass => {\n const templateClass: TemplateClass = { name, span: input.sourceSpan };\n\n return templateClass;\n };\n\n return names.map(templateClassOf);\n};\n\nconst inputClasses = (input: TmplAstBoundAttribute): TemplateClass[] => {\n const bound = boundClassName(input);\n\n if (bound !== null) {\n const templateClass: TemplateClass = { name: bound, span: input.keySpan };\n\n return [templateClass];\n }\n\n const isExpression = isClassExpression(input);\n\n if (!isExpression) return [];\n\n return expressionClasses(input);\n};\n\nexport const templateClasses = (node: ClassAttributeHost): TemplateClass[] => {\n const classes: TemplateClass[] = [];\n\n for (const attribute of node.attributes) {\n const isClassName = CLASS_ATTRIBUTES.includes(attribute.name);\n\n if (isClassName) {\n const found = staticClasses(attribute);\n\n classes.push(...found);\n }\n }\n\n for (const input of node.inputs) {\n const found = inputClasses(input);\n\n classes.push(...found);\n }\n\n return classes;\n};\n", "export const toRegExp = (pattern: string): RegExp => new RegExp(pattern, 'u');\n", "import type { ChildNode, Container, Root, Rule } from 'postcss';\n\nimport { resolveSelectors } from '../selector-classes.ts';\n\ntype ResolvedRuleVisitor = (\n rule: Rule,\n resolved: string[],\n parents: string[]\n) => void;\n\nconst walkContainer = (\n container: Container<ChildNode>,\n parents: string[],\n visit: ResolvedRuleVisitor\n): void => {\n for (const node of container.nodes ?? []) {\n if (node.type === 'rule') {\n const resolved = resolveSelectors(node.selectors, parents);\n\n visit(node, resolved, parents);\n walkContainer(node, resolved, visit);\n continue;\n }\n\n if (node.type !== 'atrule') continue;\n\n walkContainer(node, parents, visit);\n }\n};\n\nexport const walkResolvedRules = (\n root: Root,\n visit: ResolvedRuleVisitor\n): void => {\n walkContainer(root, [], visit);\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["stylelint", "import_node_fs", "import_node_path", "import_node_fs", "import_node_path", "cache", "templates", "import_compiler", "selectorParser", "INTERPOLATION_TOKEN", "import_compiler", "UNKNOWN_USAGE", "expressionSource", "stylelint", "addNames", "collect", "templates", "stylelint", "stylelintScss", "bemPattern"]
7
7
  }
package/stylelint.js CHANGED
@@ -630,7 +630,12 @@ var classExpressionUsage = (source) => {
630
630
 
631
631
  // packages/lint-suite/src/lib/rules/utils/template-classes.util.ts
632
632
  import { ParseSourceSpan as ParseSourceSpan2 } from "@angular/compiler";
633
- var CLASS_ATTRIBUTE = "class";
633
+ var CLASS_ATTRIBUTES = [
634
+ "class",
635
+ "routerLinkActive",
636
+ "animate.enter",
637
+ "animate.leave"
638
+ ];
634
639
  var CLASS_BINDING_PREFIX = "class.";
635
640
  var TOKEN = /\S+/gu;
636
641
  var expressionSource = (value) => {
@@ -659,11 +664,11 @@ var boundClassName = (input) => {
659
664
  return input.name;
660
665
  };
661
666
  var isClassExpression = (input) => {
662
- const isClassName = input.name === CLASS_ATTRIBUTE;
667
+ const isClassName = CLASS_ATTRIBUTES.includes(input.name);
663
668
  if (!isClassName) return false;
664
669
  const { details } = input.keySpan;
665
670
  if (details === null) return true;
666
- return details === CLASS_ATTRIBUTE;
671
+ return details === input.name;
667
672
  };
668
673
  var expressionClasses = (input) => {
669
674
  const source = expressionSource(input.value);
@@ -688,7 +693,7 @@ var inputClasses = (input) => {
688
693
  var templateClasses = (node) => {
689
694
  const classes = [];
690
695
  for (const attribute of node.attributes) {
691
- const isClassName = attribute.name === CLASS_ATTRIBUTE;
696
+ const isClassName = CLASS_ATTRIBUTES.includes(attribute.name);
692
697
  if (isClassName) {
693
698
  const found = staticClasses(attribute);
694
699
  classes.push(...found);
@@ -705,7 +710,6 @@ var templateClasses = (node) => {
705
710
  var toRegExp = (pattern) => new RegExp(pattern, "u");
706
711
 
707
712
  // packages/lint-suite/src/lib/rules/no-unused-classes/template/template-usage.ts
708
- var CLASS_ATTRIBUTE2 = "class";
709
713
  var NG_CLASS_ATTRIBUTE = "ngClass";
710
714
  var matchesNone = () => false;
711
715
  var UNKNOWN_USAGE2 = {
@@ -722,11 +726,7 @@ var expressionSource2 = (value) => {
722
726
  var isClassInput = (input) => {
723
727
  const isNgClass = input.name === NG_CLASS_ATTRIBUTE;
724
728
  if (isNgClass) return true;
725
- const isClass = input.name === CLASS_ATTRIBUTE2;
726
- if (!isClass) return false;
727
- const { details } = input.keySpan;
728
- if (details === null) return true;
729
- return details === CLASS_ATTRIBUTE2;
729
+ return isClassExpression(input);
730
730
  };
731
731
  var ClassUsageVisitor = class extends TmplAstRecursiveVisitor {
732
732
  names = /* @__PURE__ */ new Set();
@@ -844,6 +844,23 @@ var extendedClasses = (root) => {
844
844
  root.walkAtRules("extend", collect2);
845
845
  return names;
846
846
  };
847
+ var isEmittingRule = (rule) => {
848
+ const isEmittingNode = (node) => {
849
+ return node.type === "decl" || node.type === "atrule";
850
+ };
851
+ const children = rule.nodes;
852
+ return children.some(isEmittingNode);
853
+ };
854
+ var emittedClasses = (root) => {
855
+ const names = /* @__PURE__ */ new Set();
856
+ const visit = (rule, resolved) => {
857
+ const isEmitting = isEmittingRule(rule);
858
+ if (!isEmitting) return;
859
+ for (const selector of resolved) addNames2(selector, names);
860
+ };
861
+ walkResolvedRules(root, visit);
862
+ return names;
863
+ };
847
864
  var ruleClasses = (resolved, parents) => {
848
865
  const inherited = /* @__PURE__ */ new Set();
849
866
  for (const parent of parents) addNames2(parent, inherited);
@@ -858,6 +875,8 @@ var ruleClasses = (resolved, parents) => {
858
875
  return [...own];
859
876
  };
860
877
  var reportUnused = (context, rule, name) => {
878
+ const isEmitted = context.emitted.has(name);
879
+ if (!isEmitted) return;
861
880
  const matchesIgnored = (pattern) => pattern.test(name);
862
881
  const isIgnored = context.ignored.some(matchesIgnored);
863
882
  if (isIgnored) return;
@@ -889,10 +908,12 @@ var noUnusedClasses = (primary, secondary) => {
889
908
  const patterns = secondary?.ignoreClassPatterns ?? DEFAULT_IGNORE_PATTERNS;
890
909
  const ignored = patterns.map(toRegExp);
891
910
  const extended = extendedClasses(root);
911
+ const emitted = emittedClasses(root);
892
912
  const context = {
893
913
  result,
894
914
  ignored,
895
915
  extended,
916
+ emitted,
896
917
  isUsed: usage.has
897
918
  };
898
919
  const visit = (rule, resolved, parents) => {