remediation 0.1.2 → 0.2.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.
@@ -2,4 +2,5 @@ import { Rule } from '../../types';
2
2
  export declare const componentRules: Rule[];
3
3
  export { deadComponentsRule } from './dead/rule';
4
4
  export { duplicatesRule } from './duplicates/rule';
5
+ export { variantSplitRule } from './variant-split/rule';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/rules/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAInC,eAAO,MAAM,cAAc,EAAE,IAAI,EAGhC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/rules/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAKnC,eAAO,MAAM,cAAc,EAAE,IAAI,EAIhC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,14 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.duplicatesRule = exports.deadComponentsRule = exports.componentRules = void 0;
3
+ exports.variantSplitRule = exports.duplicatesRule = exports.deadComponentsRule = exports.componentRules = void 0;
4
4
  const rule_1 = require("./dead/rule");
5
5
  const rule_2 = require("./duplicates/rule");
6
+ const rule_3 = require("./variant-split/rule");
6
7
  exports.componentRules = [
7
8
  rule_1.deadComponentsRule,
8
9
  rule_2.duplicatesRule,
10
+ rule_3.variantSplitRule,
9
11
  ];
10
- var rule_3 = require("./dead/rule");
11
- Object.defineProperty(exports, "deadComponentsRule", { enumerable: true, get: function () { return rule_3.deadComponentsRule; } });
12
- var rule_4 = require("./duplicates/rule");
13
- Object.defineProperty(exports, "duplicatesRule", { enumerable: true, get: function () { return rule_4.duplicatesRule; } });
12
+ var rule_4 = require("./dead/rule");
13
+ Object.defineProperty(exports, "deadComponentsRule", { enumerable: true, get: function () { return rule_4.deadComponentsRule; } });
14
+ var rule_5 = require("./duplicates/rule");
15
+ Object.defineProperty(exports, "duplicatesRule", { enumerable: true, get: function () { return rule_5.duplicatesRule; } });
16
+ var rule_6 = require("./variant-split/rule");
17
+ Object.defineProperty(exports, "variantSplitRule", { enumerable: true, get: function () { return rule_6.variantSplitRule; } });
14
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/rules/components/index.ts"],"names":[],"mappings":";;;AACA,sCAAiD;AACjD,4CAAmD;AAEtC,QAAA,cAAc,GAAW;IACpC,yBAAkB;IAClB,qBAAc;CACf,CAAC;AAEF,oCAAiD;AAAxC,0GAAA,kBAAkB,OAAA;AAC3B,0CAAmD;AAA1C,sGAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/rules/components/index.ts"],"names":[],"mappings":";;;AACA,sCAAiD;AACjD,4CAAmD;AACnD,+CAAwD;AAE3C,QAAA,cAAc,GAAW;IACpC,yBAAkB;IAClB,qBAAc;IACd,uBAAgB;CACjB,CAAC;AAEF,oCAAiD;AAAxC,0GAAA,kBAAkB,OAAA;AAC3B,0CAAmD;AAA1C,sGAAA,cAAc,OAAA;AACvB,6CAAwD;AAA/C,wGAAA,gBAAgB,OAAA"}
@@ -0,0 +1,3 @@
1
+ import { Rule } from '../../../types';
2
+ export declare const variantSplitRule: Rule;
3
+ //# sourceMappingURL=rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../../../src/core/rules/components/variant-split/rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA0B,MAAM,gBAAgB,CAAC;AA+G9D,eAAO,MAAM,gBAAgB,EAAE,IA+B9B,CAAC"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.variantSplitRule = void 0;
4
+ const VARIANT_PROPS = ['variant', 'size', 'type', 'kind'];
5
+ const propPattern = (props) => new RegExp(`(?:function\\s+\\w+\\s*\\(|const\\s+\\w+\\s*=\\s*(?:\\([^)]*\\)|\\w+)\\s*=>|const\\s+\\w+\\s*=\\s*\\()\\s*\\{\\s*(?:${props.join('|')})\\b`, 'g');
6
+ const ternaryPattern = (props) => new RegExp(`\\b(${props.join('|')})\\s*(?:===?|!==?)\\s*['"][^'"]+['"]\\s*\\?`, 'g');
7
+ const switchPattern = (props) => new RegExp(`switch\\s*\\(\\s*(${props.join('|')})\\s*\\)`, 'g');
8
+ function findPropsInFile(content) {
9
+ const found = [];
10
+ for (const prop of VARIANT_PROPS) {
11
+ const regex = propPattern([prop]);
12
+ if (regex.test(content)) {
13
+ found.push(prop);
14
+ }
15
+ }
16
+ return found;
17
+ }
18
+ function findVariantsOnProp(content, prop) {
19
+ const issues = [];
20
+ const lines = content.split('\n');
21
+ const ternaryOnProp = new RegExp(`\\b${prop}\\s*(?:===?|!==?)\\s*['"][^'"]+['"]\\s*\\?`, 'g');
22
+ const ternaryShorthand = new RegExp(`\\b${prop}\\s*\\?`, 'g');
23
+ const sw = new RegExp(`switch\\s*\\(\\s*${prop}\\s*\\)`, 'g');
24
+ const ternaryConditionOnly = new RegExp(`\\b${prop}\\s*(?:===?|!==?)\\s*['"][^'"]+['"]`, 'g');
25
+ lines.forEach((line, index) => {
26
+ let match;
27
+ ternaryOnProp.lastIndex = 0;
28
+ while ((match = ternaryOnProp.exec(line)) !== null) {
29
+ issues.push({
30
+ line: index + 1,
31
+ column: match.index + 1,
32
+ message: `Conditional rendering based on ${prop}`,
33
+ });
34
+ }
35
+ ternaryShorthand.lastIndex = 0;
36
+ while ((match = ternaryShorthand.exec(line)) !== null) {
37
+ const alreadyFound = issues.some(i => i.line === index + 1 && i.column <= match.index + 10);
38
+ if (!alreadyFound) {
39
+ issues.push({
40
+ line: index + 1,
41
+ column: match.index + 1,
42
+ message: `Conditional rendering based on ${prop}`,
43
+ });
44
+ }
45
+ }
46
+ sw.lastIndex = 0;
47
+ while ((match = sw.exec(line)) !== null) {
48
+ issues.push({
49
+ line: index + 1,
50
+ column: match.index + 1,
51
+ message: `Switch statement on ${prop}`,
52
+ });
53
+ }
54
+ ternaryConditionOnly.lastIndex = 0;
55
+ while ((match = ternaryConditionOnly.exec(line)) !== null) {
56
+ const nextLine = lines[index + 1];
57
+ if (nextLine && nextLine.trim().startsWith('?')) {
58
+ const alreadyFound = issues.some(i => i.line === index + 1);
59
+ if (!alreadyFound) {
60
+ issues.push({
61
+ line: index + 1,
62
+ column: match.index + 1,
63
+ message: `Conditional rendering based on ${prop}`,
64
+ });
65
+ }
66
+ }
67
+ }
68
+ });
69
+ return issues;
70
+ }
71
+ exports.variantSplitRule = {
72
+ name: 'components/variant-split',
73
+ description: 'Detects components with conditional rendering based on variant props that should be split',
74
+ detect(file) {
75
+ const violations = [];
76
+ if (!file.path.match(/\.(tsx?|jsx?)$/)) {
77
+ return violations;
78
+ }
79
+ const propsInFile = findPropsInFile(file.content);
80
+ for (const prop of propsInFile) {
81
+ const issues = findVariantsOnProp(file.content, prop);
82
+ for (const issue of issues) {
83
+ violations.push({
84
+ rule: 'components/variant-split',
85
+ file: file.path,
86
+ line: issue.line,
87
+ column: issue.column,
88
+ message: `${issue.message} — consider splitting into separate components`,
89
+ severity: 'warning',
90
+ suggestion: `Split into separate components based on ${prop} values`,
91
+ });
92
+ }
93
+ }
94
+ return violations;
95
+ },
96
+ };
97
+ //# sourceMappingURL=rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.js","sourceRoot":"","sources":["../../../../../src/core/rules/components/variant-split/rule.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remediation",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "CLI tool that scans React source code and detects design system inconsistencies",
5
5
  "license": "MIT",
6
6
  "bin": {