pasika 0.10.37 → 0.10.39

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
@@ -105,7 +105,7 @@ The guides ship in this repository and are adopted into a project through `vulyk
105
105
  npm run lint # eslint, including the framework's own docs rules
106
106
  npm run typecheck
107
107
  npm run test:unit
108
- npm run coverage # every requirement still has recorded enforcement
108
+ npm run test:requirements # every requirement still has recorded enforcement
109
109
  npm run build
110
110
  npm run dogfood -- ../some/repo # lint a sibling repo with the built presets
111
111
  ```
@@ -605,25 +605,55 @@ var noMixedConcernsRule = {
605
605
  };
606
606
 
607
607
  // eslint/rules/no-arbitrary-tailwind.ts
608
- var ARBITRARY_VALUE_RE = /(?:^|(?<=\s))(?:[a-z]+(?:-[a-z]+)*)-\[[^\]]+\](?![-\w]*:)/g;
608
+ var ARBITRARY_VALUE_RE = /\[[^\]]+\]/;
609
+ var CUSTOM_PROPERTY_VALUE_RE = /\((?:[a-z][a-z0-9-]*:)?--[^)]+\)/;
610
+ function baseUtility(className) {
611
+ let squareDepth = 0;
612
+ let roundDepth = 0;
613
+ let lastVariantSeparator = -1;
614
+ for (let index = 0; index < className.length; index += 1) {
615
+ const character = className[index];
616
+ if (character === "[") squareDepth += 1;
617
+ else if (character === "]") squareDepth = Math.max(0, squareDepth - 1);
618
+ else if (character === "(") roundDepth += 1;
619
+ else if (character === ")") roundDepth = Math.max(0, roundDepth - 1);
620
+ else if (character === ":" && squareDepth === 0 && roundDepth === 0) lastVariantSeparator = index;
621
+ }
622
+ return className.slice(lastVariantSeparator + 1);
623
+ }
624
+ function rawValueUtility(className) {
625
+ const utility = baseUtility(className);
626
+ if (ARBITRARY_VALUE_RE.test(utility) || CUSTOM_PROPERTY_VALUE_RE.test(utility)) {
627
+ return utility;
628
+ }
629
+ return void 0;
630
+ }
609
631
  var CLASS_HELPERS = /* @__PURE__ */ new Set(["cn", "clsx", "twMerge", "twJoin"]);
632
+ function isClassProperty(property) {
633
+ const { key } = property;
634
+ if (key.type === "Identifier") return key.name === "className" || key.name === "class";
635
+ if (key.type !== "Literal" || typeof key.value !== "string") return false;
636
+ return key.value === "className" || key.value === "class";
637
+ }
610
638
  var noArbitraryTailwindRule = {
611
639
  meta: {
612
640
  schema: [],
613
641
  type: "problem",
614
642
  docs: {
615
- description: "Disallow Tailwind arbitrary-value classes like rounded-[13px]."
643
+ description: "Disallow raw Tailwind arbitrary and custom-property value classes in components."
616
644
  }
617
645
  },
618
646
  create(context) {
619
647
  function reportClassString(node, value) {
620
- ARBITRARY_VALUE_RE.lastIndex = 0;
621
- const match = ARBITRARY_VALUE_RE.exec(value);
622
- if (!match) return;
623
- context.report({
624
- node,
625
- message: `Tailwind arbitrary-value class "${match[0]}" is not allowed. Use a named token or custom utility. See docs/next-tailwind-guide/rules/arbitrary-value-rule.md`
626
- });
648
+ for (const className of value.split(/\s+/)) {
649
+ if (!className) continue;
650
+ const utility = rawValueUtility(className);
651
+ if (!utility) continue;
652
+ context.report({
653
+ node,
654
+ message: `Tailwind raw-value class "${utility}" is not allowed. Define and use a named utility instead. See docs/next-tailwind-guide/rules/arbitrary-value-rule.md`
655
+ });
656
+ }
627
657
  }
628
658
  function checkExpression(node, expression) {
629
659
  if (!expression) return;
@@ -645,6 +675,10 @@ var noArbitraryTailwindRule = {
645
675
  checkExpression(node, expression.alternate);
646
676
  return;
647
677
  }
678
+ if (expression.type === "AssignmentPattern") {
679
+ checkExpression(node, expression.right);
680
+ return;
681
+ }
648
682
  if (expression.type === "ArrayExpression") {
649
683
  for (const element of expression.elements) checkExpression(node, element);
650
684
  return;
@@ -655,6 +689,34 @@ var noArbitraryTailwindRule = {
655
689
  }
656
690
  }
657
691
  }
692
+ function checkCvaExpression(node, expression) {
693
+ if (!expression) return;
694
+ if (expression.type === "ObjectExpression") {
695
+ for (const property of expression.properties) {
696
+ if (property.type === "Property") {
697
+ if (!isClassProperty(property)) checkCvaExpression(node, property.value);
698
+ } else {
699
+ checkCvaExpression(node, property.argument);
700
+ }
701
+ }
702
+ return;
703
+ }
704
+ if (expression.type === "ArrayExpression") {
705
+ for (const element of expression.elements) checkCvaExpression(node, element);
706
+ return;
707
+ }
708
+ if (expression.type === "LogicalExpression") {
709
+ checkCvaExpression(node, expression.left);
710
+ checkCvaExpression(node, expression.right);
711
+ return;
712
+ }
713
+ if (expression.type === "ConditionalExpression") {
714
+ checkCvaExpression(node, expression.consequent);
715
+ checkCvaExpression(node, expression.alternate);
716
+ return;
717
+ }
718
+ checkExpression(node, expression);
719
+ }
658
720
  return {
659
721
  JSXAttribute(node) {
660
722
  const attributeName = node.name?.name;
@@ -663,10 +725,22 @@ var noArbitraryTailwindRule = {
663
725
  if (!value) return;
664
726
  checkExpression(node, value.type === "JSXExpressionContainer" ? value.expression : value);
665
727
  },
728
+ Property(node) {
729
+ if (!isClassProperty(node)) return;
730
+ checkExpression(node, node.value);
731
+ },
666
732
  CallExpression(node) {
667
- if (node.callee.type !== "Identifier" || !CLASS_HELPERS.has(node.callee.name)) return;
668
- for (const argument of node.arguments) {
669
- checkExpression(node, argument);
733
+ if (node.callee.type !== "Identifier") return;
734
+ if (CLASS_HELPERS.has(node.callee.name)) {
735
+ for (const argument of node.arguments) {
736
+ checkExpression(node, argument);
737
+ }
738
+ return;
739
+ }
740
+ if (node.callee.name === "cva") {
741
+ for (const argument of node.arguments) {
742
+ checkCvaExpression(node, argument);
743
+ }
670
744
  }
671
745
  }
672
746
  };
@@ -2844,6 +2918,7 @@ function tagName(node) {
2844
2918
  function isInteractive(node) {
2845
2919
  const name = tagName(node);
2846
2920
  if (name === void 0 || !INTERACTIVE_TAGS.has(name)) return false;
2921
+ if (name === "button") return true;
2847
2922
  const attributes = node.openingElement?.attributes;
2848
2923
  if (!attributes) return false;
2849
2924
  return attributes.some(
@@ -2953,7 +3028,10 @@ var interactiveComponentRule = {
2953
3028
  JSXElement(node) {
2954
3029
  if (!isInteractive(node)) return;
2955
3030
  if (isComponentElement(node.parent)) {
2956
- return;
3031
+ const name2 = tagName(node);
3032
+ if (name2 !== "button" || isComponentRoot(node.parent)) {
3033
+ return;
3034
+ }
2957
3035
  }
2958
3036
  if (isInteractive(node.parent)) {
2959
3037
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.37",
3
+ "version": "0.10.39",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,7 +43,6 @@
43
43
  ],
44
44
  "scripts": {
45
45
  "build": "tsup",
46
- "coverage": "tsx scripts/coverage.ts",
47
46
  "dogfood": "tsx scripts/dogfood.ts",
48
47
  "fix": "eslint . --fix",
49
48
  "format": "prettier --check . --ignore-unknown",
@@ -52,6 +51,7 @@
52
51
  "lint:staged": "eslint --fix",
53
52
  "prepack": "npm run build",
54
53
  "prepare": "husky",
54
+ "test:requirements": "tsx scripts/coverage.ts",
55
55
  "test:unit": "vitest run",
56
56
  "test:unit:coverage": "vitest run --coverage",
57
57
  "test:unit:staged": "vitest related --run",