@empline/preflight 1.1.58 → 1.1.59

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.
Files changed (32) hide show
  1. package/dist/checks/accessibility/accessibility-validation.d.ts.map +1 -1
  2. package/dist/checks/accessibility/accessibility-validation.js +131 -14
  3. package/dist/checks/accessibility/accessibility-validation.js.map +1 -1
  4. package/dist/checks/accessibility/wcag-advanced-validation.d.ts +10 -0
  5. package/dist/checks/accessibility/wcag-advanced-validation.d.ts.map +1 -0
  6. package/dist/checks/accessibility/wcag-advanced-validation.js +622 -0
  7. package/dist/checks/accessibility/wcag-advanced-validation.js.map +1 -0
  8. package/dist/checks/database/query-performance-validation.d.ts +10 -0
  9. package/dist/checks/database/query-performance-validation.d.ts.map +1 -0
  10. package/dist/checks/database/query-performance-validation.js +544 -0
  11. package/dist/checks/database/query-performance-validation.js.map +1 -0
  12. package/dist/checks/react/react-patterns-validation.d.ts +10 -0
  13. package/dist/checks/react/react-patterns-validation.d.ts.map +1 -0
  14. package/dist/checks/react/react-patterns-validation.js +559 -0
  15. package/dist/checks/react/react-patterns-validation.js.map +1 -0
  16. package/dist/checks/security/security-headers-validation.d.ts +10 -0
  17. package/dist/checks/security/security-headers-validation.d.ts.map +1 -0
  18. package/dist/checks/security/security-headers-validation.js +594 -0
  19. package/dist/checks/security/security-headers-validation.js.map +1 -0
  20. package/dist/reporters/github-reporter.d.ts +35 -0
  21. package/dist/reporters/github-reporter.d.ts.map +1 -0
  22. package/dist/reporters/github-reporter.js +397 -0
  23. package/dist/reporters/github-reporter.js.map +1 -0
  24. package/dist/reporters/html-report.d.ts +12 -0
  25. package/dist/reporters/html-report.d.ts.map +1 -0
  26. package/dist/reporters/html-report.js +469 -0
  27. package/dist/reporters/html-report.js.map +1 -0
  28. package/dist/reporters/index.d.ts +8 -0
  29. package/dist/reporters/index.d.ts.map +1 -0
  30. package/dist/reporters/index.js +18 -0
  31. package/dist/reporters/index.js.map +1 -0
  32. package/package.json +1 -1
@@ -0,0 +1,544 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.tags = exports.blocking = exports.category = exports.description = exports.name = exports.id = void 0;
38
+ exports.run = run;
39
+ /**
40
+ * Query Performance Validation Preflight (BLOCKING)
41
+ *
42
+ * Validates database query patterns for performance issues:
43
+ *
44
+ * 1. N+1 Query Detection:
45
+ * - Queries in loops
46
+ * - Missing includes/joins
47
+ * - Sequential related queries
48
+ *
49
+ * 2. Missing Indexes:
50
+ * - Queries filtering on non-indexed fields
51
+ * - OrderBy on non-indexed columns
52
+ * - Frequent lookups by field
53
+ *
54
+ * 3. Query Optimization:
55
+ * - Select * patterns (over-fetching)
56
+ * - Missing pagination
57
+ * - Large result set handling
58
+ *
59
+ * 4. Transaction Safety:
60
+ * - Multi-step operations without transactions
61
+ * - Inconsistent transaction handling
62
+ *
63
+ * 5. Cascade Operations:
64
+ * - Dangerous cascade deletes
65
+ * - Missing soft delete patterns
66
+ */
67
+ const fs = __importStar(require("node:fs"));
68
+ const path = __importStar(require("node:path"));
69
+ const glob_1 = require("glob");
70
+ const console_chars_1 = require("../../utils/console-chars");
71
+ exports.id = "database/query-performance-validation";
72
+ exports.name = "Query Performance Validation";
73
+ exports.description = "Validates database query patterns for N+1, missing indexes, and performance issues";
74
+ exports.category = "database";
75
+ exports.blocking = true;
76
+ exports.tags = ["database", "prisma", "performance", "n+1", "indexes", "queries"];
77
+ function getLineNumber(content, index) {
78
+ return content.substring(0, index).split("\n").length;
79
+ }
80
+ async function checkNPlusOneQueries() {
81
+ const issues = [];
82
+ const files = await (0, glob_1.glob)([
83
+ "app/**/*.ts",
84
+ "app/**/*.tsx",
85
+ "lib/**/*.ts",
86
+ ], {
87
+ cwd: process.cwd(),
88
+ ignore: ["**/node_modules/**", "**/*.test.ts", "**/*.spec.ts"],
89
+ absolute: true,
90
+ });
91
+ for (const file of files) {
92
+ if (!fs.existsSync(file))
93
+ continue;
94
+ const content = fs.readFileSync(file, "utf-8");
95
+ const relativePath = path.relative(process.cwd(), file);
96
+ // Pattern 1: Query inside a loop
97
+ const queryInLoopPatterns = [
98
+ /for\s*\([^)]*\)\s*\{[^}]*(?:prisma|db)\.\w+\.(?:find|create|update|delete)/gs,
99
+ /\.forEach\s*\([^)]*=>\s*\{[^}]*(?:prisma|db)\.\w+\.(?:find|create|update|delete)/gs,
100
+ /\.map\s*\([^)]*=>\s*\{[^}]*await\s+(?:prisma|db)\.\w+\.(?:find|create|update|delete)/gs,
101
+ /while\s*\([^)]*\)\s*\{[^}]*(?:prisma|db)\.\w+\.(?:find|create|update|delete)/gs,
102
+ ];
103
+ for (const pattern of queryInLoopPatterns) {
104
+ let match;
105
+ while ((match = pattern.exec(content)) !== null) {
106
+ issues.push({
107
+ rule: "n-plus-one-loop",
108
+ message: "Database query inside loop (potential N+1)",
109
+ file: relativePath,
110
+ line: getLineNumber(content, match.index),
111
+ severity: "warning",
112
+ suggestion: "Use include/select to fetch related data in single query, or use createMany/updateMany",
113
+ });
114
+ }
115
+ }
116
+ // Pattern 2: Sequential queries for related data (could use include)
117
+ const sequentialQueryPattern = /await\s+(?:prisma|db)\.(\w+)\.find\w+[^;]*;\s*(?:const|let|var)\s+\w+\s*=\s*await\s+(?:prisma|db)\.(\w+)\.find/g;
118
+ let match;
119
+ while ((match = sequentialQueryPattern.exec(content)) !== null) {
120
+ const model1 = match[1];
121
+ const model2 = match[2];
122
+ // Check if these might be related (simple heuristic)
123
+ const surroundingCode = content.substring(match.index, match.index + 500);
124
+ const usesRelation = new RegExp(`${model1}.*${model2}|${model2}.*${model1}|\\b${model1}Id\\b|\\b${model2}Id\\b`, "i").test(surroundingCode);
125
+ if (usesRelation) {
126
+ issues.push({
127
+ rule: "n-plus-one-sequential",
128
+ message: `Sequential queries for ${model1} and ${model2} (may be related)`,
129
+ file: relativePath,
130
+ line: getLineNumber(content, match.index),
131
+ severity: "info",
132
+ suggestion: "Consider using include to fetch related data in one query",
133
+ });
134
+ }
135
+ }
136
+ // Pattern 3: Promise.all with individual queries
137
+ const promiseAllQueriesPattern = /Promise\.all\s*\(\s*\[[^\]]*\.map\s*\([^)]*=>[^)]*(?:prisma|db)\.\w+\.find/g;
138
+ while ((match = promiseAllQueriesPattern.exec(content)) !== null) {
139
+ issues.push({
140
+ rule: "n-plus-one-promise-all",
141
+ message: "Promise.all with mapped queries (N+1 pattern)",
142
+ file: relativePath,
143
+ line: getLineNumber(content, match.index),
144
+ severity: "warning",
145
+ suggestion: "Use findMany with where: { id: { in: ids } } instead",
146
+ });
147
+ }
148
+ }
149
+ return issues;
150
+ }
151
+ async function checkMissingIncludes() {
152
+ const issues = [];
153
+ const files = await (0, glob_1.glob)([
154
+ "app/**/*.ts",
155
+ "app/**/*.tsx",
156
+ "lib/**/*.ts",
157
+ ], {
158
+ cwd: process.cwd(),
159
+ ignore: ["**/node_modules/**", "**/*.test.ts", "**/*.spec.ts"],
160
+ absolute: true,
161
+ });
162
+ for (const file of files) {
163
+ if (!fs.existsSync(file))
164
+ continue;
165
+ const content = fs.readFileSync(file, "utf-8");
166
+ const relativePath = path.relative(process.cwd(), file);
167
+ // Find queries that access relations without include
168
+ // Pattern: findUnique/findFirst followed by relation access
169
+ const queryWithRelationAccessPattern = /(?:const|let)\s+(\w+)\s*=\s*await\s+(?:prisma|db)\.(\w+)\.(?:findUnique|findFirst|findMany)\s*\([^)]*\)[^;]*;[^}]*\1\.(\w+)\./g;
170
+ let match;
171
+ while ((match = queryWithRelationAccessPattern.exec(content)) !== null) {
172
+ const varName = match[1];
173
+ const model = match[2];
174
+ const relationAccess = match[3];
175
+ // Check if the query has include
176
+ const querySection = content.substring(match.index, match.index + 300);
177
+ const hasInclude = /include\s*:/.test(querySection);
178
+ if (!hasInclude && relationAccess !== "id" && relationAccess !== "createdAt" && relationAccess !== "updatedAt") {
179
+ issues.push({
180
+ rule: "missing-include",
181
+ message: `Query on ${model} accesses .${relationAccess} without include`,
182
+ file: relativePath,
183
+ line: getLineNumber(content, match.index),
184
+ severity: "info",
185
+ suggestion: `Add include: { ${relationAccess}: true } to avoid additional query`,
186
+ });
187
+ }
188
+ }
189
+ }
190
+ return issues;
191
+ }
192
+ async function checkOverFetching() {
193
+ const issues = [];
194
+ const files = await (0, glob_1.glob)([
195
+ "app/**/*.ts",
196
+ "app/**/*.tsx",
197
+ "lib/**/*.ts",
198
+ ], {
199
+ cwd: process.cwd(),
200
+ ignore: ["**/node_modules/**", "**/*.test.ts", "**/*.spec.ts"],
201
+ absolute: true,
202
+ });
203
+ for (const file of files) {
204
+ if (!fs.existsSync(file))
205
+ continue;
206
+ const content = fs.readFileSync(file, "utf-8");
207
+ const relativePath = path.relative(process.cwd(), file);
208
+ // Check for findMany without take/limit
209
+ const findManyWithoutLimitPattern = /(?:prisma|db)\.\w+\.findMany\s*\(\s*\{(?![^}]*(?:take|cursor|limit))[^}]*\}\s*\)/g;
210
+ let match;
211
+ while ((match = findManyWithoutLimitPattern.exec(content)) !== null) {
212
+ // Skip if it's a count or aggregate
213
+ if (/count|aggregate/i.test(match[0]))
214
+ continue;
215
+ issues.push({
216
+ rule: "findmany-no-limit",
217
+ message: "findMany without take/limit may return unbounded results",
218
+ file: relativePath,
219
+ line: getLineNumber(content, match.index),
220
+ severity: "info",
221
+ suggestion: "Add take: N to limit results, or use cursor pagination",
222
+ });
223
+ }
224
+ // Check for queries that could use select but fetch all fields
225
+ const findWithoutSelectPattern = /(?:prisma|db)\.\w+\.(?:findUnique|findFirst|findMany)\s*\(\s*\{(?![^}]*select)[^}]*\}\s*\)/g;
226
+ let queryCount = 0;
227
+ while ((match = findWithoutSelectPattern.exec(content)) !== null) {
228
+ queryCount++;
229
+ }
230
+ // Only warn if there are many queries without select
231
+ if (queryCount > 5) {
232
+ issues.push({
233
+ rule: "consider-select",
234
+ message: `${queryCount} queries without select (may be over-fetching)`,
235
+ file: relativePath,
236
+ severity: "info",
237
+ suggestion: "Use select to fetch only needed fields for better performance",
238
+ });
239
+ }
240
+ }
241
+ return issues;
242
+ }
243
+ async function checkTransactionSafety() {
244
+ const issues = [];
245
+ const files = await (0, glob_1.glob)([
246
+ "app/api/**/*.ts",
247
+ "lib/**/*.ts",
248
+ ], {
249
+ cwd: process.cwd(),
250
+ ignore: ["**/node_modules/**", "**/*.test.ts", "**/*.spec.ts"],
251
+ absolute: true,
252
+ });
253
+ for (const file of files) {
254
+ if (!fs.existsSync(file))
255
+ continue;
256
+ const content = fs.readFileSync(file, "utf-8");
257
+ const relativePath = path.relative(process.cwd(), file);
258
+ // Check for multiple writes without transaction
259
+ // Pattern: create followed by another create/update without $transaction
260
+ const multiWritePattern = /await\s+(?:prisma|db)\.\w+\.(?:create|update|delete)\s*\([^;]+;\s*await\s+(?:prisma|db)\.\w+\.(?:create|update|delete)/g;
261
+ let match;
262
+ while ((match = multiWritePattern.exec(content)) !== null) {
263
+ // Check if wrapped in transaction
264
+ const beforeCode = content.substring(Math.max(0, match.index - 200), match.index);
265
+ const isInTransaction = /\$transaction|transaction\(|BEGIN/i.test(beforeCode);
266
+ if (!isInTransaction) {
267
+ issues.push({
268
+ rule: "multi-write-no-transaction",
269
+ message: "Multiple database writes without transaction",
270
+ file: relativePath,
271
+ line: getLineNumber(content, match.index),
272
+ severity: "warning",
273
+ suggestion: "Wrap related writes in prisma.$transaction() for atomicity",
274
+ });
275
+ }
276
+ }
277
+ // Check for create + update pattern (common for counters)
278
+ const createUpdatePattern = /\.create\s*\([^)]+\)[^;]*;[^}]*\.update\s*\([^)]+increment/gi;
279
+ while ((match = createUpdatePattern.exec(content)) !== null) {
280
+ const beforeCode = content.substring(Math.max(0, match.index - 200), match.index);
281
+ if (!/\$transaction/i.test(beforeCode)) {
282
+ issues.push({
283
+ rule: "create-update-no-transaction",
284
+ message: "Create followed by update/increment without transaction",
285
+ file: relativePath,
286
+ line: getLineNumber(content, match.index),
287
+ severity: "warning",
288
+ suggestion: "Use $transaction to ensure atomicity of create + update",
289
+ });
290
+ }
291
+ }
292
+ }
293
+ return issues;
294
+ }
295
+ async function checkCascadeOperations() {
296
+ const issues = [];
297
+ // Check Prisma schema for cascade deletes
298
+ const schemaPath = path.join(process.cwd(), "prisma", "schema.prisma");
299
+ if (fs.existsSync(schemaPath)) {
300
+ const content = fs.readFileSync(schemaPath, "utf-8");
301
+ // Find cascade delete relations
302
+ const cascadeDeletePattern = /onDelete:\s*Cascade/gi;
303
+ let match;
304
+ let cascadeCount = 0;
305
+ while ((match = cascadeDeletePattern.exec(content)) !== null) {
306
+ cascadeCount++;
307
+ // Check the context - which model/field
308
+ const lineStart = content.lastIndexOf("\n", match.index) + 1;
309
+ const lineEnd = content.indexOf("\n", match.index);
310
+ const line = content.substring(lineStart, lineEnd);
311
+ // Extract relation info if possible
312
+ const relationMatch = line.match(/(\w+)\s+(\w+)/);
313
+ if (relationMatch) {
314
+ issues.push({
315
+ rule: "cascade-delete-review",
316
+ message: `Cascade delete configured (ensure this is intentional)`,
317
+ file: "prisma/schema.prisma",
318
+ line: getLineNumber(content, match.index),
319
+ severity: "info",
320
+ suggestion: "Verify cascade delete won't accidentally remove important data",
321
+ });
322
+ }
323
+ }
324
+ if (cascadeCount > 5) {
325
+ issues.push({
326
+ rule: "many-cascade-deletes",
327
+ message: `${cascadeCount} cascade delete relations - review for safety`,
328
+ file: "prisma/schema.prisma",
329
+ severity: "warning",
330
+ suggestion: "Consider soft deletes for important data preservation",
331
+ });
332
+ }
333
+ }
334
+ // Check for deleteMany without where clause
335
+ const files = await (0, glob_1.glob)([
336
+ "app/api/**/*.ts",
337
+ "lib/**/*.ts",
338
+ ], {
339
+ cwd: process.cwd(),
340
+ ignore: ["**/node_modules/**"],
341
+ absolute: true,
342
+ });
343
+ for (const file of files) {
344
+ if (!fs.existsSync(file))
345
+ continue;
346
+ const content = fs.readFileSync(file, "utf-8");
347
+ const relativePath = path.relative(process.cwd(), file);
348
+ // Check for deleteMany with empty or minimal where
349
+ const deleteManyPattern = /\.deleteMany\s*\(\s*(?:\{\s*\}|\{\s*where\s*:\s*\{\s*\}\s*\})\s*\)/g;
350
+ let match;
351
+ while ((match = deleteManyPattern.exec(content)) !== null) {
352
+ issues.push({
353
+ rule: "delete-many-all",
354
+ message: "deleteMany with empty where clause deletes ALL records",
355
+ file: relativePath,
356
+ line: getLineNumber(content, match.index),
357
+ severity: "error",
358
+ suggestion: "Add specific where conditions or use delete for single record",
359
+ });
360
+ }
361
+ }
362
+ return issues;
363
+ }
364
+ async function checkIndexUsage() {
365
+ const issues = [];
366
+ // Parse Prisma schema for indexes
367
+ const schemaPath = path.join(process.cwd(), "prisma", "schema.prisma");
368
+ if (!fs.existsSync(schemaPath)) {
369
+ return issues;
370
+ }
371
+ const schemaContent = fs.readFileSync(schemaPath, "utf-8");
372
+ // Extract indexed fields
373
+ const indexedFields = new Set();
374
+ const uniqueFields = new Set();
375
+ // @@index([field1, field2])
376
+ const indexPattern = /@@index\s*\(\s*\[([^\]]+)\]/g;
377
+ let match;
378
+ while ((match = indexPattern.exec(schemaContent)) !== null) {
379
+ const fields = match[1].split(",").map(f => f.trim());
380
+ fields.forEach(f => indexedFields.add(f));
381
+ }
382
+ // @@unique([field])
383
+ const uniquePattern = /@@unique\s*\(\s*\[([^\]]+)\]/g;
384
+ while ((match = uniquePattern.exec(schemaContent)) !== null) {
385
+ const fields = match[1].split(",").map(f => f.trim());
386
+ fields.forEach(f => uniqueFields.add(f));
387
+ }
388
+ // @unique
389
+ const fieldUniquePattern = /(\w+)\s+\w+.*@unique/g;
390
+ while ((match = fieldUniquePattern.exec(schemaContent)) !== null) {
391
+ uniqueFields.add(match[1]);
392
+ }
393
+ // @id is always indexed
394
+ const idPattern = /(\w+)\s+\w+.*@id/g;
395
+ while ((match = idPattern.exec(schemaContent)) !== null) {
396
+ indexedFields.add(match[1]);
397
+ }
398
+ // Now check queries for common filter patterns
399
+ const files = await (0, glob_1.glob)([
400
+ "app/api/**/*.ts",
401
+ "lib/**/*.ts",
402
+ ], {
403
+ cwd: process.cwd(),
404
+ ignore: ["**/node_modules/**"],
405
+ absolute: true,
406
+ });
407
+ const filterFieldCounts = new Map();
408
+ for (const file of files) {
409
+ if (!fs.existsSync(file))
410
+ continue;
411
+ const content = fs.readFileSync(file, "utf-8");
412
+ // Find where clauses
413
+ const wherePattern = /where\s*:\s*\{\s*(\w+)\s*:/g;
414
+ while ((match = wherePattern.exec(content)) !== null) {
415
+ const field = match[1];
416
+ // Skip common indexed fields
417
+ if (field === "id" || field === "AND" || field === "OR" || field === "NOT")
418
+ continue;
419
+ filterFieldCounts.set(field, (filterFieldCounts.get(field) || 0) + 1);
420
+ }
421
+ // Find orderBy
422
+ const orderByPattern = /orderBy\s*:\s*\{\s*(\w+)\s*:/g;
423
+ while ((match = orderByPattern.exec(content)) !== null) {
424
+ const field = match[1];
425
+ filterFieldCounts.set(`orderBy:${field}`, (filterFieldCounts.get(`orderBy:${field}`) || 0) + 1);
426
+ }
427
+ }
428
+ // Report frequently used non-indexed fields
429
+ for (const [field, count] of filterFieldCounts) {
430
+ if (count >= 3 && !indexedFields.has(field) && !uniqueFields.has(field)) {
431
+ const isOrderBy = field.startsWith("orderBy:");
432
+ const fieldName = isOrderBy ? field.replace("orderBy:", "") : field;
433
+ issues.push({
434
+ rule: "consider-index",
435
+ message: `Field "${fieldName}" used in ${count} ${isOrderBy ? "orderBy" : "where"} clauses but not indexed`,
436
+ file: "prisma/schema.prisma",
437
+ severity: "info",
438
+ suggestion: `Consider adding @@index([${fieldName}]) for query performance`,
439
+ });
440
+ }
441
+ }
442
+ return issues;
443
+ }
444
+ async function run() {
445
+ const startTime = Date.now();
446
+ const allIssues = [];
447
+ // Run all query performance checks
448
+ allIssues.push(...await checkNPlusOneQueries());
449
+ allIssues.push(...await checkMissingIncludes());
450
+ allIssues.push(...await checkOverFetching());
451
+ allIssues.push(...await checkTransactionSafety());
452
+ allIssues.push(...await checkCascadeOperations());
453
+ allIssues.push(...await checkIndexUsage());
454
+ // Convert to findings
455
+ const findings = allIssues.map(issue => ({
456
+ level: issue.severity,
457
+ message: issue.message,
458
+ file: issue.file,
459
+ startLine: issue.line,
460
+ ruleId: issue.rule,
461
+ suggestion: issue.suggestion,
462
+ }));
463
+ const errors = findings.filter(f => f.level === "error");
464
+ const warnings = findings.filter(f => f.level === "warning");
465
+ const infos = findings.filter(f => f.level === "info");
466
+ return {
467
+ passed: errors.length === 0,
468
+ findings,
469
+ duration: Date.now() - startTime,
470
+ metadata: {
471
+ errors: errors.length,
472
+ warnings: warnings.length,
473
+ infos: infos.length,
474
+ },
475
+ };
476
+ }
477
+ async function main() {
478
+ console.log(`\n${console_chars_1.emoji.database} QUERY PERFORMANCE VALIDATION`);
479
+ console.log((0, console_chars_1.createDivider)(65, "heavy"));
480
+ const result = await run();
481
+ const { errors, warnings, infos } = result.metadata || {};
482
+ console.log(`\n${console_chars_1.emoji.search} Checking query patterns...`);
483
+ console.log(`\n${console_chars_1.emoji.chart} Summary:`);
484
+ console.log(` Errors: ${errors}`);
485
+ console.log(` Warnings: ${warnings}`);
486
+ console.log(` Info: ${infos}`);
487
+ if (result.passed && warnings === 0) {
488
+ console.log(`\n${console_chars_1.emoji.success} QUERY PERFORMANCE VALIDATION PASSED`);
489
+ console.log(`\nNo query performance issues detected.`);
490
+ process.exit(0);
491
+ }
492
+ // Group findings by rule
493
+ const findingsByRule = new Map();
494
+ for (const finding of result.findings) {
495
+ const ruleId = finding.ruleId || "unknown";
496
+ if (!findingsByRule.has(ruleId)) {
497
+ findingsByRule.set(ruleId, []);
498
+ }
499
+ findingsByRule.get(ruleId).push(finding);
500
+ }
501
+ // Print errors
502
+ const errorFindings = result.findings.filter(f => f.level === "error");
503
+ if (errorFindings.length > 0) {
504
+ console.log(`\n${console_chars_1.emoji.error} Errors (blocking):`);
505
+ for (const finding of errorFindings) {
506
+ console.log(`\n ${finding.file}${finding.startLine ? `:${finding.startLine}` : ""}`);
507
+ console.log(` ${finding.message}`);
508
+ if (finding.suggestion) {
509
+ console.log(` ${console_chars_1.emoji.hint} ${finding.suggestion}`);
510
+ }
511
+ }
512
+ }
513
+ // Print warnings
514
+ const warningFindings = result.findings.filter(f => f.level === "warning");
515
+ if (warningFindings.length > 0) {
516
+ console.log(`\n${console_chars_1.emoji.warning} Warnings:`);
517
+ for (const finding of warningFindings.slice(0, 10)) {
518
+ console.log(`\n ${finding.file}${finding.startLine ? `:${finding.startLine}` : ""}`);
519
+ console.log(` ${finding.message}`);
520
+ }
521
+ if (warningFindings.length > 10) {
522
+ console.log(`\n ... and ${warningFindings.length - 10} more warnings`);
523
+ }
524
+ }
525
+ console.log(`\n${console_chars_1.emoji.info} Query Performance Tips:`);
526
+ console.log(` - Avoid queries in loops (N+1 problem)`);
527
+ console.log(` - Use include to fetch relations in one query`);
528
+ console.log(` - Add indexes for frequently filtered fields`);
529
+ console.log(` - Wrap related writes in transactions`);
530
+ console.log(` - Use take/cursor for pagination`);
531
+ if (!result.passed) {
532
+ console.log(`\n${console_chars_1.emoji.error} QUERY PERFORMANCE VALIDATION FAILED`);
533
+ process.exit(1);
534
+ }
535
+ console.log(`\n${console_chars_1.emoji.success} QUERY PERFORMANCE VALIDATION PASSED`);
536
+ process.exit(0);
537
+ }
538
+ if (require.main === module) {
539
+ main().catch((err) => {
540
+ console.error(`${console_chars_1.emoji.error} Preflight failed:`, err);
541
+ process.exit(1);
542
+ });
543
+ }
544
+ //# sourceMappingURL=query-performance-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-performance-validation.js","sourceRoot":"","sources":["../../../src/checks/database/query-performance-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { PreflightCheckResult } from "../../core/types";
3
+ export declare const id = "react/react-patterns-validation";
4
+ export declare const name = "React Patterns Validation";
5
+ export declare const description = "Validates React patterns, hooks, Server Components, and performance best practices";
6
+ export declare const category = "react";
7
+ export declare const blocking = true;
8
+ export declare const tags: string[];
9
+ export declare function run(): Promise<PreflightCheckResult>;
10
+ //# sourceMappingURL=react-patterns-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-patterns-validation.d.ts","sourceRoot":"","sources":["../../../src/checks/react/react-patterns-validation.ts"],"names":[],"mappings":";AAmCA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAG1E,eAAO,MAAM,EAAE,oCAAoC,CAAC;AACpD,eAAO,MAAM,IAAI,8BAA8B,CAAC;AAChD,eAAO,MAAM,WAAW,uFAAuF,CAAC;AAChH,eAAO,MAAM,QAAQ,UAAU,CAAC;AAChC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAAqE,CAAC;AAkcvF,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAoCzD"}