lint-suite 1.6.3 → 2.0.0
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.
- package/README.md +117 -20
- package/eslint.cjs +3312 -492
- package/eslint.cjs.map +4 -4
- package/eslint.js +3304 -445
- package/eslint.js.map +4 -4
- package/lib/angular-template.d.ts +0 -1
- package/lib/angular-template.d.ts.map +1 -1
- package/lib/angular.d.ts +0 -1
- package/lib/angular.d.ts.map +1 -1
- package/lib/base-limits.d.ts.map +1 -1
- package/lib/rules/arrow-body-fits-line/arrow-body-fits-line.d.ts +6 -0
- package/lib/rules/arrow-body-fits-line/arrow-body-fits-line.d.ts.map +1 -0
- package/lib/rules/chain-fits-line/chain-fits-line.d.ts +6 -0
- package/lib/rules/chain-fits-line/chain-fits-line.d.ts.map +1 -0
- package/lib/rules/chain-receiver-is-name/chain-receiver-is-name.d.ts +7 -0
- package/lib/rules/chain-receiver-is-name/chain-receiver-is-name.d.ts.map +1 -0
- package/lib/rules/common/class-usage.type.d.ts +1 -0
- package/lib/rules/common/class-usage.type.d.ts.map +1 -1
- package/lib/rules/common/file-cache.type.d.ts +11 -0
- package/lib/rules/common/file-cache.type.d.ts.map +1 -0
- package/lib/rules/common/glob-matcher.type.d.ts +2 -0
- package/lib/rules/common/glob-matcher.type.d.ts.map +1 -0
- package/lib/rules/component-metadata.d.ts +2 -4
- package/lib/rules/component-metadata.d.ts.map +1 -1
- package/lib/rules/explicit-accessibility/common/explicit-accessibility.const.d.ts +1 -1
- package/lib/rules/explicit-accessibility/common/explicit-accessibility.const.d.ts.map +1 -1
- package/lib/rules/explicit-accessibility/common/explicit-accessibility.type.d.ts +4 -1
- package/lib/rules/explicit-accessibility/common/explicit-accessibility.type.d.ts.map +1 -1
- package/lib/rules/file-cache.d.ts +14 -0
- package/lib/rules/file-cache.d.ts.map +1 -0
- package/lib/rules/max-condition-operands/max-condition-operands.d.ts +10 -0
- package/lib/rules/max-condition-operands/max-condition-operands.d.ts.map +1 -0
- package/lib/rules/no-call-in-condition/common/no-call-in-condition.const.d.ts +6 -0
- package/lib/rules/no-call-in-condition/common/no-call-in-condition.const.d.ts.map +1 -0
- package/lib/rules/no-call-in-condition/common/no-call-in-condition.type.d.ts +21 -0
- package/lib/rules/no-call-in-condition/common/no-call-in-condition.type.d.ts.map +1 -0
- package/lib/rules/no-call-in-condition/no-call-in-condition.d.ts +7 -0
- package/lib/rules/no-call-in-condition/no-call-in-condition.d.ts.map +1 -0
- package/lib/rules/no-call-in-condition/utils/call-exemptions.util.d.ts +4 -0
- package/lib/rules/no-call-in-condition/utils/call-exemptions.util.d.ts.map +1 -0
- package/lib/rules/no-call-in-condition/utils/condition-calls.util.d.ts +7 -0
- package/lib/rules/no-call-in-condition/utils/condition-calls.util.d.ts.map +1 -0
- package/lib/rules/no-grouped-condition/no-grouped-condition.d.ts +7 -0
- package/lib/rules/no-grouped-condition/no-grouped-condition.d.ts.map +1 -0
- package/lib/rules/no-inline-object-types/no-inline-object-types.d.ts.map +1 -1
- package/lib/rules/no-inline-return-object/no-inline-return-object.d.ts +6 -0
- package/lib/rules/no-inline-return-object/no-inline-return-object.d.ts.map +1 -0
- package/lib/rules/no-nested-object-value/common/no-nested-object-value.const.d.ts +5 -0
- package/lib/rules/no-nested-object-value/common/no-nested-object-value.const.d.ts.map +1 -0
- package/lib/rules/no-nested-object-value/common/no-nested-object-value.type.d.ts +7 -0
- package/lib/rules/no-nested-object-value/common/no-nested-object-value.type.d.ts.map +1 -0
- package/lib/rules/no-nested-object-value/no-nested-object-value.d.ts +7 -0
- package/lib/rules/no-nested-object-value/no-nested-object-value.d.ts.map +1 -0
- package/lib/rules/no-nested-object-value/utils/decorator-config.util.d.ts +3 -0
- package/lib/rules/no-nested-object-value/utils/decorator-config.util.d.ts.map +1 -0
- package/lib/rules/no-spread-expression/no-spread-expression.d.ts +6 -0
- package/lib/rules/no-spread-expression/no-spread-expression.d.ts.map +1 -0
- package/lib/rules/no-unstyled-classes/no-unstyled-classes.d.ts.map +1 -1
- package/lib/rules/no-unstyled-classes/styles/component-stylesheets.d.ts.map +1 -1
- package/lib/rules/no-unstyled-classes/styles/linked-stylesheets.d.ts +3 -0
- package/lib/rules/no-unstyled-classes/styles/linked-stylesheets.d.ts.map +1 -0
- package/lib/rules/no-unstyled-classes/styles/stylesheet-classes.d.ts.map +1 -1
- package/lib/rules/no-unstyled-classes/styles/template-stylesheets.d.ts +1 -1
- package/lib/rules/no-unstyled-classes/styles/template-stylesheets.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-directive-index.d.ts +5 -0
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-directive-index.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-resolved-path.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-read-resolution.d.ts +0 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-read-resolution.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-reads.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-references.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/common/project-index.type.d.ts +6 -8
- package/lib/rules/no-unused-angular-instance-fields/project-usage/common/project-index.type.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/common/project-usage.type.d.ts +3 -14
- package/lib/rules/no-unused-angular-instance-fields/project-usage/common/project-usage.type.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-file-entry.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-classes.d.ts +3 -2
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-classes.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-reconciliation.d.ts +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-reconciliation.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-staleness.d.ts +8 -4
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-staleness.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-usage.d.ts +3 -2
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-usage.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/typescript/typescript-destructuring-reads.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/typescript/typescript-reads.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/utils/class-members.util.d.ts +10 -0
- package/lib/rules/no-unused-angular-instance-fields/project-usage/utils/class-members.util.d.ts.map +1 -0
- package/lib/rules/no-unused-angular-instance-fields/rule/angular/angular-class-fields.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/rule/angular/angular-imports.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/rule/angular/angular-managed-fields.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/rule/common/no-unused-angular-instance-fields.type.d.ts +2 -1
- package/lib/rules/no-unused-angular-instance-fields/rule/common/no-unused-angular-instance-fields.type.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/rule/no-unused-angular-instance-fields.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/rule/typescript/typescript-class-read-visitor.d.ts.map +1 -1
- package/lib/rules/no-unused-classes/no-unused-classes.d.ts.map +1 -1
- package/lib/rules/no-unused-classes/styles/linked-templates.d.ts +9 -0
- package/lib/rules/no-unused-classes/styles/linked-templates.d.ts.map +1 -0
- package/lib/rules/no-unused-classes/styles/stylesheet-components.d.ts.map +1 -1
- package/lib/rules/no-unused-classes/template/template-usage.d.ts.map +1 -1
- package/lib/rules/no-unused-exports/common/no-unused-exports.const.d.ts +7 -0
- package/lib/rules/no-unused-exports/common/no-unused-exports.const.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/common/no-unused-exports.type.d.ts +70 -0
- package/lib/rules/no-unused-exports/common/no-unused-exports.type.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/export-index.d.ts +6 -0
- package/lib/rules/no-unused-exports/export-index.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/no-unused-exports.d.ts +7 -0
- package/lib/rules/no-unused-exports/no-unused-exports.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/report-unused-exports.d.ts +12 -0
- package/lib/rules/no-unused-exports/report-unused-exports.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/aggregate-update.util.d.ts +4 -0
- package/lib/rules/no-unused-exports/utils/aggregate-update.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/export-edges.util.d.ts +5 -0
- package/lib/rules/no-unused-exports/utils/export-edges.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/export-nodes.util.d.ts +5 -0
- package/lib/rules/no-unused-exports/utils/export-nodes.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/export-usage.util.d.ts +4 -0
- package/lib/rules/no-unused-exports/utils/export-usage.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/exported-names.util.d.ts +3 -0
- package/lib/rules/no-unused-exports/utils/exported-names.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/file-changes.util.d.ts +4 -0
- package/lib/rules/no-unused-exports/utils/file-changes.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/module-edges.util.d.ts +4 -0
- package/lib/rules/no-unused-exports/utils/module-edges.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/module-target.util.d.ts +4 -0
- package/lib/rules/no-unused-exports/utils/module-target.util.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/utils/public-exports.util.d.ts +3 -0
- package/lib/rules/no-unused-exports/utils/public-exports.util.d.ts.map +1 -0
- package/lib/rules/one-line-guard/one-line-guard.d.ts.map +1 -1
- package/lib/rules/readonly-type-properties/readonly-type-properties.d.ts +2 -1
- package/lib/rules/readonly-type-properties/readonly-type-properties.d.ts.map +1 -1
- package/lib/rules/{utils/selector-classes.util.d.ts → selector-classes.d.ts} +2 -2
- package/lib/rules/selector-classes.d.ts.map +1 -0
- package/lib/rules/ternary-branch-shape/ternary-branch-shape.d.ts +6 -0
- package/lib/rules/ternary-branch-shape/ternary-branch-shape.d.ts.map +1 -0
- package/lib/rules/test-file-shape/common/test-file-shape.const.d.ts +14 -0
- package/lib/rules/test-file-shape/common/test-file-shape.const.d.ts.map +1 -0
- package/lib/rules/test-file-shape/common/test-file-shape.type.d.ts +7 -0
- package/lib/rules/test-file-shape/common/test-file-shape.type.d.ts.map +1 -0
- package/lib/rules/test-file-shape/mock-exports.d.ts +7 -0
- package/lib/rules/test-file-shape/mock-exports.d.ts.map +1 -0
- package/lib/rules/test-file-shape/stub-exports.d.ts +7 -0
- package/lib/rules/test-file-shape/stub-exports.d.ts.map +1 -0
- package/lib/rules/test-file-shape/test-file-shape.d.ts +7 -0
- package/lib/rules/test-file-shape/test-file-shape.d.ts.map +1 -0
- package/lib/rules/type-placement/common/type-placement.const.d.ts +5 -0
- package/lib/rules/type-placement/common/type-placement.const.d.ts.map +1 -0
- package/lib/rules/type-placement/common/type-placement.type.d.ts +7 -0
- package/lib/rules/type-placement/common/type-placement.type.d.ts.map +1 -0
- package/lib/rules/type-placement/type-placement.d.ts +7 -0
- package/lib/rules/type-placement/type-placement.d.ts.map +1 -0
- package/lib/rules/util-purity/common/util-purity.const.d.ts +10 -0
- package/lib/rules/util-purity/common/util-purity.const.d.ts.map +1 -0
- package/lib/rules/util-purity/common/util-purity.type.d.ts +7 -0
- package/lib/rules/util-purity/common/util-purity.type.d.ts.map +1 -0
- package/lib/rules/util-purity/util-purity.d.ts +7 -0
- package/lib/rules/util-purity/util-purity.d.ts.map +1 -0
- package/lib/rules/utils/class-expression-literals.util.d.ts.map +1 -1
- package/lib/rules/utils/enclosing-statement.util.d.ts +3 -0
- package/lib/rules/utils/enclosing-statement.util.d.ts.map +1 -0
- package/lib/rules/utils/glob-matcher.util.d.ts +3 -0
- package/lib/rules/utils/glob-matcher.util.d.ts.map +1 -0
- package/lib/rules/utils/indent-of.util.d.ts +3 -0
- package/lib/rules/utils/indent-of.util.d.ts.map +1 -0
- package/lib/rules/utils/template-classes.util.d.ts.map +1 -1
- package/lib/rules/utils/template-links.util.d.ts +2 -0
- package/lib/rules/utils/template-links.util.d.ts.map +1 -0
- package/lib/rules/utils/to-regexp.util.d.ts +2 -0
- package/lib/rules/utils/to-regexp.util.d.ts.map +1 -0
- package/lib/typescript-local-plugin.d.ts.map +1 -1
- package/lib/typescript-safety.d.ts.map +1 -1
- package/lib/typescript.d.ts +0 -1
- package/lib/typescript.d.ts.map +1 -1
- package/lib/vitest.d.ts.map +1 -1
- package/package.json +1 -1
- package/stylelint.cjs +303 -99
- package/stylelint.cjs.map +4 -4
- package/stylelint.d.ts.map +1 -1
- package/stylelint.js +321 -111
- package/stylelint.js.map +4 -4
- package/lib/rules/no-unused-classes/styles/component-descriptors.d.ts +0 -3
- package/lib/rules/no-unused-classes/styles/component-descriptors.d.ts.map +0 -1
- package/lib/rules/utils/selector-classes.util.d.ts.map +0 -1
package/stylelint.cjs
CHANGED
|
@@ -40,14 +40,204 @@ var import_stylelint_selector_bem_pattern = __toESM(require("stylelint-selector-
|
|
|
40
40
|
var import_stylelint = __toESM(require("stylelint"), 1);
|
|
41
41
|
|
|
42
42
|
// packages/lint-suite/src/lib/rules/no-unused-classes/styles/stylesheet-components.ts
|
|
43
|
+
var import_node_fs3 = require("node:fs");
|
|
44
|
+
var import_node_path3 = require("node:path");
|
|
45
|
+
|
|
46
|
+
// packages/lint-suite/src/lib/rules/no-unused-classes/styles/linked-templates.ts
|
|
43
47
|
var import_node_fs2 = require("node:fs");
|
|
44
|
-
var
|
|
48
|
+
var import_node_path2 = require("node:path");
|
|
45
49
|
|
|
46
|
-
// packages/lint-suite/src/lib/rules/
|
|
50
|
+
// packages/lint-suite/src/lib/rules/file-cache.ts
|
|
47
51
|
var import_node_fs = require("node:fs");
|
|
52
|
+
var import_node_path = require("node:path");
|
|
53
|
+
var CACHE_FORMAT_VERSION = 1;
|
|
54
|
+
var caches = /* @__PURE__ */ new Set();
|
|
55
|
+
var isFlushRegistered = false;
|
|
56
|
+
var cacheDirectory = () => {
|
|
57
|
+
const { LINT_SUITE_CACHE, LINT_SUITE_CACHE_DIR } = process.env;
|
|
58
|
+
const isDisabled = LINT_SUITE_CACHE === "0";
|
|
59
|
+
if (isDisabled) return null;
|
|
60
|
+
if (LINT_SUITE_CACHE_DIR) return LINT_SUITE_CACHE_DIR;
|
|
61
|
+
return (0, import_node_path.join)(process.cwd(), "node_modules", ".cache", "lint-suite");
|
|
62
|
+
};
|
|
63
|
+
var cacheFile = (name) => {
|
|
64
|
+
const directory = cacheDirectory();
|
|
65
|
+
if (directory === null) return null;
|
|
66
|
+
return (0, import_node_path.join)(directory, `${name}.v${CACHE_FORMAT_VERSION}.json`);
|
|
67
|
+
};
|
|
68
|
+
var isCachedFile = (value) => {
|
|
69
|
+
const isObject = typeof value === "object" && value !== null;
|
|
70
|
+
if (!isObject) return false;
|
|
71
|
+
const hasVersion = "version" in value && typeof value.version === "string";
|
|
72
|
+
return hasVersion && "value" in value;
|
|
73
|
+
};
|
|
74
|
+
var storedEntries = (text) => {
|
|
75
|
+
const entries = /* @__PURE__ */ new Map();
|
|
76
|
+
const parsed = JSON.parse(text);
|
|
77
|
+
const isRecord = typeof parsed === "object" && parsed !== null;
|
|
78
|
+
if (!isRecord) return entries;
|
|
79
|
+
for (const [path, entry] of Object.entries(parsed)) {
|
|
80
|
+
if (isCachedFile(entry)) entries.set(path, entry);
|
|
81
|
+
}
|
|
82
|
+
return entries;
|
|
83
|
+
};
|
|
84
|
+
var load = (cache2) => {
|
|
85
|
+
cache2.loaded = true;
|
|
86
|
+
const file = cacheFile(cache2.name);
|
|
87
|
+
if (file === null) return;
|
|
88
|
+
try {
|
|
89
|
+
const stored = storedEntries((0, import_node_fs.readFileSync)(file, "utf8"));
|
|
90
|
+
for (const [path, entry] of stored) cache2.entries.set(path, entry);
|
|
91
|
+
} catch {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
var write = (cache2) => {
|
|
96
|
+
const file = cacheFile(cache2.name);
|
|
97
|
+
if (file === null) return;
|
|
98
|
+
try {
|
|
99
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(file), { recursive: true });
|
|
100
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
101
|
+
const stored = Object.fromEntries(cache2.entries);
|
|
102
|
+
(0, import_node_fs.writeFileSync)(temporary, JSON.stringify(stored));
|
|
103
|
+
(0, import_node_fs.renameSync)(temporary, file);
|
|
104
|
+
} catch {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
var flushFileCaches = () => {
|
|
109
|
+
for (const cache2 of caches) {
|
|
110
|
+
if (!cache2.dirty) continue;
|
|
111
|
+
write(cache2);
|
|
112
|
+
cache2.dirty = false;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
var registerFlush = () => {
|
|
116
|
+
if (isFlushRegistered) return;
|
|
117
|
+
isFlushRegistered = true;
|
|
118
|
+
process.once("exit", flushFileCaches);
|
|
119
|
+
};
|
|
120
|
+
var createFileCache = (name) => {
|
|
121
|
+
const cache2 = {
|
|
122
|
+
name,
|
|
123
|
+
entries: /* @__PURE__ */ new Map(),
|
|
124
|
+
loaded: false,
|
|
125
|
+
dirty: false
|
|
126
|
+
};
|
|
127
|
+
caches.add(cache2);
|
|
128
|
+
registerFlush();
|
|
129
|
+
return cache2;
|
|
130
|
+
};
|
|
131
|
+
var readCached = (cache2, path, parse) => {
|
|
132
|
+
if (!cache2.loaded) load(cache2);
|
|
133
|
+
try {
|
|
134
|
+
const stats = (0, import_node_fs.statSync)(path, { bigint: true });
|
|
135
|
+
const version = `${stats.mtimeNs}:${stats.size}`;
|
|
136
|
+
const cached = cache2.entries.get(path);
|
|
137
|
+
if (cached?.version === version) return cached.value;
|
|
138
|
+
const value = parse((0, import_node_fs.readFileSync)(path, "utf8"), path);
|
|
139
|
+
const fresh = { value, version };
|
|
140
|
+
cache2.entries.set(path, fresh);
|
|
141
|
+
cache2.dirty = true;
|
|
142
|
+
return value;
|
|
143
|
+
} catch {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// packages/lint-suite/src/lib/rules/utils/template-links.util.ts
|
|
149
|
+
var LINK_TAG = /<link\b[^>]*>/giu;
|
|
150
|
+
var STYLESHEET_REL = /\brel\s*=\s*["']stylesheet["']/iu;
|
|
151
|
+
var HREF = /\bhref\s*=\s*["']([^"']*)["']/iu;
|
|
152
|
+
var UNRESOLVABLE = /^(?:\/|[^:/?#]+:)/u;
|
|
153
|
+
var hrefOf = (tag) => {
|
|
154
|
+
const isStylesheet = STYLESHEET_REL.test(tag);
|
|
155
|
+
if (!isStylesheet) return null;
|
|
156
|
+
const href = HREF.exec(tag)?.[1] ?? "";
|
|
157
|
+
const isUnresolvable = UNRESOLVABLE.test(href);
|
|
158
|
+
const isLocal = href.length > 0 && !isUnresolvable;
|
|
159
|
+
return isLocal ? href : null;
|
|
160
|
+
};
|
|
161
|
+
var linkedStylesheetHrefs = (template) => {
|
|
162
|
+
const tags = template.match(LINK_TAG) ?? [];
|
|
163
|
+
return tags.map(hrefOf).filter((href) => href !== null);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// packages/lint-suite/src/lib/rules/no-unused-classes/styles/linked-templates.ts
|
|
167
|
+
var TEMPLATE_EXTENSION = /\.html$/iu;
|
|
168
|
+
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist", "coverage"]);
|
|
169
|
+
var links = createFileCache("template-links");
|
|
170
|
+
var linkIndex = null;
|
|
171
|
+
var templateLinks = (templatePath) => {
|
|
172
|
+
return readCached(links, templatePath, linkedStylesheetHrefs) ?? [];
|
|
173
|
+
};
|
|
174
|
+
var isWalkable = (name) => {
|
|
175
|
+
const isDotfile = name.startsWith(".");
|
|
176
|
+
if (isDotfile) return false;
|
|
177
|
+
return !SKIPPED_DIRECTORIES.has(name);
|
|
178
|
+
};
|
|
179
|
+
var walkTemplates = (root) => {
|
|
180
|
+
const found = [];
|
|
181
|
+
const pending = [root];
|
|
182
|
+
while (pending.length > 0) {
|
|
183
|
+
const directory = pending.pop();
|
|
184
|
+
if (directory === void 0) break;
|
|
185
|
+
for (const entry of (0, import_node_fs2.readdirSync)(directory, { withFileTypes: true })) {
|
|
186
|
+
const path = (0, import_node_path2.join)(directory, entry.name);
|
|
187
|
+
const isDirectory = entry.isDirectory();
|
|
188
|
+
if (isDirectory) {
|
|
189
|
+
const canWalk = isWalkable(entry.name);
|
|
190
|
+
if (canWalk) pending.push(path);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const isTemplate = TEMPLATE_EXTENSION.test(entry.name);
|
|
194
|
+
if (isTemplate) found.push(path);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return found;
|
|
198
|
+
};
|
|
199
|
+
var templatesUnder = (root) => {
|
|
200
|
+
try {
|
|
201
|
+
return walkTemplates(root);
|
|
202
|
+
} catch {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
var templatesByStylesheet = (root) => {
|
|
207
|
+
const byStylesheet = /* @__PURE__ */ new Map();
|
|
208
|
+
for (const template of templatesUnder(root)) {
|
|
209
|
+
const directory = (0, import_node_path2.dirname)(template);
|
|
210
|
+
for (const href of templateLinks(template)) {
|
|
211
|
+
const stylesheet = (0, import_node_path2.resolve)(directory, href);
|
|
212
|
+
const linked = byStylesheet.get(stylesheet) ?? [];
|
|
213
|
+
linked.push(template);
|
|
214
|
+
byStylesheet.set(stylesheet, linked);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return byStylesheet;
|
|
218
|
+
};
|
|
219
|
+
var currentLinkIndex = () => {
|
|
220
|
+
const now = performance.now();
|
|
221
|
+
const cached = linkIndex;
|
|
222
|
+
const isFresh = cached !== null && now - cached.builtAt < cached.buildDuration * 100;
|
|
223
|
+
if (isFresh) return cached;
|
|
224
|
+
const templates2 = templatesByStylesheet(process.cwd());
|
|
225
|
+
const fresh = {
|
|
226
|
+
builtAt: now,
|
|
227
|
+
buildDuration: performance.now() - now,
|
|
228
|
+
templates: templates2
|
|
229
|
+
};
|
|
230
|
+
linkIndex = fresh;
|
|
231
|
+
return fresh;
|
|
232
|
+
};
|
|
233
|
+
var linkedTemplates = (stylesheetPath) => {
|
|
234
|
+
return currentLinkIndex().templates.get(stylesheetPath) ?? [];
|
|
235
|
+
};
|
|
48
236
|
|
|
49
237
|
// packages/lint-suite/src/lib/rules/component-metadata.ts
|
|
50
238
|
var import_typescript = require("typescript");
|
|
239
|
+
var COMPONENT_MARKER = "@Component";
|
|
240
|
+
var cache = createFileCache("component-metadata");
|
|
51
241
|
var componentArgument = (decorator) => {
|
|
52
242
|
const { expression } = decorator;
|
|
53
243
|
if (!(0, import_typescript.isCallExpression)(expression)) return null;
|
|
@@ -68,17 +258,6 @@ var decoratedMetadata = (node) => {
|
|
|
68
258
|
}
|
|
69
259
|
return null;
|
|
70
260
|
};
|
|
71
|
-
var parseComponentMetadata = (text, path) => {
|
|
72
|
-
const found = [];
|
|
73
|
-
const visit = (node) => {
|
|
74
|
-
const metadata = decoratedMetadata(node);
|
|
75
|
-
if (metadata !== null) found.push(metadata);
|
|
76
|
-
(0, import_typescript.forEachChild)(node, visit);
|
|
77
|
-
};
|
|
78
|
-
const source = (0, import_typescript.createSourceFile)(path, text, import_typescript.ScriptTarget.Latest, true);
|
|
79
|
-
(0, import_typescript.forEachChild)(source, visit);
|
|
80
|
-
return found;
|
|
81
|
-
};
|
|
82
261
|
var literalText = (node) => {
|
|
83
262
|
if (!(0, import_typescript.isStringLiteralLike)(node)) return null;
|
|
84
263
|
return node.text;
|
|
@@ -108,56 +287,61 @@ var metadataTexts = (metadata, name) => {
|
|
|
108
287
|
if (value === null) return [];
|
|
109
288
|
return literalTexts(value);
|
|
110
289
|
};
|
|
111
|
-
|
|
112
|
-
// packages/lint-suite/src/lib/rules/no-unused-classes/styles/component-descriptors.ts
|
|
113
|
-
var COMPONENT_MARKER = "@Component";
|
|
114
|
-
var cache = /* @__PURE__ */ new Map();
|
|
115
290
|
var toDescriptor = (metadata) => {
|
|
116
291
|
const [templateUrl] = metadataTexts(metadata, "templateUrl");
|
|
117
292
|
const [template] = metadataTexts(metadata, "template");
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
293
|
+
const styleUrl = metadataTexts(metadata, "styleUrl");
|
|
294
|
+
const listedStyleUrls = metadataTexts(metadata, "styleUrls");
|
|
295
|
+
const styleUrls = [...styleUrl, ...listedStyleUrls];
|
|
296
|
+
const styles = metadataTexts(metadata, "styles");
|
|
122
297
|
const descriptor = {
|
|
123
298
|
templateUrl: templateUrl ?? null,
|
|
124
299
|
template: template ?? null,
|
|
125
|
-
styleUrls
|
|
300
|
+
styleUrls,
|
|
301
|
+
styles
|
|
126
302
|
};
|
|
127
303
|
return descriptor;
|
|
128
304
|
};
|
|
129
|
-
var
|
|
305
|
+
var parseComponentMetadata = (text, path) => {
|
|
306
|
+
const found = [];
|
|
130
307
|
const hasComponent = text.includes(COMPONENT_MARKER);
|
|
131
|
-
if (!hasComponent) return
|
|
132
|
-
|
|
308
|
+
if (!hasComponent) return found;
|
|
309
|
+
const visit = (node) => {
|
|
310
|
+
const metadata = decoratedMetadata(node);
|
|
311
|
+
if (metadata !== null) found.push(toDescriptor(metadata));
|
|
312
|
+
(0, import_typescript.forEachChild)(node, visit);
|
|
313
|
+
};
|
|
314
|
+
const source = (0, import_typescript.createSourceFile)(path, text, import_typescript.ScriptTarget.Latest, true);
|
|
315
|
+
(0, import_typescript.forEachChild)(source, visit);
|
|
316
|
+
return found;
|
|
133
317
|
};
|
|
134
|
-
var
|
|
135
|
-
|
|
136
|
-
const stats = (0, import_node_fs.statSync)(path, { bigint: true });
|
|
137
|
-
const version = `${stats.mtimeNs}:${stats.size}`;
|
|
138
|
-
const cached = cache.get(path);
|
|
139
|
-
if (cached?.version === version) return cached.descriptors;
|
|
140
|
-
const descriptors = parseDescriptors((0, import_node_fs.readFileSync)(path, "utf8"), path);
|
|
141
|
-
const fresh = { descriptors, version };
|
|
142
|
-
cache.set(path, fresh);
|
|
143
|
-
return descriptors;
|
|
144
|
-
} catch {
|
|
145
|
-
return [];
|
|
146
|
-
}
|
|
318
|
+
var componentMetadata = (path) => {
|
|
319
|
+
return readCached(cache, path, parseComponentMetadata) ?? [];
|
|
147
320
|
};
|
|
148
321
|
|
|
149
322
|
// packages/lint-suite/src/lib/rules/no-unused-classes/styles/stylesheet-components.ts
|
|
150
323
|
var MODULE_EXTENSION = /\.ts$/iu;
|
|
151
324
|
var STYLE_EXTENSION = /\.(?:scss|sass|css)$/iu;
|
|
152
325
|
var UNKNOWN_TEMPLATE = { kind: "unknown" };
|
|
326
|
+
var listings = /* @__PURE__ */ new Map();
|
|
327
|
+
var directoryListing = (directory) => {
|
|
328
|
+
const stats = (0, import_node_fs3.statSync)(directory, { bigint: true });
|
|
329
|
+
const version = `${stats.mtimeNs}`;
|
|
330
|
+
const cached = listings.get(directory);
|
|
331
|
+
if (cached?.version === version) return cached.files;
|
|
332
|
+
const files = (0, import_node_fs3.readdirSync)(directory);
|
|
333
|
+
const fresh = { files, version };
|
|
334
|
+
listings.set(directory, fresh);
|
|
335
|
+
return files;
|
|
336
|
+
};
|
|
153
337
|
var declaredStylesheets = (descriptor, directory) => {
|
|
154
|
-
const resolveUrl = (url) => (0,
|
|
338
|
+
const resolveUrl = (url) => (0, import_node_path3.resolve)(directory, url);
|
|
155
339
|
return descriptor.styleUrls.map(resolveUrl);
|
|
156
340
|
};
|
|
157
341
|
var fileTemplate = (descriptor, directory) => {
|
|
158
342
|
if (descriptor.templateUrl === null) return null;
|
|
159
|
-
const path = (0,
|
|
160
|
-
const isPresent = (0,
|
|
343
|
+
const path = (0, import_node_path3.resolve)(directory, descriptor.templateUrl);
|
|
344
|
+
const isPresent = (0, import_node_fs3.existsSync)(path);
|
|
161
345
|
if (!isPresent) return null;
|
|
162
346
|
const source = { kind: "file", path };
|
|
163
347
|
return source;
|
|
@@ -172,16 +356,16 @@ var inlineTemplate = (descriptor, componentPath) => {
|
|
|
172
356
|
return source;
|
|
173
357
|
};
|
|
174
358
|
var componentTemplate = (descriptor, componentPath) => {
|
|
175
|
-
const directory = (0,
|
|
359
|
+
const directory = (0, import_node_path3.dirname)(componentPath);
|
|
176
360
|
const file = fileTemplate(descriptor, directory);
|
|
177
361
|
if (file !== null) return file;
|
|
178
362
|
const inline = inlineTemplate(descriptor, componentPath);
|
|
179
363
|
return inline ?? UNKNOWN_TEMPLATE;
|
|
180
364
|
};
|
|
181
365
|
var matchedTemplates = (componentPath, stylesheetPath) => {
|
|
182
|
-
const directory = (0,
|
|
366
|
+
const directory = (0, import_node_path3.dirname)(componentPath);
|
|
183
367
|
const sources = [];
|
|
184
|
-
for (const descriptor of
|
|
368
|
+
for (const descriptor of componentMetadata(componentPath)) {
|
|
185
369
|
const declared = declaredStylesheets(descriptor, directory);
|
|
186
370
|
const isMatch = declared.includes(stylesheetPath);
|
|
187
371
|
if (!isMatch) continue;
|
|
@@ -189,40 +373,43 @@ var matchedTemplates = (componentPath, stylesheetPath) => {
|
|
|
189
373
|
}
|
|
190
374
|
return sources;
|
|
191
375
|
};
|
|
192
|
-
var
|
|
376
|
+
var directoryFiles = (directory, extension) => {
|
|
193
377
|
try {
|
|
194
|
-
return (
|
|
378
|
+
return directoryListing(directory).filter((file) => extension.test(file));
|
|
195
379
|
} catch {
|
|
196
380
|
return [];
|
|
197
381
|
}
|
|
198
382
|
};
|
|
199
|
-
var
|
|
200
|
-
const
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
383
|
+
var fallbackTemplates = (stylesheetPath) => {
|
|
384
|
+
const sibling = stylesheetPath.replace(STYLE_EXTENSION, ".html");
|
|
385
|
+
const paths = /* @__PURE__ */ new Set();
|
|
386
|
+
const hasSibling = (0, import_node_fs3.existsSync)(sibling);
|
|
387
|
+
if (hasSibling) paths.add(sibling);
|
|
388
|
+
for (const path of linkedTemplates(stylesheetPath)) paths.add(path);
|
|
389
|
+
const toSource = (path) => {
|
|
390
|
+
const source = { kind: "file", path };
|
|
391
|
+
return source;
|
|
392
|
+
};
|
|
393
|
+
const pathList = [...paths];
|
|
394
|
+
return pathList.map(toSource);
|
|
205
395
|
};
|
|
206
396
|
var stylesheetTemplates = (stylesheetPath) => {
|
|
207
|
-
const resolved = (0,
|
|
208
|
-
const directory = (0,
|
|
397
|
+
const resolved = (0, import_node_path3.resolve)(stylesheetPath);
|
|
398
|
+
const directory = (0, import_node_path3.dirname)(resolved);
|
|
209
399
|
const sources = [];
|
|
210
|
-
for (const file of
|
|
211
|
-
const componentPath = (0,
|
|
212
|
-
|
|
400
|
+
for (const file of directoryFiles(directory, MODULE_EXTENSION)) {
|
|
401
|
+
const componentPath = (0, import_node_path3.join)(directory, file);
|
|
402
|
+
const matched = matchedTemplates(componentPath, resolved);
|
|
403
|
+
sources.push(...matched);
|
|
213
404
|
}
|
|
214
405
|
if (sources.length > 0) return sources;
|
|
215
|
-
return
|
|
406
|
+
return fallbackTemplates(resolved);
|
|
216
407
|
};
|
|
217
408
|
|
|
218
409
|
// packages/lint-suite/src/lib/rules/no-unused-classes/template/template-usage.ts
|
|
219
410
|
var import_compiler3 = require("@angular/compiler");
|
|
220
|
-
var import_node_fs3 = require("node:fs");
|
|
221
411
|
|
|
222
|
-
// packages/lint-suite/src/lib/rules/
|
|
223
|
-
var import_compiler = require("@angular/compiler");
|
|
224
|
-
|
|
225
|
-
// packages/lint-suite/src/lib/rules/utils/selector-classes.util.ts
|
|
412
|
+
// packages/lint-suite/src/lib/rules/selector-classes.ts
|
|
226
413
|
var import_postcss_selector_parser = __toESM(require("postcss-selector-parser"), 1);
|
|
227
414
|
var INTERPOLATION_TOKEN = "zzinterpzz";
|
|
228
415
|
var PARENT_TOKEN = "zzparentzz";
|
|
@@ -302,7 +489,8 @@ var selectorTemplateClasses = (selector) => {
|
|
|
302
489
|
} catch {
|
|
303
490
|
return [];
|
|
304
491
|
}
|
|
305
|
-
|
|
492
|
+
const uniqueNames = new Set(names);
|
|
493
|
+
return [...uniqueNames];
|
|
306
494
|
};
|
|
307
495
|
var classMatcher = (exact, patterns) => {
|
|
308
496
|
const matches = (name) => {
|
|
@@ -314,6 +502,7 @@ var classMatcher = (exact, patterns) => {
|
|
|
314
502
|
};
|
|
315
503
|
|
|
316
504
|
// packages/lint-suite/src/lib/rules/utils/class-expression-literals.util.ts
|
|
505
|
+
var import_compiler = require("@angular/compiler");
|
|
317
506
|
var WHITESPACE = /\s+/u;
|
|
318
507
|
var EXPRESSION_FILE = "class-expression";
|
|
319
508
|
var INTERPOLATION_TOKEN2 = "zzinterpzz";
|
|
@@ -383,7 +572,8 @@ var classExpressionLiterals = (source) => {
|
|
|
383
572
|
if (ast === null) return [];
|
|
384
573
|
const names = [];
|
|
385
574
|
collect(ast, names);
|
|
386
|
-
|
|
575
|
+
const uniqueNames = new Set(names);
|
|
576
|
+
return [...uniqueNames];
|
|
387
577
|
};
|
|
388
578
|
var isSpreadKey = (key) => key.kind === "spread";
|
|
389
579
|
var isDynamicAst = (ast) => {
|
|
@@ -408,9 +598,11 @@ var interpolationUsage = (ast) => {
|
|
|
408
598
|
const named = tokens.filter(isNamedToken);
|
|
409
599
|
const patterns = named.filter(isPatternToken).map(classNamePattern);
|
|
410
600
|
const names = named.filter(isPlainToken);
|
|
601
|
+
const uniqueNames = new Set(names);
|
|
602
|
+
const uniquePatterns = new Set(patterns);
|
|
411
603
|
const usage = {
|
|
412
|
-
names: [...
|
|
413
|
-
patterns: [...
|
|
604
|
+
names: [...uniqueNames],
|
|
605
|
+
patterns: [...uniquePatterns],
|
|
414
606
|
isDynamic: named.length < tokens.length
|
|
415
607
|
};
|
|
416
608
|
return usage;
|
|
@@ -427,8 +619,9 @@ var classExpressionUsage = (source) => {
|
|
|
427
619
|
const names = [];
|
|
428
620
|
collect(ast, names);
|
|
429
621
|
const isDynamic = isDynamicAst(ast);
|
|
622
|
+
const uniqueNames = new Set(names);
|
|
430
623
|
const usage = {
|
|
431
|
-
names: [...
|
|
624
|
+
names: [...uniqueNames],
|
|
432
625
|
patterns: [],
|
|
433
626
|
isDynamic
|
|
434
627
|
};
|
|
@@ -496,14 +689,21 @@ var templateClasses = (node) => {
|
|
|
496
689
|
const classes = [];
|
|
497
690
|
for (const attribute of node.attributes) {
|
|
498
691
|
const isClassName = attribute.name === CLASS_ATTRIBUTE;
|
|
499
|
-
if (isClassName)
|
|
692
|
+
if (isClassName) {
|
|
693
|
+
const found = staticClasses(attribute);
|
|
694
|
+
classes.push(...found);
|
|
695
|
+
}
|
|
500
696
|
}
|
|
501
697
|
for (const input of node.inputs) {
|
|
502
|
-
|
|
698
|
+
const found = inputClasses(input);
|
|
699
|
+
classes.push(...found);
|
|
503
700
|
}
|
|
504
701
|
return classes;
|
|
505
702
|
};
|
|
506
703
|
|
|
704
|
+
// packages/lint-suite/src/lib/rules/utils/to-regexp.util.ts
|
|
705
|
+
var toRegExp = (pattern) => new RegExp(pattern, "u");
|
|
706
|
+
|
|
507
707
|
// packages/lint-suite/src/lib/rules/no-unused-classes/template/template-usage.ts
|
|
508
708
|
var CLASS_ATTRIBUTE2 = "class";
|
|
509
709
|
var NG_CLASS_ATTRIBUTE = "ngClass";
|
|
@@ -513,7 +713,7 @@ var UNKNOWN_USAGE2 = {
|
|
|
513
713
|
isDynamic: true,
|
|
514
714
|
size: 0
|
|
515
715
|
};
|
|
516
|
-
var
|
|
716
|
+
var templates = createFileCache("template-usage");
|
|
517
717
|
var expressionSource2 = (value) => {
|
|
518
718
|
const isWithSource = value instanceof import_compiler3.ASTWithSource;
|
|
519
719
|
if (!isWithSource) return null;
|
|
@@ -562,33 +762,35 @@ var ClassUsageVisitor = class extends import_compiler3.TmplAstRecursiveVisitor {
|
|
|
562
762
|
if (usage.isDynamic) this.isDynamic = true;
|
|
563
763
|
}
|
|
564
764
|
};
|
|
565
|
-
var
|
|
765
|
+
var parseUsage = (text, path) => {
|
|
766
|
+
const parsed = (0, import_compiler3.parseTemplate)(text, path);
|
|
767
|
+
if (parsed.errors !== null) return null;
|
|
768
|
+
const visitor = new ClassUsageVisitor();
|
|
769
|
+
(0, import_compiler3.tmplAstVisitAll)(visitor, parsed.nodes);
|
|
770
|
+
const names = [...visitor.names];
|
|
771
|
+
const patterns = [...visitor.patterns];
|
|
772
|
+
const entry = { names, patterns, isDynamic: visitor.isDynamic };
|
|
773
|
+
return entry;
|
|
774
|
+
};
|
|
775
|
+
var sourceUsage = (source) => {
|
|
566
776
|
if (source.kind === "unknown") return null;
|
|
567
|
-
if (source.kind === "inline")
|
|
568
|
-
|
|
569
|
-
return inline;
|
|
570
|
-
}
|
|
571
|
-
try {
|
|
572
|
-
const text = (0, import_node_fs3.readFileSync)(source.path, "utf8");
|
|
573
|
-
const file = { text, path: source.path };
|
|
574
|
-
return file;
|
|
575
|
-
} catch {
|
|
576
|
-
return null;
|
|
577
|
-
}
|
|
777
|
+
if (source.kind === "inline") return parseUsage(source.source, source.path);
|
|
778
|
+
return readCached(templates, source.path, parseUsage) ?? null;
|
|
578
779
|
};
|
|
579
780
|
var templateUsage = (sources) => {
|
|
580
|
-
const
|
|
781
|
+
const names = /* @__PURE__ */ new Set();
|
|
782
|
+
const patterns = /* @__PURE__ */ new Set();
|
|
581
783
|
for (const source of sources) {
|
|
582
|
-
const
|
|
583
|
-
if (
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
(
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
const
|
|
590
|
-
const has = classMatcher(
|
|
591
|
-
const size =
|
|
784
|
+
const entry = sourceUsage(source);
|
|
785
|
+
if (entry === null) return UNKNOWN_USAGE2;
|
|
786
|
+
if (entry.isDynamic) return UNKNOWN_USAGE2;
|
|
787
|
+
for (const name of entry.names) names.add(name);
|
|
788
|
+
for (const pattern of entry.patterns) patterns.add(pattern);
|
|
789
|
+
}
|
|
790
|
+
const patternList = [...patterns];
|
|
791
|
+
const compiled = patternList.map(toRegExp);
|
|
792
|
+
const has = classMatcher(names, compiled);
|
|
793
|
+
const size = names.size;
|
|
592
794
|
const usage = { has, isDynamic: false, size };
|
|
593
795
|
return usage;
|
|
594
796
|
};
|
|
@@ -622,7 +824,6 @@ var meta = {
|
|
|
622
824
|
url: "https://github.com/F0rty-Tw0/lint-suite#no-unused-classes"
|
|
623
825
|
};
|
|
624
826
|
var isString = (value) => typeof value === "string";
|
|
625
|
-
var toRegExp2 = (pattern) => new RegExp(pattern, "u");
|
|
626
827
|
var validate = (result, primary, secondary) => {
|
|
627
828
|
const primaryOptions = { actual: primary, possible: [true] };
|
|
628
829
|
const possible = { ignoreClassPatterns: [isString] };
|
|
@@ -681,12 +882,12 @@ var noUnusedClasses = (primary, secondary) => {
|
|
|
681
882
|
if (!isValid) return;
|
|
682
883
|
const file = root.source?.input.file;
|
|
683
884
|
if (file === void 0) return;
|
|
684
|
-
const
|
|
685
|
-
if (
|
|
686
|
-
const usage = templateUsage(
|
|
885
|
+
const templates2 = stylesheetTemplates(file);
|
|
886
|
+
if (templates2.length === 0) return;
|
|
887
|
+
const usage = templateUsage(templates2);
|
|
687
888
|
if (usage.isDynamic) return;
|
|
688
889
|
const patterns = secondary?.ignoreClassPatterns ?? DEFAULT_IGNORE_PATTERNS;
|
|
689
|
-
const ignored = patterns.map(
|
|
890
|
+
const ignored = patterns.map(toRegExp);
|
|
690
891
|
const extended = extendedClasses(root);
|
|
691
892
|
const context = {
|
|
692
893
|
result,
|
|
@@ -731,6 +932,9 @@ var stylelint2 = {
|
|
|
731
932
|
ignoreCustomProperties: ["^--mdc", "^--sys"]
|
|
732
933
|
},
|
|
733
934
|
"no-descending-specificity": null,
|
|
935
|
+
// A stylesheet class no linked template uses is reported.
|
|
936
|
+
// Bad: .ghost {} used by no template
|
|
937
|
+
// Good: delete it, or use it in a template
|
|
734
938
|
"lint-suite/no-unused-classes": true
|
|
735
939
|
}
|
|
736
940
|
}
|