@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,594 @@
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
+ * Security Headers Validation Preflight (BLOCKING)
41
+ *
42
+ * Validates security headers and OWASP best practices:
43
+ *
44
+ * 1. Next.js Security Headers:
45
+ * - Content-Security-Policy configured
46
+ * - X-Frame-Options for clickjacking prevention
47
+ * - X-Content-Type-Options: nosniff
48
+ * - Referrer-Policy configured
49
+ * - Permissions-Policy for feature restrictions
50
+ *
51
+ * 2. Cookie Security:
52
+ * - HttpOnly flag for sensitive cookies
53
+ * - Secure flag for HTTPS
54
+ * - SameSite attribute configured
55
+ *
56
+ * 3. Subresource Integrity:
57
+ * - External scripts have integrity attribute
58
+ * - External stylesheets have integrity
59
+ *
60
+ * 4. CORS Configuration:
61
+ * - No wildcard origins in production
62
+ * - Credentials handling
63
+ *
64
+ * 5. Input Validation:
65
+ * - Command injection prevention
66
+ * - Path traversal prevention
67
+ * - SSRF prevention
68
+ */
69
+ const fs = __importStar(require("node:fs"));
70
+ const path = __importStar(require("node:path"));
71
+ const glob_1 = require("glob");
72
+ const console_chars_1 = require("../../utils/console-chars");
73
+ exports.id = "security/security-headers-validation";
74
+ exports.name = "Security Headers Validation";
75
+ exports.description = "Validates security headers, cookies, SRI, CORS, and OWASP best practices";
76
+ exports.category = "security";
77
+ exports.blocking = true;
78
+ exports.tags = ["security", "headers", "owasp", "csp", "cors", "cookies"];
79
+ function getLineNumber(content, index) {
80
+ return content.substring(0, index).split("\n").length;
81
+ }
82
+ async function checkSecurityHeaders() {
83
+ const issues = [];
84
+ // Check next.config.js/ts for security headers
85
+ const configFiles = await (0, glob_1.glob)([
86
+ "next.config.js",
87
+ "next.config.mjs",
88
+ "next.config.ts",
89
+ ], {
90
+ cwd: process.cwd(),
91
+ absolute: true,
92
+ });
93
+ let hasSecurityHeaders = false;
94
+ let hasCSP = false;
95
+ let hasXFrameOptions = false;
96
+ let hasXContentTypeOptions = false;
97
+ for (const file of configFiles) {
98
+ if (!fs.existsSync(file))
99
+ continue;
100
+ const content = fs.readFileSync(file, "utf-8");
101
+ // Check for headers configuration
102
+ if (/headers\s*:?\s*(?:async\s*)?\(\s*\)|headers\s*:\s*\[/.test(content)) {
103
+ hasSecurityHeaders = true;
104
+ }
105
+ // Check for specific headers
106
+ if (/Content-Security-Policy|contentSecurityPolicy/i.test(content)) {
107
+ hasCSP = true;
108
+ }
109
+ if (/X-Frame-Options/i.test(content)) {
110
+ hasXFrameOptions = true;
111
+ }
112
+ if (/X-Content-Type-Options/i.test(content)) {
113
+ hasXContentTypeOptions = true;
114
+ }
115
+ }
116
+ // Also check middleware for headers
117
+ const middlewareFile = path.join(process.cwd(), "middleware.ts");
118
+ if (fs.existsSync(middlewareFile)) {
119
+ const content = fs.readFileSync(middlewareFile, "utf-8");
120
+ if (/headers|Header/i.test(content)) {
121
+ hasSecurityHeaders = true;
122
+ }
123
+ if (/Content-Security-Policy/i.test(content)) {
124
+ hasCSP = true;
125
+ }
126
+ }
127
+ if (!hasSecurityHeaders) {
128
+ issues.push({
129
+ rule: "security-headers-missing",
130
+ message: "No security headers configuration found",
131
+ file: "next.config.js or middleware.ts",
132
+ severity: "warning",
133
+ suggestion: "Add headers() configuration in next.config.js or middleware.ts",
134
+ owaspCategory: "A05:2021 Security Misconfiguration",
135
+ });
136
+ }
137
+ else {
138
+ if (!hasCSP) {
139
+ issues.push({
140
+ rule: "csp-missing",
141
+ message: "Content-Security-Policy header not configured",
142
+ file: "next.config.js",
143
+ severity: "warning",
144
+ suggestion: "Add Content-Security-Policy header to prevent XSS attacks",
145
+ owaspCategory: "A03:2021 Injection",
146
+ });
147
+ }
148
+ if (!hasXFrameOptions) {
149
+ issues.push({
150
+ rule: "x-frame-options-missing",
151
+ message: "X-Frame-Options header not configured",
152
+ file: "next.config.js",
153
+ severity: "info",
154
+ suggestion: "Add X-Frame-Options: DENY or SAMEORIGIN to prevent clickjacking",
155
+ owaspCategory: "A05:2021 Security Misconfiguration",
156
+ });
157
+ }
158
+ if (!hasXContentTypeOptions) {
159
+ issues.push({
160
+ rule: "x-content-type-options-missing",
161
+ message: "X-Content-Type-Options header not configured",
162
+ file: "next.config.js",
163
+ severity: "info",
164
+ suggestion: "Add X-Content-Type-Options: nosniff to prevent MIME sniffing",
165
+ owaspCategory: "A05:2021 Security Misconfiguration",
166
+ });
167
+ }
168
+ }
169
+ return issues;
170
+ }
171
+ async function checkCookieSecurity() {
172
+ const issues = [];
173
+ const files = await (0, glob_1.glob)([
174
+ "app/api/**/*.ts",
175
+ "lib/**/*.ts",
176
+ "middleware.ts",
177
+ ], {
178
+ cwd: process.cwd(),
179
+ ignore: ["**/node_modules/**"],
180
+ absolute: true,
181
+ });
182
+ for (const file of files) {
183
+ if (!fs.existsSync(file))
184
+ continue;
185
+ const content = fs.readFileSync(file, "utf-8");
186
+ const relativePath = path.relative(process.cwd(), file);
187
+ // Check for cookie setting without security attributes
188
+ const setCookieRegex = /cookies\s*\(\s*\)\s*\.set\s*\([^)]+\)/g;
189
+ let match;
190
+ while ((match = setCookieRegex.exec(content)) !== null) {
191
+ const cookieCall = match[0];
192
+ // Check for security attributes
193
+ const hasHttpOnly = /httpOnly\s*:\s*true/i.test(cookieCall);
194
+ const hasSecure = /secure\s*:\s*true/i.test(cookieCall);
195
+ const hasSameSite = /sameSite\s*:/i.test(cookieCall);
196
+ if (!hasHttpOnly) {
197
+ issues.push({
198
+ rule: "cookie-httponly",
199
+ message: "Cookie set without httpOnly flag",
200
+ file: relativePath,
201
+ line: getLineNumber(content, match.index),
202
+ severity: "warning",
203
+ suggestion: "Add httpOnly: true to prevent XSS access to cookie",
204
+ owaspCategory: "A07:2021 Identification and Authentication Failures",
205
+ });
206
+ }
207
+ if (!hasSecure) {
208
+ issues.push({
209
+ rule: "cookie-secure",
210
+ message: "Cookie set without secure flag",
211
+ file: relativePath,
212
+ line: getLineNumber(content, match.index),
213
+ severity: "info",
214
+ suggestion: "Add secure: true for HTTPS-only transmission",
215
+ owaspCategory: "A02:2021 Cryptographic Failures",
216
+ });
217
+ }
218
+ if (!hasSameSite) {
219
+ issues.push({
220
+ rule: "cookie-samesite",
221
+ message: "Cookie set without sameSite attribute",
222
+ file: relativePath,
223
+ line: getLineNumber(content, match.index),
224
+ severity: "info",
225
+ suggestion: "Add sameSite: 'lax' or 'strict' to prevent CSRF",
226
+ owaspCategory: "A01:2021 Broken Access Control",
227
+ });
228
+ }
229
+ }
230
+ }
231
+ return issues;
232
+ }
233
+ async function checkSubresourceIntegrity() {
234
+ const issues = [];
235
+ const files = await (0, glob_1.glob)([
236
+ "app/**/*.tsx",
237
+ "components/**/*.tsx",
238
+ "app/layout.tsx",
239
+ ], {
240
+ cwd: process.cwd(),
241
+ ignore: ["**/node_modules/**"],
242
+ absolute: true,
243
+ });
244
+ for (const file of files) {
245
+ if (!fs.existsSync(file))
246
+ continue;
247
+ const content = fs.readFileSync(file, "utf-8");
248
+ const relativePath = path.relative(process.cwd(), file);
249
+ // Check for external scripts without integrity
250
+ const externalScriptRegex = /<script[^>]*src\s*=\s*["'](https?:\/\/[^"']+)["'][^>]*>/gi;
251
+ let match;
252
+ while ((match = externalScriptRegex.exec(content)) !== null) {
253
+ const scriptTag = match[0];
254
+ if (!/\bintegrity\s*=/.test(scriptTag)) {
255
+ issues.push({
256
+ rule: "sri-script",
257
+ message: `External script missing integrity attribute: ${match[1].substring(0, 50)}...`,
258
+ file: relativePath,
259
+ line: getLineNumber(content, match.index),
260
+ severity: "warning",
261
+ suggestion: "Add integrity and crossorigin attributes for subresource integrity",
262
+ owaspCategory: "A08:2021 Software and Data Integrity Failures",
263
+ });
264
+ }
265
+ }
266
+ // Check for external stylesheets without integrity
267
+ const externalStyleRegex = /<link[^>]*href\s*=\s*["'](https?:\/\/[^"']+\.css[^"']*)["'][^>]*>/gi;
268
+ while ((match = externalStyleRegex.exec(content)) !== null) {
269
+ const linkTag = match[0];
270
+ if (!/\bintegrity\s*=/.test(linkTag)) {
271
+ issues.push({
272
+ rule: "sri-stylesheet",
273
+ message: `External stylesheet missing integrity attribute`,
274
+ file: relativePath,
275
+ line: getLineNumber(content, match.index),
276
+ severity: "info",
277
+ suggestion: "Add integrity attribute for stylesheet integrity verification",
278
+ owaspCategory: "A08:2021 Software and Data Integrity Failures",
279
+ });
280
+ }
281
+ }
282
+ }
283
+ return issues;
284
+ }
285
+ async function checkCORSConfiguration() {
286
+ const issues = [];
287
+ const files = await (0, glob_1.glob)([
288
+ "app/api/**/*.ts",
289
+ "next.config.*",
290
+ "middleware.ts",
291
+ ], {
292
+ cwd: process.cwd(),
293
+ ignore: ["**/node_modules/**"],
294
+ absolute: true,
295
+ });
296
+ for (const file of files) {
297
+ if (!fs.existsSync(file))
298
+ continue;
299
+ const content = fs.readFileSync(file, "utf-8");
300
+ const relativePath = path.relative(process.cwd(), file);
301
+ // Check for wildcard CORS origin
302
+ const wildcardCorsRegex = /Access-Control-Allow-Origin['"]\s*,\s*['"]?\*['"]?|origin\s*:\s*['"]\*['"]/gi;
303
+ let match;
304
+ while ((match = wildcardCorsRegex.exec(content)) !== null) {
305
+ issues.push({
306
+ rule: "cors-wildcard",
307
+ message: "Wildcard CORS origin (*) allows any domain",
308
+ file: relativePath,
309
+ line: getLineNumber(content, match.index),
310
+ severity: "warning",
311
+ suggestion: "Specify allowed origins explicitly in production",
312
+ owaspCategory: "A01:2021 Broken Access Control",
313
+ });
314
+ }
315
+ // Check for CORS with credentials and wildcard
316
+ if (/Access-Control-Allow-Credentials.*true/i.test(content) &&
317
+ /Access-Control-Allow-Origin.*\*/i.test(content)) {
318
+ issues.push({
319
+ rule: "cors-credentials-wildcard",
320
+ message: "CORS allows credentials with wildcard origin (security risk)",
321
+ file: relativePath,
322
+ severity: "error",
323
+ suggestion: "Cannot use credentials with wildcard origin - specify explicit origins",
324
+ owaspCategory: "A01:2021 Broken Access Control",
325
+ });
326
+ }
327
+ }
328
+ return issues;
329
+ }
330
+ async function checkCommandInjection() {
331
+ const issues = [];
332
+ const files = await (0, glob_1.glob)([
333
+ "app/api/**/*.ts",
334
+ "lib/**/*.ts",
335
+ "scripts/**/*.ts",
336
+ ], {
337
+ cwd: process.cwd(),
338
+ ignore: ["**/node_modules/**", "**/preflight*/**"],
339
+ absolute: true,
340
+ });
341
+ for (const file of files) {
342
+ if (!fs.existsSync(file))
343
+ continue;
344
+ const content = fs.readFileSync(file, "utf-8");
345
+ const relativePath = path.relative(process.cwd(), file);
346
+ // Check for exec/spawn with user input
347
+ const execPatterns = [
348
+ /exec\s*\(\s*`[^`]*\$\{/g, // exec(`...${userInput}`)
349
+ /execSync\s*\(\s*`[^`]*\$\{/g, // execSync with template literal
350
+ /spawn\s*\([^,]+\+/g, // spawn(cmd + userInput)
351
+ /child_process.*exec.*\+/g, // child_process exec with concatenation
352
+ ];
353
+ for (const pattern of execPatterns) {
354
+ let match;
355
+ while ((match = pattern.exec(content)) !== null) {
356
+ issues.push({
357
+ rule: "command-injection",
358
+ message: "Potential command injection vulnerability",
359
+ file: relativePath,
360
+ line: getLineNumber(content, match.index),
361
+ severity: "error",
362
+ suggestion: "Never interpolate user input into shell commands - use spawn with arguments array",
363
+ owaspCategory: "A03:2021 Injection",
364
+ });
365
+ }
366
+ }
367
+ }
368
+ return issues;
369
+ }
370
+ async function checkPathTraversal() {
371
+ const issues = [];
372
+ const files = await (0, glob_1.glob)([
373
+ "app/api/**/*.ts",
374
+ "lib/**/*.ts",
375
+ ], {
376
+ cwd: process.cwd(),
377
+ ignore: ["**/node_modules/**"],
378
+ absolute: true,
379
+ });
380
+ for (const file of files) {
381
+ if (!fs.existsSync(file))
382
+ continue;
383
+ const content = fs.readFileSync(file, "utf-8");
384
+ const relativePath = path.relative(process.cwd(), file);
385
+ // Check for path.join with user input without sanitization
386
+ const pathJoinRegex = /path\.(?:join|resolve)\s*\([^)]*(?:req\.|params\.|query\.|body\.)/gi;
387
+ let match;
388
+ while ((match = pathJoinRegex.exec(content)) !== null) {
389
+ // Check if there's path traversal protection nearby
390
+ const surroundingCode = content.substring(Math.max(0, match.index - 300), match.index + 200);
391
+ const hasProtection = /\.\.\/|\.includes\s*\(\s*["']\.\.|normalize|sanitize|isAbsolute/i.test(surroundingCode);
392
+ if (!hasProtection) {
393
+ issues.push({
394
+ rule: "path-traversal",
395
+ message: "Potential path traversal vulnerability",
396
+ file: relativePath,
397
+ line: getLineNumber(content, match.index),
398
+ severity: "warning",
399
+ suggestion: "Validate user input doesn't contain '..' and normalize paths",
400
+ owaspCategory: "A01:2021 Broken Access Control",
401
+ });
402
+ }
403
+ }
404
+ }
405
+ return issues;
406
+ }
407
+ async function checkSSRF() {
408
+ const issues = [];
409
+ const files = await (0, glob_1.glob)([
410
+ "app/api/**/*.ts",
411
+ "lib/**/*.ts",
412
+ ], {
413
+ cwd: process.cwd(),
414
+ ignore: ["**/node_modules/**"],
415
+ absolute: true,
416
+ });
417
+ for (const file of files) {
418
+ if (!fs.existsSync(file))
419
+ continue;
420
+ const content = fs.readFileSync(file, "utf-8");
421
+ const relativePath = path.relative(process.cwd(), file);
422
+ // Check for fetch/axios with user-provided URLs
423
+ const ssrfPatterns = [
424
+ /fetch\s*\(\s*(?:req\.|params\.|query\.|body\.)(\w+)/g,
425
+ /axios\.(?:get|post|put|delete)\s*\(\s*(?:req\.|params\.|query\.|body\.)/g,
426
+ /fetch\s*\(\s*`\$\{/g, // fetch with template literal
427
+ ];
428
+ for (const pattern of ssrfPatterns) {
429
+ let match;
430
+ while ((match = pattern.exec(content)) !== null) {
431
+ // Check for URL validation
432
+ const surroundingCode = content.substring(Math.max(0, match.index - 500), match.index + 300);
433
+ const hasValidation = /URL|validateUrl|allowedHosts|whitelist|allowlist|isValidUrl/i.test(surroundingCode);
434
+ if (!hasValidation) {
435
+ issues.push({
436
+ rule: "ssrf-prevention",
437
+ message: "Potential SSRF vulnerability - user-controlled URL in request",
438
+ file: relativePath,
439
+ line: getLineNumber(content, match.index),
440
+ severity: "warning",
441
+ suggestion: "Validate URLs against allowlist and block internal addresses",
442
+ owaspCategory: "A10:2021 Server-Side Request Forgery",
443
+ });
444
+ }
445
+ }
446
+ }
447
+ }
448
+ return issues;
449
+ }
450
+ async function checkHardcodedSecrets() {
451
+ const issues = [];
452
+ const files = await (0, glob_1.glob)([
453
+ "app/**/*.ts",
454
+ "app/**/*.tsx",
455
+ "lib/**/*.ts",
456
+ "components/**/*.tsx",
457
+ ], {
458
+ cwd: process.cwd(),
459
+ ignore: ["**/node_modules/**", "**/*.test.ts", "**/*.spec.ts"],
460
+ absolute: true,
461
+ });
462
+ const secretPatterns = [
463
+ { pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*["'][a-zA-Z0-9]{20,}["']/gi, name: "API key" },
464
+ { pattern: /(?:secret|token)\s*[:=]\s*["'][a-zA-Z0-9_-]{20,}["']/gi, name: "secret/token" },
465
+ { pattern: /(?:password|passwd|pwd)\s*[:=]\s*["'][^"']{8,}["']/gi, name: "password" },
466
+ { pattern: /sk_(?:live|test)_[a-zA-Z0-9]{20,}/g, name: "Stripe key" },
467
+ { pattern: /ghp_[a-zA-Z0-9]{36}/g, name: "GitHub token" },
468
+ { pattern: /xox[baprs]-[a-zA-Z0-9-]+/g, name: "Slack token" },
469
+ ];
470
+ for (const file of files) {
471
+ if (!fs.existsSync(file))
472
+ continue;
473
+ const content = fs.readFileSync(file, "utf-8");
474
+ const relativePath = path.relative(process.cwd(), file);
475
+ for (const { pattern, name } of secretPatterns) {
476
+ let match;
477
+ const regex = new RegExp(pattern.source, pattern.flags);
478
+ while ((match = regex.exec(content)) !== null) {
479
+ // Skip if it's in a comment or type definition
480
+ const lineStart = content.lastIndexOf("\n", match.index) + 1;
481
+ const line = content.substring(lineStart, content.indexOf("\n", match.index));
482
+ if (line.includes("//") || line.includes("/*") || line.includes("type ") || line.includes("interface "))
483
+ continue;
484
+ // Skip if it's a placeholder
485
+ if (/xxx|placeholder|example|your_|YOUR_|dummy/i.test(match[0]))
486
+ continue;
487
+ issues.push({
488
+ rule: "hardcoded-secret",
489
+ message: `Potential hardcoded ${name} detected`,
490
+ file: relativePath,
491
+ line: getLineNumber(content, match.index),
492
+ severity: "error",
493
+ suggestion: "Use environment variables for secrets",
494
+ owaspCategory: "A02:2021 Cryptographic Failures",
495
+ });
496
+ }
497
+ }
498
+ }
499
+ return issues;
500
+ }
501
+ async function run() {
502
+ const startTime = Date.now();
503
+ const allIssues = [];
504
+ // Run all security checks
505
+ allIssues.push(...await checkSecurityHeaders());
506
+ allIssues.push(...await checkCookieSecurity());
507
+ allIssues.push(...await checkSubresourceIntegrity());
508
+ allIssues.push(...await checkCORSConfiguration());
509
+ allIssues.push(...await checkCommandInjection());
510
+ allIssues.push(...await checkPathTraversal());
511
+ allIssues.push(...await checkSSRF());
512
+ allIssues.push(...await checkHardcodedSecrets());
513
+ // Convert to findings
514
+ const findings = allIssues.map(issue => ({
515
+ level: issue.severity,
516
+ message: issue.message + (issue.owaspCategory ? ` [${issue.owaspCategory}]` : ""),
517
+ file: issue.file,
518
+ startLine: issue.line,
519
+ ruleId: issue.rule,
520
+ suggestion: issue.suggestion,
521
+ }));
522
+ const errors = findings.filter(f => f.level === "error");
523
+ const warnings = findings.filter(f => f.level === "warning");
524
+ const infos = findings.filter(f => f.level === "info");
525
+ return {
526
+ passed: errors.length === 0,
527
+ findings,
528
+ duration: Date.now() - startTime,
529
+ metadata: {
530
+ errors: errors.length,
531
+ warnings: warnings.length,
532
+ infos: infos.length,
533
+ owaspCoverage: [...new Set(allIssues.map(i => i.owaspCategory).filter(Boolean))],
534
+ },
535
+ };
536
+ }
537
+ async function main() {
538
+ console.log(`\n${console_chars_1.emoji.shield} SECURITY HEADERS VALIDATION`);
539
+ console.log((0, console_chars_1.createDivider)(65, "heavy"));
540
+ const result = await run();
541
+ const { errors, warnings, infos, owaspCoverage } = result.metadata || {};
542
+ console.log(`\n${console_chars_1.emoji.search} Checking security configuration...`);
543
+ console.log(` OWASP coverage: ${(owaspCoverage || []).length} categories`);
544
+ console.log(`\n${console_chars_1.emoji.chart} Summary:`);
545
+ console.log(` Errors: ${errors}`);
546
+ console.log(` Warnings: ${warnings}`);
547
+ console.log(` Info: ${infos}`);
548
+ if (result.passed && warnings === 0) {
549
+ console.log(`\n${console_chars_1.emoji.success} SECURITY HEADERS VALIDATION PASSED`);
550
+ process.exit(0);
551
+ }
552
+ // Print findings
553
+ const errorFindings = result.findings.filter(f => f.level === "error");
554
+ if (errorFindings.length > 0) {
555
+ console.log(`\n${console_chars_1.emoji.error} Errors (blocking):`);
556
+ for (const finding of errorFindings) {
557
+ console.log(`\n ${finding.file}${finding.startLine ? `:${finding.startLine}` : ""}`);
558
+ console.log(` ${finding.message}`);
559
+ if (finding.suggestion) {
560
+ console.log(` ${console_chars_1.emoji.hint} ${finding.suggestion}`);
561
+ }
562
+ }
563
+ }
564
+ const warningFindings = result.findings.filter(f => f.level === "warning");
565
+ if (warningFindings.length > 0) {
566
+ console.log(`\n${console_chars_1.emoji.warning} Warnings:`);
567
+ for (const finding of warningFindings.slice(0, 10)) {
568
+ console.log(`\n ${finding.file}${finding.startLine ? `:${finding.startLine}` : ""}`);
569
+ console.log(` ${finding.message}`);
570
+ }
571
+ if (warningFindings.length > 10) {
572
+ console.log(`\n ... and ${warningFindings.length - 10} more warnings`);
573
+ }
574
+ }
575
+ console.log(`\n${console_chars_1.emoji.info} Security Best Practices:`);
576
+ console.log(` - Configure Content-Security-Policy`);
577
+ console.log(` - Set secure cookie attributes (HttpOnly, Secure, SameSite)`);
578
+ console.log(` - Use Subresource Integrity for external resources`);
579
+ console.log(` - Validate user input before shell commands`);
580
+ console.log(` - Prevent SSRF with URL allowlists`);
581
+ if (!result.passed) {
582
+ console.log(`\n${console_chars_1.emoji.error} SECURITY HEADERS VALIDATION FAILED`);
583
+ process.exit(1);
584
+ }
585
+ console.log(`\n${console_chars_1.emoji.success} SECURITY HEADERS VALIDATION PASSED`);
586
+ process.exit(0);
587
+ }
588
+ if (require.main === module) {
589
+ main().catch((err) => {
590
+ console.error(`${console_chars_1.emoji.error} Preflight failed:`, err);
591
+ process.exit(1);
592
+ });
593
+ }
594
+ //# sourceMappingURL=security-headers-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-headers-validation.js","sourceRoot":"","sources":["../../../src/checks/security/security-headers-validation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmhBA,kBAuCC;AAzjBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,4CAA8B;AAC9B,gDAAkC;AAClC,+BAA4B;AAE5B,6DAAiE;AAEpD,QAAA,EAAE,GAAG,sCAAsC,CAAC;AAC5C,QAAA,IAAI,GAAG,6BAA6B,CAAC;AACrC,QAAA,WAAW,GAAG,0EAA0E,CAAC;AACzF,QAAA,QAAQ,GAAG,UAAU,CAAC;AACtB,QAAA,QAAQ,GAAG,IAAI,CAAC;AAChB,QAAA,IAAI,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAY/E,SAAS,aAAa,CAAC,OAAe,EAAE,KAAa;IACnD,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,oBAAoB;IACjC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,+CAA+C;IAC/C,MAAM,WAAW,GAAG,MAAM,IAAA,WAAI,EAAC;QAC7B,gBAAgB;QAChB,iBAAiB;QACjB,gBAAgB;KACjB,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,sBAAsB,GAAG,KAAK,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAE/C,kCAAkC;QAClC,IAAI,sDAAsD,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACzE,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,6BAA6B;QAC7B,IAAI,gDAAgD,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACnE,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,gBAAgB,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,IAAI,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,sBAAsB,GAAG,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IACjE,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACzD,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,0BAA0B;YAChC,OAAO,EAAE,yCAAyC;YAClD,IAAI,EAAE,iCAAiC;YACvC,QAAQ,EAAE,SAAS;YACnB,UAAU,EAAE,gEAAgE;YAC5E,aAAa,EAAE,oCAAoC;SACpD,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,+CAA+C;gBACxD,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,SAAS;gBACnB,UAAU,EAAE,2DAA2D;gBACvE,aAAa,EAAE,oBAAoB;aACpC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,yBAAyB;gBAC/B,OAAO,EAAE,uCAAuC;gBAChD,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,MAAM;gBAChB,UAAU,EAAE,iEAAiE;gBAC7E,aAAa,EAAE,oCAAoC;aACpD,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,gCAAgC;gBACtC,OAAO,EAAE,8CAA8C;gBACvD,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,MAAM;gBAChB,UAAU,EAAE,8DAA8D;gBAC1E,aAAa,EAAE,oCAAoC;aACpD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,mBAAmB;IAChC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC;QACvB,iBAAiB;QACjB,aAAa;QACb,eAAe;KAChB,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;QAC9B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAExD,uDAAuD;QACvD,MAAM,cAAc,GAAG,wCAAwC,CAAC;QAChE,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACvD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAE5B,gCAAgC;YAChC,MAAM,WAAW,GAAG,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACxD,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAErD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,kCAAkC;oBAC3C,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,SAAS;oBACnB,UAAU,EAAE,oDAAoD;oBAChE,aAAa,EAAE,qDAAqD;iBACrE,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,eAAe;oBACrB,OAAO,EAAE,gCAAgC;oBACzC,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,MAAM;oBAChB,UAAU,EAAE,8CAA8C;oBAC1D,aAAa,EAAE,iCAAiC;iBACjD,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,uCAAuC;oBAChD,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,MAAM;oBAChB,UAAU,EAAE,iDAAiD;oBAC7D,aAAa,EAAE,gCAAgC;iBAChD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,yBAAyB;IACtC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC;QACvB,cAAc;QACd,qBAAqB;QACrB,gBAAgB;KACjB,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;QAC9B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAExD,+CAA+C;QAC/C,MAAM,mBAAmB,GAAG,2DAA2D,CAAC;QACxF,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvC,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,YAAY;oBAClB,OAAO,EAAE,gDAAgD,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK;oBACvF,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,SAAS;oBACnB,UAAU,EAAE,oEAAoE;oBAChF,aAAa,EAAE,+CAA+C;iBAC/D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,mDAAmD;QACnD,MAAM,kBAAkB,GAAG,qEAAqE,CAAC;QACjG,OAAO,CAAC,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,iDAAiD;oBAC1D,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,MAAM;oBAChB,UAAU,EAAE,+DAA+D;oBAC3E,aAAa,EAAE,+CAA+C;iBAC/D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,sBAAsB;IACnC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC;QACvB,iBAAiB;QACjB,eAAe;QACf,eAAe;KAChB,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;QAC9B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAExD,iCAAiC;QACjC,MAAM,iBAAiB,GAAG,8EAA8E,CAAC;QACzG,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1D,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,4CAA4C;gBACrD,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;gBACzC,QAAQ,EAAE,SAAS;gBACnB,UAAU,EAAE,kDAAkD;gBAC9D,aAAa,EAAE,gCAAgC;aAChD,CAAC,CAAC;QACL,CAAC;QAED,+CAA+C;QAC/C,IAAI,yCAAyC,CAAC,IAAI,CAAC,OAAO,CAAC;YACvD,kCAAkC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,8DAA8D;gBACvE,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,wEAAwE;gBACpF,aAAa,EAAE,gCAAgC;aAChD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,qBAAqB;IAClC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC;QACvB,iBAAiB;QACjB,aAAa;QACb,iBAAiB;KAClB,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;QAClD,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAExD,uCAAuC;QACvC,MAAM,YAAY,GAAG;YACnB,yBAAyB,EAAY,0BAA0B;YAC/D,6BAA6B,EAAQ,iCAAiC;YACtE,oBAAoB,EAAiB,yBAAyB;YAC9D,0BAA0B,EAAW,wCAAwC;SAC9E,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC;YACV,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChD,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,mBAAmB;oBACzB,OAAO,EAAE,2CAA2C;oBACpD,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,OAAO;oBACjB,UAAU,EAAE,mFAAmF;oBAC/F,aAAa,EAAE,oBAAoB;iBACpC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC;QACvB,iBAAiB;QACjB,aAAa;KACd,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;QAC9B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAExD,2DAA2D;QAC3D,MAAM,aAAa,GAAG,qEAAqE,CAAC;QAC5F,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACtD,oDAAoD;YACpD,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CACvC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,EAC9B,KAAK,CAAC,KAAK,GAAG,GAAG,CAClB,CAAC;YACF,MAAM,aAAa,GAAG,kEAAkE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAE/G,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,wCAAwC;oBACjD,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,SAAS;oBACnB,UAAU,EAAE,8DAA8D;oBAC1E,aAAa,EAAE,gCAAgC;iBAChD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC;QACvB,iBAAiB;QACjB,aAAa;KACd,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;QAC9B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAExD,gDAAgD;QAChD,MAAM,YAAY,GAAG;YACnB,sDAAsD;YACtD,0EAA0E;YAC1E,qBAAqB,EAAG,8BAA8B;SACvD,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC;YACV,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChD,2BAA2B;gBAC3B,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CACvC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,EAC9B,KAAK,CAAC,KAAK,GAAG,GAAG,CAClB,CAAC;gBACF,MAAM,aAAa,GAAG,8DAA8D,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAE3G,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,iBAAiB;wBACvB,OAAO,EAAE,+DAA+D;wBACxE,IAAI,EAAE,YAAY;wBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;wBACzC,QAAQ,EAAE,SAAS;wBACnB,UAAU,EAAE,8DAA8D;wBAC1E,aAAa,EAAE,sCAAsC;qBACtD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,qBAAqB;IAClC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC;QACvB,aAAa;QACb,cAAc;QACd,aAAa;QACb,qBAAqB;KACtB,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,oBAAoB,EAAE,cAAc,EAAE,cAAc,CAAC;QAC9D,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG;QACrB,EAAE,OAAO,EAAE,4DAA4D,EAAE,IAAI,EAAE,SAAS,EAAE;QAC1F,EAAE,OAAO,EAAE,wDAAwD,EAAE,IAAI,EAAE,cAAc,EAAE;QAC3F,EAAE,OAAO,EAAE,sDAAsD,EAAE,IAAI,EAAE,UAAU,EAAE;QACrF,EAAE,OAAO,EAAE,oCAAoC,EAAE,IAAI,EAAE,YAAY,EAAE;QACrE,EAAE,OAAO,EAAE,sBAAsB,EAAE,IAAI,EAAE,cAAc,EAAE;QACzD,EAAE,OAAO,EAAE,2BAA2B,EAAE,IAAI,EAAE,aAAa,EAAE;KAC9D,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAExD,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,cAAc,EAAE,CAAC;YAC/C,IAAI,KAAK,CAAC;YACV,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC9C,+CAA+C;gBAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC9E,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;oBAAE,SAAS;gBAElH,6BAA6B;gBAC7B,IAAI,4CAA4C,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAAE,SAAS;gBAE1E,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,kBAAkB;oBACxB,OAAO,EAAE,uBAAuB,IAAI,WAAW;oBAC/C,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;oBACzC,QAAQ,EAAE,OAAO;oBACjB,UAAU,EAAE,uCAAuC;oBACnD,aAAa,EAAE,iCAAiC;iBACjD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,GAAG;IACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAoB,EAAE,CAAC;IAEtC,0BAA0B;IAC1B,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,oBAAoB,EAAE,CAAC,CAAC;IAChD,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,mBAAmB,EAAE,CAAC,CAAC;IAC/C,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,yBAAyB,EAAE,CAAC,CAAC;IACrD,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,sBAAsB,EAAE,CAAC,CAAC;IAClD,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,qBAAqB,EAAE,CAAC,CAAC;IACjD,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,kBAAkB,EAAE,CAAC,CAAC;IAC9C,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,SAAS,EAAE,CAAC,CAAC;IACrC,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,qBAAqB,EAAE,CAAC,CAAC;IAEjD,sBAAsB;IACtB,MAAM,QAAQ,GAAuB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ;QACrB,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,MAAM,EAAE,KAAK,CAAC,IAAI;QAClB,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC,CAAC;IAEJ,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;IAEvD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC3B,QAAQ;QACR,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;QAChC,QAAQ,EAAE;YACR,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,QAAQ,CAAC,MAAM;YACzB,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,aAAa,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;SACjF;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,MAAM,8BAA8B,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,IAAA,6BAAa,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEzE,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,MAAM,qCAAqC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,aAAyB,IAAI,EAAE,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC;IAEzF,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,KAAK,WAAW,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC;IAEjC,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,iBAAiB;IACjB,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;IACvE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,KAAK,qBAAqB,CAAC,CAAC;QACnD,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,QAAQ,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvF,OAAO,CAAC,GAAG,CAAC,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YACvC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,QAAQ,qBAAK,CAAC,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAC3E,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,OAAO,YAAY,CAAC,CAAC;QAC5C,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,QAAQ,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvF,OAAO,CAAC,GAAG,CAAC,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,eAAe,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,gBAAgB,eAAe,CAAC,MAAM,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,IAAI,2BAA2B,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IAErD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,KAAK,qCAAqC,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,GAAG,qBAAK,CAAC,KAAK,oBAAoB,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ import { PreflightReport } from "../core/types";
3
+ interface GitHubReporterOptions {
4
+ token?: string;
5
+ repo?: string;
6
+ prNumber?: number;
7
+ commitSha?: string;
8
+ baselineReport?: PreflightReport;
9
+ commentOnPr?: boolean;
10
+ updateStatus?: boolean;
11
+ outputMarkdown?: string;
12
+ }
13
+ export declare function generateMarkdownReport(report: PreflightReport, options?: GitHubReporterOptions): string;
14
+ /**
15
+ * Post comment to GitHub PR
16
+ */
17
+ export declare function postPrComment(markdown: string, options: GitHubReporterOptions): Promise<void>;
18
+ /**
19
+ * Update GitHub commit status
20
+ */
21
+ export declare function updateCommitStatus(report: PreflightReport, options: GitHubReporterOptions): Promise<void>;
22
+ /**
23
+ * Detect GitHub environment from CI variables
24
+ */
25
+ export declare function detectGitHubEnvironment(): Partial<GitHubReporterOptions>;
26
+ /**
27
+ * Get current git info
28
+ */
29
+ export declare function getGitInfo(): {
30
+ branch: string;
31
+ sha: string;
32
+ repo?: string;
33
+ };
34
+ export {};
35
+ //# sourceMappingURL=github-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-reporter.d.ts","sourceRoot":"","sources":["../../src/reporters/github-reporter.ts"],"names":[],"mappings":";AAgBA,OAAO,EAAE,eAAe,EAAqC,MAAM,eAAe,CAAC;AAEnF,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAkCD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,GAAE,qBAA0B,GAAG,MAAM,CA+I3G;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CA8BxE;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAoB3E"}