@pandacss/eslint-plugin 2.0.0-beta.8 → 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 +13 -0
- package/dist/{chunk-3ZHMGIZ2.js → chunk-4YDZVIGF.js} +237 -67
- package/dist/index.d.ts +26 -6
- package/dist/index.js +13 -3
- package/dist/oxlint.d.ts +2 -2
- package/dist/oxlint.js +1 -1
- package/dist/{shared-B-c4H6nv.d.ts → shared-BdjJwg93.d.ts} +9 -26
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -147,6 +147,8 @@ The rest are off by default. Turn them on per project:
|
|
|
147
147
|
- `consistent-property-style` — enforce one property style: Panda shorthand aliases (`ml`) or longhand canonical names
|
|
148
148
|
(`marginLeft`). Autofixable. Takes `style: 'shorthand' | 'longhand'` (default `longhand`) and `ignore`.
|
|
149
149
|
- `prefer-text-style` — a style object setting two or more typography properties that should be one `textStyle` token.
|
|
150
|
+
- `no-primitive-token` — a primitive/core token where a semantic token exists for that category. Takes `categories` and
|
|
151
|
+
`allow`.
|
|
150
152
|
|
|
151
153
|
Enable an opt-in rule like any other:
|
|
152
154
|
|
|
@@ -190,6 +192,17 @@ Quick-fixes apply to each offending leaf — flat literals (`color: '#f00'`), va
|
|
|
190
192
|
(`color: { base: '#f00' }`), and responsive-array elements (`color: ['#f00', ...]`). Coverage spans `css()`, style
|
|
191
193
|
props, and recipe styles in `cva()` / `sva()` / `styled('div', { ... })` (`base`, `variants`, `compoundVariants`).
|
|
192
194
|
|
|
195
|
+
`no-primitive-token` takes `categories` (which token categories to enforce; defaults to categories with semantic tokens)
|
|
196
|
+
and `allow` (primitive token paths to permit):
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
{ rules: { '@pandacss/no-primitive-token': ['error', { categories: ['colors'], allow: ['red.500'] }] } }
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
This complements `prefer-token`: `prefer-token` maps hardcoded CSS values to tokens; `no-primitive-token` maps primitive
|
|
203
|
+
tokens to semantic tokens. Categories without semantic tokens are skipped, so spacing primitives are allowed unless you
|
|
204
|
+
define semantic spacing tokens.
|
|
205
|
+
|
|
193
206
|
### Migrating from `no-hardcoded-color`
|
|
194
207
|
|
|
195
208
|
`no-hardcoded-color` is now `prefer-token` scoped to colors. Replace it with:
|
|
@@ -174,65 +174,21 @@ function reportToken(context, token, range) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// src/core/inspector.ts
|
|
177
|
-
|
|
178
|
-
#entries = /* @__PURE__ */ new WeakMap();
|
|
179
|
-
inspect(compiler, path, source) {
|
|
180
|
-
let byPath = this.#entries.get(compiler);
|
|
181
|
-
if (!byPath) {
|
|
182
|
-
byPath = /* @__PURE__ */ new Map();
|
|
183
|
-
this.#entries.set(compiler, byPath);
|
|
184
|
-
}
|
|
185
|
-
const sourceKey = sourceCacheKey(source);
|
|
186
|
-
const cached = byPath.get(path);
|
|
187
|
-
if (cached?.sourceKey === sourceKey) return cached.result;
|
|
188
|
-
const result = compiler.inspectFile({ path, source });
|
|
189
|
-
byPath.set(path, { sourceKey, result });
|
|
190
|
-
return result;
|
|
191
|
-
}
|
|
192
|
-
clear(compiler) {
|
|
193
|
-
if (compiler) {
|
|
194
|
-
this.#entries.delete(compiler);
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
this.#entries = /* @__PURE__ */ new WeakMap();
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
function sourceCacheKey(source) {
|
|
201
|
-
let hash = 2166136261;
|
|
202
|
-
for (let i = 0; i < source.length; i++) {
|
|
203
|
-
hash ^= source.charCodeAt(i);
|
|
204
|
-
hash = Math.imul(hash, 16777619);
|
|
205
|
-
}
|
|
206
|
-
return `${source.length}:${hash >>> 0}`;
|
|
207
|
-
}
|
|
177
|
+
import { FileInspector, sourceCacheKey } from "@pandacss/compiler/tooling";
|
|
208
178
|
|
|
209
179
|
// src/core/project-cache.ts
|
|
210
|
-
import {
|
|
211
|
-
import { loadConfig } from "@pandacss/config";
|
|
180
|
+
import { createProjectFromConfig } from "@pandacss/compiler/tooling";
|
|
212
181
|
var ProjectCache = class {
|
|
213
182
|
#projects = /* @__PURE__ */ new Map();
|
|
214
|
-
#
|
|
215
|
-
#createCompiler;
|
|
183
|
+
#createProject;
|
|
216
184
|
constructor(options = {}) {
|
|
217
|
-
this.#
|
|
218
|
-
cwd: settings.cwd,
|
|
219
|
-
...settings.configPath ? { file: settings.configPath } : {}
|
|
220
|
-
}));
|
|
221
|
-
this.#createCompiler = options.createCompiler ?? createCompilerFromSnapshot;
|
|
185
|
+
this.#createProject = options.createProject ?? ((settings) => createProjectFromConfig({ cwd: settings.cwd, configPath: settings.configPath }));
|
|
222
186
|
}
|
|
223
187
|
get(settings) {
|
|
224
188
|
const key = projectCacheKey(settings);
|
|
225
189
|
const cached = this.#projects.get(key);
|
|
226
190
|
if (cached) return cached;
|
|
227
|
-
const project = this.#
|
|
228
|
-
compiler: this.#createCompiler({
|
|
229
|
-
config: result.config,
|
|
230
|
-
callbacks: result.callbacks,
|
|
231
|
-
...result.hooks ? { hooks: result.hooks } : {}
|
|
232
|
-
}),
|
|
233
|
-
configPath: result.path,
|
|
234
|
-
dependencies: result.dependencies
|
|
235
|
-
}));
|
|
191
|
+
const project = this.#createProject(settings);
|
|
236
192
|
this.#projects.set(key, project);
|
|
237
193
|
return project;
|
|
238
194
|
}
|
|
@@ -268,7 +224,7 @@ var Linter = class {
|
|
|
268
224
|
#inspector;
|
|
269
225
|
constructor(options = {}) {
|
|
270
226
|
this.#projectCache = options.projectCache ?? new ProjectCache();
|
|
271
|
-
this.#inspector = options.inspector ?? new
|
|
227
|
+
this.#inspector = options.inspector ?? new FileInspector();
|
|
272
228
|
}
|
|
273
229
|
getProject(context) {
|
|
274
230
|
return this.#projectCache.get(resolvePandaSettings(context));
|
|
@@ -469,6 +425,85 @@ function report(context, kind, name, deprecation, range) {
|
|
|
469
425
|
});
|
|
470
426
|
}
|
|
471
427
|
|
|
428
|
+
// src/rules/no-descendant-selectors.ts
|
|
429
|
+
var noDescendantSelectorsRuleName = "no-descendant-selectors";
|
|
430
|
+
function* topLevelChars(selector) {
|
|
431
|
+
let depth = 0;
|
|
432
|
+
let quote;
|
|
433
|
+
for (let i = 0; i < selector.length; i++) {
|
|
434
|
+
const ch = selector[i];
|
|
435
|
+
if (quote) {
|
|
436
|
+
if (ch === "\\") i++;
|
|
437
|
+
else if (ch === quote) quote = void 0;
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
if (ch === "\\") {
|
|
441
|
+
i++;
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
if (ch === '"' || ch === "'") {
|
|
445
|
+
quote = ch;
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
if (ch === "[" || ch === "(") depth++;
|
|
449
|
+
else if (ch === "]" || ch === ")") depth--;
|
|
450
|
+
else if (depth === 0) yield [i, ch];
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function splitSelectorList(selector) {
|
|
454
|
+
const cuts = [];
|
|
455
|
+
for (const [i, ch] of topLevelChars(selector)) {
|
|
456
|
+
if (ch === ",") cuts.push(i);
|
|
457
|
+
}
|
|
458
|
+
const parts = [];
|
|
459
|
+
let start = 0;
|
|
460
|
+
for (const cut of cuts) {
|
|
461
|
+
parts.push(selector.slice(start, cut));
|
|
462
|
+
start = cut + 1;
|
|
463
|
+
}
|
|
464
|
+
parts.push(selector.slice(start));
|
|
465
|
+
return parts.map((p) => p.trim()).filter(Boolean);
|
|
466
|
+
}
|
|
467
|
+
function targetsOtherElement(part) {
|
|
468
|
+
if (!part.includes("&")) return false;
|
|
469
|
+
for (const [, ch] of topLevelChars(part)) {
|
|
470
|
+
if (ch === " " || ch === " " || ch === ">" || ch === "+" || ch === "~") return true;
|
|
471
|
+
}
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
function createNoDescendantSelectorsRule(options) {
|
|
475
|
+
return {
|
|
476
|
+
meta: {
|
|
477
|
+
type: "suggestion",
|
|
478
|
+
docs: {
|
|
479
|
+
description: "Disallow selectors that style other elements, keeping every style scoped to its own element."
|
|
480
|
+
},
|
|
481
|
+
schema: [],
|
|
482
|
+
messages: {
|
|
483
|
+
descendant: 'Selector "{{selector}}" styles another element. Keep styles on the element they belong to, or use a condition like "_groupHover" for cross-element state.'
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
create(context) {
|
|
487
|
+
return {
|
|
488
|
+
Program() {
|
|
489
|
+
const inspection = options.inspect(context);
|
|
490
|
+
if (!inspection) return;
|
|
491
|
+
for (const entry of inspection.styleEntries) {
|
|
492
|
+
if (entry.kind !== "selector") continue;
|
|
493
|
+
if (entry.origin === "generated") continue;
|
|
494
|
+
if (!splitSelectorList(entry.name).some(targetsOtherElement)) continue;
|
|
495
|
+
context.report({
|
|
496
|
+
messageId: "descendant",
|
|
497
|
+
data: { selector: entry.name },
|
|
498
|
+
loc: toEslintLoc(entry.range)
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
|
|
472
507
|
// src/rules/no-important.ts
|
|
473
508
|
var noImportantRuleName = "no-important";
|
|
474
509
|
var MESSAGE3 = "Avoid `!important`; it escalates specificity and is hard to override.";
|
|
@@ -558,6 +593,141 @@ function createNoInvalidNestingRule(options) {
|
|
|
558
593
|
};
|
|
559
594
|
}
|
|
560
595
|
|
|
596
|
+
// src/rules/no-primitive-token.ts
|
|
597
|
+
var noPrimitiveTokenRuleName = "no-primitive-token";
|
|
598
|
+
var MAX_SUGGESTIONS = 3;
|
|
599
|
+
function isAllowed(token, allow) {
|
|
600
|
+
if (allow.size === 0) return false;
|
|
601
|
+
return allow.has(token.path) || allow.has(token.categoryPath);
|
|
602
|
+
}
|
|
603
|
+
function modifierSuffix(token, sourcePath) {
|
|
604
|
+
if (sourcePath?.startsWith(`${token.path}/`)) return sourcePath.slice(token.path.length);
|
|
605
|
+
return token.modifier ? `/${token.modifier}` : "";
|
|
606
|
+
}
|
|
607
|
+
function shouldReport(token, config) {
|
|
608
|
+
if (token.semantic || !token.semanticCategory) return false;
|
|
609
|
+
if (config.categories && !config.categories.has(token.category)) return false;
|
|
610
|
+
return !isAllowed(token, config.allow);
|
|
611
|
+
}
|
|
612
|
+
function replacementForRange(source, range, value) {
|
|
613
|
+
const current = source.slice(range[0], range[1]);
|
|
614
|
+
const quote = current[0];
|
|
615
|
+
return quote === '"' || quote === "'" || quote === "`" ? `${quote}${value}${quote}` : value;
|
|
616
|
+
}
|
|
617
|
+
function tokenRefFixRange(source, span, token) {
|
|
618
|
+
const outerStart = byteToIndex(source, span.start);
|
|
619
|
+
const outerEnd = byteToIndex(source, span.end);
|
|
620
|
+
const text = source.slice(outerStart, outerEnd);
|
|
621
|
+
for (const quote of ["'", '"', "`"]) {
|
|
622
|
+
const needle = `${quote}${token}${quote}`;
|
|
623
|
+
const index2 = text.indexOf(needle);
|
|
624
|
+
if (index2 >= 0) return [outerStart + index2, outerStart + index2 + needle.length];
|
|
625
|
+
}
|
|
626
|
+
const index = text.indexOf(token);
|
|
627
|
+
return index >= 0 ? [outerStart + index, outerStart + index + token.length] : void 0;
|
|
628
|
+
}
|
|
629
|
+
function tokenRefSourcePath(source, span, path) {
|
|
630
|
+
const outerStart = byteToIndex(source, span.start);
|
|
631
|
+
const outerEnd = byteToIndex(source, span.end);
|
|
632
|
+
const text = source.slice(outerStart, outerEnd);
|
|
633
|
+
const index = text.indexOf(path);
|
|
634
|
+
if (index < 0) return path;
|
|
635
|
+
let end = index + path.length;
|
|
636
|
+
if (text[end] === "/") {
|
|
637
|
+
end += 1;
|
|
638
|
+
while (end < text.length && !["'", '"', "`", ",", ")", " ", "\n", "\r", " "].includes(text[end])) end += 1;
|
|
639
|
+
}
|
|
640
|
+
return text.slice(index, end);
|
|
641
|
+
}
|
|
642
|
+
function reportPrimitiveToken(context, source, config, token, loc, fixRange, replacementPath, sourcePath) {
|
|
643
|
+
if (!shouldReport(token, config)) return;
|
|
644
|
+
const suffix = modifierSuffix(token, sourcePath);
|
|
645
|
+
const suggestions = config.suggestSemanticTokens(token.path).slice(0, MAX_SUGGESTIONS);
|
|
646
|
+
const descriptor = {
|
|
647
|
+
messageId: "primitive",
|
|
648
|
+
data: { category: token.category, token: token.categoryPath },
|
|
649
|
+
loc: toEslintLoc(loc)
|
|
650
|
+
};
|
|
651
|
+
if (source && fixRange && suggestions.length > 0) {
|
|
652
|
+
descriptor.suggest = suggestions.map((suggestion) => {
|
|
653
|
+
const replacement = replacementPath(suggestion, suffix);
|
|
654
|
+
return {
|
|
655
|
+
desc: `Use the semantic token "${replacement}"`,
|
|
656
|
+
fix: (fixer) => fixer.replaceTextRange(fixRange, replacementForRange(source, fixRange, replacement))
|
|
657
|
+
};
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
context.report(descriptor);
|
|
661
|
+
}
|
|
662
|
+
function reportStyleEntries(context, inspection, config, source) {
|
|
663
|
+
for (const entry of inspection.styleEntries) {
|
|
664
|
+
if (entry.kind !== "utility") continue;
|
|
665
|
+
for (const leaf of entry.valueSpans ?? []) {
|
|
666
|
+
if (!leaf.token) continue;
|
|
667
|
+
const fixRange = source ? [byteToIndex(source, leaf.span.start), byteToIndex(source, leaf.span.end)] : void 0;
|
|
668
|
+
reportPrimitiveToken(context, source, config, leaf.token, entry.range, fixRange, (suggestion, suffix) => {
|
|
669
|
+
return `${suggestion.token}${suffix}`;
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
function reportTokenRefs(context, inspection, config, source) {
|
|
675
|
+
for (const tokenRef of inspection.tokenRefs) {
|
|
676
|
+
if (!tokenRef.resolved || !tokenRef.token) continue;
|
|
677
|
+
const sourcePath = source ? tokenRefSourcePath(source, tokenRef.span, tokenRef.path) : tokenRef.path;
|
|
678
|
+
const fixRange = source ? tokenRefFixRange(source, tokenRef.span, sourcePath) : void 0;
|
|
679
|
+
reportPrimitiveToken(
|
|
680
|
+
context,
|
|
681
|
+
source,
|
|
682
|
+
config,
|
|
683
|
+
tokenRef.token,
|
|
684
|
+
tokenRef.range,
|
|
685
|
+
fixRange,
|
|
686
|
+
(suggestion, suffix) => `${tokenRef.token?.category}.${suggestion.token}${suffix}`,
|
|
687
|
+
sourcePath
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
function reportPrimitiveTokenViolations(context, inspection, config) {
|
|
692
|
+
const source = getSourceText(context);
|
|
693
|
+
reportStyleEntries(context, inspection, config, source);
|
|
694
|
+
reportTokenRefs(context, inspection, config, source);
|
|
695
|
+
}
|
|
696
|
+
function createNoPrimitiveTokenRule(options) {
|
|
697
|
+
return {
|
|
698
|
+
meta: {
|
|
699
|
+
type: "suggestion",
|
|
700
|
+
docs: { description: "Prefer semantic tokens over primitive tokens when semantic tokens exist for a category." },
|
|
701
|
+
schema: [
|
|
702
|
+
{
|
|
703
|
+
type: "object",
|
|
704
|
+
properties: {
|
|
705
|
+
categories: { type: "array", items: { type: "string" }, uniqueItems: true },
|
|
706
|
+
allow: { type: "array", items: { type: "string" }, uniqueItems: true }
|
|
707
|
+
},
|
|
708
|
+
additionalProperties: false
|
|
709
|
+
}
|
|
710
|
+
],
|
|
711
|
+
messages: {
|
|
712
|
+
primitive: 'Use a semantic {{category}} token instead of the primitive token "{{token}}".'
|
|
713
|
+
},
|
|
714
|
+
hasSuggestions: true
|
|
715
|
+
},
|
|
716
|
+
create(context) {
|
|
717
|
+
const configured = context.options?.[0];
|
|
718
|
+
const categories = configured?.categories ? new Set(configured.categories) : void 0;
|
|
719
|
+
const allow = new Set(configured?.allow ?? []);
|
|
720
|
+
return {
|
|
721
|
+
Program() {
|
|
722
|
+
const inspection = options.inspect(context);
|
|
723
|
+
if (!inspection) return;
|
|
724
|
+
reportPrimitiveTokenViolations(context, inspection, { ...options, categories, allow });
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
|
|
561
731
|
// src/rules/no-margin-properties.ts
|
|
562
732
|
var noMarginPropertiesRuleName = "no-margin-properties";
|
|
563
733
|
var MESSAGE4 = "Avoid margin properties; prefer `gap` or a layout pattern for spacing.";
|
|
@@ -947,10 +1117,13 @@ function createPreferTextStyleRule(options) {
|
|
|
947
1117
|
};
|
|
948
1118
|
}
|
|
949
1119
|
|
|
1120
|
+
// src/plugin.ts
|
|
1121
|
+
import { SpecIndex } from "@pandacss/compiler/tooling";
|
|
1122
|
+
|
|
950
1123
|
// package.json
|
|
951
1124
|
var package_default = {
|
|
952
1125
|
name: "@pandacss/eslint-plugin",
|
|
953
|
-
version: "2.0.0
|
|
1126
|
+
version: "2.0.0",
|
|
954
1127
|
description: "ESLint rules for Panda CSS",
|
|
955
1128
|
keywords: [
|
|
956
1129
|
"eslint",
|
|
@@ -1003,8 +1176,8 @@ var package_default = {
|
|
|
1003
1176
|
"@pandacss/config": "workspace:*"
|
|
1004
1177
|
},
|
|
1005
1178
|
devDependencies: {
|
|
1006
|
-
"@typescript-eslint/parser": "8.
|
|
1007
|
-
eslint: "9.39.
|
|
1179
|
+
"@typescript-eslint/parser": "8.69.0",
|
|
1180
|
+
eslint: "9.39.5"
|
|
1008
1181
|
},
|
|
1009
1182
|
peerDependencies: {
|
|
1010
1183
|
eslint: ">=9"
|
|
@@ -1025,17 +1198,6 @@ async function loadPandaProject(options = {}) {
|
|
|
1025
1198
|
});
|
|
1026
1199
|
return { linter, project };
|
|
1027
1200
|
}
|
|
1028
|
-
function tokenCategoryByProperty(spec) {
|
|
1029
|
-
const map = /* @__PURE__ */ new Map();
|
|
1030
|
-
for (const [name, property] of Object.entries(spec.utilities.properties)) {
|
|
1031
|
-
if (property.tokenCategory) map.set(name, property.tokenCategory);
|
|
1032
|
-
}
|
|
1033
|
-
for (const [shorthand, canonical] of Object.entries(spec.utilities.shorthands)) {
|
|
1034
|
-
const category = map.get(canonical);
|
|
1035
|
-
if (category) map.set(shorthand, category);
|
|
1036
|
-
}
|
|
1037
|
-
return map;
|
|
1038
|
-
}
|
|
1039
1201
|
var RAW_VALUE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
1040
1202
|
"inherit",
|
|
1041
1203
|
"initial",
|
|
@@ -1081,10 +1243,11 @@ function patternDeprecations(spec) {
|
|
|
1081
1243
|
}
|
|
1082
1244
|
function bindRules(linter, project) {
|
|
1083
1245
|
const spec = project.compiler.spec();
|
|
1084
|
-
const
|
|
1085
|
-
const categoryOf = (prop) =>
|
|
1246
|
+
const specIndex = new SpecIndex(spec);
|
|
1247
|
+
const categoryOf = (prop) => specIndex.resolveTokenCategoryForProperty(prop);
|
|
1086
1248
|
const isHardcodedValue = hardcodedValueClassifier(project.compiler);
|
|
1087
1249
|
const suggest = (prop, value) => project.compiler.suggestTokens(prop, value);
|
|
1250
|
+
const suggestSemanticTokens = (path) => project.compiler.suggestSemanticTokens(path);
|
|
1088
1251
|
const inspect = (context) => linter.inspectProject(project, getContextFilename(context), getContextSource(context));
|
|
1089
1252
|
const rules = {
|
|
1090
1253
|
[extractionDiagnosticsRuleName]: createExtractionDiagnosticsRule({ inspect }),
|
|
@@ -1104,8 +1267,10 @@ function bindRules(linter, project) {
|
|
|
1104
1267
|
[noDebugRuleName]: createNoDebugRule({ inspect }),
|
|
1105
1268
|
// `recommended` scopes prefer-token to colors (the old `no-hardcoded-color`).
|
|
1106
1269
|
[preferTokenRuleName]: createPreferTokenRule({ inspect, categoryOf, isHardcodedValue, suggest }),
|
|
1270
|
+
[noPrimitiveTokenRuleName]: createNoPrimitiveTokenRule({ inspect, suggestSemanticTokens }),
|
|
1107
1271
|
// Opt-in style/enforcement rules (not in `recommended`).
|
|
1108
1272
|
[noImportantRuleName]: createNoImportantRule({ inspect }),
|
|
1273
|
+
[noDescendantSelectorsRuleName]: createNoDescendantSelectorsRule({ inspect }),
|
|
1109
1274
|
[noMarginPropertiesRuleName]: createNoMarginPropertiesRule({ inspect }),
|
|
1110
1275
|
[noPhysicalPropertiesRuleName]: createNoPhysicalPropertiesRule({ inspect }),
|
|
1111
1276
|
[noShorthandLonghandMixRuleName]: createNoShorthandLonghandMixRule({ inspect }),
|
|
@@ -1136,7 +1301,7 @@ export {
|
|
|
1136
1301
|
reportDiagnostics,
|
|
1137
1302
|
noInvalidTokenPathsRuleName,
|
|
1138
1303
|
createNoInvalidTokenPathsRule,
|
|
1139
|
-
|
|
1304
|
+
FileInspector,
|
|
1140
1305
|
sourceCacheKey,
|
|
1141
1306
|
ProjectCache,
|
|
1142
1307
|
projectCacheKey,
|
|
@@ -1150,10 +1315,15 @@ export {
|
|
|
1150
1315
|
createNoDebugRule,
|
|
1151
1316
|
noDeprecatedRuleName,
|
|
1152
1317
|
createNoDeprecatedRule,
|
|
1318
|
+
noDescendantSelectorsRuleName,
|
|
1319
|
+
createNoDescendantSelectorsRule,
|
|
1153
1320
|
noImportantRuleName,
|
|
1154
1321
|
createNoImportantRule,
|
|
1155
1322
|
noInvalidNestingRuleName,
|
|
1156
1323
|
createNoInvalidNestingRule,
|
|
1324
|
+
noPrimitiveTokenRuleName,
|
|
1325
|
+
reportPrimitiveTokenViolations,
|
|
1326
|
+
createNoPrimitiveTokenRule,
|
|
1157
1327
|
noMarginPropertiesRuleName,
|
|
1158
1328
|
createNoMarginPropertiesRule,
|
|
1159
1329
|
noPhysicalPropertiesRuleName,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { L as Linter,
|
|
2
|
-
export {
|
|
1
|
+
import { L as Linter, R as RuleModuleLike, I as Inspect, a as RuleContextWithReport } from './shared-BdjJwg93.js';
|
|
2
|
+
export { c as LintInspection, b as LintRuleContextLike, d as LinterOptions, h as PandaLintSettings, f as ProjectCache, P as ProjectCacheOptions, l as ReportDescriptor, i as RuleContextLike, j as RuleFixer, S as SourceCodeLike, k as SuggestionDescriptor, n as byteToIndex, g as getContextFilename, e as getContextSource, m as getSourceText, p as projectCacheKey, r as resolvePandaSettings, t as toEslintLoc } from './shared-BdjJwg93.js';
|
|
3
|
+
import { Project } from '@pandacss/compiler/tooling';
|
|
4
|
+
export { FileInspectionCacheEntry as InspectionCacheEntry, FileInspector as Inspector, sourceCacheKey } from '@pandacss/compiler/tooling';
|
|
3
5
|
import { Span, Diagnostic, Deprecation, TokenSuggestion, FileInspectionResult } from '@pandacss/compiler';
|
|
4
|
-
import '@pandacss/config';
|
|
5
6
|
|
|
6
7
|
interface RangeLike {
|
|
7
8
|
span: Span;
|
|
@@ -27,7 +28,7 @@ interface PandaPluginOptions {
|
|
|
27
28
|
}
|
|
28
29
|
interface PandaProject {
|
|
29
30
|
linter: Linter;
|
|
30
|
-
project:
|
|
31
|
+
project: Project;
|
|
31
32
|
}
|
|
32
33
|
interface PandaPlugin {
|
|
33
34
|
rules: Record<string, RuleModuleLike>;
|
|
@@ -35,7 +36,7 @@ interface PandaPlugin {
|
|
|
35
36
|
/** Preload one Panda project (config load + compiler) for a `(cwd, configPath)`. */
|
|
36
37
|
declare function loadPandaProject(options?: PandaPluginOptions): Promise<PandaProject>;
|
|
37
38
|
/** Bind every rule to an already-loaded project so rule visitors stay synchronous. */
|
|
38
|
-
declare function bindRules(linter: Linter, project:
|
|
39
|
+
declare function bindRules(linter: Linter, project: Project): Record<string, RuleModuleLike>;
|
|
39
40
|
declare function createPandaPlugin(options?: PandaPluginOptions): Promise<PandaPlugin>;
|
|
40
41
|
|
|
41
42
|
/** Flat-config plugin key; rule ids are `@pandacss/<rule>`. */
|
|
@@ -131,6 +132,11 @@ interface NoDeprecatedRuleOptions {
|
|
|
131
132
|
}
|
|
132
133
|
declare function createNoDeprecatedRule(options: NoDeprecatedRuleOptions): RuleModuleLike;
|
|
133
134
|
|
|
135
|
+
declare const noDescendantSelectorsRuleName = "no-descendant-selectors";
|
|
136
|
+
declare function createNoDescendantSelectorsRule(options: {
|
|
137
|
+
inspect: Inspect;
|
|
138
|
+
}): RuleModuleLike;
|
|
139
|
+
|
|
134
140
|
declare const noImportantRuleName = "no-important";
|
|
135
141
|
declare function createNoImportantRule(options: {
|
|
136
142
|
inspect: Inspect;
|
|
@@ -141,6 +147,20 @@ declare function createNoInvalidNestingRule(options: {
|
|
|
141
147
|
inspect: Inspect;
|
|
142
148
|
}): RuleModuleLike;
|
|
143
149
|
|
|
150
|
+
declare const noPrimitiveTokenRuleName = "no-primitive-token";
|
|
151
|
+
interface NoPrimitiveTokenRuleOptions {
|
|
152
|
+
inspect: Inspect;
|
|
153
|
+
/** Semantic tokens that carry the same value as a full token path. */
|
|
154
|
+
suggestSemanticTokens: (path: string) => TokenSuggestion[];
|
|
155
|
+
}
|
|
156
|
+
interface ReportConfig$1 extends NoPrimitiveTokenRuleOptions {
|
|
157
|
+
/** Categories to enforce; `undefined` means every category with semantic tokens. */
|
|
158
|
+
categories?: ReadonlySet<string>;
|
|
159
|
+
allow: ReadonlySet<string>;
|
|
160
|
+
}
|
|
161
|
+
declare function reportPrimitiveTokenViolations(context: RuleContextWithReport, inspection: FileInspectionResult, config: ReportConfig$1): void;
|
|
162
|
+
declare function createNoPrimitiveTokenRule(options: NoPrimitiveTokenRuleOptions): RuleModuleLike;
|
|
163
|
+
|
|
144
164
|
declare const noMarginPropertiesRuleName = "no-margin-properties";
|
|
145
165
|
declare function createNoMarginPropertiesRule(options: {
|
|
146
166
|
inspect: Inspect;
|
|
@@ -196,4 +216,4 @@ declare const _default: {
|
|
|
196
216
|
};
|
|
197
217
|
};
|
|
198
218
|
|
|
199
|
-
export { type ConsistentPropertyStyleRuleOptions, type DeprecationKind, type ExtractionDiagnosticsRuleOptions, type FileNotIncludedRuleOptions, Inspect, Linter, type NoDebugRuleOptions, type NoDeprecatedRuleOptions, PLUGIN_NAMESPACE, type PandaFlatConfig, type PandaPlugin, type PandaPluginOptions, type PandaProject, type PreferTokenRuleOptions,
|
|
219
|
+
export { type ConsistentPropertyStyleRuleOptions, type DeprecationKind, type ExtractionDiagnosticsRuleOptions, type FileNotIncludedRuleOptions, Inspect, Linter, type NoDebugRuleOptions, type NoDeprecatedRuleOptions, type NoPrimitiveTokenRuleOptions, PLUGIN_NAMESPACE, type PandaFlatConfig, type PandaPlugin, type PandaPluginOptions, type PandaProject, type PreferTokenRuleOptions, RangeIndex, type RangeLike, type RecommendedOptions, RuleContextWithReport, RuleModuleLike, type SuggestTokens, type TokenRuleOptions, bindRules, collectStrings, configs, consistentPropertyStyleRuleName, createConsistentPropertyStyleRule, createExtractionDiagnosticsRule, createFileNotIncludedRule, createNoDebugRule, createNoDeprecatedRule, createNoDescendantSelectorsRule, createNoImportantRule, createNoInvalidNestingRule, createNoInvalidTokenPathsRule, createNoMarginPropertiesRule, createNoPhysicalPropertiesRule, createNoPrimitiveTokenRule, createNoShorthandLonghandMixRule, createPandaPlugin, createPreferTextStyleRule, createPreferTokenRule, _default as default, extractionDiagnosticsRuleName, fileNotIncludedRuleName, loadPandaProject, noDebugRuleName, noDeprecatedRuleName, noDescendantSelectorsRuleName, noImportantRuleName, noInvalidNestingRuleName, noInvalidTokenPathsRuleName, noMarginPropertiesRuleName, noPhysicalPropertiesRuleName, noPrimitiveTokenRuleName, noShorthandLonghandMixRuleName, pluginMeta, preferTextStyleRuleName, preferTokenRuleName, recommended, reportDiagnostics, reportPrimitiveTokenViolations, reportTokenViolations };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
FileInspector,
|
|
3
3
|
Linter,
|
|
4
4
|
ProjectCache,
|
|
5
5
|
bindRules,
|
|
@@ -11,11 +11,13 @@ import {
|
|
|
11
11
|
createFileNotIncludedRule,
|
|
12
12
|
createNoDebugRule,
|
|
13
13
|
createNoDeprecatedRule,
|
|
14
|
+
createNoDescendantSelectorsRule,
|
|
14
15
|
createNoImportantRule,
|
|
15
16
|
createNoInvalidNestingRule,
|
|
16
17
|
createNoInvalidTokenPathsRule,
|
|
17
18
|
createNoMarginPropertiesRule,
|
|
18
19
|
createNoPhysicalPropertiesRule,
|
|
20
|
+
createNoPrimitiveTokenRule,
|
|
19
21
|
createNoShorthandLonghandMixRule,
|
|
20
22
|
createPandaPlugin,
|
|
21
23
|
createPreferTextStyleRule,
|
|
@@ -28,22 +30,25 @@ import {
|
|
|
28
30
|
loadPandaProject,
|
|
29
31
|
noDebugRuleName,
|
|
30
32
|
noDeprecatedRuleName,
|
|
33
|
+
noDescendantSelectorsRuleName,
|
|
31
34
|
noImportantRuleName,
|
|
32
35
|
noInvalidNestingRuleName,
|
|
33
36
|
noInvalidTokenPathsRuleName,
|
|
34
37
|
noMarginPropertiesRuleName,
|
|
35
38
|
noPhysicalPropertiesRuleName,
|
|
39
|
+
noPrimitiveTokenRuleName,
|
|
36
40
|
noShorthandLonghandMixRuleName,
|
|
37
41
|
pluginMeta,
|
|
38
42
|
preferTextStyleRuleName,
|
|
39
43
|
preferTokenRuleName,
|
|
40
44
|
projectCacheKey,
|
|
41
45
|
reportDiagnostics,
|
|
46
|
+
reportPrimitiveTokenViolations,
|
|
42
47
|
reportTokenViolations,
|
|
43
48
|
resolvePandaSettings,
|
|
44
49
|
sourceCacheKey,
|
|
45
50
|
toEslintLoc
|
|
46
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-4YDZVIGF.js";
|
|
47
52
|
|
|
48
53
|
// src/core/range-index.ts
|
|
49
54
|
var RangeIndex = class {
|
|
@@ -97,7 +102,7 @@ var configs = { recommended };
|
|
|
97
102
|
// src/index.ts
|
|
98
103
|
var index_default = { meta: pluginMeta, configs };
|
|
99
104
|
export {
|
|
100
|
-
Inspector,
|
|
105
|
+
FileInspector as Inspector,
|
|
101
106
|
Linter,
|
|
102
107
|
PLUGIN_NAMESPACE,
|
|
103
108
|
ProjectCache,
|
|
@@ -112,11 +117,13 @@ export {
|
|
|
112
117
|
createFileNotIncludedRule,
|
|
113
118
|
createNoDebugRule,
|
|
114
119
|
createNoDeprecatedRule,
|
|
120
|
+
createNoDescendantSelectorsRule,
|
|
115
121
|
createNoImportantRule,
|
|
116
122
|
createNoInvalidNestingRule,
|
|
117
123
|
createNoInvalidTokenPathsRule,
|
|
118
124
|
createNoMarginPropertiesRule,
|
|
119
125
|
createNoPhysicalPropertiesRule,
|
|
126
|
+
createNoPrimitiveTokenRule,
|
|
120
127
|
createNoShorthandLonghandMixRule,
|
|
121
128
|
createPandaPlugin,
|
|
122
129
|
createPreferTextStyleRule,
|
|
@@ -130,11 +137,13 @@ export {
|
|
|
130
137
|
loadPandaProject,
|
|
131
138
|
noDebugRuleName,
|
|
132
139
|
noDeprecatedRuleName,
|
|
140
|
+
noDescendantSelectorsRuleName,
|
|
133
141
|
noImportantRuleName,
|
|
134
142
|
noInvalidNestingRuleName,
|
|
135
143
|
noInvalidTokenPathsRuleName,
|
|
136
144
|
noMarginPropertiesRuleName,
|
|
137
145
|
noPhysicalPropertiesRuleName,
|
|
146
|
+
noPrimitiveTokenRuleName,
|
|
138
147
|
noShorthandLonghandMixRuleName,
|
|
139
148
|
pluginMeta,
|
|
140
149
|
preferTextStyleRuleName,
|
|
@@ -142,6 +151,7 @@ export {
|
|
|
142
151
|
projectCacheKey,
|
|
143
152
|
recommended,
|
|
144
153
|
reportDiagnostics,
|
|
154
|
+
reportPrimitiveTokenViolations,
|
|
145
155
|
reportTokenViolations,
|
|
146
156
|
resolvePandaSettings,
|
|
147
157
|
sourceCacheKey,
|
package/dist/oxlint.d.ts
CHANGED
package/dist/oxlint.js
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
interface InspectionCacheEntry {
|
|
5
|
-
sourceKey: string;
|
|
6
|
-
result: FileInspectionResult;
|
|
7
|
-
}
|
|
8
|
-
declare class Inspector {
|
|
9
|
-
#private;
|
|
10
|
-
inspect(compiler: Compiler, path: string, source: string): FileInspectionResult;
|
|
11
|
-
clear(compiler?: Compiler): void;
|
|
12
|
-
}
|
|
13
|
-
declare function sourceCacheKey(source: string): string;
|
|
1
|
+
import { FileInspectionResult, SourceRange } from '@pandacss/compiler';
|
|
2
|
+
import { Project, FileInspector } from '@pandacss/compiler/tooling';
|
|
14
3
|
|
|
15
4
|
interface PandaLintSettings {
|
|
16
5
|
configPath?: string;
|
|
@@ -23,19 +12,13 @@ interface RuleContextLike {
|
|
|
23
12
|
}
|
|
24
13
|
declare function resolvePandaSettings(context: RuleContextLike): PandaLintSettings;
|
|
25
14
|
|
|
26
|
-
interface ProjectContext {
|
|
27
|
-
compiler: Compiler;
|
|
28
|
-
configPath: string;
|
|
29
|
-
dependencies: string[];
|
|
30
|
-
}
|
|
31
15
|
interface ProjectCacheOptions {
|
|
32
|
-
|
|
33
|
-
createCompiler?: typeof createCompilerFromSnapshot;
|
|
16
|
+
createProject?: (settings: PandaLintSettings) => Promise<Project>;
|
|
34
17
|
}
|
|
35
18
|
declare class ProjectCache {
|
|
36
19
|
#private;
|
|
37
20
|
constructor(options?: ProjectCacheOptions);
|
|
38
|
-
get(settings: PandaLintSettings): Promise<
|
|
21
|
+
get(settings: PandaLintSettings): Promise<Project>;
|
|
39
22
|
clear(): void;
|
|
40
23
|
}
|
|
41
24
|
declare function projectCacheKey(settings: PandaLintSettings): string;
|
|
@@ -53,7 +36,7 @@ interface LintRuleContextLike extends RuleContextLike {
|
|
|
53
36
|
getSourceCode?: () => SourceCodeLike;
|
|
54
37
|
}
|
|
55
38
|
interface LintInspection {
|
|
56
|
-
project:
|
|
39
|
+
project: Project;
|
|
57
40
|
settings: PandaLintSettings;
|
|
58
41
|
path: string;
|
|
59
42
|
source: string;
|
|
@@ -61,14 +44,14 @@ interface LintInspection {
|
|
|
61
44
|
}
|
|
62
45
|
interface LinterOptions {
|
|
63
46
|
projectCache?: ProjectCache;
|
|
64
|
-
inspector?:
|
|
47
|
+
inspector?: FileInspector;
|
|
65
48
|
}
|
|
66
49
|
declare class Linter {
|
|
67
50
|
#private;
|
|
68
51
|
constructor(options?: LinterOptions);
|
|
69
|
-
getProject(context: LintRuleContextLike): Promise<
|
|
52
|
+
getProject(context: LintRuleContextLike): Promise<Project>;
|
|
70
53
|
inspect(context: LintRuleContextLike): Promise<LintInspection>;
|
|
71
|
-
inspectProject(project:
|
|
54
|
+
inspectProject(project: Project, path: string, source: string): FileInspectionResult;
|
|
72
55
|
clear(): void;
|
|
73
56
|
}
|
|
74
57
|
declare function getContextFilename(context: LintRuleContextLike): string;
|
|
@@ -123,4 +106,4 @@ declare function byteToIndex(text: string, byteOffset: number): number;
|
|
|
123
106
|
/** ESLint columns are 0-based; Panda source ranges are 1-based. */
|
|
124
107
|
declare function toEslintLoc(range: SourceRange): ReportDescriptor['loc'];
|
|
125
108
|
|
|
126
|
-
export { type Inspect as I, Linter as L, type
|
|
109
|
+
export { type Inspect as I, Linter as L, type ProjectCacheOptions as P, type RuleModuleLike as R, type SourceCodeLike as S, type RuleContextWithReport as a, type LintRuleContextLike as b, type LintInspection as c, type LinterOptions as d, getContextSource as e, ProjectCache as f, getContextFilename as g, type PandaLintSettings as h, type RuleContextLike as i, type RuleFixer as j, type SuggestionDescriptor as k, type ReportDescriptor as l, getSourceText as m, byteToIndex as n, projectCacheKey as p, resolvePandaSettings as r, toEslintLoc as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pandacss/eslint-plugin",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "ESLint rules for Panda CSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"dist"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@pandacss/compiler": "2.0.0
|
|
46
|
-
"@pandacss/compiler-shared": "2.0.0
|
|
47
|
-
"@pandacss/config": "2.0.0
|
|
45
|
+
"@pandacss/compiler": "2.0.0",
|
|
46
|
+
"@pandacss/compiler-shared": "2.0.0",
|
|
47
|
+
"@pandacss/config": "2.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@typescript-eslint/parser": "8.
|
|
51
|
-
"eslint": "9.39.
|
|
50
|
+
"@typescript-eslint/parser": "8.69.0",
|
|
51
|
+
"eslint": "9.39.5"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"eslint": ">=9"
|