@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 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
- var Inspector = class {
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 { createCompilerFromSnapshot } from "@pandacss/compiler";
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
- #load;
215
- #createCompiler;
183
+ #createProject;
216
184
  constructor(options = {}) {
217
- this.#load = options.load ?? ((settings) => loadConfig({
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.#load(settings).then((result) => ({
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 Inspector();
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-beta.8",
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.58.2",
1007
- eslint: "9.39.1"
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 categoryByProperty = tokenCategoryByProperty(spec);
1085
- const categoryOf = (prop) => categoryByProperty.get(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
- Inspector,
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, P as ProjectContext, R as RuleModuleLike, I as Inspect, a as RuleContextWithReport } from './shared-B-c4H6nv.js';
2
- export { b as InspectionCacheEntry, c as Inspector, e as LintInspection, d as LintRuleContextLike, f as LinterOptions, k as PandaLintSettings, j as ProjectCache, i as ProjectCacheOptions, o as ReportDescriptor, l as RuleContextLike, m as RuleFixer, S as SourceCodeLike, n as SuggestionDescriptor, t as byteToIndex, g as getContextFilename, h as getContextSource, q as getSourceText, p as projectCacheKey, r as resolvePandaSettings, s as sourceCacheKey, u as toEslintLoc } from './shared-B-c4H6nv.js';
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: ProjectContext;
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: ProjectContext): Record<string, RuleModuleLike>;
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, ProjectContext, RangeIndex, type RangeLike, type RecommendedOptions, RuleContextWithReport, RuleModuleLike, type SuggestTokens, type TokenRuleOptions, bindRules, collectStrings, configs, consistentPropertyStyleRuleName, createConsistentPropertyStyleRule, createExtractionDiagnosticsRule, createFileNotIncludedRule, createNoDebugRule, createNoDeprecatedRule, createNoImportantRule, createNoInvalidNestingRule, createNoInvalidTokenPathsRule, createNoMarginPropertiesRule, createNoPhysicalPropertiesRule, createNoShorthandLonghandMixRule, createPandaPlugin, createPreferTextStyleRule, createPreferTokenRule, _default as default, extractionDiagnosticsRuleName, fileNotIncludedRuleName, loadPandaProject, noDebugRuleName, noDeprecatedRuleName, noImportantRuleName, noInvalidNestingRuleName, noInvalidTokenPathsRuleName, noMarginPropertiesRuleName, noPhysicalPropertiesRuleName, noShorthandLonghandMixRuleName, pluginMeta, preferTextStyleRuleName, preferTokenRuleName, recommended, reportDiagnostics, reportTokenViolations };
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
- Inspector,
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-3ZHMGIZ2.js";
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
@@ -1,6 +1,6 @@
1
- import { R as RuleModuleLike } from './shared-B-c4H6nv.js';
1
+ import { R as RuleModuleLike } from './shared-BdjJwg93.js';
2
2
  import '@pandacss/compiler';
3
- import '@pandacss/config';
3
+ import '@pandacss/compiler/tooling';
4
4
 
5
5
  declare const _default: {
6
6
  meta: {
package/dist/oxlint.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createPandaPlugin
3
- } from "./chunk-3ZHMGIZ2.js";
3
+ } from "./chunk-4YDZVIGF.js";
4
4
 
5
5
  // src/oxlint.ts
6
6
  var configPath = process.env.PANDA_CONFIG_PATH;
@@ -1,16 +1,5 @@
1
- import { Compiler, FileInspectionResult, createCompilerFromSnapshot, SourceRange } from '@pandacss/compiler';
2
- import { LoadConfigResult } from '@pandacss/config';
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
- load?: (settings: PandaLintSettings) => Promise<LoadConfigResult>;
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<ProjectContext>;
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: ProjectContext;
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?: Inspector;
47
+ inspector?: FileInspector;
65
48
  }
66
49
  declare class Linter {
67
50
  #private;
68
51
  constructor(options?: LinterOptions);
69
- getProject(context: LintRuleContextLike): Promise<ProjectContext>;
52
+ getProject(context: LintRuleContextLike): Promise<Project>;
70
53
  inspect(context: LintRuleContextLike): Promise<LintInspection>;
71
- inspectProject(project: ProjectContext, path: string, source: string): FileInspectionResult;
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 ProjectContext as P, type RuleModuleLike as R, type SourceCodeLike as S, type RuleContextWithReport as a, type InspectionCacheEntry as b, Inspector as c, type LintRuleContextLike as d, type LintInspection as e, type LinterOptions as f, getContextFilename as g, getContextSource as h, type ProjectCacheOptions as i, ProjectCache as j, type PandaLintSettings as k, type RuleContextLike as l, type RuleFixer as m, type SuggestionDescriptor as n, type ReportDescriptor as o, projectCacheKey as p, getSourceText as q, resolvePandaSettings as r, sourceCacheKey as s, byteToIndex as t, toEslintLoc as u };
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-beta.8",
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-beta.8",
46
- "@pandacss/compiler-shared": "2.0.0-beta.8",
47
- "@pandacss/config": "2.0.0-beta.8"
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.58.2",
51
- "eslint": "9.39.1"
50
+ "@typescript-eslint/parser": "8.69.0",
51
+ "eslint": "9.39.5"
52
52
  },
53
53
  "peerDependencies": {
54
54
  "eslint": ">=9"