projscan 0.2.0 → 0.3.1
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/README.md +84 -20
- package/dist/analyzers/architectureCheck.js +1 -0
- package/dist/analyzers/architectureCheck.js.map +1 -1
- package/dist/analyzers/securityCheck.js +16 -1
- package/dist/analyzers/securityCheck.js.map +1 -1
- package/dist/cli/index.js +107 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/core/repositoryScanner.d.ts +4 -1
- package/dist/core/repositoryScanner.js +6 -3
- package/dist/core/repositoryScanner.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/reporters/sarifReporter.d.ts +61 -0
- package/dist/reporters/sarifReporter.js +102 -0
- package/dist/reporters/sarifReporter.js.map +1 -0
- package/dist/types.d.ts +24 -1
- package/dist/utils/banner.js +16 -7
- package/dist/utils/banner.js.map +1 -1
- package/dist/utils/changedFiles.d.ts +14 -0
- package/dist/utils/changedFiles.js +113 -0
- package/dist/utils/changedFiles.js.map +1 -0
- package/dist/utils/config.d.ts +8 -0
- package/dist/utils/config.js +117 -0
- package/dist/utils/config.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
const DEFAULT_BASE_REFS = ['origin/main', 'origin/master', 'main', 'master'];
|
|
6
|
+
/**
|
|
7
|
+
* Return files changed since a git base ref. Uses three-dot diff semantics
|
|
8
|
+
* (merge-base…HEAD) to surface "new in this branch" changes. Falls back
|
|
9
|
+
* across a list of common base refs, then HEAD~1 if none exist.
|
|
10
|
+
*
|
|
11
|
+
* Returned paths are relative (POSIX-style) to rootPath, matching FileEntry.relativePath.
|
|
12
|
+
*/
|
|
13
|
+
export async function getChangedFiles(rootPath, explicitBaseRef) {
|
|
14
|
+
const isRepo = await isGitRepo(rootPath);
|
|
15
|
+
if (!isRepo) {
|
|
16
|
+
return {
|
|
17
|
+
available: false,
|
|
18
|
+
reason: 'not a git repository',
|
|
19
|
+
baseRef: null,
|
|
20
|
+
files: [],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const candidates = explicitBaseRef ? [explicitBaseRef] : [...DEFAULT_BASE_REFS, 'HEAD~1'];
|
|
24
|
+
let lastError = null;
|
|
25
|
+
for (const ref of candidates) {
|
|
26
|
+
const exists = await refExists(rootPath, ref);
|
|
27
|
+
if (!exists) {
|
|
28
|
+
lastError = `ref not found: ${ref}`;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const files = await diffNames(rootPath, ref);
|
|
33
|
+
return { available: true, baseRef: ref, files };
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
lastError = err instanceof Error ? err.message : String(err);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Last resort: include uncommitted changes only
|
|
40
|
+
try {
|
|
41
|
+
const files = await statusNames(rootPath);
|
|
42
|
+
if (files.length > 0) {
|
|
43
|
+
return { available: true, baseRef: '(working tree)', files };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
lastError = err instanceof Error ? err.message : String(err);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
available: false,
|
|
51
|
+
reason: lastError ?? 'no usable base ref found',
|
|
52
|
+
baseRef: null,
|
|
53
|
+
files: [],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function isGitRepo(rootPath) {
|
|
57
|
+
try {
|
|
58
|
+
await execFileAsync('git', ['rev-parse', '--git-dir'], { cwd: rootPath });
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function refExists(rootPath, ref) {
|
|
66
|
+
try {
|
|
67
|
+
await execFileAsync('git', ['rev-parse', '--verify', '--quiet', ref], { cwd: rootPath });
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function diffNames(rootPath, baseRef) {
|
|
75
|
+
const { stdout } = await execFileAsync('git', ['diff', '--name-only', '--diff-filter=d', `${baseRef}...HEAD`], { cwd: rootPath, maxBuffer: 10 * 1024 * 1024 });
|
|
76
|
+
// Also include uncommitted changes so PR-style runs cover work-in-progress edits.
|
|
77
|
+
let uncommitted = [];
|
|
78
|
+
try {
|
|
79
|
+
uncommitted = await statusNames(rootPath);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// ignore
|
|
83
|
+
}
|
|
84
|
+
const set = new Set();
|
|
85
|
+
for (const raw of stdout.split('\n')) {
|
|
86
|
+
const line = raw.trim();
|
|
87
|
+
if (line)
|
|
88
|
+
set.add(normalizePath(line));
|
|
89
|
+
}
|
|
90
|
+
for (const f of uncommitted)
|
|
91
|
+
set.add(f);
|
|
92
|
+
return [...set].sort();
|
|
93
|
+
}
|
|
94
|
+
async function statusNames(rootPath) {
|
|
95
|
+
const { stdout } = await execFileAsync('git', ['status', '--porcelain'], { cwd: rootPath, maxBuffer: 10 * 1024 * 1024 });
|
|
96
|
+
const out = new Set();
|
|
97
|
+
for (const raw of stdout.split('\n')) {
|
|
98
|
+
const line = raw.trim();
|
|
99
|
+
if (!line)
|
|
100
|
+
continue;
|
|
101
|
+
// Format: "XY path" or "XY orig -> new" for renames
|
|
102
|
+
const withoutStatus = line.replace(/^..\s+/, '');
|
|
103
|
+
const renamed = withoutStatus.includes(' -> ')
|
|
104
|
+
? withoutStatus.split(' -> ').pop()
|
|
105
|
+
: withoutStatus;
|
|
106
|
+
out.add(normalizePath(renamed));
|
|
107
|
+
}
|
|
108
|
+
return [...out];
|
|
109
|
+
}
|
|
110
|
+
function normalizePath(p) {
|
|
111
|
+
return p.split(path.sep).join('/');
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=changedFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changedFiles.js","sourceRoot":"","sources":["../../src/utils/changedFiles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Issue, LoadedConfig, ProjscanConfig } from '../types.js';
|
|
2
|
+
export declare function loadConfig(rootPath: string, explicitPath?: string): Promise<LoadedConfig>;
|
|
3
|
+
/**
|
|
4
|
+
* Apply config rules to a list of issues:
|
|
5
|
+
* - drop issues whose id matches any disableRules entry (exact match or prefix with trailing "*")
|
|
6
|
+
* - remap severities via severityOverrides (exact id match wins)
|
|
7
|
+
*/
|
|
8
|
+
export declare function applyConfigToIssues(issues: Issue[], config: ProjscanConfig): Issue[];
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const CONFIG_CANDIDATES = ['.projscanrc.json', '.projscanrc'];
|
|
4
|
+
const PKG_KEY = 'projscan';
|
|
5
|
+
const VALID_SEVERITIES = ['info', 'warning', 'error'];
|
|
6
|
+
export async function loadConfig(rootPath, explicitPath) {
|
|
7
|
+
if (explicitPath) {
|
|
8
|
+
const resolved = path.isAbsolute(explicitPath)
|
|
9
|
+
? explicitPath
|
|
10
|
+
: path.join(rootPath, explicitPath);
|
|
11
|
+
const raw = await fs.readFile(resolved, 'utf-8');
|
|
12
|
+
const parsed = safeParse(raw, resolved);
|
|
13
|
+
return { config: normalize(parsed), source: resolved };
|
|
14
|
+
}
|
|
15
|
+
for (const name of CONFIG_CANDIDATES) {
|
|
16
|
+
const candidate = path.join(rootPath, name);
|
|
17
|
+
let raw;
|
|
18
|
+
try {
|
|
19
|
+
raw = await fs.readFile(candidate, 'utf-8');
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// File not present — try next candidate.
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const parsed = safeParse(raw, candidate);
|
|
26
|
+
return { config: normalize(parsed), source: candidate };
|
|
27
|
+
}
|
|
28
|
+
// Try package.json "projscan" key
|
|
29
|
+
const pkgPath = path.join(rootPath, 'package.json');
|
|
30
|
+
try {
|
|
31
|
+
const raw = await fs.readFile(pkgPath, 'utf-8');
|
|
32
|
+
const pkg = JSON.parse(raw);
|
|
33
|
+
const embedded = pkg[PKG_KEY];
|
|
34
|
+
if (embedded && typeof embedded === 'object') {
|
|
35
|
+
return { config: normalize(embedded), source: `${pkgPath}#${PKG_KEY}` };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// No package.json or unreadable
|
|
40
|
+
}
|
|
41
|
+
return { config: {}, source: null };
|
|
42
|
+
}
|
|
43
|
+
function safeParse(raw, filePath) {
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(raw);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
49
|
+
throw new Error(`Invalid JSON in ${filePath}: ${msg}`, { cause: err });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function normalize(input) {
|
|
53
|
+
if (!input || typeof input !== 'object')
|
|
54
|
+
return {};
|
|
55
|
+
const obj = input;
|
|
56
|
+
const out = {};
|
|
57
|
+
if (typeof obj.minScore === 'number' && Number.isFinite(obj.minScore)) {
|
|
58
|
+
out.minScore = Math.max(0, Math.min(100, Math.floor(obj.minScore)));
|
|
59
|
+
}
|
|
60
|
+
if (typeof obj.baseRef === 'string' && obj.baseRef.trim()) {
|
|
61
|
+
out.baseRef = obj.baseRef.trim();
|
|
62
|
+
}
|
|
63
|
+
if (obj.hotspots && typeof obj.hotspots === 'object') {
|
|
64
|
+
const h = obj.hotspots;
|
|
65
|
+
const hotspots = {};
|
|
66
|
+
if (typeof h.limit === 'number' && Number.isFinite(h.limit)) {
|
|
67
|
+
hotspots.limit = Math.max(1, Math.min(100, Math.floor(h.limit)));
|
|
68
|
+
}
|
|
69
|
+
if (typeof h.since === 'string' && h.since.trim()) {
|
|
70
|
+
hotspots.since = h.since.trim();
|
|
71
|
+
}
|
|
72
|
+
if (Object.keys(hotspots).length)
|
|
73
|
+
out.hotspots = hotspots;
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(obj.ignore)) {
|
|
76
|
+
out.ignore = obj.ignore.filter((v) => typeof v === 'string' && v.length > 0);
|
|
77
|
+
}
|
|
78
|
+
if (Array.isArray(obj.disableRules)) {
|
|
79
|
+
out.disableRules = obj.disableRules.filter((v) => typeof v === 'string' && v.length > 0);
|
|
80
|
+
}
|
|
81
|
+
if (obj.severityOverrides && typeof obj.severityOverrides === 'object') {
|
|
82
|
+
const raw = obj.severityOverrides;
|
|
83
|
+
const overrides = {};
|
|
84
|
+
for (const [key, val] of Object.entries(raw)) {
|
|
85
|
+
if (typeof val === 'string' && VALID_SEVERITIES.includes(val)) {
|
|
86
|
+
overrides[key] = val;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (Object.keys(overrides).length)
|
|
90
|
+
out.severityOverrides = overrides;
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Apply config rules to a list of issues:
|
|
96
|
+
* - drop issues whose id matches any disableRules entry (exact match or prefix with trailing "*")
|
|
97
|
+
* - remap severities via severityOverrides (exact id match wins)
|
|
98
|
+
*/
|
|
99
|
+
export function applyConfigToIssues(issues, config) {
|
|
100
|
+
const disabled = config.disableRules ?? [];
|
|
101
|
+
const overrides = config.severityOverrides ?? {};
|
|
102
|
+
return issues
|
|
103
|
+
.filter((issue) => !isRuleDisabled(issue.id, disabled))
|
|
104
|
+
.map((issue) => overrides[issue.id] && overrides[issue.id] !== issue.severity
|
|
105
|
+
? { ...issue, severity: overrides[issue.id] }
|
|
106
|
+
: issue);
|
|
107
|
+
}
|
|
108
|
+
function isRuleDisabled(id, disabled) {
|
|
109
|
+
for (const rule of disabled) {
|
|
110
|
+
if (rule === id)
|
|
111
|
+
return true;
|
|
112
|
+
if (rule.endsWith('*') && id.startsWith(rule.slice(0, -1)))
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projscan",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Instant codebase insights — doctor, hotspots, and MCP server for any repository",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Instant codebase insights — doctor, hotspots, SARIF for Code Scanning, and MCP server for any repository",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|