pasika 0.10.122 → 0.10.124

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.
@@ -9889,20 +9889,33 @@ function colorRoleUsageMessage(className) {
9889
9889
 
9890
9890
  // eslint/rules/tailwind/color-role-usage.ts
9891
9891
  var COLOR_TOKEN = /^--color-[a-z][a-z0-9-]*-(?:canvas|ink|edge)$/u;
9892
+ var BACKGROUND_IMAGE_TOKEN = /^--background-image-[a-z][a-z0-9-]*-canvas$/u;
9892
9893
  var colorRoleUsageRule = {
9893
9894
  meta: {
9894
9895
  schema: [],
9895
9896
  type: "problem",
9896
- docs: { description: "Require semantic color-token names and matching Tailwind color utilities." }
9897
+ docs: {
9898
+ description: "Require semantic color and background-image token names and matching Tailwind color utilities."
9899
+ }
9897
9900
  },
9898
9901
  create(context) {
9899
9902
  return {
9900
9903
  "StyleSheet:exit"(node) {
9901
9904
  for (const theme of atrulesNamed(node, "theme")) {
9902
9905
  const source = context.sourceCode.getText(theme).replace(/\/\*[\s\S]*?\*\//gu, " ");
9903
- for (const match of source.matchAll(/(?:^|[{;\r\n])\s*(?<token>--color-[a-z][a-z0-9-]*)\s*:/gu)) {
9906
+ for (const match of source.matchAll(
9907
+ /(?:^|[{;\r\n])\s*(?<token>--(?:color|background-image)-[a-z][a-z0-9-]*)\s*:/gu
9908
+ )) {
9904
9909
  const token = match.groups?.token;
9905
- if (token && !COLOR_TOKEN.test(token)) {
9910
+ if (!token) continue;
9911
+ if (token.startsWith("--background-image-")) {
9912
+ if (!BACKGROUND_IMAGE_TOKEN.test(token)) {
9913
+ context.report({
9914
+ node: theme,
9915
+ message: `Background-image token "${token}" needs a semantic role ending in -canvas.`
9916
+ });
9917
+ }
9918
+ } else if (!COLOR_TOKEN.test(token)) {
9906
9919
  context.report({
9907
9920
  node: theme,
9908
9921
  message: `Color token "${token}" needs a semantic role ending in -canvas, -ink, or -edge.`
@@ -10627,7 +10640,7 @@ import path72 from "path";
10627
10640
  import { generate as generate3, parse as parse6, walk as walk3 } from "@eslint/css-tree";
10628
10641
  var INLINE_MESSAGE = "Define design tokens with direct values in @theme, not @theme inline.";
10629
10642
  var INDIRECT_MESSAGE = "Define design tokens that reference CSS variables via var() in @theme inline.";
10630
- var MIXED_THEME_MESSAGE = "Use either @theme or @theme inline across the project, not both.";
10643
+ var MIXED_THEME_MESSAGE = "Use either @theme or @theme inline across the project; external font-loader mappings with valid fallbacks are the only exception.";
10631
10644
  var REDUNDANT_INLINE_MESSAGE = (name) => `Tailwind token "${name}" has no runtime overrides; define its value directly in @theme instead of using :root and @theme inline.`;
10632
10645
  var EXTERNAL_FONT_FALLBACK_MESSAGE = (name, variable) => `Tailwind font token "${name}" references external font "${variable}" without a fallback inside var(); use var(${variable}, Arial) or another font-family fallback.`;
10633
10646
  function hasVarFallback(source, variable) {
@@ -10644,7 +10657,7 @@ var rootVariablesRule = {
10644
10657
  schema: [],
10645
10658
  type: "problem",
10646
10659
  docs: {
10647
- description: "Require @theme for fixed tokens, matching :root variables for @theme inline tokens, and no other token redeclarations."
10660
+ description: "Require @theme for fixed tokens and fixed-token aliases, matching :root variables for @theme inline tokens, and no other token redeclarations."
10648
10661
  }
10649
10662
  },
10650
10663
  create(context) {
@@ -10661,12 +10674,26 @@ var rootVariablesRule = {
10661
10674
  modules: [],
10662
10675
  includeReferences: false
10663
10676
  });
10677
+ const themeValues = new Map(
10678
+ graph.definitions.filter((symbol) => symbol.kind === "theme-token" && symbol.value !== void 0).map((symbol) => [symbol.name, symbol.value ?? ""])
10679
+ );
10664
10680
  const names = new Set(
10665
10681
  graph.definitions.filter((symbol) => symbol.kind === "theme-token").map((symbol) => symbol.name)
10666
10682
  );
10683
+ function isFixedThemeAlias(name, value, visited = /* @__PURE__ */ new Set()) {
10684
+ const match = /^var\(\s*(?<target>--[a-z][\w-]*)\s*\)$/u.exec(value.trim());
10685
+ const target = match?.groups?.target;
10686
+ if (!target || target === name || visited.has(target)) return false;
10687
+ const next = themeValues.get(target);
10688
+ if (!next) return false;
10689
+ if (!/\bvar\s*\(/u.test(next)) return true;
10690
+ visited.add(target);
10691
+ return isFixedThemeAlias(name, next, visited);
10692
+ }
10667
10693
  const mirroredTokens = /* @__PURE__ */ new Set();
10668
10694
  let hasPlainThemeBlocks = false;
10669
10695
  let hasInlineThemeBlocks = false;
10696
+ let inlineBlocksAreExternalFonts = true;
10670
10697
  for (const file of [...stylesheets.filter((candidate) => path72.normalize(candidate) !== current), current]) {
10671
10698
  const source = (path72.normalize(file) === current ? context.sourceCode.text : textOf(file)).replace(
10672
10699
  /\/\*[\s\S]*?\*\//gu,
@@ -10676,6 +10703,25 @@ var rootVariablesRule = {
10676
10703
  if (/\binline\b/u.test(header.groups?.options ?? "")) hasInlineThemeBlocks = true;
10677
10704
  else hasPlainThemeBlocks = true;
10678
10705
  }
10706
+ const inlineHeaders = [...source.matchAll(/@theme\s+inline\s*\{/gu)];
10707
+ const inlineBlocks = [...source.matchAll(/@theme\s+inline\s*\{(?<body>[^{}]*)\}/gu)];
10708
+ if (inlineHeaders.length !== inlineBlocks.length) inlineBlocksAreExternalFonts = false;
10709
+ for (const block of inlineBlocks) {
10710
+ const declarations = (block.groups?.body ?? "").split(";").map((part) => part.trim()).filter(Boolean);
10711
+ if (declarations.length === 0) inlineBlocksAreExternalFonts = false;
10712
+ for (const declaration of declarations) {
10713
+ const match = /^(?<token>--font-[a-z][\w-]*)\s*:\s*(?<value>.+)$/u.exec(declaration);
10714
+ const name = match?.groups?.token;
10715
+ const value = match?.groups?.value ?? "";
10716
+ const references = [...value.matchAll(/\bvar\s*\(\s*(?<name>--[\w-]+)/gu)].map(
10717
+ (reference) => reference.groups?.name
10718
+ );
10719
+ const runtime = references[0];
10720
+ if (!name || references.length !== 1 || !runtime?.startsWith("--font-") || runtime === name || names.has(runtime) || !hasVarFallback(value, runtime)) {
10721
+ inlineBlocksAreExternalFonts = false;
10722
+ }
10723
+ }
10724
+ }
10679
10725
  for (const theme of source.matchAll(/@theme(?<options>(?:\s+[\w-]+)*)\s*\{(?<body>[^{}]*)\}/gu)) {
10680
10726
  const inline = /\binline\b/u.test(theme.groups?.options ?? "");
10681
10727
  for (const declaration of (theme.groups?.body ?? "").matchAll(
@@ -10715,7 +10761,7 @@ var rootVariablesRule = {
10715
10761
  return {
10716
10762
  "StyleSheet:exit"(node) {
10717
10763
  const localThemes = atrulesNamed(node, "theme");
10718
- if (hasPlainThemeBlocks && hasInlineThemeBlocks && localThemes[0]) {
10764
+ if (hasPlainThemeBlocks && hasInlineThemeBlocks && !inlineBlocksAreExternalFonts && localThemes[0]) {
10719
10765
  context.report({ node: localThemes[0], message: MIXED_THEME_MESSAGE });
10720
10766
  }
10721
10767
  for (const theme of localThemes) {
@@ -10757,7 +10803,7 @@ var rootVariablesRule = {
10757
10803
  context.report({ node: theme, message: REDUNDANT_INLINE_MESSAGE(name) });
10758
10804
  }
10759
10805
  }
10760
- if (inline === referencesVariable) continue;
10806
+ if (inline === referencesVariable || !inline && isFixedThemeAlias(name, unquoted)) continue;
10761
10807
  const offset = (theme.loc?.start.offset ?? 0) + match.index + match[0].indexOf(name);
10762
10808
  const preceding = context.sourceCode.text.slice(0, offset);
10763
10809
  const line = preceding.split("\n").length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.122",
3
+ "version": "0.10.124",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",