sickbay 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DiffApp-QTG772WX.js → DiffApp-TDXQ3AGJ.js} +2 -2
- package/dist/{DoctorApp-T45ZNMZQ.js → DoctorApp-YVQXYJKB.js} +3 -3
- package/dist/{FixApp-P2FHGJKZ.js → FixApp-P3HE5VBZ.js} +3 -3
- package/dist/{StatsApp-ONUVROC5.js → StatsApp-OQ3UHHCX.js} +3 -3
- package/dist/{TrendApp-OXM6QDE5.js → TrendApp-3UFL4P7I.js} +3 -3
- package/dist/{TuiApp-6MPPK4JT.js → TuiApp-XJALAKP6.js} +4 -4
- package/dist/{chunk-YAGUN3VM.js → chunk-AO3RLT4Q.js} +1 -1
- package/dist/{chunk-FEM4GJAY.js → chunk-MFINHA55.js} +1 -1
- package/dist/{chunk-YHFU2XTS.js → chunk-X3OVB6OA.js} +48 -7
- package/dist/config.js +1 -1
- package/dist/{dist-FNOE2KCN.js → dist-CC44WX2U.js} +1 -1
- package/dist/index.js +25 -25
- package/dist/{init-JY7XQS3Q.js → init-IDUYC5ZY.js} +1 -1
- package/dist/{resolve-package-U5UYD7TW.js → resolve-package-W7BS3CDL.js} +2 -2
- package/dist/web/assets/{index-Bt4RJTHa.css → index-B23n764F.css} +1 -1
- package/dist/web/assets/{index-BuiDF5iO.js → index-BSAa6zMs.js} +7 -7
- package/dist/web/assets/index-BSAa6zMs.js.map +1 -0
- package/dist/web/index.html +2 -2
- package/dist/{web-T63BRGAM.js → web-7OLVXHBT.js} +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-BuiDF5iO.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Header
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AO3RLT4Q.js";
|
|
4
4
|
import "./chunk-JSBRDJBE.js";
|
|
5
5
|
|
|
6
6
|
// src/components/DiffApp.tsx
|
|
@@ -120,7 +120,7 @@ function DiffApp({ projectPath, branch, jsonOutput, checks, verbose }) {
|
|
|
120
120
|
useEffect(() => {
|
|
121
121
|
(async () => {
|
|
122
122
|
try {
|
|
123
|
-
const { runSickbay } = await import("./dist-
|
|
123
|
+
const { runSickbay } = await import("./dist-CC44WX2U.js");
|
|
124
124
|
const currentReport = await runSickbay({
|
|
125
125
|
projectPath,
|
|
126
126
|
checks,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MFINHA55.js";
|
|
4
4
|
import {
|
|
5
5
|
Header
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AO3RLT4Q.js";
|
|
7
7
|
import {
|
|
8
8
|
detectPackageManager,
|
|
9
9
|
detectProject
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-X3OVB6OA.js";
|
|
11
11
|
import "./chunk-JSBRDJBE.js";
|
|
12
12
|
|
|
13
13
|
// src/components/DoctorApp.tsx
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MFINHA55.js";
|
|
4
4
|
import {
|
|
5
5
|
ProgressList
|
|
6
6
|
} from "./chunk-MBVA75EM.js";
|
|
7
7
|
import {
|
|
8
8
|
Header
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-AO3RLT4Q.js";
|
|
10
10
|
import {
|
|
11
11
|
runSickbay
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-X3OVB6OA.js";
|
|
13
13
|
import "./chunk-JSBRDJBE.js";
|
|
14
14
|
|
|
15
15
|
// src/components/FixApp.tsx
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MFINHA55.js";
|
|
4
4
|
import {
|
|
5
5
|
Header
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AO3RLT4Q.js";
|
|
7
7
|
import {
|
|
8
8
|
detectProject
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-X3OVB6OA.js";
|
|
10
10
|
import "./chunk-JSBRDJBE.js";
|
|
11
11
|
|
|
12
12
|
// src/components/StatsApp.tsx
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
} from "./chunk-SHO3ZXTH.js";
|
|
5
5
|
import {
|
|
6
6
|
shortName
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-MFINHA55.js";
|
|
8
8
|
import {
|
|
9
9
|
Header
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-AO3RLT4Q.js";
|
|
11
|
+
import "./chunk-X3OVB6OA.js";
|
|
12
12
|
import {
|
|
13
13
|
detectRegressions,
|
|
14
14
|
loadHistory
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
detectMonorepo,
|
|
15
15
|
runSickbay,
|
|
16
16
|
runSickbayMonorepo
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-X3OVB6OA.js";
|
|
18
18
|
import {
|
|
19
19
|
loadHistory
|
|
20
20
|
} from "./chunk-3OR2GFVE.js";
|
|
@@ -690,7 +690,7 @@ function TuiApp({
|
|
|
690
690
|
return () => timers.forEach(clearTimeout);
|
|
691
691
|
}, []);
|
|
692
692
|
useEffect7(() => {
|
|
693
|
-
checkForUpdate("1.
|
|
693
|
+
checkForUpdate("1.13.0").then((info) => {
|
|
694
694
|
if (info) setUpdateInfo(info);
|
|
695
695
|
});
|
|
696
696
|
}, []);
|
|
@@ -716,7 +716,7 @@ function TuiApp({
|
|
|
716
716
|
} catch {
|
|
717
717
|
}
|
|
718
718
|
try {
|
|
719
|
-
const { getDependencyTree } = await import("./dist-
|
|
719
|
+
const { getDependencyTree } = await import("./dist-CC44WX2U.js");
|
|
720
720
|
const { saveDepTree } = await import("./history-KXLC45VS.js");
|
|
721
721
|
const tree = await getDependencyTree(projectPath, result.projectInfo.packageManager);
|
|
722
722
|
saveDepTree(projectPath, tree);
|
|
@@ -820,7 +820,7 @@ function TuiApp({
|
|
|
820
820
|
const webReport = monorepoReportRef.current ?? reportRef.current;
|
|
821
821
|
if (!webReport) return;
|
|
822
822
|
try {
|
|
823
|
-
const { serveWeb } = await import("./web-
|
|
823
|
+
const { serveWeb } = await import("./web-7OLVXHBT.js");
|
|
824
824
|
const { default: openBrowser } = await import("open");
|
|
825
825
|
let aiService;
|
|
826
826
|
if (withAI && process.env.ANTHROPIC_API_KEY && !monorepoReportRef.current) {
|
|
@@ -11,7 +11,7 @@ var ASCII_ART = `
|
|
|
11
11
|
A vitals health check for your app
|
|
12
12
|
`.trim();
|
|
13
13
|
function Header({ projectName }) {
|
|
14
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.
|
|
14
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.13.0")), projectName && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " Analyzing "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: "white" }, projectName)));
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export {
|
|
@@ -2710,7 +2710,8 @@ var AngularBuildConfigRunner = class extends BaseRunner {
|
|
|
2710
2710
|
severity: "warning",
|
|
2711
2711
|
message: "Production build has sourceMap enabled \u2014 ships source code to end users",
|
|
2712
2712
|
fix: {
|
|
2713
|
-
description: 'Set "sourceMap": false in the production build configuration.'
|
|
2713
|
+
description: 'Set "sourceMap": false in the production build configuration.',
|
|
2714
|
+
command: `ng config projects.${projectName}.architect.build.configurations.production.sourceMap false`
|
|
2714
2715
|
},
|
|
2715
2716
|
reportedBy: ["angular-build-config"]
|
|
2716
2717
|
});
|
|
@@ -2720,7 +2721,8 @@ var AngularBuildConfigRunner = class extends BaseRunner {
|
|
|
2720
2721
|
severity: "warning",
|
|
2721
2722
|
message: "Production build has optimization disabled \u2014 no minification or tree-shaking",
|
|
2722
2723
|
fix: {
|
|
2723
|
-
description: 'Set "optimization": true in the production build configuration.'
|
|
2724
|
+
description: 'Set "optimization": true in the production build configuration.',
|
|
2725
|
+
command: `ng config projects.${projectName}.architect.build.configurations.production.optimization true`
|
|
2724
2726
|
},
|
|
2725
2727
|
reportedBy: ["angular-build-config"]
|
|
2726
2728
|
});
|
|
@@ -2740,7 +2742,8 @@ var AngularBuildConfigRunner = class extends BaseRunner {
|
|
|
2740
2742
|
severity: "warning",
|
|
2741
2743
|
message: "Production build has AOT compilation disabled \u2014 JIT compilation is slower and less secure",
|
|
2742
2744
|
fix: {
|
|
2743
|
-
description: 'Remove "aot": false from the production build configuration. AOT is the default since Angular 9.'
|
|
2745
|
+
description: 'Remove "aot": false from the production build configuration. AOT is the default since Angular 9.',
|
|
2746
|
+
command: `ng config projects.${projectName}.architect.build.configurations.production.aot true`
|
|
2744
2747
|
},
|
|
2745
2748
|
reportedBy: ["angular-build-config"]
|
|
2746
2749
|
});
|
|
@@ -2796,6 +2799,7 @@ var AngularChangeDetectionRunner = class extends BaseRunner {
|
|
|
2796
2799
|
severity: "warning",
|
|
2797
2800
|
message: `${file} \u2014 component missing OnPush change detection`,
|
|
2798
2801
|
file,
|
|
2802
|
+
suppressMatch: file,
|
|
2799
2803
|
fix: {
|
|
2800
2804
|
description: "Add `changeDetection: ChangeDetectionStrategy.OnPush` to the @Component decorator to prevent unnecessary re-renders."
|
|
2801
2805
|
},
|
|
@@ -2902,6 +2906,7 @@ var AngularLazyRoutesRunner = class extends BaseRunner {
|
|
|
2902
2906
|
severity: "warning",
|
|
2903
2907
|
message: `${relPath}:${i + 1} \u2014 static route component import; consider lazy loading`,
|
|
2904
2908
|
file: relPath,
|
|
2909
|
+
suppressMatch: relPath,
|
|
2905
2910
|
fix: {
|
|
2906
2911
|
description: "Replace `component: MyComponent` with `loadComponent: () => import('./my.component').then(m => m.MyComponent)` to enable route-level code splitting."
|
|
2907
2912
|
},
|
|
@@ -2996,6 +3001,7 @@ var AngularSecurityRunner = class extends BaseRunner {
|
|
|
2996
3001
|
severity: "warning",
|
|
2997
3002
|
message: `${relPath}:${i + 1} \u2014 DomSanitizer ${method.slice(0, -1)}() bypasses XSS protection`,
|
|
2998
3003
|
file: relPath,
|
|
3004
|
+
suppressMatch: relPath,
|
|
2999
3005
|
fix: {
|
|
3000
3006
|
description: "Avoid bypassing Angular's built-in sanitization. Use safe values or sanitize input before rendering."
|
|
3001
3007
|
},
|
|
@@ -3008,6 +3014,7 @@ var AngularSecurityRunner = class extends BaseRunner {
|
|
|
3008
3014
|
severity: "warning",
|
|
3009
3015
|
message: `${relPath}:${i + 1} \u2014 [innerHTML] binding is a potential XSS vector if content is user-controlled`,
|
|
3010
3016
|
file: relPath,
|
|
3017
|
+
suppressMatch: relPath,
|
|
3011
3018
|
fix: {
|
|
3012
3019
|
description: "Prefer Angular's built-in text interpolation or use DomSanitizer explicitly when innerHTML is required."
|
|
3013
3020
|
},
|
|
@@ -3189,6 +3196,7 @@ var AngularSubscriptionsRunner = class extends BaseRunner {
|
|
|
3189
3196
|
severity: "warning",
|
|
3190
3197
|
message: `${file} \u2014 possible unguarded subscription (no takeUntilDestroyed, takeUntil, or ngOnDestroy found)`,
|
|
3191
3198
|
file,
|
|
3199
|
+
suppressMatch: file,
|
|
3192
3200
|
fix: {
|
|
3193
3201
|
description: "Use `takeUntilDestroyed()` from `@angular/core/rxjs-interop` or call `.unsubscribe()` in `ngOnDestroy` to prevent memory leaks."
|
|
3194
3202
|
},
|
|
@@ -3311,6 +3319,7 @@ function checkNgForTrackBy(template, relPath, issues) {
|
|
|
3311
3319
|
severity: "warning",
|
|
3312
3320
|
message: `${relPath} \u2014 *ngFor without trackBy causes full list re-renders on any array change`,
|
|
3313
3321
|
file: relPath,
|
|
3322
|
+
suppressMatch: relPath,
|
|
3314
3323
|
fix: {
|
|
3315
3324
|
description: 'Add a trackBy function to the *ngFor directive (e.g. *ngFor="let item of items; trackBy: trackById").'
|
|
3316
3325
|
},
|
|
@@ -3329,6 +3338,7 @@ function checkForTrack(template, relPath, issues) {
|
|
|
3329
3338
|
severity: "warning",
|
|
3330
3339
|
message: `${relPath} \u2014 @for without track expression causes full list re-renders`,
|
|
3331
3340
|
file: relPath,
|
|
3341
|
+
suppressMatch: relPath,
|
|
3332
3342
|
fix: {
|
|
3333
3343
|
description: "Add a track expression to the @for block (e.g. @for (item of items; track item.id))."
|
|
3334
3344
|
},
|
|
@@ -3345,8 +3355,9 @@ function checkFunctionCalls(template, relPath, issues) {
|
|
|
3345
3355
|
if (fnName === "$any" || fnName === "$event") continue;
|
|
3346
3356
|
issues.push({
|
|
3347
3357
|
severity: "warning",
|
|
3348
|
-
message: `${relPath} \u2014 function call {
|
|
3358
|
+
message: `${relPath} \u2014 function call \`${fnName}()\` in template re-runs on every change detection cycle`,
|
|
3349
3359
|
file: relPath,
|
|
3360
|
+
suppressMatch: relPath,
|
|
3350
3361
|
fix: {
|
|
3351
3362
|
description: "Replace the function call with a pre-computed property, a pipe, or use memoization to avoid re-execution on every change detection cycle."
|
|
3352
3363
|
},
|
|
@@ -3359,8 +3370,9 @@ function checkFunctionCalls(template, relPath, issues) {
|
|
|
3359
3370
|
if (fnName === "$any" || fnName === "$event") continue;
|
|
3360
3371
|
issues.push({
|
|
3361
3372
|
severity: "warning",
|
|
3362
|
-
message: `${relPath} \u2014 function call
|
|
3373
|
+
message: `${relPath} \u2014 function call \`${fnName}()\` in property binding re-runs on every change detection cycle`,
|
|
3363
3374
|
file: relPath,
|
|
3375
|
+
suppressMatch: relPath,
|
|
3364
3376
|
fix: {
|
|
3365
3377
|
description: "Replace the function call with a pre-computed property, a pipe, or use memoization to avoid re-execution on every change detection cycle."
|
|
3366
3378
|
},
|
|
@@ -3437,6 +3449,7 @@ var AssetSizeRunner = class extends BaseRunner {
|
|
|
3437
3449
|
issues.push({
|
|
3438
3450
|
severity: "critical",
|
|
3439
3451
|
message: `${asset.path} \u2014 ${sizeMB}MB image (exceeds 2MB)`,
|
|
3452
|
+
suppressMatch: asset.path,
|
|
3440
3453
|
file: asset.path,
|
|
3441
3454
|
fix: {
|
|
3442
3455
|
description: "Compress with tools like squoosh.app, tinypng.com, or convert to WebP/AVIF format"
|
|
@@ -3447,6 +3460,7 @@ var AssetSizeRunner = class extends BaseRunner {
|
|
|
3447
3460
|
issues.push({
|
|
3448
3461
|
severity: "warning",
|
|
3449
3462
|
message: `${asset.path} \u2014 ${sizeKB}KB image (exceeds 500KB)`,
|
|
3463
|
+
suppressMatch: asset.path,
|
|
3450
3464
|
file: asset.path,
|
|
3451
3465
|
fix: { description: "Compress or convert to a more efficient format (WebP, AVIF)" },
|
|
3452
3466
|
reportedBy: ["asset-size"]
|
|
@@ -3457,6 +3471,7 @@ var AssetSizeRunner = class extends BaseRunner {
|
|
|
3457
3471
|
issues.push({
|
|
3458
3472
|
severity: "warning",
|
|
3459
3473
|
message: `${asset.path} \u2014 ${sizeKB}KB SVG (exceeds 100KB, likely unoptimized)`,
|
|
3474
|
+
suppressMatch: asset.path,
|
|
3460
3475
|
file: asset.path,
|
|
3461
3476
|
fix: {
|
|
3462
3477
|
description: "Optimize with SVGO or svgomg.net \u2014 remove metadata, simplify paths"
|
|
@@ -3469,6 +3484,7 @@ var AssetSizeRunner = class extends BaseRunner {
|
|
|
3469
3484
|
issues.push({
|
|
3470
3485
|
severity: "warning",
|
|
3471
3486
|
message: `${asset.path} \u2014 ${sizeKB}KB font (exceeds 500KB)`,
|
|
3487
|
+
suppressMatch: asset.path,
|
|
3472
3488
|
file: asset.path,
|
|
3473
3489
|
fix: {
|
|
3474
3490
|
description: "Subset the font to include only needed characters, or use WOFF2 format"
|
|
@@ -3673,6 +3689,7 @@ var ComplexityRunner = class extends BaseRunner {
|
|
|
3673
3689
|
issues.push({
|
|
3674
3690
|
severity: f.lines >= critical ? "warning" : "info",
|
|
3675
3691
|
message: `${f.path} (${label}): ${f.lines} lines \u2014 consider splitting (threshold: ${warn})`,
|
|
3692
|
+
suppressMatch: f.path,
|
|
3676
3693
|
fix: { description: "Extract concerns into smaller, focused files" },
|
|
3677
3694
|
reportedBy: ["complexity"]
|
|
3678
3695
|
});
|
|
@@ -4138,6 +4155,7 @@ var DepcheckRunner = class extends BaseRunner {
|
|
|
4138
4155
|
localDir: coreLocalDir
|
|
4139
4156
|
});
|
|
4140
4157
|
const data = parseJsonOutput(stdout, "{}");
|
|
4158
|
+
const pm = detectPackageManager(projectPath);
|
|
4141
4159
|
const issues = [];
|
|
4142
4160
|
for (const [dep, files] of Object.entries(data.missing ?? {})) {
|
|
4143
4161
|
if (dep.startsWith("virtual:") || dep.startsWith("node:")) {
|
|
@@ -4146,7 +4164,8 @@ var DepcheckRunner = class extends BaseRunner {
|
|
|
4146
4164
|
issues.push({
|
|
4147
4165
|
severity: "critical",
|
|
4148
4166
|
message: `Missing dependency: ${dep} (used in ${files.length} file${files.length > 1 ? "s" : ""})`,
|
|
4149
|
-
|
|
4167
|
+
suppressMatch: dep,
|
|
4168
|
+
fix: { description: `Install ${dep}`, command: `${pm} install ${dep}` },
|
|
4150
4169
|
reportedBy: ["depcheck"]
|
|
4151
4170
|
});
|
|
4152
4171
|
}
|
|
@@ -4219,6 +4238,7 @@ var ESLintRunner = class extends BaseRunner {
|
|
|
4219
4238
|
issues.push({
|
|
4220
4239
|
severity: file.errorCount > 0 ? "warning" : "info",
|
|
4221
4240
|
message: `${relPath}: ${parts.join(", ")}`,
|
|
4241
|
+
suppressMatch: relPath,
|
|
4222
4242
|
fix: {
|
|
4223
4243
|
description: `Fix ESLint issues in ${relPath}`,
|
|
4224
4244
|
command: `eslint ${relPath} --fix`,
|
|
@@ -4447,6 +4467,7 @@ var HeavyDepsRunner = class extends BaseRunner {
|
|
|
4447
4467
|
const issues = found.map((f) => ({
|
|
4448
4468
|
severity: f.info.severity,
|
|
4449
4469
|
message: `${f.name} \u2014 ${f.info.reason}`,
|
|
4470
|
+
suppressMatch: f.name,
|
|
4450
4471
|
fix: {
|
|
4451
4472
|
description: `Consider replacing with ${f.info.alternative}`
|
|
4452
4473
|
},
|
|
@@ -4604,6 +4625,7 @@ var KnipRunner = class extends BaseRunner {
|
|
|
4604
4625
|
issues.push({
|
|
4605
4626
|
severity: "warning",
|
|
4606
4627
|
message: `Unused file: ${filePath}`,
|
|
4628
|
+
suppressMatch: filePath,
|
|
4607
4629
|
file: filePath,
|
|
4608
4630
|
fix: { description: `Remove ${filePath}` },
|
|
4609
4631
|
reportedBy: ["knip"]
|
|
@@ -4626,6 +4648,7 @@ var KnipRunner = class extends BaseRunner {
|
|
|
4626
4648
|
(dep) => issues.push({
|
|
4627
4649
|
severity: "warning",
|
|
4628
4650
|
message: `Unused dependency: ${dep}`,
|
|
4651
|
+
suppressMatch: dep,
|
|
4629
4652
|
fix: { description: `Remove ${dep}` },
|
|
4630
4653
|
reportedBy: ["knip"]
|
|
4631
4654
|
})
|
|
@@ -4634,6 +4657,7 @@ var KnipRunner = class extends BaseRunner {
|
|
|
4634
4657
|
(dep) => issues.push({
|
|
4635
4658
|
severity: "info",
|
|
4636
4659
|
message: `Unused devDependency: ${dep}`,
|
|
4660
|
+
suppressMatch: dep,
|
|
4637
4661
|
fix: { description: `Remove ${dep}` },
|
|
4638
4662
|
reportedBy: ["knip"]
|
|
4639
4663
|
})
|
|
@@ -4642,6 +4666,7 @@ var KnipRunner = class extends BaseRunner {
|
|
|
4642
4666
|
(exp) => issues.push({
|
|
4643
4667
|
severity: "info",
|
|
4644
4668
|
message: `Unused export: ${exp}`,
|
|
4669
|
+
suppressMatch: exp,
|
|
4645
4670
|
reportedBy: ["knip"]
|
|
4646
4671
|
})
|
|
4647
4672
|
);
|
|
@@ -4711,6 +4736,7 @@ var LicenseCheckerRunner = class extends BaseRunner {
|
|
|
4711
4736
|
issues.push({
|
|
4712
4737
|
severity: "warning",
|
|
4713
4738
|
message: `${pkg} uses ${license} license \u2014 may be incompatible with commercial use`,
|
|
4739
|
+
suppressMatch: pkg.lastIndexOf("@") > 0 ? pkg.slice(0, pkg.lastIndexOf("@")) : pkg,
|
|
4714
4740
|
fix: { description: `Review or replace ${pkg.split("@")[0]}` },
|
|
4715
4741
|
reportedBy: ["license-checker"]
|
|
4716
4742
|
});
|
|
@@ -4812,6 +4838,7 @@ var MadgeRunner = class extends BaseRunner {
|
|
|
4812
4838
|
const issues = circles.map((cycle) => ({
|
|
4813
4839
|
severity: "warning",
|
|
4814
4840
|
message: `Circular dependency: ${cycle.join(" \u2192 ")}`,
|
|
4841
|
+
suppressMatch: cycle[0],
|
|
4815
4842
|
fix: { description: "Refactor to break the circular dependency cycle" },
|
|
4816
4843
|
reportedBy: ["madge"]
|
|
4817
4844
|
}));
|
|
@@ -4871,6 +4898,7 @@ var NextClientComponentsRunner = class extends BaseRunner {
|
|
|
4871
4898
|
severity: "warning",
|
|
4872
4899
|
message: `${file} \u2014 may not need 'use client' (no hooks or event handlers detected)`,
|
|
4873
4900
|
file,
|
|
4901
|
+
suppressMatch: file,
|
|
4874
4902
|
fix: {
|
|
4875
4903
|
description: "This component may not need 'use client' \u2014 it contains no hooks or event handlers. Moving it to a Server Component reduces client bundle size."
|
|
4876
4904
|
},
|
|
@@ -4970,6 +4998,7 @@ var NextFontsRunner = class extends BaseRunner {
|
|
|
4970
4998
|
severity: "warning",
|
|
4971
4999
|
message: `${layoutPath} \u2014 Google Fonts loaded via external stylesheet; use next/font/google`,
|
|
4972
5000
|
file: layoutPath,
|
|
5001
|
+
suppressMatch: layoutPath,
|
|
4973
5002
|
fix: {
|
|
4974
5003
|
description: "Use next/font/google instead of a <link> stylesheet to self-host fonts and improve Core Web Vitals (eliminates render-blocking request)."
|
|
4975
5004
|
},
|
|
@@ -5030,6 +5059,7 @@ var NextImagesRunner = class extends BaseRunner {
|
|
|
5030
5059
|
severity: "warning",
|
|
5031
5060
|
message: `${file} \u2014 raw image element; use next/image for automatic optimization`,
|
|
5032
5061
|
file,
|
|
5062
|
+
suppressMatch: file,
|
|
5033
5063
|
fix: {
|
|
5034
5064
|
description: "Replace <img> with the <Image> component from next/image for automatic optimization, lazy loading, and Core Web Vitals improvements."
|
|
5035
5065
|
},
|
|
@@ -5116,6 +5146,7 @@ var NextLinkRunner = class extends BaseRunner {
|
|
|
5116
5146
|
severity: "warning",
|
|
5117
5147
|
message: `${file} \u2014 raw anchor tag for internal navigation; use next/link`,
|
|
5118
5148
|
file,
|
|
5149
|
+
suppressMatch: file,
|
|
5119
5150
|
fix: {
|
|
5120
5151
|
description: 'Replace <a href="/path"> with <Link href="/path"> from next/link to enable client-side navigation and prefetching.'
|
|
5121
5152
|
},
|
|
@@ -5203,6 +5234,7 @@ var NextMissingBoundariesRunner = class extends BaseRunner {
|
|
|
5203
5234
|
issues.push({
|
|
5204
5235
|
severity: "info",
|
|
5205
5236
|
message: `${relDir} \u2014 missing loading.tsx (Suspense boundary for this route segment)`,
|
|
5237
|
+
suppressMatch: relDir,
|
|
5206
5238
|
fix: {
|
|
5207
5239
|
description: "Add loading.tsx to show a skeleton UI while this route's data loads (App Router Suspense boundary)."
|
|
5208
5240
|
},
|
|
@@ -5214,6 +5246,7 @@ var NextMissingBoundariesRunner = class extends BaseRunner {
|
|
|
5214
5246
|
issues.push({
|
|
5215
5247
|
severity: "info",
|
|
5216
5248
|
message: `${relDir} \u2014 missing error.tsx (error boundary for this route segment)`,
|
|
5249
|
+
suppressMatch: relDir,
|
|
5217
5250
|
fix: {
|
|
5218
5251
|
description: "Add error.tsx with 'use client' to gracefully handle errors in this route segment."
|
|
5219
5252
|
},
|
|
@@ -5477,6 +5510,7 @@ var NodeAsyncErrorsRunner = class extends BaseRunner {
|
|
|
5477
5510
|
} catch {
|
|
5478
5511
|
}
|
|
5479
5512
|
}
|
|
5513
|
+
const pm = detectPackageManager(projectPath);
|
|
5480
5514
|
const issues = [];
|
|
5481
5515
|
if (routeFiles === 0) {
|
|
5482
5516
|
return {
|
|
@@ -5497,7 +5531,8 @@ var NodeAsyncErrorsRunner = class extends BaseRunner {
|
|
|
5497
5531
|
severity: unprotectedFiles === routeFiles ? "critical" : "warning",
|
|
5498
5532
|
message: `${unprotectedFiles} of ${routeFiles} route file(s) contain async handlers without try/catch. Unhandled promise rejections will crash the process in Node.js <15 or produce silent failures.`,
|
|
5499
5533
|
fix: {
|
|
5500
|
-
description: "Wrap async route handlers in try/catch or use express-async-errors to auto-wrap all handlers"
|
|
5534
|
+
description: "Wrap async route handlers in try/catch or use express-async-errors to auto-wrap all handlers",
|
|
5535
|
+
command: `${pm} install express-async-errors`
|
|
5501
5536
|
},
|
|
5502
5537
|
reportedBy: ["node-async-errors"]
|
|
5503
5538
|
});
|
|
@@ -5783,6 +5818,7 @@ function parseNpmAudit(data) {
|
|
|
5783
5818
|
issues.push({
|
|
5784
5819
|
severity: vuln.severity === "critical" || vuln.severity === "high" ? "critical" : "warning",
|
|
5785
5820
|
message: formatAuditMessage(vuln.name, title, url),
|
|
5821
|
+
suppressMatch: vuln.name,
|
|
5786
5822
|
fix: typeof vuln.fixAvailable === "object" ? { description: `Upgrade to ${vuln.fixAvailable.name}@${vuln.fixAvailable.version}` } : { description: "No automatic fix available" },
|
|
5787
5823
|
reportedBy: ["npm-audit"],
|
|
5788
5824
|
...url && { file: url }
|
|
@@ -5805,6 +5841,7 @@ function parsePnpmAudit(data, projectPath) {
|
|
|
5805
5841
|
advisory.title || `Vulnerability in ${pkgName}`,
|
|
5806
5842
|
advisory.url
|
|
5807
5843
|
),
|
|
5844
|
+
suppressMatch: pkgName,
|
|
5808
5845
|
fix: advisory.recommendation ? { description: advisory.recommendation } : { description: "No automatic fix available" },
|
|
5809
5846
|
reportedBy: ["npm-audit"],
|
|
5810
5847
|
...advisory.url && { file: advisory.url }
|
|
@@ -5867,6 +5904,7 @@ var OutdatedRunner = class extends BaseRunner {
|
|
|
5867
5904
|
return {
|
|
5868
5905
|
severity: isMajor ? "warning" : "info",
|
|
5869
5906
|
message: `${e.name}: ${e.current} \u2192 ${e.latest} (${updateType})`,
|
|
5907
|
+
suppressMatch: e.name,
|
|
5870
5908
|
fix: isMajor ? {
|
|
5871
5909
|
description: `Update ${e.name} to ${e.latest} (major \u2014 review changelog before upgrading)`
|
|
5872
5910
|
} : {
|
|
@@ -5960,6 +5998,7 @@ var ReactPerfRunner = class extends BaseRunner {
|
|
|
5960
5998
|
severity: f.severity,
|
|
5961
5999
|
message: f.line > 0 ? `${f.file}:${f.line} \u2014 ${f.pattern}` : `${f.file} \u2014 ${f.pattern}`,
|
|
5962
6000
|
file: f.file,
|
|
6001
|
+
suppressMatch: f.file,
|
|
5963
6002
|
fix: { description: getFixDescription(f.pattern) },
|
|
5964
6003
|
reportedBy: ["react-perf"]
|
|
5965
6004
|
}));
|
|
@@ -6190,6 +6229,7 @@ var SecretsRunner = class extends BaseRunner {
|
|
|
6190
6229
|
const issues = findings.map((f) => ({
|
|
6191
6230
|
severity: "critical",
|
|
6192
6231
|
message: f.line > 0 ? `${f.file}:${f.line} \u2014 ${f.pattern} detected` : `${f.file} \u2014 ${f.pattern}`,
|
|
6232
|
+
suppressMatch: f.pattern,
|
|
6193
6233
|
file: f.file,
|
|
6194
6234
|
fix: {
|
|
6195
6235
|
description: "Move secrets to environment variables",
|
|
@@ -6488,6 +6528,7 @@ var TodoScannerRunner = class extends BaseRunner {
|
|
|
6488
6528
|
const issues = todos.map((t) => ({
|
|
6489
6529
|
severity: t.kind === "FIXME" || t.kind === "HACK" ? "warning" : "info",
|
|
6490
6530
|
message: `${t.file}:${t.line} \u2014 ${t.kind}: ${t.text || "(no description)"}`,
|
|
6531
|
+
suppressMatch: t.file,
|
|
6491
6532
|
reportedBy: ["todo-scanner"]
|
|
6492
6533
|
}));
|
|
6493
6534
|
const fixmeCount = todos.filter((t) => t.kind === "FIXME" || t.kind === "HACK").length;
|
package/dist/config.js
CHANGED