react-anti-pattern-sniffer 0.1.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/.snifferrc.json +29 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/bin/react-sniff.js +3 -0
- package/dist/src/cli/arg-parser.d.ts +10 -0
- package/dist/src/cli/arg-parser.d.ts.map +1 -0
- package/dist/src/cli/arg-parser.js +81 -0
- package/dist/src/cli/arg-parser.js.map +1 -0
- package/dist/src/cli/config-loader.d.ts +11 -0
- package/dist/src/cli/config-loader.d.ts.map +1 -0
- package/dist/src/cli/config-loader.js +140 -0
- package/dist/src/cli/config-loader.js.map +1 -0
- package/dist/src/cli/help.d.ts +3 -0
- package/dist/src/cli/help.d.ts.map +1 -0
- package/dist/src/cli/help.js +59 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/index.d.ts +2 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +107 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/core/file-discoverer.d.ts +8 -0
- package/dist/src/core/file-discoverer.d.ts.map +1 -0
- package/dist/src/core/file-discoverer.js +151 -0
- package/dist/src/core/file-discoverer.js.map +1 -0
- package/dist/src/core/orchestrator.d.ts +13 -0
- package/dist/src/core/orchestrator.d.ts.map +1 -0
- package/dist/src/core/orchestrator.js +176 -0
- package/dist/src/core/orchestrator.js.map +1 -0
- package/dist/src/core/sniffer-ignore.d.ts +25 -0
- package/dist/src/core/sniffer-ignore.d.ts.map +1 -0
- package/dist/src/core/sniffer-ignore.js +91 -0
- package/dist/src/core/sniffer-ignore.js.map +1 -0
- package/dist/src/core/sniffer-registry.d.ts +8 -0
- package/dist/src/core/sniffer-registry.d.ts.map +1 -0
- package/dist/src/core/sniffer-registry.js +64 -0
- package/dist/src/core/sniffer-registry.js.map +1 -0
- package/dist/src/core/worker-pool.d.ts +27 -0
- package/dist/src/core/worker-pool.d.ts.map +1 -0
- package/dist/src/core/worker-pool.js +176 -0
- package/dist/src/core/worker-pool.js.map +1 -0
- package/dist/src/core/worker-runner.d.ts +2 -0
- package/dist/src/core/worker-runner.d.ts.map +1 -0
- package/dist/src/core/worker-runner.js +52 -0
- package/dist/src/core/worker-runner.js.map +1 -0
- package/dist/src/output/formatter.d.ts +3 -0
- package/dist/src/output/formatter.d.ts.map +1 -0
- package/dist/src/output/formatter.js +13 -0
- package/dist/src/output/formatter.js.map +1 -0
- package/dist/src/output/json-renderer.d.ts +3 -0
- package/dist/src/output/json-renderer.d.ts.map +1 -0
- package/dist/src/output/json-renderer.js +49 -0
- package/dist/src/output/json-renderer.js.map +1 -0
- package/dist/src/output/markdown-renderer.d.ts +3 -0
- package/dist/src/output/markdown-renderer.d.ts.map +1 -0
- package/dist/src/output/markdown-renderer.js +70 -0
- package/dist/src/output/markdown-renderer.js.map +1 -0
- package/dist/src/plugins/plugin-loader.d.ts +7 -0
- package/dist/src/plugins/plugin-loader.d.ts.map +1 -0
- package/dist/src/plugins/plugin-loader.js +47 -0
- package/dist/src/plugins/plugin-loader.js.map +1 -0
- package/dist/src/plugins/plugin-sandbox.d.ts +3 -0
- package/dist/src/plugins/plugin-sandbox.d.ts.map +1 -0
- package/dist/src/plugins/plugin-sandbox.js +105 -0
- package/dist/src/plugins/plugin-sandbox.js.map +1 -0
- package/dist/src/plugins/plugin-validator.d.ts +14 -0
- package/dist/src/plugins/plugin-validator.d.ts.map +1 -0
- package/dist/src/plugins/plugin-validator.js +92 -0
- package/dist/src/plugins/plugin-validator.js.map +1 -0
- package/dist/src/sniffers/god-hook-sniffer.d.ts +12 -0
- package/dist/src/sniffers/god-hook-sniffer.d.ts.map +1 -0
- package/dist/src/sniffers/god-hook-sniffer.js +109 -0
- package/dist/src/sniffers/god-hook-sniffer.js.map +1 -0
- package/dist/src/sniffers/prop-drilling-sniffer.d.ts +5 -0
- package/dist/src/sniffers/prop-drilling-sniffer.d.ts.map +1 -0
- package/dist/src/sniffers/prop-drilling-sniffer.js +145 -0
- package/dist/src/sniffers/prop-drilling-sniffer.js.map +1 -0
- package/dist/src/sniffers/prop-explosion-sniffer.d.ts +4 -0
- package/dist/src/sniffers/prop-explosion-sniffer.d.ts.map +1 -0
- package/dist/src/sniffers/prop-explosion-sniffer.js +134 -0
- package/dist/src/sniffers/prop-explosion-sniffer.js.map +1 -0
- package/dist/src/sniffers/sniffer-interface.d.ts +88 -0
- package/dist/src/sniffers/sniffer-interface.d.ts.map +1 -0
- package/dist/src/sniffers/sniffer-interface.js +18 -0
- package/dist/src/sniffers/sniffer-interface.js.map +1 -0
- package/dist/src/tui/interactive-viewer.d.ts +7 -0
- package/dist/src/tui/interactive-viewer.d.ts.map +1 -0
- package/dist/src/tui/interactive-viewer.js +453 -0
- package/dist/src/tui/interactive-viewer.js.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +90 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/regex-helpers.d.ts +53 -0
- package/dist/src/utils/regex-helpers.d.ts.map +1 -0
- package/dist/src/utils/regex-helpers.js +275 -0
- package/dist/src/utils/regex-helpers.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const regex_helpers_js_1 = require("../utils/regex-helpers.js");
|
|
4
|
+
function buildSuggestion(componentName) {
|
|
5
|
+
return (`**Consider refactoring \`${componentName}\`:**\n` +
|
|
6
|
+
'- Group related props into object props (e.g., `userConfig`, `handlers`)\n' +
|
|
7
|
+
'- Use React Context for widely-shared values\n' +
|
|
8
|
+
'- Split into smaller, focused components\n' +
|
|
9
|
+
'- Consider the Compound Components pattern');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detect destructured props in component declarations that exceed the threshold.
|
|
13
|
+
*
|
|
14
|
+
* Searches for PascalCase function declarations with destructured parameters
|
|
15
|
+
* and counts the individual prop names.
|
|
16
|
+
*/
|
|
17
|
+
function detectDestructuredProps(cleaned, originalSource, filePath, threshold, severity) {
|
|
18
|
+
const detections = [];
|
|
19
|
+
// Reset the regex since it has the global flag
|
|
20
|
+
const regex = new RegExp(regex_helpers_js_1.FUNCTIONAL_COMPONENT_DECL.source, regex_helpers_js_1.FUNCTIONAL_COMPONENT_DECL.flags);
|
|
21
|
+
let match;
|
|
22
|
+
while ((match = regex.exec(cleaned)) !== null) {
|
|
23
|
+
// Component name is in group 1 (function decl), group 2 (memo/forwardRef), or group 3 (const assignment)
|
|
24
|
+
const componentName = match[1] || match[2] || match[3];
|
|
25
|
+
if (!componentName)
|
|
26
|
+
continue;
|
|
27
|
+
// Find the destructured props after this match
|
|
28
|
+
// Look for the opening paren + destructuring pattern starting from the match
|
|
29
|
+
const afterMatch = cleaned.substring(match.index);
|
|
30
|
+
const destructuredMatch = regex_helpers_js_1.DESTRUCTURED_PROPS.exec(afterMatch);
|
|
31
|
+
if (!destructuredMatch)
|
|
32
|
+
continue;
|
|
33
|
+
const propsString = destructuredMatch[1];
|
|
34
|
+
const propNames = (0, regex_helpers_js_1.parseDestructuredProps)(propsString);
|
|
35
|
+
const propCount = propNames.length;
|
|
36
|
+
if (propCount > threshold) {
|
|
37
|
+
// Use the position in the original source for accurate line/column
|
|
38
|
+
const line = (0, regex_helpers_js_1.getLineNumber)(originalSource, match.index);
|
|
39
|
+
const column = (0, regex_helpers_js_1.getColumnNumber)(originalSource, match.index);
|
|
40
|
+
detections.push({
|
|
41
|
+
snifferName: 'prop-explosion',
|
|
42
|
+
filePath,
|
|
43
|
+
line,
|
|
44
|
+
column,
|
|
45
|
+
message: `Component "${componentName}" has ${propCount} props (threshold: ${threshold})`,
|
|
46
|
+
severity,
|
|
47
|
+
suggestion: buildSuggestion(componentName),
|
|
48
|
+
details: {
|
|
49
|
+
componentName,
|
|
50
|
+
propCount,
|
|
51
|
+
propNames,
|
|
52
|
+
threshold,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return detections;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Detect JSX usage sites where a PascalCase component receives too many attributes.
|
|
61
|
+
*
|
|
62
|
+
* Counts non-spread attributes on JSX opening tags. Spread attributes are excluded
|
|
63
|
+
* because they represent an unknown number of props.
|
|
64
|
+
*/
|
|
65
|
+
function detectJsxAttributeExplosion(cleaned, originalSource, filePath, threshold, severity) {
|
|
66
|
+
const detections = [];
|
|
67
|
+
const jsxRegex = new RegExp(regex_helpers_js_1.JSX_OPENING_TAG.source, regex_helpers_js_1.JSX_OPENING_TAG.flags);
|
|
68
|
+
let match;
|
|
69
|
+
while ((match = jsxRegex.exec(cleaned)) !== null) {
|
|
70
|
+
const componentName = match[1];
|
|
71
|
+
const attributesText = match[2];
|
|
72
|
+
// Only look at PascalCase component names (skip HTML elements)
|
|
73
|
+
if (!componentName || !/^[A-Z]/.test(componentName))
|
|
74
|
+
continue;
|
|
75
|
+
// Skip self-referencing / no attributes
|
|
76
|
+
if (!attributesText || !attributesText.trim())
|
|
77
|
+
continue;
|
|
78
|
+
// Count non-spread attributes
|
|
79
|
+
const attrRegex = new RegExp(regex_helpers_js_1.JSX_ATTRIBUTE.source, regex_helpers_js_1.JSX_ATTRIBUTE.flags);
|
|
80
|
+
const propNames = [];
|
|
81
|
+
let attrMatch;
|
|
82
|
+
while ((attrMatch = attrRegex.exec(attributesText)) !== null) {
|
|
83
|
+
if (attrMatch[1]) {
|
|
84
|
+
propNames.push(attrMatch[1]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const propCount = propNames.length;
|
|
88
|
+
if (propCount > threshold) {
|
|
89
|
+
const line = (0, regex_helpers_js_1.getLineNumber)(originalSource, match.index);
|
|
90
|
+
const column = (0, regex_helpers_js_1.getColumnNumber)(originalSource, match.index);
|
|
91
|
+
detections.push({
|
|
92
|
+
snifferName: 'prop-explosion',
|
|
93
|
+
filePath,
|
|
94
|
+
line,
|
|
95
|
+
column,
|
|
96
|
+
message: `Component "${componentName}" has ${propCount} props (threshold: ${threshold})`,
|
|
97
|
+
severity,
|
|
98
|
+
suggestion: buildSuggestion(componentName),
|
|
99
|
+
details: {
|
|
100
|
+
componentName,
|
|
101
|
+
propCount,
|
|
102
|
+
propNames,
|
|
103
|
+
threshold,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return detections;
|
|
109
|
+
}
|
|
110
|
+
const propExplosionSniffer = {
|
|
111
|
+
name: 'prop-explosion',
|
|
112
|
+
description: 'Detects React components that receive too many props, suggesting they should be refactored into smaller components or use composition patterns.',
|
|
113
|
+
meta: {
|
|
114
|
+
name: 'prop-explosion',
|
|
115
|
+
description: 'Detects React components that receive too many props, suggesting they should be refactored into smaller components or use composition patterns.',
|
|
116
|
+
category: 'props',
|
|
117
|
+
severity: 'warning',
|
|
118
|
+
defaultConfig: {
|
|
119
|
+
threshold: 7,
|
|
120
|
+
severity: 'warning',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
detect(fileContent, filePath, config) {
|
|
124
|
+
const threshold = typeof config.threshold === 'number' ? config.threshold : 7;
|
|
125
|
+
const severity = config.severity || 'warning';
|
|
126
|
+
// Strip comments and strings so we don't get false positives
|
|
127
|
+
const cleaned = (0, regex_helpers_js_1.stripCommentsAndStrings)(fileContent);
|
|
128
|
+
const declarationDetections = detectDestructuredProps(cleaned, fileContent, filePath, threshold, severity);
|
|
129
|
+
const jsxDetections = detectJsxAttributeExplosion(cleaned, fileContent, filePath, threshold, severity);
|
|
130
|
+
return [...declarationDetections, ...jsxDetections];
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
exports.default = propExplosionSniffer;
|
|
134
|
+
//# sourceMappingURL=prop-explosion-sniffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prop-explosion-sniffer.js","sourceRoot":"","sources":["../../../src/sniffers/prop-explosion-sniffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export type Severity = 'info' | 'warning' | 'error';
|
|
2
|
+
export type SnifferCategory = 'props' | 'hooks' | 'architecture' | 'custom';
|
|
3
|
+
export interface Detection {
|
|
4
|
+
snifferName: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
line: number;
|
|
7
|
+
column: number;
|
|
8
|
+
message: string;
|
|
9
|
+
severity: Severity;
|
|
10
|
+
suggestion: string;
|
|
11
|
+
details?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface SnifferMeta {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
category: SnifferCategory;
|
|
17
|
+
severity: Severity;
|
|
18
|
+
defaultConfig: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export interface SnifferExport {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
meta: SnifferMeta;
|
|
24
|
+
detect(fileContent: string, filePath: string, config: Record<string, unknown>): Detection[];
|
|
25
|
+
}
|
|
26
|
+
export interface SnifferResult {
|
|
27
|
+
snifferName: string;
|
|
28
|
+
filePath: string;
|
|
29
|
+
detections: Detection[];
|
|
30
|
+
durationMs: number;
|
|
31
|
+
error: string | null;
|
|
32
|
+
}
|
|
33
|
+
export interface SnifferConfig {
|
|
34
|
+
include: string[];
|
|
35
|
+
exclude: string[];
|
|
36
|
+
parallel: boolean;
|
|
37
|
+
maxWorkers: number;
|
|
38
|
+
timeoutMs: number;
|
|
39
|
+
outputFormat: 'markdown' | 'json';
|
|
40
|
+
outputPath: string | null;
|
|
41
|
+
sniffers: Record<string, Record<string, unknown>>;
|
|
42
|
+
plugins: PluginEntry[];
|
|
43
|
+
}
|
|
44
|
+
export interface PluginEntry {
|
|
45
|
+
path: string;
|
|
46
|
+
config?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
export interface SnifferEntry {
|
|
49
|
+
name: string;
|
|
50
|
+
snifferPath: string;
|
|
51
|
+
config: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
export interface WorkerTask {
|
|
54
|
+
type: 'run-sniffer';
|
|
55
|
+
taskId: string;
|
|
56
|
+
snifferPath: string;
|
|
57
|
+
fileContent: string;
|
|
58
|
+
filePath: string;
|
|
59
|
+
config: Record<string, unknown>;
|
|
60
|
+
timeoutMs: number;
|
|
61
|
+
}
|
|
62
|
+
export interface WorkerResultMessage {
|
|
63
|
+
type: 'sniffer-result';
|
|
64
|
+
taskId: string;
|
|
65
|
+
result: SnifferResult;
|
|
66
|
+
}
|
|
67
|
+
export interface WorkerErrorMessage {
|
|
68
|
+
type: 'sniffer-error';
|
|
69
|
+
taskId: string;
|
|
70
|
+
error: string;
|
|
71
|
+
}
|
|
72
|
+
export type WorkerMessage = WorkerResultMessage | WorkerErrorMessage | {
|
|
73
|
+
type: 'shutdown';
|
|
74
|
+
};
|
|
75
|
+
export declare const REQUIRED_EXPORT_SCHEMA: {
|
|
76
|
+
readonly name: "string";
|
|
77
|
+
readonly description: "string";
|
|
78
|
+
readonly meta: "object";
|
|
79
|
+
readonly detect: "function";
|
|
80
|
+
};
|
|
81
|
+
export declare const REQUIRED_META_SCHEMA: {
|
|
82
|
+
readonly name: "string";
|
|
83
|
+
readonly description: "string";
|
|
84
|
+
readonly category: "string";
|
|
85
|
+
readonly severity: "string";
|
|
86
|
+
readonly defaultConfig: "object";
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=sniffer-interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sniffer-interface.d.ts","sourceRoot":"","sources":["../../../src/sniffers/sniffer-interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.REQUIRED_META_SCHEMA = exports.REQUIRED_EXPORT_SCHEMA = void 0;
|
|
4
|
+
// Validation schema for plugin exports
|
|
5
|
+
exports.REQUIRED_EXPORT_SCHEMA = {
|
|
6
|
+
name: 'string',
|
|
7
|
+
description: 'string',
|
|
8
|
+
meta: 'object',
|
|
9
|
+
detect: 'function',
|
|
10
|
+
};
|
|
11
|
+
exports.REQUIRED_META_SCHEMA = {
|
|
12
|
+
name: 'string',
|
|
13
|
+
description: 'string',
|
|
14
|
+
category: 'string',
|
|
15
|
+
severity: 'string',
|
|
16
|
+
defaultConfig: 'object',
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=sniffer-interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sniffer-interface.js","sourceRoot":"","sources":["../../../src/sniffers/sniffer-interface.ts"],"names":[],"mappings":";;;AAqFA,uCAAuC;AAC1B,QAAA,sBAAsB,GAAG;IACpC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,QAAQ;IACrB,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,UAAU;CACV,CAAC;AAEE,QAAA,oBAAoB,GAAG;IAClC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,QAAQ;IAClB,aAAa,EAAE,QAAQ;CACf,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SnifferResult } from '../sniffers/sniffer-interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Launch the interactive TUI viewer.
|
|
4
|
+
* Returns a promise that resolves when the user quits.
|
|
5
|
+
*/
|
|
6
|
+
export declare function interactiveViewer(results: Map<string, SnifferResult[]>, totalIssues: number, fileCount: number, targetDir: string, batchSize: number): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=interactive-viewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-viewer.d.ts","sourceRoot":"","sources":["../../../src/tui/interactive-viewer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAkSjF;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,EACrC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAqOf"}
|