pasika 0.10.129 → 0.10.131

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.
@@ -121,6 +121,7 @@ declare const nextjsPackageJsonRules: {
121
121
 
122
122
  declare const tailwindRules: {
123
123
  "theme-reset": _eslint_css.CSSRuleDefinition;
124
+ "theme-mode": _eslint_css.CSSRuleDefinition;
124
125
  "color-role-usage": _eslint_css.CSSRuleDefinition;
125
126
  "root-variables": _eslint_css.CSSRuleDefinition;
126
127
  "apply-usage": _eslint_css.CSSRuleDefinition;
@@ -161,6 +162,7 @@ declare const pasikaPlugin: {
161
162
  "lint-setup": _eslint_json.JSONRuleDefinition;
162
163
  "vitest-coverage": _eslint_json.JSONRuleDefinition;
163
164
  "theme-reset": _eslint_css.CSSRuleDefinition;
165
+ "theme-mode": _eslint_css.CSSRuleDefinition;
164
166
  "color-role-usage": _eslint_css.CSSRuleDefinition;
165
167
  "root-variables": _eslint_css.CSSRuleDefinition;
166
168
  "apply-usage": _eslint_css.CSSRuleDefinition;
@@ -2866,6 +2866,16 @@ var rulePairedExamplesRule = {
2866
2866
  node,
2867
2867
  message: `${String(incorrect.length)} Incorrect and ${String(correct.length)} Correct examples`
2868
2868
  });
2869
+ } else {
2870
+ const misplaced = exampleHeadings.find(
2871
+ (heading, index) => !heading.text.startsWith(index % 2 === 0 ? "Incorrect" : "Correct")
2872
+ );
2873
+ if (misplaced) {
2874
+ context.report({
2875
+ node,
2876
+ message: `Rule examples must alternate Incorrect then Correct; found "${misplaced.text}" at line ${String(misplaced.line)}.`
2877
+ });
2878
+ }
2869
2879
  }
2870
2880
  }
2871
2881
  };
@@ -9932,10 +9942,12 @@ var colorRoleUsageRule = {
9932
9942
  };
9933
9943
 
9934
9944
  // eslint/rules/tailwind/css-entry-point.ts
9935
- import { statSync as statSync4 } from "fs";
9945
+ import { existsSync as existsSync9, statSync as statSync4 } from "fs";
9936
9946
  import path67 from "path";
9937
9947
  var APP_STYLES_DIR = path67.join("app", "styles");
9938
9948
  var GLOBAL_STYLESHEET_PATH = path67.join(APP_STYLES_DIR, "globals.css");
9949
+ var FEATURE_STYLESHEET_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*\.css$/u;
9950
+ var FEATURE_STYLESHEET_ERROR = "Only globals.css and <feature>.css matching an existing src/features/<feature>/ directory are allowed in src/app/styles/.";
9939
9951
  var cssEntryPointRule = {
9940
9952
  meta: {
9941
9953
  schema: [],
@@ -10016,6 +10028,13 @@ var cssEntryPointRule = {
10016
10028
  });
10017
10029
  return;
10018
10030
  }
10031
+ const basename = path67.basename(current);
10032
+ const featureName = basename.slice(0, -".css".length);
10033
+ const featureDir = path67.join(sourceRoot, "features", featureName);
10034
+ const isFeatureStylesheet = path67.dirname(current) === path67.join(sourceRoot, APP_STYLES_DIR) && FEATURE_STYLESHEET_NAME.test(basename) && existsSync9(featureDir) && statSync4(featureDir).isDirectory();
10035
+ if (!isFeatureStylesheet) {
10036
+ context.report({ node, message: FEATURE_STYLESHEET_ERROR });
10037
+ }
10019
10038
  if (!directChildren.has(current)) {
10020
10039
  context.report({
10021
10040
  node,
@@ -10070,7 +10089,7 @@ var customUtilityApplyRule = {
10070
10089
  };
10071
10090
 
10072
10091
  // eslint/rules/tailwind/feature-css-placement.ts
10073
- import { existsSync as existsSync9 } from "fs";
10092
+ import { existsSync as existsSync10 } from "fs";
10074
10093
  import path70 from "path";
10075
10094
 
10076
10095
  // eslint/rules/tailwind/css-dependency-graph.ts
@@ -10519,7 +10538,7 @@ var featureCssPlacementRule = {
10519
10538
  if (!relative.startsWith(`${STYLES_DIR}${path70.sep}`)) return {};
10520
10539
  const basename = path70.basename(current);
10521
10540
  const featureName = basename.slice(0, -".css".length);
10522
- const isFeatureFile = path70.dirname(current) === styles && FEATURE_CSS.test(basename) && existsSync9(path70.join(sourceRoot, "features", featureName));
10541
+ const isFeatureFile = path70.dirname(current) === styles && FEATURE_CSS.test(basename) && existsSync10(path70.join(sourceRoot, "features", featureName));
10523
10542
  const read = cachedTextReader();
10524
10543
  const css2 = findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({ path: file, content: read(file) }));
10525
10544
  const modules = findFiles(sourceRoot, MODULE_EXTENSIONS4).map((file) => ({ path: file, content: read(file) }));
@@ -10532,7 +10551,7 @@ var featureCssPlacementRule = {
10532
10551
  const owner = owners.get(symbolId(definition));
10533
10552
  if (!owner) continue;
10534
10553
  const expected = owner === GLOBALS ? GLOBALS : `${owner}.css`;
10535
- if (owner !== GLOBALS && (basename === GLOBALS || !isFeatureFile) && !existsSync9(path70.join(styles, expected))) {
10554
+ if (owner !== GLOBALS && (basename === GLOBALS || !isFeatureFile) && !existsSync10(path70.join(styles, expected))) {
10536
10555
  continue;
10537
10556
  }
10538
10557
  if (basename === expected) continue;
@@ -10552,7 +10571,7 @@ var featureCssPlacementRule = {
10552
10571
  };
10553
10572
 
10554
10573
  // eslint/rules/tailwind/global-stylesheet.ts
10555
- import { existsSync as existsSync10 } from "fs";
10574
+ import { existsSync as existsSync11 } from "fs";
10556
10575
  import path71 from "path";
10557
10576
  var MISSING_REGISTRATION = 'Global stylesheet must register Tailwind with @import "tailwindcss".';
10558
10577
  var MISSING_ENTRYPOINT = "Project CSS must have a canonical global stylesheet at src/app/styles/globals.css.";
@@ -10570,7 +10589,7 @@ var globalStylesheetRule = {
10570
10589
  const entryPoint = path71.normalize(path71.join(sourceRoot, "app", "styles", "globals.css"));
10571
10590
  const current = path71.normalize(path71.resolve(context.filename));
10572
10591
  const isEntryPoint = current === entryPoint;
10573
- const hasEntryPoint = existsSync10(entryPoint);
10592
+ const hasEntryPoint = existsSync11(entryPoint);
10574
10593
  const isFirstStylesheet = !hasEntryPoint && [current, ...findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => path71.normalize(file))].sort()[0] === current;
10575
10594
  if (!isEntryPoint && !isFirstStylesheet) return {};
10576
10595
  return {
@@ -10820,19 +10839,16 @@ var rootVariablesRule = {
10820
10839
  return;
10821
10840
  }
10822
10841
  const isConditional = conditional || currentNode.type === "Atrule" && currentNode.name !== "layer";
10823
- if (currentNode.type === "Rule") {
10824
- const selector = context.sourceCode.getText(currentNode.prelude).trim();
10825
- const isDefaultRoot = selector === ":root" && !isConditional;
10826
- if (!isDefaultRoot) {
10827
- for (const declaration of blockChildren2(currentNode)) {
10828
- if (declaration.type !== "Declaration") continue;
10829
- if (mirroredTokens.has(declaration.property)) continue;
10830
- if (!names.has(declaration.property) && !declaration.property.startsWith("--color-")) continue;
10831
- context.report({
10832
- node: declaration,
10833
- message: `Tailwind token "${declaration.property}" must not be redeclared outside @theme; map it through @theme inline to its same-named runtime variable instead.`
10834
- });
10835
- }
10842
+ const isDefaultRoot = currentNode.type === "Rule" && context.sourceCode.getText(currentNode.prelude).trim() === ":root" && !isConditional;
10843
+ if (currentNode.type === "Rule" && !isDefaultRoot || currentNode.type === "Atrule" && currentNode.name === "variant") {
10844
+ for (const declaration of blockChildren2(currentNode)) {
10845
+ if (declaration.type !== "Declaration") continue;
10846
+ if (mirroredTokens.has(declaration.property)) continue;
10847
+ if (!names.has(declaration.property) && !declaration.property.startsWith("--color-")) continue;
10848
+ context.report({
10849
+ node: declaration,
10850
+ message: `Tailwind token "${declaration.property}" must not be redeclared outside @theme; map it through @theme inline to its same-named runtime variable instead.`
10851
+ });
10836
10852
  }
10837
10853
  }
10838
10854
  const children = currentNode.type === "StyleSheet" ? currentNode.children : blockChildren2(currentNode);
@@ -10860,7 +10876,27 @@ var rootVariablesRule = {
10860
10876
 
10861
10877
  // eslint/rules/tailwind/stylesheet-ordering.ts
10862
10878
  import path73 from "path";
10879
+ import { generate as generate4 } from "@eslint/css-tree";
10863
10880
  var SECTION_ORDER = ["imports", "custom-variant", "root", "theme", "utility", "base styles", "keyframes"];
10881
+ var LATE_RESET_ERROR = "The global --*: initial theme reset must precede feature stylesheet imports, or it will erase their theme tokens.";
10882
+ function themeBody(node, source) {
10883
+ if (node.type !== "Atrule" || node.name !== "theme" || !node.loc) return void 0;
10884
+ const raw = source.slice(node.loc.start.offset, node.loc.end.offset);
10885
+ const start = raw.indexOf("{");
10886
+ const end = raw.lastIndexOf("}");
10887
+ if (start < 0 || end <= start) return void 0;
10888
+ return raw.slice(start + 1, end).replace(/\/\*[\s\S]*?\*\//gu, "").trim();
10889
+ }
10890
+ function containsThemeReset(body) {
10891
+ return body !== void 0 && /(?:^|[;{])\s*--\*\s*:\s*initial\s*(?:;|$)/u.test(body);
10892
+ }
10893
+ function isStandaloneThemeReset(body) {
10894
+ return body !== void 0 && /^--\*\s*:\s*initial\s*;?$/u.test(body);
10895
+ }
10896
+ function isTailwindImport(node) {
10897
+ if (node.type !== "Atrule" || node.name !== "import" || !node.prelude) return false;
10898
+ return /^["']tailwindcss["'](?:\s|$)/u.test(generate4(node.prelude).trim());
10899
+ }
10864
10900
  function scopesCustomProperties(node) {
10865
10901
  if (node.type === "Declaration") return node.property.startsWith("--");
10866
10902
  if (node.type === "Atrule" && !["media", "supports", "container"].includes(node.name)) return false;
@@ -10883,9 +10919,24 @@ var stylesheetOrderingRule = {
10883
10919
  "StyleSheet:exit"(node) {
10884
10920
  const sections = [];
10885
10921
  let index = 0;
10922
+ let sawTailwindImport = false;
10923
+ let sawFeatureImport = false;
10924
+ let sawNonImport = false;
10925
+ let sawEarlyReset = false;
10886
10926
  for (const child of node.children) {
10927
+ const body = themeBody(child, context.sourceCode.text);
10928
+ let isEarlyReset = false;
10929
+ if (containsThemeReset(body) && sawFeatureImport) {
10930
+ context.report({ node: child, message: LATE_RESET_ERROR });
10931
+ return;
10932
+ }
10887
10933
  if (child.type === "Atrule" && child.name === "import") {
10888
10934
  sections.push({ name: "imports", at: index });
10935
+ if (isTailwindImport(child)) sawTailwindImport = true;
10936
+ else sawFeatureImport = true;
10937
+ } else if (isStandaloneThemeReset(body) && sawTailwindImport && !sawFeatureImport && !sawNonImport && !sawEarlyReset) {
10938
+ sawEarlyReset = true;
10939
+ isEarlyReset = true;
10889
10940
  } else if (child.type === "Atrule" && child.name === "custom-variant") {
10890
10941
  sections.push({ name: "custom-variant", at: index });
10891
10942
  } else if (child.type === "Atrule" && child.name === "theme") {
@@ -10903,6 +10954,9 @@ var stylesheetOrderingRule = {
10903
10954
  } else if (child.type === "Atrule" && scopesCustomProperties(child)) {
10904
10955
  sections.push({ name: "root", at: index });
10905
10956
  }
10957
+ if (child.type !== "Comment" && !(child.type === "Atrule" && child.name === "import") && !isEarlyReset) {
10958
+ sawNonImport = true;
10959
+ }
10906
10960
  index += 1;
10907
10961
  }
10908
10962
  const firstAt = /* @__PURE__ */ new Map();
@@ -10943,14 +10997,135 @@ var stylesheetOrderingRule = {
10943
10997
  }
10944
10998
  };
10945
10999
 
10946
- // eslint/rules/tailwind/theme-reset.ts
10947
- import { existsSync as existsSync11 } from "fs";
11000
+ // eslint/rules/tailwind/theme-mode.ts
10948
11001
  import path74 from "path";
10949
- import { generate as generate4, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
11002
+ import { generate as generate5 } from "@eslint/css-tree";
11003
+ var MODE_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
11004
+ var MODE_REFERENCE = /(?:^|[^a-z0-9-])(?<name>[a-z][a-z0-9]*(?:-[a-z0-9]+)*):(?=[a-z[(])/gu;
11005
+ var MODE_ATTRIBUTE = /data-theme\s*=\s*["'](?<name>[a-z][a-z0-9]*(?:-[a-z0-9]+)*)["']/gu;
11006
+ var CUSTOM_REGISTRATION = /@custom-variant\s+(?<name>[a-z][a-z0-9-]*)\b(?<selector>[^;]*);/gu;
11007
+ var MODE_SELECTOR = /\[\s*data-theme\s*=\s*["']?(?<mode>[a-z][a-z0-9-]*)["']?\s*\]/u;
11008
+ var SELECTOR_OVERRIDE = "Use a data-theme @custom-variant for mode-specific styles; direct [data-theme] selectors are not allowed.";
11009
+ var CLASS_OVERRIDE = "Use the data-theme @custom-variant instead of a .dark CSS selector.";
11010
+ var SYSTEM_OVERRIDE = "Use data-theme with @custom-variant for mode styling; resolve system preferences in application code, not a prefers-color-scheme CSS media query.";
11011
+ var MODE_LOCATION = "Declare appearance-mode @custom-variant definitions in globals.css only.";
11012
+ var MISSING_CSS_VARIANT = (name) => `CSS @variant "${name}" requires a matching @custom-variant declaration in globals.css.`;
11013
+ function variantName(prelude) {
11014
+ return /^(?<name>[a-z][a-z0-9-]*)\b/u.exec(prelude.trim())?.groups?.name;
11015
+ }
11016
+ function isModeVariant(name, prelude) {
11017
+ return name === "dark" || name.startsWith("theme-") || /\[\s*data-theme\b/u.test(prelude);
11018
+ }
11019
+ function canonicalModePrelude(name, source) {
11020
+ if (!MODE_NAME.test(name)) return false;
11021
+ const normalized = source.replace(/\/\*[\s\S]*?\*\//gu, "").replace(/["']/gu, "").replace(/\s+/gu, "");
11022
+ return normalized === `${name}(&:where([data-theme=${name}],[data-theme=${name}]*))`;
11023
+ }
11024
+ function registeredModes(source) {
11025
+ const result = /* @__PURE__ */ new Set();
11026
+ for (const match of source.replace(/\/\*[\s\S]*?\*\//gu, "").matchAll(CUSTOM_REGISTRATION)) {
11027
+ const name = match.groups?.name;
11028
+ if (name && isModeVariant(name, `${name}${match.groups?.selector ?? ""}`)) result.add(name);
11029
+ }
11030
+ return result;
11031
+ }
11032
+ var themeModeRule = {
11033
+ meta: {
11034
+ schema: [],
11035
+ type: "problem",
11036
+ docs: { description: "Require a single data-theme/@custom-variant strategy for appearance modes." }
11037
+ },
11038
+ create(context) {
11039
+ const sourceRoot = sourceRootOf(context);
11040
+ const current = path74.normalize(path74.resolve(context.filename));
11041
+ const globalFile = path74.normalize(path74.join(sourceRoot, "app", "styles", "globals.css"));
11042
+ if (path74.dirname(current) !== path74.dirname(globalFile)) return {};
11043
+ const read = cachedTextReader();
11044
+ return {
11045
+ "StyleSheet:exit"(node) {
11046
+ const registered = /* @__PURE__ */ new Set();
11047
+ for (const variant of atrulesNamed(node, "custom-variant")) {
11048
+ if (variant.type !== "Atrule") continue;
11049
+ const prelude = variant.prelude ? generate5(variant.prelude) : "";
11050
+ const name = variantName(prelude);
11051
+ if (!name) continue;
11052
+ if (!isModeVariant(name, prelude)) continue;
11053
+ if (current !== globalFile) {
11054
+ context.report({ node: variant, message: MODE_LOCATION });
11055
+ continue;
11056
+ }
11057
+ if (!canonicalModePrelude(name, prelude)) {
11058
+ const selected = MODE_SELECTOR.exec(prelude)?.groups?.mode;
11059
+ context.report({
11060
+ node: variant,
11061
+ message: selected && selected !== name ? `Theme variant "${name}" must be named "${selected}" to match its data-theme selector.` : `Theme variant "${name}" must match both [data-theme="${name}"] and its descendants with &:where(...).`
11062
+ });
11063
+ }
11064
+ if (registered.has(name)) {
11065
+ context.report({ node: variant, message: `Theme variant "${name}" is already defined in globals.css.` });
11066
+ }
11067
+ registered.add(name);
11068
+ }
11069
+ const modeHints = /* @__PURE__ */ new Set();
11070
+ for (const file of findFiles(sourceRoot, MODULE_EXTENSIONS4)) {
11071
+ for (const match of read(file).matchAll(MODE_ATTRIBUTE)) {
11072
+ if (match.groups?.name) modeHints.add(match.groups.name);
11073
+ }
11074
+ }
11075
+ const globalRegistrations = current === globalFile ? registered : registeredModes(read(globalFile));
11076
+ for (const variant of atrulesNamed(node, "variant")) {
11077
+ if (variant.type !== "Atrule" || !variant.prelude) continue;
11078
+ const name = variantName(generate5(variant.prelude));
11079
+ if (name && (name === "dark" || name.startsWith("theme-") || globalRegistrations.has(name) || modeHints.has(name)) && !globalRegistrations.has(name)) {
11080
+ context.report({ node: variant, message: MISSING_CSS_VARIANT(name) });
11081
+ }
11082
+ }
11083
+ for (const rule of rules(node)) {
11084
+ if (rule.type !== "Rule") continue;
11085
+ const selector = generate5(rule.prelude);
11086
+ if (/\[\s*data-theme(?:\s*[~|^$*]?=|\s*\])/u.test(selector)) {
11087
+ context.report({ node: rule, message: SELECTOR_OVERRIDE });
11088
+ } else if (/\.dark(?![\w-])/u.test(selector)) {
11089
+ context.report({ node: rule, message: CLASS_OVERRIDE });
11090
+ }
11091
+ }
11092
+ walkNodes(node, (child) => {
11093
+ if (child.type !== "Atrule" || child.name !== "media" || !child.prelude) return;
11094
+ if (/\bprefers-color-scheme\b/u.test(generate5(child.prelude))) {
11095
+ context.report({ node: child, message: SYSTEM_OVERRIDE });
11096
+ }
11097
+ });
11098
+ if (current !== globalFile) return;
11099
+ const referenced = /* @__PURE__ */ new Set();
11100
+ for (const file of findFiles(sourceRoot, MODULE_EXTENSIONS4)) {
11101
+ for (const match of read(file).matchAll(MODE_REFERENCE)) {
11102
+ const name = match.groups?.name;
11103
+ if (!name) continue;
11104
+ if (name === "dark" || name.startsWith("theme-") || registered.has(name) || modeHints.has(name)) {
11105
+ referenced.add(name);
11106
+ }
11107
+ }
11108
+ }
11109
+ for (const name of referenced) {
11110
+ if (!registered.has(name)) {
11111
+ context.report({
11112
+ node,
11113
+ message: `Theme utility prefix "${name}:" requires a matching @custom-variant in globals.css; Tailwind's default media-based dark mode is not allowed.`
11114
+ });
11115
+ }
11116
+ }
11117
+ }
11118
+ };
11119
+ }
11120
+ };
11121
+
11122
+ // eslint/rules/tailwind/theme-reset.ts
11123
+ import path75 from "path";
11124
+ import { generate as generate6 } from "@eslint/css-tree";
10950
11125
  function isThemeReset(node) {
10951
11126
  if (!node) return false;
10952
- if (node.type === "Declaration") return node.property === "--*" && generate4(node.value).trim() === "initial";
10953
- if (node.type === "Raw") return /--\*\s*:\s*initial\s*;/u.test(node.value);
11127
+ if (node.type === "Declaration") return node.property === "--*" && generate6(node.value).trim() === "initial";
11128
+ if (node.type === "Raw") return /(?:^|[;{])\s*--\*\s*:\s*initial\s*(?:;|$)/u.test(node.value);
10954
11129
  return false;
10955
11130
  }
10956
11131
  function hasThemeReset(node) {
@@ -10968,46 +11143,39 @@ var themeResetRule = {
10968
11143
  schema: [],
10969
11144
  type: "problem",
10970
11145
  docs: {
10971
- description: "Require the CSS tree to reset Tailwind's default theme with --*: initial."
11146
+ description: "Require the default-theme reset in globals.css, never in feature stylesheets."
10972
11147
  }
10973
11148
  },
10974
11149
  create(context) {
10975
11150
  const sourceRoot = sourceRootOf(context);
10976
- const current = path74.normalize(path74.resolve(context.filename));
10977
- const entryPoint = path74.normalize(path74.join(sourceRoot, "app", "styles", "globals.css"));
10978
- if (current !== entryPoint) return {};
11151
+ const current = path75.normalize(path75.resolve(context.filename));
11152
+ const entryPoint = path75.normalize(path75.join(sourceRoot, "app", "styles", "globals.css"));
11153
+ if (path75.dirname(current) !== path75.dirname(entryPoint)) return {};
10979
11154
  return {
10980
11155
  "StyleSheet:exit"(node) {
10981
- if (hasThemeReset(node)) return;
10982
- const textOf = cachedTextReader();
10983
- const seen = /* @__PURE__ */ new Set([current]);
10984
- const queue = [{ file: current, source: context.sourceCode.text }];
10985
- while (queue.length > 0) {
10986
- const from = queue.shift();
10987
- if (!from) continue;
10988
- for (const specifier of importedSpecifiers(from.source)) {
10989
- const target = resolveSpecifier2(from.file, specifier, sourceRoot);
10990
- if (!target || path74.extname(target) !== ".css") continue;
10991
- const filename = path74.normalize(target);
10992
- if (seen.has(filename) || !existsSync11(filename)) continue;
10993
- seen.add(filename);
10994
- const source = textOf(filename);
10995
- const parsed = toPlainObject2(parse7(source, { parseAtrulePrelude: false }));
10996
- if (parsed.type === "StyleSheet" && hasThemeReset(parsed)) return;
10997
- queue.push({ file: filename, source });
11156
+ const hasReset = hasThemeReset(node);
11157
+ if (current !== entryPoint) {
11158
+ if (hasReset) {
11159
+ context.report({
11160
+ node,
11161
+ message: "Only globals.css may reset Tailwind's default theme with --*: initial; remove it from feature stylesheets."
11162
+ });
10998
11163
  }
11164
+ return;
11165
+ }
11166
+ if (!hasReset) {
11167
+ context.report({
11168
+ node,
11169
+ message: "globals.css must reset Tailwind's default theme with --*: initial inside @theme or @theme inline."
11170
+ });
10999
11171
  }
11000
- context.report({
11001
- node,
11002
- message: "The global stylesheet must reset Tailwind's default theme with --*: initial inside an @theme block."
11003
- });
11004
11172
  }
11005
11173
  };
11006
11174
  }
11007
11175
  };
11008
11176
 
11009
11177
  // eslint/rules/tailwind/unique-css-definition.ts
11010
- import path75 from "path";
11178
+ import path76 from "path";
11011
11179
  function ownershipKey(symbol) {
11012
11180
  if (symbol.kind === "selector") return void 0;
11013
11181
  if (symbol.kind === "root-variable" && symbol.scope !== "default") return void 0;
@@ -11039,7 +11207,7 @@ var uniqueCssDefinitionRule = {
11039
11207
  },
11040
11208
  create(context) {
11041
11209
  const sourceRoot = sourceRootOf(context);
11042
- const current = path75.normalize(path75.resolve(context.filename));
11210
+ const current = path76.normalize(path76.resolve(context.filename));
11043
11211
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11044
11212
  if (cssFiles.length === 0) return {};
11045
11213
  const textOf = cachedTextReader();
@@ -11047,7 +11215,7 @@ var uniqueCssDefinitionRule = {
11047
11215
  sourceRoot,
11048
11216
  css: cssFiles.map((file) => ({
11049
11217
  path: file,
11050
- content: path75.normalize(file) === current ? context.sourceCode.text : textOf(file)
11218
+ content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
11051
11219
  })),
11052
11220
  modules: [],
11053
11221
  includeReferences: false
@@ -11069,7 +11237,7 @@ var uniqueCssDefinitionRule = {
11069
11237
  if (!canonical) continue;
11070
11238
  for (const symbol of definitions.slice(1)) {
11071
11239
  if (symbol.file !== current) continue;
11072
- const message = symbol.file === canonical.file ? `${symbolLabel(symbol)} "${symbol.name}" is defined more than once in this CSS file; define it only once.` : `${symbolLabel(symbol)} "${symbol.name}" is also defined in ${path75.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
11240
+ const message = symbol.file === canonical.file ? `${symbolLabel(symbol)} "${symbol.name}" is defined more than once in this CSS file; define it only once.` : `${symbolLabel(symbol)} "${symbol.name}" is also defined in ${path76.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
11073
11241
  context.report({
11074
11242
  node,
11075
11243
  loc: {
@@ -11086,7 +11254,7 @@ var uniqueCssDefinitionRule = {
11086
11254
  };
11087
11255
 
11088
11256
  // eslint/rules/tailwind/unique-css-token-value.ts
11089
- import path76 from "path";
11257
+ import path77 from "path";
11090
11258
  function valueIdentity(value) {
11091
11259
  const text = value.trim();
11092
11260
  const hex = /^#(?<digits>[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/iu.exec(text)?.groups?.digits;
@@ -11114,14 +11282,14 @@ var uniqueCssTokenValueRule = {
11114
11282
  },
11115
11283
  create(context) {
11116
11284
  const sourceRoot = sourceRootOf(context);
11117
- const current = path76.normalize(path76.resolve(context.filename));
11285
+ const current = path77.normalize(path77.resolve(context.filename));
11118
11286
  const textOf = cachedTextReader();
11119
11287
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11120
11288
  const graph = buildCssDependencyGraph({
11121
11289
  sourceRoot,
11122
11290
  css: cssFiles.map((file) => ({
11123
11291
  path: file,
11124
- content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
11292
+ content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
11125
11293
  })),
11126
11294
  modules: [],
11127
11295
  includeReferences: false
@@ -11153,7 +11321,7 @@ var uniqueCssTokenValueRule = {
11153
11321
  start: { line: definition.line, column: 1 },
11154
11322
  end: { line: definition.line, column: 2 }
11155
11323
  },
11156
- message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path76.relative(
11324
+ message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path77.relative(
11157
11325
  sourceRoot,
11158
11326
  original.file
11159
11327
  )}:${String(original.line)}; reuse one design token.`
@@ -11166,7 +11334,7 @@ var uniqueCssTokenValueRule = {
11166
11334
 
11167
11335
  // eslint/rules/tailwind/unused-utility.ts
11168
11336
  import { statSync as statSync5 } from "fs";
11169
- import path77 from "path";
11337
+ import path78 from "path";
11170
11338
  var unusedUtilityRule = {
11171
11339
  meta: {
11172
11340
  schema: [],
@@ -11182,7 +11350,7 @@ var unusedUtilityRule = {
11182
11350
  } catch {
11183
11351
  return {};
11184
11352
  }
11185
- const current = path77.normalize(path77.resolve(context.filename));
11353
+ const current = path78.normalize(path78.resolve(context.filename));
11186
11354
  const textOf = cachedTextReader();
11187
11355
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11188
11356
  const moduleFiles = findFiles(sourceRoot, MODULE_EXTENSIONS4);
@@ -11190,7 +11358,7 @@ var unusedUtilityRule = {
11190
11358
  sourceRoot,
11191
11359
  css: cssFiles.map((file) => ({
11192
11360
  path: file,
11193
- content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
11361
+ content: path78.normalize(file) === current ? context.sourceCode.text : textOf(file)
11194
11362
  })),
11195
11363
  modules: moduleFiles.map((file) => ({ path: file, content: textOf(file) }))
11196
11364
  });
@@ -11213,7 +11381,7 @@ var unusedUtilityRule = {
11213
11381
  // eslint/rules/tailwind/utility-mapping.ts
11214
11382
  import { spawnSync } from "child_process";
11215
11383
  import { existsSync as existsSync12 } from "fs";
11216
- import path78 from "path";
11384
+ import path79 from "path";
11217
11385
  function applyOperationCount(utility, textOf) {
11218
11386
  let count = 0;
11219
11387
  for (const apply of atrulesNamed(utility, "apply")) {
@@ -11540,13 +11708,13 @@ var utilityMappingRule = {
11540
11708
  },
11541
11709
  create(context) {
11542
11710
  const sourceRoot = sourceRootOf(context);
11543
- const current = path78.normalize(path78.resolve(context.filename));
11711
+ const current = path79.normalize(path79.resolve(context.filename));
11544
11712
  const textOf = cachedTextReader();
11545
11713
  const graph = buildCssDependencyGraph({
11546
11714
  sourceRoot,
11547
11715
  css: findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({
11548
11716
  path: file,
11549
- content: path78.normalize(file) === current ? context.sourceCode.text : textOf(file)
11717
+ content: path79.normalize(file) === current ? context.sourceCode.text : textOf(file)
11550
11718
  })),
11551
11719
  modules: [],
11552
11720
  includeReferences: false
@@ -11694,8 +11862,8 @@ var utilityMappingRule = {
11694
11862
  const generatorCandidates = utilities.map(
11695
11863
  (utility) => themeCandidate(preludeIdentifiers(utility)[0] ?? "unknown", context.sourceCode.getText(utility))
11696
11864
  ).filter((candidate) => Boolean(candidate && requiresGeneratorProbe(candidate)));
11697
- const physicalDir = path78.dirname(context.physicalFilename);
11698
- const tailwindCwd = path78.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
11865
+ const physicalDir = path79.dirname(context.physicalFilename);
11866
+ const tailwindCwd = path79.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
11699
11867
  const themeGenerators = themeSupportedGenerators(generatorCandidates, tailwindCwd);
11700
11868
  for (const utility of utilities) {
11701
11869
  const name = preludeIdentifiers(utility)[0] ?? "unknown";
@@ -11806,8 +11974,8 @@ var utilityMappingRule = {
11806
11974
  import { spawnSync as spawnSync2 } from "child_process";
11807
11975
  import { createHash } from "crypto";
11808
11976
  import { existsSync as existsSync13 } from "fs";
11809
- import path79 from "path";
11810
- import { generate as generate5, parse as parse8, toPlainObject as toPlainObject3 } from "@eslint/css-tree";
11977
+ import path80 from "path";
11978
+ import { generate as generate7, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
11811
11979
  function numericPart(value) {
11812
11980
  const match = /^(?<negative>-?)(?<number>(?:\d+(?:\.\d+)?|\.\d+))(?<unit>%|px|rem|em|vw|vh|dvw|dvh|ch|fr|s|ms|deg|turn)?$/u.exec(
11813
11981
  value
@@ -11907,7 +12075,7 @@ function compileApplies(applies, cwd) {
11907
12075
  }
11908
12076
  function compiledOperation(compiled, index) {
11909
12077
  if (!compiled.css) return void 0;
11910
- const sheet = toPlainObject3(parse8(compiled.css, { parseValue: false }));
12078
+ const sheet = toPlainObject2(parse7(compiled.css, { parseValue: false }));
11911
12079
  const probe = rules(sheet).find((candidate) => selectorNames(candidate).includes(`pasika-probe-${String(index)}`));
11912
12080
  if (!probe) return void 0;
11913
12081
  const declarations = blockChildren2(probe).filter(
@@ -11921,10 +12089,10 @@ function compiledOperation(compiled, index) {
11921
12089
  (child) => child.type === "Declaration" && child.property === "--tw-shadow"
11922
12090
  );
11923
12091
  if (shadow?.type === "Declaration") {
11924
- return { property: "box-shadow", value: generate5(shadow.value).trim() };
12092
+ return { property: "box-shadow", value: generate7(shadow.value).trim() };
11925
12093
  }
11926
12094
  }
11927
- return { property: declaration.property, value: generate5(declaration.value).trim() };
12095
+ return { property: declaration.property, value: generate7(declaration.value).trim() };
11928
12096
  }
11929
12097
  function expectedName(operation) {
11930
12098
  const value = compoundValue(operation.value);
@@ -11956,8 +12124,8 @@ var utilityNameParityRule = {
11956
12124
  return apply ? [{ utility, name, apply }] : [];
11957
12125
  });
11958
12126
  if (candidates.length === 0) return;
11959
- const physicalDir = path79.dirname(context.physicalFilename);
11960
- const cwd = path79.isAbsolute(physicalDir) && existsSync13(physicalDir) ? physicalDir : context.cwd;
12127
+ const physicalDir = path80.dirname(context.physicalFilename);
12128
+ const cwd = path80.isAbsolute(physicalDir) && existsSync13(physicalDir) ? physicalDir : context.cwd;
11961
12129
  const compiled = compileApplies(
11962
12130
  candidates.map((candidate) => candidate.apply),
11963
12131
  cwd
@@ -11987,6 +12155,7 @@ var utilityNameParityRule = {
11987
12155
  // eslint/rules/tailwind/index.ts
11988
12156
  var tailwindRules = {
11989
12157
  "theme-reset": themeResetRule,
12158
+ "theme-mode": themeModeRule,
11990
12159
  "color-role-usage": colorRoleUsageRule,
11991
12160
  "root-variables": rootVariablesRule,
11992
12161
  "apply-usage": applyUsageRule,
@@ -12005,7 +12174,7 @@ var tailwindRules = {
12005
12174
  };
12006
12175
 
12007
12176
  // eslint/rules/type-extraction.ts
12008
- import path80 from "path";
12177
+ import path81 from "path";
12009
12178
  var typeExtractionRule = {
12010
12179
  meta: {
12011
12180
  schema: [],
@@ -12016,7 +12185,7 @@ var typeExtractionRule = {
12016
12185
  },
12017
12186
  create(context) {
12018
12187
  const sourceRoot = sourceRootOf(context);
12019
- const file = path80.resolve(context.filename);
12188
+ const file = path81.resolve(context.filename);
12020
12189
  const segments = segmentsOf(file, sourceRoot);
12021
12190
  if (segments.length === 0) return {};
12022
12191
  const index = getProjectIndex(sourceRoot);
@@ -12157,7 +12326,7 @@ var uiStateRule = {
12157
12326
  // eslint/rules/unknown-utility.ts
12158
12327
  import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
12159
12328
  import { createRequire } from "module";
12160
- import path81 from "path";
12329
+ import path82 from "path";
12161
12330
  var PREFIX_NAMESPACES = {
12162
12331
  bg: ["color", "background-image"],
12163
12332
  text: ["color", "text"],
@@ -12443,7 +12612,7 @@ function stylesheetFiles(dir) {
12443
12612
  }
12444
12613
  return entries.flatMap((entry) => {
12445
12614
  if (entry.startsWith(".") || entry === "node_modules") return [];
12446
- const entryPath = path81.join(dir, entry);
12615
+ const entryPath = path82.join(dir, entry);
12447
12616
  let stats;
12448
12617
  try {
12449
12618
  stats = statSync6(entryPath);
@@ -12451,7 +12620,7 @@ function stylesheetFiles(dir) {
12451
12620
  return [];
12452
12621
  }
12453
12622
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
12454
- return path81.extname(entry) === ".css" ? [entryPath] : [];
12623
+ return path82.extname(entry) === ".css" ? [entryPath] : [];
12455
12624
  });
12456
12625
  }
12457
12626
  function packageNameOf(specifier) {
@@ -12462,10 +12631,10 @@ function packageNameOf(specifier) {
12462
12631
  function resolvePackageStylesheet(fromFile, specifier) {
12463
12632
  const packageName = packageNameOf(specifier);
12464
12633
  if (!packageName || packageName === "tailwindcss") return void 0;
12465
- let directory = path81.dirname(fromFile);
12466
- while (directory !== path81.dirname(directory)) {
12467
- const packageRoot = path81.join(directory, "node_modules", packageName);
12468
- const manifestPath = path81.join(packageRoot, "package.json");
12634
+ let directory = path82.dirname(fromFile);
12635
+ while (directory !== path82.dirname(directory)) {
12636
+ const packageRoot = path82.join(directory, "node_modules", packageName);
12637
+ const manifestPath = path82.join(packageRoot, "package.json");
12469
12638
  if (existsSync14(manifestPath)) {
12470
12639
  try {
12471
12640
  const manifest = readFileSync15(manifestPath, "utf8");
@@ -12473,13 +12642,13 @@ function resolvePackageStylesheet(fromFile, specifier) {
12473
12642
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
12474
12643
  const target = stylesheet ?? main;
12475
12644
  if (!target) return void 0;
12476
- const resolved = path81.resolve(packageRoot, target);
12645
+ const resolved = path82.resolve(packageRoot, target);
12477
12646
  return existsSync14(resolved) ? resolved : void 0;
12478
12647
  } catch {
12479
12648
  return void 0;
12480
12649
  }
12481
12650
  }
12482
- directory = path81.dirname(directory);
12651
+ directory = path82.dirname(directory);
12483
12652
  }
12484
12653
  return void 0;
12485
12654
  }
@@ -12751,7 +12920,7 @@ var unknownUtilityRule = {
12751
12920
  };
12752
12921
 
12753
12922
  // eslint/rules/util-file-name.ts
12754
- import path82 from "path";
12923
+ import path83 from "path";
12755
12924
  function toKebabCase2(value) {
12756
12925
  return value.replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/g, "$<lower>-$<upper>").replace(/(?<first>[A-Z])(?<rest>[A-Z][a-z])/g, "$<first>-$<rest>").toLowerCase();
12757
12926
  }
@@ -12764,7 +12933,7 @@ var utilFileNameRule = {
12764
12933
  }
12765
12934
  },
12766
12935
  create(context) {
12767
- const filename = path82.resolve(context.filename);
12936
+ const filename = path83.resolve(context.filename);
12768
12937
  const segments = filename.replace(/\\/g, "/").split("/");
12769
12938
  if (!segments.includes("utils")) return {};
12770
12939
  let module;
@@ -12778,13 +12947,13 @@ var utilFileNameRule = {
12778
12947
  const functionName = functions[0]?.name;
12779
12948
  if (!functionName) return {};
12780
12949
  const expected = toKebabCase2(functionName);
12781
- const actual = path82.basename(filename, path82.extname(filename));
12950
+ const actual = path83.basename(filename, path83.extname(filename));
12782
12951
  if (!expected || actual === expected) return {};
12783
12952
  return {
12784
12953
  Program(node) {
12785
12954
  context.report({
12786
12955
  node,
12787
- message: `A utility file exporting ${functionName} must be named ${expected}.${path82.extname(filename).slice(1)}.`
12956
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path83.extname(filename).slice(1)}.`
12788
12957
  });
12789
12958
  }
12790
12959
  };
@@ -12792,7 +12961,7 @@ var utilFileNameRule = {
12792
12961
  };
12793
12962
 
12794
12963
  // eslint/rules/value-extraction.ts
12795
- import path83 from "path";
12964
+ import path84 from "path";
12796
12965
  var valueExtractionRule = {
12797
12966
  meta: {
12798
12967
  schema: [],
@@ -12803,7 +12972,7 @@ var valueExtractionRule = {
12803
12972
  },
12804
12973
  create(context) {
12805
12974
  const sourceRoot = sourceRootOf(context);
12806
- const file = path83.resolve(context.filename);
12975
+ const file = path84.resolve(context.filename);
12807
12976
  const segments = segmentsOf(file, sourceRoot);
12808
12977
  if (segments.length === 0 || segments[0] !== "app") return {};
12809
12978
  const index = getProjectIndex(sourceRoot);
@@ -12825,7 +12994,7 @@ var valueExtractionRule = {
12825
12994
 
12826
12995
  // eslint/rules/vulyk/tracked-docs.ts
12827
12996
  import { existsSync as existsSync15, readFileSync as readFileSync16 } from "fs";
12828
- import path84 from "path";
12997
+ import path85 from "path";
12829
12998
  var PASIKA_REPO = "Bredansky/pasika";
12830
12999
  var BASE_REQUIRED_TRACKED_DOCS = [
12831
13000
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -12858,8 +13027,8 @@ var trackedDocsRule = {
12858
13027
  if (!context.filename.endsWith("package.json")) return;
12859
13028
  const root = node.body;
12860
13029
  if (root.type !== "Object") return;
12861
- const projectRoot = path84.dirname(path84.resolve(context.filename));
12862
- const configPath = path84.join(projectRoot, "vulyk.config.ts");
13030
+ const projectRoot = path85.dirname(path85.resolve(context.filename));
13031
+ const configPath = path85.join(projectRoot, "vulyk.config.ts");
12863
13032
  if (!existsSync15(configPath)) {
12864
13033
  context.report({
12865
13034
  node,
@@ -12884,7 +13053,7 @@ var trackedDocsRule = {
12884
13053
  });
12885
13054
  }
12886
13055
  }
12887
- const agentsPath = path84.join(projectRoot, "AGENTS.md");
13056
+ const agentsPath = path85.join(projectRoot, "AGENTS.md");
12888
13057
  if (!existsSync15(agentsPath)) {
12889
13058
  context.report({
12890
13059
  node,
@@ -12984,7 +13153,7 @@ var withResponseHelperRule = {
12984
13153
 
12985
13154
  // eslint/rules/zirka-baseline.ts
12986
13155
  import fs7 from "fs";
12987
- import path85 from "path";
13156
+ import path86 from "path";
12988
13157
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
12989
13158
  var PRETTIER_CONFIGS = [
12990
13159
  "prettier.config.mjs",
@@ -13003,10 +13172,10 @@ var zirkaBaselineRule = {
13003
13172
  }
13004
13173
  },
13005
13174
  create(context) {
13006
- const filename = path85.resolve(context.filename);
13007
- const basename = path85.basename(filename);
13175
+ const filename = path86.resolve(context.filename);
13176
+ const basename = path86.basename(filename);
13008
13177
  if (!ESLINT_CONFIG.test(basename)) return {};
13009
- const projectRoot = path85.dirname(filename);
13178
+ const projectRoot = path86.dirname(filename);
13010
13179
  const report3 = (message) => {
13011
13180
  context.report({
13012
13181
  node: context.sourceCode.ast,
@@ -13021,7 +13190,7 @@ var zirkaBaselineRule = {
13021
13190
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
13022
13191
  );
13023
13192
  }
13024
- const tsconfigPath = path85.join(projectRoot, "tsconfig.json");
13193
+ const tsconfigPath = path86.join(projectRoot, "tsconfig.json");
13025
13194
  if (!fs7.existsSync(tsconfigPath)) {
13026
13195
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
13027
13196
  } else {
@@ -13039,13 +13208,13 @@ var zirkaBaselineRule = {
13039
13208
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
13040
13209
  }
13041
13210
  }
13042
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path85.join(projectRoot, name)));
13211
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path86.join(projectRoot, name)));
13043
13212
  if (!prettierConfigFile) {
13044
13213
  report3(
13045
13214
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
13046
13215
  );
13047
13216
  } else {
13048
- const content = fs7.readFileSync(path85.join(projectRoot, prettierConfigFile), "utf8");
13217
+ const content = fs7.readFileSync(path86.join(projectRoot, prettierConfigFile), "utf8");
13049
13218
  if (!content.includes("zirka")) {
13050
13219
  report3(
13051
13220
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -13381,7 +13550,7 @@ var tailwindStructureRules = {
13381
13550
  languageOptions: { tolerant: true },
13382
13551
  rules: Object.fromEntries(
13383
13552
  tailwindRuleIds.filter(
13384
- (id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/utility-mapping" && id !== "pasika/utility-name-parity" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage"
13553
+ (id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/utility-mapping" && id !== "pasika/utility-name-parity" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage" && id !== "pasika/theme-mode"
13385
13554
  ).map((id) => [id, "error"])
13386
13555
  )
13387
13556
  };
@@ -13402,7 +13571,8 @@ var tailwindImportGraph = {
13402
13571
  "pasika/utility-name-parity": "error",
13403
13572
  "pasika/no-utility-alias": "error",
13404
13573
  "pasika/root-variables": "error",
13405
- "pasika/color-role-usage": "error"
13574
+ "pasika/color-role-usage": "error",
13575
+ "pasika/theme-mode": "error"
13406
13576
  }
13407
13577
  };
13408
13578
  var pasikaAppPackageJsonConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.129",
3
+ "version": "0.10.131",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",