codeant-cli 0.1.5 → 0.1.7
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/239.index.js +1 -0
- package/dist/701.index.js +1 -0
- package/dist/935.index.js +1 -0
- package/dist/index.js +20 -0
- package/dist/package.json +3 -0
- package/package.json +12 -4
- package/src/commands/getBaseUrl.js +0 -25
- package/src/commands/login.js +0 -124
- package/src/commands/logout.js +0 -30
- package/src/commands/review.js +0 -239
- package/src/commands/secrets.js +0 -268
- package/src/commands/securityAnalysis.js +0 -284
- package/src/commands/setBaseUrl.js +0 -37
- package/src/commands/staticAnalysis.js +0 -405
- package/src/components/ReviewUI.js +0 -127
- package/src/components/Welcome.js +0 -143
- package/src/index.js +0 -202
- package/src/tools/bashTool.js +0 -17
- package/src/tools/executeTool.js +0 -35
- package/src/tools/globTool.js +0 -9
- package/src/tools/grepTool.js +0 -18
- package/src/tools/lsTool.js +0 -7
- package/src/tools/readTool.js +0 -12
- package/src/utils/commonApiHelper.js +0 -101
- package/src/utils/config.js +0 -42
- package/src/utils/fetchApi.js +0 -42
- package/src/utils/gitDiffHelper.js +0 -774
- package/src/utils/reviewApiHelper.js +0 -139
- package/src/utils/secretsApiHelper.js +0 -134
- package/src/utils/securityAnalysisApiHelper.js +0 -119
- package/src/utils/staticAnalysisApiHelper.js +0 -119
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import CommonApiHelper from './commonApiHelper.js';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
|
|
5
|
-
const MAX_REVIEW_FILES = 10;
|
|
6
|
-
|
|
7
|
-
const EXCLUDED_FILENAMES = new Set([
|
|
8
|
-
'package-lock.json',
|
|
9
|
-
'yarn.lock',
|
|
10
|
-
'pnpm-lock.yaml',
|
|
11
|
-
'composer.lock',
|
|
12
|
-
'Gemfile.lock',
|
|
13
|
-
'Cargo.lock',
|
|
14
|
-
'poetry.lock',
|
|
15
|
-
'Pipfile.lock',
|
|
16
|
-
'go.sum',
|
|
17
|
-
'.DS_Store',
|
|
18
|
-
'Thumbs.db',
|
|
19
|
-
]);
|
|
20
|
-
|
|
21
|
-
const EXCLUDED_EXTENSIONS = new Set([
|
|
22
|
-
// Images
|
|
23
|
-
'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.svg', '.webp', '.avif',
|
|
24
|
-
// Fonts
|
|
25
|
-
'.woff', '.woff2', '.ttf', '.eot', '.otf',
|
|
26
|
-
// Binary / compiled
|
|
27
|
-
'.exe', '.dll', '.so', '.dylib', '.bin', '.o', '.a', '.class', '.pyc', '.pyo',
|
|
28
|
-
'.wasm', '.jar', '.war', '.ear',
|
|
29
|
-
// Archives
|
|
30
|
-
'.zip', '.tar', '.gz', '.bz2', '.7z', '.rar',
|
|
31
|
-
// Media
|
|
32
|
-
'.mp3', '.mp4', '.wav', '.avi', '.mov', '.flv', '.wmv', '.ogg', '.webm',
|
|
33
|
-
// Data / generated
|
|
34
|
-
'.min.js', '.min.css', '.map',
|
|
35
|
-
'.pb', '.proto.bin',
|
|
36
|
-
// PDF / docs
|
|
37
|
-
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
|
|
38
|
-
]);
|
|
39
|
-
|
|
40
|
-
function isReviewableFile(filePath) {
|
|
41
|
-
const basename = path.basename(filePath);
|
|
42
|
-
|
|
43
|
-
if (EXCLUDED_FILENAMES.has(basename)) return false;
|
|
44
|
-
|
|
45
|
-
const ext = path.extname(basename).toLowerCase();
|
|
46
|
-
if (EXCLUDED_EXTENSIONS.has(ext)) return false;
|
|
47
|
-
|
|
48
|
-
// Check for .min.js / .min.css (double extension)
|
|
49
|
-
if (basename.endsWith('.min.js') || basename.endsWith('.min.css')) return false;
|
|
50
|
-
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Transforms git diff data into the format expected by the agentic review API
|
|
56
|
-
*/
|
|
57
|
-
class ReviewApiHelper extends CommonApiHelper {
|
|
58
|
-
/**
|
|
59
|
-
* Pass structured diffs through so buildReviewApiRequest can filter them
|
|
60
|
-
*/
|
|
61
|
-
_transformDiffsToApiFormat(diffs) {
|
|
62
|
-
return diffs;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Build the complete request body for the agentic review API
|
|
67
|
-
*/
|
|
68
|
-
async buildReviewApiRequest(type = 'staged-only', includePatterns = [], excludePatterns = [], options = {}) {
|
|
69
|
-
const diffs = await this.getFilesForType(type, options);
|
|
70
|
-
|
|
71
|
-
// diffs is either a string (from getAllDiffs) or an array of structured diff objects
|
|
72
|
-
if (typeof diffs === 'string') {
|
|
73
|
-
// Extract filenames from diff headers and read their contents
|
|
74
|
-
const gitRoot = this.getGitRoot() || process.cwd();
|
|
75
|
-
const fileContents = {};
|
|
76
|
-
const fileMatches = diffs.matchAll(/^diff --git a\/.+ b\/(.+)$/gm);
|
|
77
|
-
for (const match of fileMatches) {
|
|
78
|
-
const f = match[1];
|
|
79
|
-
if (!isReviewableFile(f)) continue;
|
|
80
|
-
try {
|
|
81
|
-
const fullPath = path.resolve(gitRoot, f);
|
|
82
|
-
if (fs.existsSync(fullPath)) {
|
|
83
|
-
fileContents[f] = fs.readFileSync(fullPath, 'utf-8');
|
|
84
|
-
}
|
|
85
|
-
} catch {
|
|
86
|
-
// Skip files that can't be read
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return { diff_content: diffs, file_contents: fileContents };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Filter to reviewable files only
|
|
93
|
-
const reviewable = diffs.filter(d => isReviewableFile(d.filename_str));
|
|
94
|
-
|
|
95
|
-
// Dedupe by filename, keeping all hunks, but limit unique files to MAX_REVIEW_FILES
|
|
96
|
-
const fileOrder = [];
|
|
97
|
-
const fileHunks = new Map();
|
|
98
|
-
for (const d of reviewable) {
|
|
99
|
-
const f = d.filename_str;
|
|
100
|
-
if (!fileHunks.has(f)) {
|
|
101
|
-
if (fileOrder.length >= MAX_REVIEW_FILES) continue;
|
|
102
|
-
fileOrder.push(f);
|
|
103
|
-
fileHunks.set(f, []);
|
|
104
|
-
}
|
|
105
|
-
fileHunks.get(f).push(d);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Reconstruct a combined diff string from the filtered hunks
|
|
109
|
-
const parts = [];
|
|
110
|
-
for (const f of fileOrder) {
|
|
111
|
-
const hunks = fileHunks.get(f);
|
|
112
|
-
// Build a file-level diff header + all hunk patches
|
|
113
|
-
const first = hunks[0];
|
|
114
|
-
const header = `diff --git a/${f} b/${f}\n--- a/${f}\n+++ b/${f}`;
|
|
115
|
-
const hunkPatches = hunks.map(h => h.patch_str).filter(Boolean);
|
|
116
|
-
if (hunkPatches.length > 0) {
|
|
117
|
-
parts.push(header + '\n' + hunkPatches.join('\n'));
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Read full file contents for each changed file
|
|
122
|
-
const gitRoot = this.getGitRoot() || process.cwd();
|
|
123
|
-
const fileContents = {};
|
|
124
|
-
for (const f of fileOrder) {
|
|
125
|
-
try {
|
|
126
|
-
const fullPath = path.resolve(gitRoot, f);
|
|
127
|
-
if (fs.existsSync(fullPath)) {
|
|
128
|
-
fileContents[f] = fs.readFileSync(fullPath, 'utf-8');
|
|
129
|
-
}
|
|
130
|
-
} catch {
|
|
131
|
-
// Skip files that can't be read
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return { diff_content: parts.join('\n'), file_contents: fileContents };
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export default ReviewApiHelper;
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import CommonApiHelper from './commonApiHelper.js';
|
|
2
|
-
import { minimatch } from 'minimatch';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Transforms git diff data into the format expected by the secrets detection API
|
|
6
|
-
*
|
|
7
|
-
* API Input Format:
|
|
8
|
-
* {
|
|
9
|
-
* "files": [
|
|
10
|
-
* {
|
|
11
|
-
* "file_path": str,
|
|
12
|
-
* "code": str,
|
|
13
|
-
* "diffs": [{ "start_line": int, "end_line": int }]
|
|
14
|
-
* }
|
|
15
|
-
* ]
|
|
16
|
-
* }
|
|
17
|
-
*/
|
|
18
|
-
class SecretsApiHelper extends CommonApiHelper {
|
|
19
|
-
/**
|
|
20
|
-
* Transform diff info array to API format
|
|
21
|
-
* Groups by file and extracts diff ranges
|
|
22
|
-
*/
|
|
23
|
-
_transformDiffsToApiFormat(diffs) {
|
|
24
|
-
// Group diffs by filename
|
|
25
|
-
const fileMap = new Map();
|
|
26
|
-
|
|
27
|
-
for (const diff of diffs) {
|
|
28
|
-
const filePath = diff.filename_str;
|
|
29
|
-
|
|
30
|
-
// Skip diffs with missing or invalid filename
|
|
31
|
-
if (!filePath) {
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!fileMap.has(filePath)) {
|
|
36
|
-
fileMap.set(filePath, {
|
|
37
|
-
file_path: filePath,
|
|
38
|
-
code: diff.head_file_str || '',
|
|
39
|
-
diffs: []
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Add diff range if available
|
|
44
|
-
if (diff.start_line_str && diff.end_line_str) {
|
|
45
|
-
const startLine = parseInt(diff.start_line_str, 10);
|
|
46
|
-
const endLine = parseInt(diff.end_line_str, 10);
|
|
47
|
-
|
|
48
|
-
if (!isNaN(startLine) && !isNaN(endLine)) {
|
|
49
|
-
fileMap.get(filePath).diffs.push({
|
|
50
|
-
start_line: startLine,
|
|
51
|
-
end_line: endLine
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return Array.from(fileMap.values());
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Filter files based on include and exclude glob patterns
|
|
62
|
-
* @param {Array} files - Array of file objects with 'file_path' property
|
|
63
|
-
* @param {Array} includePatterns - Array of glob pattern strings to include
|
|
64
|
-
* @param {Array} excludePatterns - Array of glob pattern strings to exclude
|
|
65
|
-
*/
|
|
66
|
-
_filterFiles(files, includePatterns = [], excludePatterns = []) {
|
|
67
|
-
return files.filter(fileObj => {
|
|
68
|
-
const filePath = fileObj.file_path;
|
|
69
|
-
|
|
70
|
-
// If include patterns are specified, file must match at least one
|
|
71
|
-
if (includePatterns.length > 0) {
|
|
72
|
-
const matchesInclude = includePatterns.some(pattern => {
|
|
73
|
-
try {
|
|
74
|
-
if (pattern instanceof RegExp) {
|
|
75
|
-
return pattern.test(filePath);
|
|
76
|
-
}
|
|
77
|
-
return minimatch(filePath, pattern, { matchBase: true });
|
|
78
|
-
} catch (e) {
|
|
79
|
-
console.warn(`Invalid include pattern: ${pattern}`, e.message);
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
if (!matchesInclude) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// If exclude patterns are specified, file must not match any
|
|
90
|
-
if (excludePatterns.length > 0) {
|
|
91
|
-
const matchesExclude = excludePatterns.some(pattern => {
|
|
92
|
-
try {
|
|
93
|
-
if (pattern instanceof RegExp) {
|
|
94
|
-
return pattern.test(filePath);
|
|
95
|
-
}
|
|
96
|
-
return minimatch(filePath, pattern, { matchBase: true });
|
|
97
|
-
} catch (e) {
|
|
98
|
-
console.warn(`Invalid exclude pattern: ${pattern}`, e.message);
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
if (matchesExclude) {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return true;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Build the complete request body for the secrets API
|
|
114
|
-
* @param {string} type - Type of scan (staged-only, branch-diff, etc.)
|
|
115
|
-
* @param {Array} includePatterns - Optional array of glob patterns to include files
|
|
116
|
-
* @param {Array} excludePatterns - Optional array of glob patterns to exclude files
|
|
117
|
-
* @param {Object} options - Additional options like lastNCommits
|
|
118
|
-
*/
|
|
119
|
-
async buildSecretsApiRequest(type = 'staged-only', includePatterns = [], excludePatterns = [], options = {}) {
|
|
120
|
-
let files = await this.getFilesForType(type, options);
|
|
121
|
-
|
|
122
|
-
// Handle null/undefined return
|
|
123
|
-
if (!files || !Array.isArray(files)) {
|
|
124
|
-
files = [];
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Apply include/exclude filters
|
|
128
|
-
files = this._filterFiles(files, includePatterns, excludePatterns);
|
|
129
|
-
|
|
130
|
-
return { files };
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export default SecretsApiHelper;
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import CommonApiHelper from './commonApiHelper.js';
|
|
2
|
-
import { minimatch } from 'minimatch';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Transforms git diff data into the format expected by the static analysis API
|
|
6
|
-
*
|
|
7
|
-
* API Input Format:
|
|
8
|
-
* {
|
|
9
|
-
* "filesData": [
|
|
10
|
-
* {
|
|
11
|
-
* "file": str,
|
|
12
|
-
* "code": str
|
|
13
|
-
* }
|
|
14
|
-
* ]
|
|
15
|
-
* }
|
|
16
|
-
*/
|
|
17
|
-
class SecurityAnalysisApiHelper extends CommonApiHelper {
|
|
18
|
-
/**
|
|
19
|
-
* Transform diff info array to API format
|
|
20
|
-
* Groups by file (without diff ranges for static analysis)
|
|
21
|
-
*/
|
|
22
|
-
_transformDiffsToApiFormat(diffs) {
|
|
23
|
-
// Group diffs by filename
|
|
24
|
-
const fileMap = new Map();
|
|
25
|
-
|
|
26
|
-
for (const diff of diffs) {
|
|
27
|
-
const filePath = diff.filename_str;
|
|
28
|
-
|
|
29
|
-
// Skip diffs with missing or invalid filename
|
|
30
|
-
if (!filePath) {
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!fileMap.has(filePath)) {
|
|
35
|
-
fileMap.set(filePath, {
|
|
36
|
-
file_path: filePath,
|
|
37
|
-
code: diff.head_file_str || ''
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return Array.from(fileMap.values());
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Filter files based on include and exclude glob patterns
|
|
47
|
-
* @param {Array} files - Array of file objects with 'file' property
|
|
48
|
-
* @param {Array} includePatterns - Array of glob pattern strings to include
|
|
49
|
-
* @param {Array} excludePatterns - Array of glob pattern strings to exclude
|
|
50
|
-
*/
|
|
51
|
-
_filterFiles(files, includePatterns = [], excludePatterns = []) {
|
|
52
|
-
return files.filter(fileObj => {
|
|
53
|
-
const filePath = fileObj.file;
|
|
54
|
-
|
|
55
|
-
// If include patterns are specified, file must match at least one
|
|
56
|
-
if (includePatterns.length > 0) {
|
|
57
|
-
const matchesInclude = includePatterns.some(pattern => {
|
|
58
|
-
try {
|
|
59
|
-
if (pattern instanceof RegExp) {
|
|
60
|
-
return pattern.test(filePath);
|
|
61
|
-
}
|
|
62
|
-
return minimatch(filePath, pattern, { matchBase: true });
|
|
63
|
-
} catch (e) {
|
|
64
|
-
console.warn(`Invalid include pattern: ${pattern}`, e.message);
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
if (!matchesInclude) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// If exclude patterns are specified, file must not match any
|
|
75
|
-
if (excludePatterns.length > 0) {
|
|
76
|
-
const matchesExclude = excludePatterns.some(pattern => {
|
|
77
|
-
try {
|
|
78
|
-
if (pattern instanceof RegExp) {
|
|
79
|
-
return pattern.test(filePath);
|
|
80
|
-
}
|
|
81
|
-
return minimatch(filePath, pattern, { matchBase: true });
|
|
82
|
-
} catch (e) {
|
|
83
|
-
console.warn(`Invalid exclude pattern: ${pattern}`, e.message);
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
if (matchesExclude) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return true;
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Build the complete request body for the static analysis API
|
|
99
|
-
* @param {string} type - Type of scan (staged-only, branch-diff, etc.)
|
|
100
|
-
* @param {Array} includePatterns - Optional array of glob patterns to include files
|
|
101
|
-
* @param {Array} excludePatterns - Optional array of glob patterns to exclude files
|
|
102
|
-
* @param {Object} options - Additional options like lastNCommits
|
|
103
|
-
*/
|
|
104
|
-
async buildSecurityAnalysisApiRequest(type = 'staged-only', includePatterns = [], excludePatterns = [], options = {}) {
|
|
105
|
-
let files = await this.getFilesForType(type, options);
|
|
106
|
-
|
|
107
|
-
// Handle null/undefined return
|
|
108
|
-
if (!files || !Array.isArray(files)) {
|
|
109
|
-
files = [];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Apply include/exclude filters
|
|
113
|
-
files = this._filterFiles(files, includePatterns, excludePatterns);
|
|
114
|
-
|
|
115
|
-
return { files };
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export default SecurityAnalysisApiHelper;
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import CommonApiHelper from './commonApiHelper.js';
|
|
2
|
-
import { minimatch } from 'minimatch';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Transforms git diff data into the format expected by the static analysis API
|
|
6
|
-
*
|
|
7
|
-
* API Input Format:
|
|
8
|
-
* {
|
|
9
|
-
* "filesData": [
|
|
10
|
-
* {
|
|
11
|
-
* "file": str,
|
|
12
|
-
* "code": str
|
|
13
|
-
* }
|
|
14
|
-
* ]
|
|
15
|
-
* }
|
|
16
|
-
*/
|
|
17
|
-
class StaticAnalysisApiHelper extends CommonApiHelper {
|
|
18
|
-
/**
|
|
19
|
-
* Transform diff info array to API format
|
|
20
|
-
* Groups by file (without diff ranges for static analysis)
|
|
21
|
-
*/
|
|
22
|
-
_transformDiffsToApiFormat(diffs) {
|
|
23
|
-
// Group diffs by filename
|
|
24
|
-
const fileMap = new Map();
|
|
25
|
-
|
|
26
|
-
for (const diff of diffs) {
|
|
27
|
-
const filePath = diff.filename_str;
|
|
28
|
-
|
|
29
|
-
// Skip diffs with missing or invalid filename
|
|
30
|
-
if (!filePath) {
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!fileMap.has(filePath)) {
|
|
35
|
-
fileMap.set(filePath, {
|
|
36
|
-
file: filePath,
|
|
37
|
-
code: diff.head_file_str || ''
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return Array.from(fileMap.values());
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Filter files based on include and exclude glob patterns
|
|
47
|
-
* @param {Array} files - Array of file objects with 'file' property
|
|
48
|
-
* @param {Array} includePatterns - Array of glob pattern strings to include
|
|
49
|
-
* @param {Array} excludePatterns - Array of glob pattern strings to exclude
|
|
50
|
-
*/
|
|
51
|
-
_filterFiles(files, includePatterns = [], excludePatterns = []) {
|
|
52
|
-
return files.filter(fileObj => {
|
|
53
|
-
const filePath = fileObj.file;
|
|
54
|
-
|
|
55
|
-
// If include patterns are specified, file must match at least one
|
|
56
|
-
if (includePatterns.length > 0) {
|
|
57
|
-
const matchesInclude = includePatterns.some(pattern => {
|
|
58
|
-
try {
|
|
59
|
-
if (pattern instanceof RegExp) {
|
|
60
|
-
return pattern.test(filePath);
|
|
61
|
-
}
|
|
62
|
-
return minimatch(filePath, pattern, { matchBase: true });
|
|
63
|
-
} catch (e) {
|
|
64
|
-
console.warn(`Invalid include pattern: ${pattern}`, e.message);
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
if (!matchesInclude) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// If exclude patterns are specified, file must not match any
|
|
75
|
-
if (excludePatterns.length > 0) {
|
|
76
|
-
const matchesExclude = excludePatterns.some(pattern => {
|
|
77
|
-
try {
|
|
78
|
-
if (pattern instanceof RegExp) {
|
|
79
|
-
return pattern.test(filePath);
|
|
80
|
-
}
|
|
81
|
-
return minimatch(filePath, pattern, { matchBase: true });
|
|
82
|
-
} catch (e) {
|
|
83
|
-
console.warn(`Invalid exclude pattern: ${pattern}`, e.message);
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
if (matchesExclude) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return true;
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Build the complete request body for the static analysis API
|
|
99
|
-
* @param {string} type - Type of scan (staged-only, branch-diff, etc.)
|
|
100
|
-
* @param {Array} includePatterns - Optional array of glob patterns to include files
|
|
101
|
-
* @param {Array} excludePatterns - Optional array of glob patterns to exclude files
|
|
102
|
-
* @param {Object} options - Additional options like lastNCommits
|
|
103
|
-
*/
|
|
104
|
-
async buildStaticAnalysisApiRequest(type = 'staged-only', includePatterns = [], excludePatterns = [], options = {}) {
|
|
105
|
-
let files = await this.getFilesForType(type, options);
|
|
106
|
-
|
|
107
|
-
// Handle null/undefined return
|
|
108
|
-
if (!files || !Array.isArray(files)) {
|
|
109
|
-
files = [];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Apply include/exclude filters
|
|
113
|
-
files = this._filterFiles(files, includePatterns, excludePatterns);
|
|
114
|
-
|
|
115
|
-
return { filesData: files };
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export default StaticAnalysisApiHelper;
|