@empline/preflight 1.1.47 → 1.1.49
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/dist/bin/init.d.ts +18 -0
- package/dist/bin/init.d.ts.map +1 -0
- package/dist/bin/init.js +369 -0
- package/dist/bin/init.js.map +1 -0
- package/dist/bin/preflight.js +201 -0
- package/dist/bin/preflight.js.map +1 -1
- package/dist/bin/preinstall.js +7 -0
- package/dist/bin/preinstall.js.map +1 -1
- package/dist/checks/react/vercel-react-best-practices.d.ts +38 -0
- package/dist/checks/react/vercel-react-best-practices.d.ts.map +1 -0
- package/dist/checks/react/vercel-react-best-practices.js +547 -0
- package/dist/checks/react/vercel-react-best-practices.js.map +1 -0
- package/dist/checks/system/preflight-actionable-output.d.ts +18 -0
- package/dist/checks/system/preflight-actionable-output.d.ts.map +1 -0
- package/dist/checks/system/preflight-actionable-output.js +216 -0
- package/dist/checks/system/preflight-actionable-output.js.map +1 -0
- package/dist/checks/ui/responsive-text-truncation.d.ts.map +1 -1
- package/dist/checks/ui/responsive-text-truncation.js +16 -8
- package/dist/checks/ui/responsive-text-truncation.js.map +1 -1
- package/dist/checks/ui/web-design-guidelines.d.ts +37 -0
- package/dist/checks/ui/web-design-guidelines.d.ts.map +1 -0
- package/dist/checks/ui/web-design-guidelines.js +545 -0
- package/dist/checks/ui/web-design-guidelines.js.map +1 -0
- package/dist/lib/activation.d.ts +18 -0
- package/dist/lib/activation.d.ts.map +1 -0
- package/dist/lib/activation.js +283 -0
- package/dist/lib/activation.js.map +1 -0
- package/dist/lib/ai-commands.d.ts +72 -0
- package/dist/lib/ai-commands.d.ts.map +1 -0
- package/dist/lib/ai-commands.js +393 -0
- package/dist/lib/ai-commands.js.map +1 -0
- package/dist/runner.d.ts +20 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +176 -54
- package/dist/runner.js.map +1 -1
- package/dist/shared/concurrency-config.d.ts +2 -0
- package/dist/shared/concurrency-config.d.ts.map +1 -1
- package/dist/shared/concurrency-config.js +12 -1
- package/dist/shared/concurrency-config.js.map +1 -1
- package/dist/utils/console-chars.d.ts +6 -6
- package/package.json +2 -1
- package/templates/domain-specific/trading-card-system/missing-page-layout.ts +377 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Preflight: Vercel React Best Practices
|
|
5
|
+
*
|
|
6
|
+
* Validates React and Next.js code against Vercel's performance optimization guidelines.
|
|
7
|
+
* Based on: https://github.com/vercel-labs/agent-skills (vercel-react-best-practices)
|
|
8
|
+
*
|
|
9
|
+
* Categories checked:
|
|
10
|
+
* - Bundle Size Optimization (CRITICAL) - barrel imports, dynamic imports
|
|
11
|
+
* - Eliminating Waterfalls (CRITICAL) - sequential awaits, Promise.all
|
|
12
|
+
* - Server-Side Performance (HIGH) - server action auth, RSC serialization
|
|
13
|
+
* - Re-render Optimization (MEDIUM) - functional setState, lazy initialization
|
|
14
|
+
*
|
|
15
|
+
* Each finding includes the rule ID for reference to the full documentation.
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.tags = exports.description = exports.blocking = exports.category = exports.name = exports.id = void 0;
|
|
52
|
+
exports.run = run;
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const path = __importStar(require("path"));
|
|
55
|
+
const glob_1 = require("glob");
|
|
56
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
57
|
+
function createDivider(length, _style) {
|
|
58
|
+
return "═".repeat(length);
|
|
59
|
+
}
|
|
60
|
+
function writeFindings(findings) {
|
|
61
|
+
// Findings are already logged in summary, this is for structured output
|
|
62
|
+
if (process.env.PREFLIGHT_JSON_OUTPUT) {
|
|
63
|
+
console.log(JSON.stringify(findings, null, 2));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Check metadata
|
|
67
|
+
exports.id = "react/vercel-best-practices";
|
|
68
|
+
exports.name = "Vercel React Best Practices";
|
|
69
|
+
exports.category = "react";
|
|
70
|
+
exports.blocking = false; // Advisory - warns but doesn't block
|
|
71
|
+
exports.description = "Validates code against Vercel's React/Next.js performance guidelines";
|
|
72
|
+
exports.tags = ["react", "nextjs", "performance", "vercel", "bundle-size", "optimization"];
|
|
73
|
+
// =============================================================================
|
|
74
|
+
// CONFIGURATION
|
|
75
|
+
// =============================================================================
|
|
76
|
+
const FILE_PATTERNS = [
|
|
77
|
+
"app/**/*.{ts,tsx}",
|
|
78
|
+
"src/**/*.{ts,tsx}",
|
|
79
|
+
"pages/**/*.{ts,tsx}",
|
|
80
|
+
"components/**/*.{ts,tsx}",
|
|
81
|
+
];
|
|
82
|
+
const EXCLUDE_PATTERNS = [
|
|
83
|
+
"node_modules/**",
|
|
84
|
+
"**/*.test.{ts,tsx}",
|
|
85
|
+
"**/*.spec.{ts,tsx}",
|
|
86
|
+
"**/*.stories.{tsx}",
|
|
87
|
+
"**/*.d.ts",
|
|
88
|
+
".next/**",
|
|
89
|
+
"dist/**",
|
|
90
|
+
"build/**",
|
|
91
|
+
];
|
|
92
|
+
// Libraries known to have expensive barrel exports (200-800ms import cost)
|
|
93
|
+
const BARREL_LIBRARIES = [
|
|
94
|
+
{ name: "lucide-react", directPath: "lucide-react/dist/esm/icons/" },
|
|
95
|
+
{ name: "@mui/material", directPath: "@mui/material/" },
|
|
96
|
+
{ name: "@mui/icons-material", directPath: "@mui/icons-material/" },
|
|
97
|
+
{ name: "@tabler/icons-react", directPath: "@tabler/icons-react/dist/esm/icons/" },
|
|
98
|
+
{ name: "react-icons", directPath: "react-icons/" },
|
|
99
|
+
{ name: "@radix-ui/react-icons", directPath: "@radix-ui/react-icons/" },
|
|
100
|
+
{ name: "lodash", directPath: "lodash/" },
|
|
101
|
+
{ name: "date-fns", directPath: "date-fns/" },
|
|
102
|
+
];
|
|
103
|
+
// Heavy components that should use dynamic imports
|
|
104
|
+
const HEAVY_COMPONENTS = [
|
|
105
|
+
{ pattern: /monaco.*editor/i, name: "Monaco Editor", size: "~300KB" },
|
|
106
|
+
{ pattern: /codemirror/i, name: "CodeMirror", size: "~200KB" },
|
|
107
|
+
{ pattern: /chart\.?js|recharts|victory|nivo/i, name: "Charting library", size: "~100-300KB" },
|
|
108
|
+
{ pattern: /pdf.*viewer|react-pdf/i, name: "PDF viewer", size: "~200KB" },
|
|
109
|
+
{ pattern: /mapbox|leaflet|google.*maps/i, name: "Maps library", size: "~150KB" },
|
|
110
|
+
{ pattern: /three\.?js|@react-three/i, name: "Three.js/3D", size: "~500KB" },
|
|
111
|
+
{ pattern: /quill|draft-?js|slate|tiptap|prosemirror/i, name: "Rich text editor", size: "~100-200KB" },
|
|
112
|
+
{ pattern: /video.*player|react-player/i, name: "Video player", size: "~100KB" },
|
|
113
|
+
];
|
|
114
|
+
// =============================================================================
|
|
115
|
+
// DETECTION FUNCTIONS
|
|
116
|
+
// =============================================================================
|
|
117
|
+
/**
|
|
118
|
+
* Rule 2.1: Avoid Barrel File Imports (CRITICAL)
|
|
119
|
+
* Detects imports from barrel files that cause 200-800ms import overhead
|
|
120
|
+
*/
|
|
121
|
+
function detectBarrelImports(content, filePath) {
|
|
122
|
+
const findings = [];
|
|
123
|
+
const lines = content.split("\n");
|
|
124
|
+
for (let i = 0; i < lines.length; i++) {
|
|
125
|
+
const line = lines[i];
|
|
126
|
+
for (const lib of BARREL_LIBRARIES) {
|
|
127
|
+
// Match: import { X, Y } from 'library'
|
|
128
|
+
const barrelPattern = new RegExp(`import\\s*\\{[^}]+\\}\\s*from\\s*['"]${lib.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}['"]`);
|
|
129
|
+
if (barrelPattern.test(line)) {
|
|
130
|
+
findings.push({
|
|
131
|
+
file: filePath,
|
|
132
|
+
line: i + 1,
|
|
133
|
+
rule: "bundle-barrel-imports",
|
|
134
|
+
impact: "CRITICAL",
|
|
135
|
+
message: `Barrel import from '${lib.name}' loads entire library (200-800ms)`,
|
|
136
|
+
suggestion: `Import directly: import X from '${lib.directPath}x'`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return findings;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Rule 2.4: Dynamic Imports for Heavy Components (CRITICAL)
|
|
145
|
+
* Detects static imports of heavy components that should be dynamically imported
|
|
146
|
+
*/
|
|
147
|
+
function detectHeavyStaticImports(content, filePath) {
|
|
148
|
+
const findings = [];
|
|
149
|
+
const lines = content.split("\n");
|
|
150
|
+
// Skip if file already uses dynamic imports for heavy components
|
|
151
|
+
const usesDynamicImport = /dynamic\s*\(|import\s*\(/.test(content);
|
|
152
|
+
for (let i = 0; i < lines.length; i++) {
|
|
153
|
+
const line = lines[i];
|
|
154
|
+
// Only check static imports
|
|
155
|
+
if (!line.includes("import ") || line.includes("import("))
|
|
156
|
+
continue;
|
|
157
|
+
for (const heavy of HEAVY_COMPONENTS) {
|
|
158
|
+
if (heavy.pattern.test(line)) {
|
|
159
|
+
findings.push({
|
|
160
|
+
file: filePath,
|
|
161
|
+
line: i + 1,
|
|
162
|
+
rule: "bundle-dynamic-imports",
|
|
163
|
+
impact: "CRITICAL",
|
|
164
|
+
message: `Static import of ${heavy.name} (${heavy.size}) blocks initial load`,
|
|
165
|
+
suggestion: `Use dynamic import: const Component = dynamic(() => import('...'), { ssr: false })`,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return findings;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Rule 1.4: Promise.all() for Independent Operations (CRITICAL)
|
|
174
|
+
* Detects sequential awaits that could be parallelized
|
|
175
|
+
*/
|
|
176
|
+
function detectSequentialAwaits(content, filePath) {
|
|
177
|
+
const findings = [];
|
|
178
|
+
const lines = content.split("\n");
|
|
179
|
+
// Track consecutive await statements
|
|
180
|
+
let consecutiveAwaits = [];
|
|
181
|
+
for (let i = 0; i < lines.length; i++) {
|
|
182
|
+
const line = lines[i].trim();
|
|
183
|
+
// Match standalone await statements (const x = await ...)
|
|
184
|
+
if (/^(const|let|var)\s+\w+\s*=\s*await\s+/.test(line)) {
|
|
185
|
+
consecutiveAwaits.push(i + 1);
|
|
186
|
+
}
|
|
187
|
+
else if (consecutiveAwaits.length > 0 && line !== "" && !line.startsWith("//")) {
|
|
188
|
+
// Non-await line encountered, check if we had 3+ consecutive awaits
|
|
189
|
+
if (consecutiveAwaits.length >= 3) {
|
|
190
|
+
findings.push({
|
|
191
|
+
file: filePath,
|
|
192
|
+
line: consecutiveAwaits[0],
|
|
193
|
+
rule: "async-parallel",
|
|
194
|
+
impact: "CRITICAL",
|
|
195
|
+
message: `${consecutiveAwaits.length} sequential awaits detected (lines ${consecutiveAwaits[0]}-${consecutiveAwaits[consecutiveAwaits.length - 1]})`,
|
|
196
|
+
suggestion: "Use Promise.all() for independent operations: const [a, b, c] = await Promise.all([...])",
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
consecutiveAwaits = [];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return findings;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Rule 3.1: Authenticate Server Actions (CRITICAL)
|
|
206
|
+
* Detects Server Actions without authentication checks
|
|
207
|
+
*/
|
|
208
|
+
function detectUnauthenticatedServerActions(content, filePath) {
|
|
209
|
+
const findings = [];
|
|
210
|
+
// Only check files with "use server"
|
|
211
|
+
if (!content.includes('"use server"') && !content.includes("'use server'")) {
|
|
212
|
+
return findings;
|
|
213
|
+
}
|
|
214
|
+
const lines = content.split("\n");
|
|
215
|
+
let inServerAction = false;
|
|
216
|
+
let actionStartLine = 0;
|
|
217
|
+
let hasAuthCheck = false;
|
|
218
|
+
let braceDepth = 0;
|
|
219
|
+
for (let i = 0; i < lines.length; i++) {
|
|
220
|
+
const line = lines[i];
|
|
221
|
+
// Detect function start after "use server"
|
|
222
|
+
if (/export\s+(async\s+)?function\s+\w+/.test(line)) {
|
|
223
|
+
inServerAction = true;
|
|
224
|
+
actionStartLine = i + 1;
|
|
225
|
+
hasAuthCheck = false;
|
|
226
|
+
braceDepth = 0;
|
|
227
|
+
}
|
|
228
|
+
if (inServerAction) {
|
|
229
|
+
// Count braces to track function scope
|
|
230
|
+
braceDepth += (line.match(/{/g) || []).length;
|
|
231
|
+
braceDepth -= (line.match(/}/g) || []).length;
|
|
232
|
+
// Check for auth patterns
|
|
233
|
+
if (/auth\s*\(|verifySession|getSession|getCurrentUser|checkAuth|isAuthenticated/.test(line)) {
|
|
234
|
+
hasAuthCheck = true;
|
|
235
|
+
}
|
|
236
|
+
// Function ended
|
|
237
|
+
if (braceDepth <= 0 && line.includes("}")) {
|
|
238
|
+
if (!hasAuthCheck) {
|
|
239
|
+
findings.push({
|
|
240
|
+
file: filePath,
|
|
241
|
+
line: actionStartLine,
|
|
242
|
+
rule: "server-auth",
|
|
243
|
+
impact: "CRITICAL",
|
|
244
|
+
message: "Server Action without authentication check",
|
|
245
|
+
suggestion: "Add auth check: const session = await verifySession(); if (!session) throw unauthorized()",
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
inServerAction = false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return findings;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Rule 5.5: Use Functional setState Updates (MEDIUM)
|
|
256
|
+
* Detects setState calls that reference state directly instead of using functional form
|
|
257
|
+
*/
|
|
258
|
+
function detectDirectStateUpdates(content, filePath) {
|
|
259
|
+
const findings = [];
|
|
260
|
+
const lines = content.split("\n");
|
|
261
|
+
// Find useState declarations
|
|
262
|
+
const stateVars = [];
|
|
263
|
+
const useStatePattern = /const\s+\[(\w+),\s*(\w+)\]\s*=\s*useState/g;
|
|
264
|
+
for (let i = 0; i < lines.length; i++) {
|
|
265
|
+
let match;
|
|
266
|
+
while ((match = useStatePattern.exec(lines[i])) !== null) {
|
|
267
|
+
stateVars.push({ name: match[1], setter: match[2], line: i + 1 });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Check for direct state references in setters
|
|
271
|
+
for (const state of stateVars) {
|
|
272
|
+
for (let i = 0; i < lines.length; i++) {
|
|
273
|
+
const line = lines[i];
|
|
274
|
+
// Pattern: setX([...x, ...]) or setX(x.filter(...)) etc
|
|
275
|
+
const directUpdatePattern = new RegExp(`${state.setter}\\s*\\(\\s*(?:\\[\\s*\\.\\.\\.${state.name}|${state.name}\\s*\\.(?:filter|map|concat|slice))`);
|
|
276
|
+
if (directUpdatePattern.test(line)) {
|
|
277
|
+
findings.push({
|
|
278
|
+
file: filePath,
|
|
279
|
+
line: i + 1,
|
|
280
|
+
rule: "rerender-functional-setstate",
|
|
281
|
+
impact: "MEDIUM",
|
|
282
|
+
message: `Direct state reference in ${state.setter}() may cause stale closures`,
|
|
283
|
+
suggestion: `Use functional update: ${state.setter}(prev => [...prev, newItem])`,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return findings;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Rule 5.6: Use Lazy State Initialization (MEDIUM)
|
|
292
|
+
* Detects expensive computations in useState initializers
|
|
293
|
+
*/
|
|
294
|
+
function detectEagerStateInit(content, filePath) {
|
|
295
|
+
const findings = [];
|
|
296
|
+
const lines = content.split("\n");
|
|
297
|
+
const expensivePatterns = [
|
|
298
|
+
{ pattern: /useState\s*\(\s*JSON\.parse/, name: "JSON.parse" },
|
|
299
|
+
{ pattern: /useState\s*\(\s*localStorage\.getItem/, name: "localStorage.getItem" },
|
|
300
|
+
{ pattern: /useState\s*\(\s*sessionStorage\.getItem/, name: "sessionStorage.getItem" },
|
|
301
|
+
{ pattern: /useState\s*\(\s*\w+\.map\s*\(/, name: "array transformation" },
|
|
302
|
+
{ pattern: /useState\s*\(\s*\w+\.filter\s*\(/, name: "array filter" },
|
|
303
|
+
{ pattern: /useState\s*\(\s*\w+\.reduce\s*\(/, name: "array reduce" },
|
|
304
|
+
{ pattern: /useState\s*\(\s*new\s+Map\s*\(/, name: "new Map()" },
|
|
305
|
+
{ pattern: /useState\s*\(\s*new\s+Set\s*\(/, name: "new Set()" },
|
|
306
|
+
];
|
|
307
|
+
for (let i = 0; i < lines.length; i++) {
|
|
308
|
+
const line = lines[i];
|
|
309
|
+
for (const exp of expensivePatterns) {
|
|
310
|
+
if (exp.pattern.test(line)) {
|
|
311
|
+
findings.push({
|
|
312
|
+
file: filePath,
|
|
313
|
+
line: i + 1,
|
|
314
|
+
rule: "rerender-lazy-state-init",
|
|
315
|
+
impact: "MEDIUM",
|
|
316
|
+
message: `Expensive ${exp.name} runs on every render, not just initialization`,
|
|
317
|
+
suggestion: "Use lazy initialization: useState(() => expensive())",
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return findings;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Rule 7.12: Use toSorted() Instead of sort() (MEDIUM)
|
|
326
|
+
* Detects .sort() mutations on state/props
|
|
327
|
+
*/
|
|
328
|
+
function detectSortMutations(content, filePath) {
|
|
329
|
+
const findings = [];
|
|
330
|
+
const lines = content.split("\n");
|
|
331
|
+
for (let i = 0; i < lines.length; i++) {
|
|
332
|
+
const line = lines[i];
|
|
333
|
+
// Detect .sort() without spread/toSorted
|
|
334
|
+
if (/\w+\.sort\s*\(/.test(line) && !line.includes("[...") && !line.includes("toSorted")) {
|
|
335
|
+
// Skip if it's clearly a local variable being sorted
|
|
336
|
+
if (!/^(const|let|var)\s+\w+\s*=.*\.sort/.test(line.trim())) {
|
|
337
|
+
findings.push({
|
|
338
|
+
file: filePath,
|
|
339
|
+
line: i + 1,
|
|
340
|
+
rule: "js-tosorted",
|
|
341
|
+
impact: "MEDIUM",
|
|
342
|
+
message: ".sort() mutates array in place, may corrupt React state/props",
|
|
343
|
+
suggestion: "Use .toSorted() or [...arr].sort() for immutability",
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return findings;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Rule 6.7: Use Explicit Conditional Rendering (LOW)
|
|
352
|
+
* Detects && conditionals with numbers that may render "0"
|
|
353
|
+
*/
|
|
354
|
+
function detectImplicitConditionals(content, filePath) {
|
|
355
|
+
const findings = [];
|
|
356
|
+
const lines = content.split("\n");
|
|
357
|
+
for (let i = 0; i < lines.length; i++) {
|
|
358
|
+
const line = lines[i];
|
|
359
|
+
// Pattern: {count && <Component />} where count could be 0
|
|
360
|
+
if (/\{\s*\w+(?:\.length|Count|count|num|size)\s*&&/.test(line)) {
|
|
361
|
+
findings.push({
|
|
362
|
+
file: filePath,
|
|
363
|
+
line: i + 1,
|
|
364
|
+
rule: "rendering-explicit-conditional",
|
|
365
|
+
impact: "LOW",
|
|
366
|
+
message: "Numeric && conditional may render '0' or 'NaN' as text",
|
|
367
|
+
suggestion: "Use explicit ternary: {count > 0 ? <Component /> : null}",
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return findings;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Rule 2.3: Defer Non-Critical Third-Party Libraries (MEDIUM)
|
|
375
|
+
* Detects static imports of analytics/logging that should load after hydration
|
|
376
|
+
*/
|
|
377
|
+
function detectEagerAnalytics(content, filePath) {
|
|
378
|
+
const findings = [];
|
|
379
|
+
const lines = content.split("\n");
|
|
380
|
+
const analyticsLibs = [
|
|
381
|
+
"@vercel/analytics",
|
|
382
|
+
"@vercel/speed-insights",
|
|
383
|
+
"mixpanel",
|
|
384
|
+
"amplitude",
|
|
385
|
+
"segment",
|
|
386
|
+
"@sentry/nextjs",
|
|
387
|
+
"@sentry/react",
|
|
388
|
+
"posthog",
|
|
389
|
+
"hotjar",
|
|
390
|
+
"heap",
|
|
391
|
+
"datadog",
|
|
392
|
+
];
|
|
393
|
+
for (let i = 0; i < lines.length; i++) {
|
|
394
|
+
const line = lines[i];
|
|
395
|
+
// Skip dynamic imports
|
|
396
|
+
if (line.includes("dynamic(") || line.includes("import("))
|
|
397
|
+
continue;
|
|
398
|
+
for (const lib of analyticsLibs) {
|
|
399
|
+
if (line.includes(`from '${lib}'`) || line.includes(`from "${lib}"`)) {
|
|
400
|
+
findings.push({
|
|
401
|
+
file: filePath,
|
|
402
|
+
line: i + 1,
|
|
403
|
+
rule: "bundle-defer-third-party",
|
|
404
|
+
impact: "MEDIUM",
|
|
405
|
+
message: `Static import of ${lib} blocks initial bundle`,
|
|
406
|
+
suggestion: `Use dynamic import: const Analytics = dynamic(() => import('${lib}'), { ssr: false })`,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return findings;
|
|
412
|
+
}
|
|
413
|
+
// =============================================================================
|
|
414
|
+
// MAIN
|
|
415
|
+
// =============================================================================
|
|
416
|
+
async function run() {
|
|
417
|
+
const startTime = Date.now();
|
|
418
|
+
const allFindings = [];
|
|
419
|
+
console.log(`\n${console_chars_1.emoji.lightning} VERCEL REACT BEST PRACTICES`);
|
|
420
|
+
console.log(createDivider(65, "heavy"));
|
|
421
|
+
// Find all files
|
|
422
|
+
const allFiles = [];
|
|
423
|
+
for (const pattern of FILE_PATTERNS) {
|
|
424
|
+
const matches = await (0, glob_1.glob)(pattern, {
|
|
425
|
+
cwd: process.cwd(),
|
|
426
|
+
ignore: EXCLUDE_PATTERNS,
|
|
427
|
+
});
|
|
428
|
+
allFiles.push(...matches);
|
|
429
|
+
}
|
|
430
|
+
const uniqueFiles = [...new Set(allFiles)];
|
|
431
|
+
if (uniqueFiles.length === 0) {
|
|
432
|
+
console.log(`${console_chars_1.emoji.skip} No React/TypeScript files found`);
|
|
433
|
+
return {
|
|
434
|
+
passed: true,
|
|
435
|
+
findings: [],
|
|
436
|
+
duration: Date.now() - startTime,
|
|
437
|
+
metadata: { skipped: true },
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
console.log(`\n${console_chars_1.emoji.search || "[SEARCH]"} Scanning ${uniqueFiles.length} files...`);
|
|
441
|
+
// Analyze each file
|
|
442
|
+
for (const relativePath of uniqueFiles) {
|
|
443
|
+
const filePath = path.join(process.cwd(), relativePath);
|
|
444
|
+
if (!fs.existsSync(filePath))
|
|
445
|
+
continue;
|
|
446
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
447
|
+
// Run all detection functions
|
|
448
|
+
allFindings.push(...detectBarrelImports(content, relativePath));
|
|
449
|
+
allFindings.push(...detectHeavyStaticImports(content, relativePath));
|
|
450
|
+
allFindings.push(...detectSequentialAwaits(content, relativePath));
|
|
451
|
+
allFindings.push(...detectUnauthenticatedServerActions(content, relativePath));
|
|
452
|
+
allFindings.push(...detectDirectStateUpdates(content, relativePath));
|
|
453
|
+
allFindings.push(...detectEagerStateInit(content, relativePath));
|
|
454
|
+
allFindings.push(...detectSortMutations(content, relativePath));
|
|
455
|
+
allFindings.push(...detectImplicitConditionals(content, relativePath));
|
|
456
|
+
allFindings.push(...detectEagerAnalytics(content, relativePath));
|
|
457
|
+
}
|
|
458
|
+
// Group findings by impact
|
|
459
|
+
const critical = allFindings.filter((f) => f.impact === "CRITICAL");
|
|
460
|
+
const high = allFindings.filter((f) => f.impact === "HIGH");
|
|
461
|
+
const medium = allFindings.filter((f) => f.impact === "MEDIUM");
|
|
462
|
+
const low = allFindings.filter((f) => f.impact === "LOW");
|
|
463
|
+
// Convert to PreflightFinding format
|
|
464
|
+
const preflightFindings = allFindings.map((f) => ({
|
|
465
|
+
message: `[${f.rule}] ${f.message}`,
|
|
466
|
+
level: f.impact === "CRITICAL" || f.impact === "HIGH" ? "error" : "warning",
|
|
467
|
+
file: f.file,
|
|
468
|
+
line: f.line,
|
|
469
|
+
code: `vercel-${f.rule}`,
|
|
470
|
+
suggestion: f.suggestion,
|
|
471
|
+
}));
|
|
472
|
+
// Summary
|
|
473
|
+
console.log(`\n${console_chars_1.emoji.chart || "[CHART]"} Summary:`);
|
|
474
|
+
console.log(` Files scanned: ${uniqueFiles.length}`);
|
|
475
|
+
console.log(` CRITICAL: ${critical.length}`);
|
|
476
|
+
console.log(` HIGH: ${high.length}`);
|
|
477
|
+
console.log(` MEDIUM: ${medium.length}`);
|
|
478
|
+
console.log(` LOW: ${low.length}`);
|
|
479
|
+
writeFindings(preflightFindings.map((f) => ({
|
|
480
|
+
message: f.message,
|
|
481
|
+
severity: f.level === "error" ? "error" : "warning",
|
|
482
|
+
file: f.file,
|
|
483
|
+
line: f.line,
|
|
484
|
+
code: f.code || exports.id,
|
|
485
|
+
suggestion: f.suggestion,
|
|
486
|
+
})));
|
|
487
|
+
if (allFindings.length === 0) {
|
|
488
|
+
console.log(`\n${console_chars_1.emoji.success || "[OK]"} VERCEL REACT BEST PRACTICES PASSED`);
|
|
489
|
+
console.log(`\nNo performance issues detected.`);
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
// Show critical findings
|
|
493
|
+
if (critical.length > 0) {
|
|
494
|
+
console.log(`\n${console_chars_1.emoji.error || "[ERROR]"} CRITICAL Issues (fix these first):`);
|
|
495
|
+
for (const f of critical.slice(0, 10)) {
|
|
496
|
+
console.log(`\n ${f.file}:${f.line}`);
|
|
497
|
+
console.log(` Rule: ${f.rule}`);
|
|
498
|
+
console.log(` Issue: ${f.message}`);
|
|
499
|
+
console.log(` Fix: ${f.suggestion}`);
|
|
500
|
+
}
|
|
501
|
+
if (critical.length > 10) {
|
|
502
|
+
console.log(`\n ... and ${critical.length - 10} more critical issues`);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
// Show some high/medium findings
|
|
506
|
+
if (high.length > 0 || medium.length > 0) {
|
|
507
|
+
const otherFindings = [...high, ...medium].slice(0, 5);
|
|
508
|
+
console.log(`\n${console_chars_1.emoji.warning || "[WARN]"} Other Issues:`);
|
|
509
|
+
for (const f of otherFindings) {
|
|
510
|
+
console.log(` ${f.file}:${f.line} [${f.impact}] ${f.message}`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
console.log(`\n${console_chars_1.emoji.info || "[INFO]"} Reference:`);
|
|
514
|
+
console.log(` Full documentation: https://github.com/vercel-labs/agent-skills`);
|
|
515
|
+
console.log(` Run 'npx add-skill vercel-labs/agent-skills' for AI agent integration`);
|
|
516
|
+
const status = critical.length > 0 ? "FAILED" : "PASSED WITH WARNINGS";
|
|
517
|
+
console.log(`\n${critical.length > 0 ? console_chars_1.emoji.error : console_chars_1.emoji.warning} VERCEL REACT BEST PRACTICES ${status}`);
|
|
518
|
+
}
|
|
519
|
+
return {
|
|
520
|
+
passed: critical.length === 0, // Only fail on CRITICAL issues
|
|
521
|
+
findings: preflightFindings,
|
|
522
|
+
duration: Date.now() - startTime,
|
|
523
|
+
metadata: {
|
|
524
|
+
filesScanned: uniqueFiles.length,
|
|
525
|
+
critical: critical.length,
|
|
526
|
+
high: high.length,
|
|
527
|
+
medium: medium.length,
|
|
528
|
+
low: low.length,
|
|
529
|
+
rules: [
|
|
530
|
+
"bundle-barrel-imports",
|
|
531
|
+
"bundle-dynamic-imports",
|
|
532
|
+
"async-parallel",
|
|
533
|
+
"server-auth",
|
|
534
|
+
"rerender-functional-setstate",
|
|
535
|
+
"rerender-lazy-state-init",
|
|
536
|
+
"js-tosorted",
|
|
537
|
+
"rendering-explicit-conditional",
|
|
538
|
+
"bundle-defer-third-party",
|
|
539
|
+
],
|
|
540
|
+
},
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
// Standalone execution
|
|
544
|
+
if (require.main === module) {
|
|
545
|
+
run().then((result) => process.exit(result.passed ? 0 : 1));
|
|
546
|
+
}
|
|
547
|
+
//# sourceMappingURL=vercel-react-best-practices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-react-best-practices.js","sourceRoot":"","sources":["../../../src/checks/react/vercel-react-best-practices.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preflight Actionable Output Validation
|
|
3
|
+
*
|
|
4
|
+
* Validates that preflight checks produce AI-friendly actionable output:
|
|
5
|
+
* - File paths in findings
|
|
6
|
+
* - Line numbers when applicable
|
|
7
|
+
* - Suggestions for how to fix issues
|
|
8
|
+
*
|
|
9
|
+
* This ensures preflights are useful for automated fixing.
|
|
10
|
+
*/
|
|
11
|
+
import { PreflightCheckResult } from "../../core/types";
|
|
12
|
+
export declare const id = "system/preflight-actionable-output";
|
|
13
|
+
export declare const name = "Preflight Actionable Output";
|
|
14
|
+
export declare const category = "system";
|
|
15
|
+
export declare const blocking = false;
|
|
16
|
+
export declare const description = "Validates preflights produce actionable findings with file paths and suggestions";
|
|
17
|
+
export declare function run(): Promise<PreflightCheckResult>;
|
|
18
|
+
//# sourceMappingURL=preflight-actionable-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-actionable-output.d.ts","sourceRoot":"","sources":["../../../src/checks/system/preflight-actionable-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAG1E,eAAO,MAAM,EAAE,uCAAuC,CAAC;AACvD,eAAO,MAAM,IAAI,gCAAgC,CAAC;AAClD,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,WAAW,qFAAqF,CAAC;AAkF9G,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAqFzD"}
|