@anren-utils/mcp-audit 1.0.0 → 1.0.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/index.js +24151 -0
- package/package.json +14 -25
- package/.editorconfig +0 -13
- package/dist/audit/auditUtils.d.ts +0 -12
- package/dist/audit/auditUtils.d.ts.map +0 -1
- package/dist/audit/auditUtils.js +0 -22
- package/dist/audit/auditUtils.js.map +0 -1
- package/dist/audit/currentAudit.d.ts +0 -53
- package/dist/audit/currentAudit.d.ts.map +0 -1
- package/dist/audit/currentAudit.js +0 -54
- package/dist/audit/currentAudit.js.map +0 -1
- package/dist/audit/getDepChain.d.ts +0 -16
- package/dist/audit/getDepChain.d.ts.map +0 -1
- package/dist/audit/getDepChain.js +0 -60
- package/dist/audit/getDepChain.js.map +0 -1
- package/dist/audit/index.d.ts +0 -11
- package/dist/audit/index.d.ts.map +0 -1
- package/dist/audit/index.js +0 -64
- package/dist/audit/index.js.map +0 -1
- package/dist/audit/normalizeAuditResult.d.ts +0 -13
- package/dist/audit/normalizeAuditResult.d.ts.map +0 -1
- package/dist/audit/normalizeAuditResult.js +0 -81
- package/dist/audit/normalizeAuditResult.js.map +0 -1
- package/dist/audit/remoteAudit.d.ts +0 -3
- package/dist/audit/remoteAudit.d.ts.map +0 -1
- package/dist/audit/remoteAudit.js +0 -24
- package/dist/audit/remoteAudit.js.map +0 -1
- package/dist/generateLock/index.d.ts +0 -17
- package/dist/generateLock/index.d.ts.map +0 -1
- package/dist/generateLock/index.js +0 -141
- package/dist/generateLock/index.js.map +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -48
- package/dist/index.js.map +0 -1
- package/dist/mcpServer.d.ts +0 -2
- package/dist/mcpServer.d.ts.map +0 -1
- package/dist/mcpServer.js +0 -34
- package/dist/mcpServer.js.map +0 -1
- package/dist/parseProject/detectPackageManager.d.ts +0 -8
- package/dist/parseProject/detectPackageManager.d.ts.map +0 -1
- package/dist/parseProject/detectPackageManager.js +0 -22
- package/dist/parseProject/detectPackageManager.js.map +0 -1
- package/dist/parseProject/index.d.ts +0 -11
- package/dist/parseProject/index.d.ts.map +0 -1
- package/dist/parseProject/index.js +0 -20
- package/dist/parseProject/index.js.map +0 -1
- package/dist/parseProject/parseLocalProject.d.ts +0 -17
- package/dist/parseProject/parseLocalProject.d.ts.map +0 -1
- package/dist/parseProject/parseLocalProject.js +0 -28
- package/dist/parseProject/parseLocalProject.js.map +0 -1
- package/dist/parseProject/parseLocalWorkspace.d.ts +0 -2
- package/dist/parseProject/parseLocalWorkspace.d.ts.map +0 -1
- package/dist/parseProject/parseLocalWorkspace.js +0 -2
- package/dist/parseProject/parseLocalWorkspace.js.map +0 -1
- package/dist/parseProject/parseRemoteProject.d.ts +0 -41
- package/dist/parseProject/parseRemoteProject.d.ts.map +0 -1
- package/dist/parseProject/parseRemoteProject.js +0 -180
- package/dist/parseProject/parseRemoteProject.js.map +0 -1
- package/dist/parseProject/parseRemoteWorkspace.d.ts +0 -2
- package/dist/parseProject/parseRemoteWorkspace.d.ts.map +0 -1
- package/dist/parseProject/parseRemoteWorkspace.js +0 -2
- package/dist/parseProject/parseRemoteWorkspace.js.map +0 -1
- package/dist/parseProject/parseWorkspace.d.ts +0 -19
- package/dist/parseProject/parseWorkspace.d.ts.map +0 -1
- package/dist/parseProject/parseWorkspace.js +0 -140
- package/dist/parseProject/parseWorkspace.js.map +0 -1
- package/dist/render/index.d.ts +0 -9
- package/dist/render/index.d.ts.map +0 -1
- package/dist/render/index.js +0 -24
- package/dist/render/index.js.map +0 -1
- package/dist/render/markdown.d.ts +0 -12
- package/dist/render/markdown.d.ts.map +0 -1
- package/dist/render/markdown.js +0 -16
- package/dist/render/markdown.js.map +0 -1
- package/dist/types.d.ts +0 -371
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/dirUtils.d.ts +0 -11
- package/dist/utils/dirUtils.d.ts.map +0 -1
- package/dist/utils/dirUtils.js +0 -28
- package/dist/utils/dirUtils.js.map +0 -1
- package/dist/utils/index.d.ts +0 -34
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -74
- package/dist/utils/index.js.map +0 -1
- package/eslint.config.js +0 -38
- package/src/audit/auditUtils.ts +0 -24
- package/src/audit/currentAudit.ts +0 -116
- package/src/audit/getDepChain.ts +0 -71
- package/src/audit/index.ts +0 -90
- package/src/audit/normalizeAuditResult.ts +0 -99
- package/src/audit/remoteAudit.ts +0 -26
- package/src/generateLock/index.ts +0 -203
- package/src/index.ts +0 -48
- package/src/mcpServer.ts +0 -43
- package/src/parseProject/detectPackageManager.ts +0 -24
- package/src/parseProject/index.ts +0 -20
- package/src/parseProject/parseLocalProject.ts +0 -39
- package/src/parseProject/parseRemoteProject.ts +0 -225
- package/src/parseProject/parseWorkspace.ts +0 -202
- package/src/render/index.ts +0 -30
- package/src/render/markdown.ts +0 -29
- package/src/render/template/audit.ejs +0 -30
- package/src/render/template/detail-item.ejs +0 -32
- package/src/render/template/detail.ejs +0 -7
- package/src/render/template/index.ejs +0 -8
- package/src/types.ts +0 -429
- package/src/utils/dirUtils.ts +0 -31
- package/src/utils/index.ts +0 -88
- package/tsconfig.json +0 -42
- /package/{dist/render/template → template}/audit.ejs +0 -0
- /package/{dist/render/template → template}/detail-item.ejs +0 -0
- /package/{dist/render/template → template}/detail.ejs +0 -0
- /package/{dist/render/template → template}/index.ejs +0 -0
package/dist/utils/dirUtils.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @Desc: 创建工作目录
|
|
3
|
-
* @return {string} 工作目录路径
|
|
4
|
-
*/
|
|
5
|
-
export declare function createWorkDir(workDirPath?: string): Promise<string>;
|
|
6
|
-
/**
|
|
7
|
-
* @Desc: 删除工作目录
|
|
8
|
-
* @param {string} workDir 工作目录路径
|
|
9
|
-
*/
|
|
10
|
-
export declare function deleteWorkDir(workDir?: string): Promise<void>;
|
|
11
|
-
//# sourceMappingURL=dirUtils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dirUtils.d.ts","sourceRoot":"","sources":["../../src/utils/dirUtils.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAsB,aAAa,CAAC,WAAW,SAAe,mBAI7D;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,SAAe,iBAEzD"}
|
package/dist/utils/dirUtils.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { getDirname, uniqueId } from "./index.js";
|
|
4
|
-
// 获取当前文件的目录名称
|
|
5
|
-
const __dirname = getDirname(import.meta.url);
|
|
6
|
-
// 获取上两级目录(项目根目录)
|
|
7
|
-
const basepath = join(__dirname, "../..");
|
|
8
|
-
// 定义工作目录路径
|
|
9
|
-
const workBasePath = join(basepath, "work");
|
|
10
|
-
// 确保工作目录存在
|
|
11
|
-
fs.mkdirSync(workBasePath, { recursive: true });
|
|
12
|
-
/**
|
|
13
|
-
* @Desc: 创建工作目录
|
|
14
|
-
* @return {string} 工作目录路径
|
|
15
|
-
*/
|
|
16
|
-
export async function createWorkDir(workDirPath = workBasePath) {
|
|
17
|
-
const workDir = join(workDirPath, uniqueId());
|
|
18
|
-
await fs.promises.mkdir(workDir, { recursive: true });
|
|
19
|
-
return workDir;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* @Desc: 删除工作目录
|
|
23
|
-
* @param {string} workDir 工作目录路径
|
|
24
|
-
*/
|
|
25
|
-
export async function deleteWorkDir(workDir = workBasePath) {
|
|
26
|
-
await fs.promises.rm(workDir, { recursive: true, force: true });
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=dirUtils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dirUtils.js","sourceRoot":"","sources":["../../src/utils/dirUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAElD,cAAc;AACd,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE9C,iBAAiB;AACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC1C,WAAW;AACX,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC5C,WAAW;AACX,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAW,GAAG,YAAY;IAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAO,GAAG,YAAY;IACxD,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC"}
|
package/dist/utils/index.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { RemoteProjectUrlInfo } from "../parseProject/parseRemoteProject.js";
|
|
2
|
-
/**
|
|
3
|
-
* @Desc: 执行shell命令
|
|
4
|
-
* @return {*}
|
|
5
|
-
* @param {string} cmd 命令
|
|
6
|
-
* @param {string} cwd 工作目录
|
|
7
|
-
*/
|
|
8
|
-
export declare function runCommand(cmd: string, cwd: string): Promise<string>;
|
|
9
|
-
/**
|
|
10
|
-
* @Desc: 生成唯一ID
|
|
11
|
-
* @return {string} 唯一ID
|
|
12
|
-
*/
|
|
13
|
-
export declare function uniqueId(): string;
|
|
14
|
-
/**
|
|
15
|
-
* @Desc: 获取文件名
|
|
16
|
-
* @return {string} 文件名
|
|
17
|
-
* @param {string} importMetaUrl 导入元URL
|
|
18
|
-
*/
|
|
19
|
-
export declare function getFilename(importMetaUrl: string): string;
|
|
20
|
-
/**
|
|
21
|
-
* @Desc: 获取文件目录
|
|
22
|
-
* @return {string} 文件目录
|
|
23
|
-
* @param {string} importMetaUrl 导入元URL
|
|
24
|
-
*/
|
|
25
|
-
export declare function getDirname(importMetaUrl: string): string;
|
|
26
|
-
/**
|
|
27
|
-
* @Desc: 根据不同的平台类型,得到获取文件内容的链接
|
|
28
|
-
* @param {RemoteProjectUrlInfo} gitInfo 仓库URL信息
|
|
29
|
-
* @param {string} branchName 分支名称
|
|
30
|
-
* @param {string} path 文件路径
|
|
31
|
-
* @return {string} 获取文件内容的链接
|
|
32
|
-
*/
|
|
33
|
-
export declare function getReadFileUrl(gitInfo: RemoteProjectUrlInfo, branchName: string, path: string): string;
|
|
34
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AASlF;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,mBAexD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,WAEvB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,UAEhD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,UAE/C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,UAeb"}
|
package/dist/utils/index.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { dirname } from "path";
|
|
2
|
-
import { fileURLToPath } from "url";
|
|
3
|
-
import { exec } from "child_process";
|
|
4
|
-
import { promisify } from "util";
|
|
5
|
-
const execAsync = promisify(exec);
|
|
6
|
-
/**
|
|
7
|
-
* @Desc: 执行shell命令
|
|
8
|
-
* @return {*}
|
|
9
|
-
* @param {string} cmd 命令
|
|
10
|
-
* @param {string} cwd 工作目录
|
|
11
|
-
*/
|
|
12
|
-
export async function runCommand(cmd, cwd) {
|
|
13
|
-
try {
|
|
14
|
-
const stdout = await execAsync(cmd, {
|
|
15
|
-
cwd,
|
|
16
|
-
// stdio: ["ignore", "pipe", "pipe"],
|
|
17
|
-
});
|
|
18
|
-
// 返回 audit 的 JSON 结果
|
|
19
|
-
return stdout.stdout.toString();
|
|
20
|
-
}
|
|
21
|
-
catch (err) {
|
|
22
|
-
const error = err;
|
|
23
|
-
if (error.stdout) {
|
|
24
|
-
return error.stdout.toString();
|
|
25
|
-
}
|
|
26
|
-
throw err;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* @Desc: 生成唯一ID
|
|
31
|
-
* @return {string} 唯一ID
|
|
32
|
-
*/
|
|
33
|
-
export function uniqueId() {
|
|
34
|
-
return Math.random().toString(36).substring(2, 15) + Date.now().toString(36);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* @Desc: 获取文件名
|
|
38
|
-
* @return {string} 文件名
|
|
39
|
-
* @param {string} importMetaUrl 导入元URL
|
|
40
|
-
*/
|
|
41
|
-
export function getFilename(importMetaUrl) {
|
|
42
|
-
return fileURLToPath(importMetaUrl);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* @Desc: 获取文件目录
|
|
46
|
-
* @return {string} 文件目录
|
|
47
|
-
* @param {string} importMetaUrl 导入元URL
|
|
48
|
-
*/
|
|
49
|
-
export function getDirname(importMetaUrl) {
|
|
50
|
-
return dirname(getFilename(importMetaUrl));
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* @Desc: 根据不同的平台类型,得到获取文件内容的链接
|
|
54
|
-
* @param {RemoteProjectUrlInfo} gitInfo 仓库URL信息
|
|
55
|
-
* @param {string} branchName 分支名称
|
|
56
|
-
* @param {string} path 文件路径
|
|
57
|
-
* @return {string} 获取文件内容的链接
|
|
58
|
-
*/
|
|
59
|
-
export function getReadFileUrl(gitInfo, branchName, path) {
|
|
60
|
-
const { owner, repo, platform } = gitInfo;
|
|
61
|
-
switch (platform) {
|
|
62
|
-
case "github":
|
|
63
|
-
return `https://raw.githubusercontent.com/${owner}/${repo}/${branchName}/${path}`;
|
|
64
|
-
case "gitee":
|
|
65
|
-
// return `https://raw.gitee.com/${owner}/${repo}/${branchName}/${path}`;
|
|
66
|
-
return `https://gitee.com/${owner}/${repo}/raw/${branchName}/${path}`;
|
|
67
|
-
case "gitlab":
|
|
68
|
-
// return `https://rawlab.com/${owner}/${repo}/${branchName}/${path}`;
|
|
69
|
-
return `https://gitlab.com/${owner}/${repo}/-/raw/${branchName}/${path}`;
|
|
70
|
-
default:
|
|
71
|
-
throw new Error(`Unsupported platform: ${platform}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAGjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAOlC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,GAAW;IACvD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;YAClC,GAAG;YACH,qCAAqC;SACtC,CAAC,CAAC;QACH,qBAAqB;QACrB,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,GAAqB,CAAC;QACpC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACjC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,aAAqB;IAC/C,OAAO,aAAa,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,aAAqB;IAC9C,OAAO,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,OAA6B,EAC7B,UAAkB,EAClB,IAAY;IAEZ,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC1C,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,qCAAqC,KAAK,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACpF,KAAK,OAAO;YACV,yEAAyE;YACzE,OAAO,qBAAqB,KAAK,IAAI,IAAI,QAAQ,UAAU,IAAI,IAAI,EAAE,CAAC;QACxE,KAAK,QAAQ;YACX,sEAAsE;YACtE,OAAO,sBAAsB,KAAK,IAAI,IAAI,UAAU,UAAU,IAAI,IAAI,EAAE,CAAC;QAC3E;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
|
package/eslint.config.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import js from "@eslint/js";
|
|
2
|
-
import tseslint from "@typescript-eslint/eslint-plugin";
|
|
3
|
-
import tsparser from "@typescript-eslint/parser";
|
|
4
|
-
import globals from "globals";
|
|
5
|
-
|
|
6
|
-
export default [
|
|
7
|
-
js.configs.recommended,
|
|
8
|
-
{
|
|
9
|
-
files: ["**/*.ts"],
|
|
10
|
-
languageOptions: {
|
|
11
|
-
parser: tsparser,
|
|
12
|
-
parserOptions: {
|
|
13
|
-
ecmaVersion: "latest",
|
|
14
|
-
sourceType: "module",
|
|
15
|
-
},
|
|
16
|
-
globals: {
|
|
17
|
-
...globals.node,
|
|
18
|
-
console: "readonly",
|
|
19
|
-
process: "readonly",
|
|
20
|
-
Buffer: "readonly",
|
|
21
|
-
__dirname: "readonly",
|
|
22
|
-
__filename: "readonly",
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
plugins: {
|
|
26
|
-
"@typescript-eslint": tseslint,
|
|
27
|
-
},
|
|
28
|
-
rules: {
|
|
29
|
-
...tseslint.configs.recommended.rules,
|
|
30
|
-
"@typescript-eslint/no-unused-vars": "warn",
|
|
31
|
-
"@typescript-eslint/no-explicit-any": "warn",
|
|
32
|
-
"no-console": "off",
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
ignores: ["node_modules/**", "dist/**"],
|
|
37
|
-
},
|
|
38
|
-
];
|
package/src/audit/auditUtils.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { AuditResult } from "../types.js";
|
|
2
|
-
import { runCommand } from "../utils/index.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @Desc: 执行npm audit命令,返回审计结果
|
|
6
|
-
* @param {string} workDir
|
|
7
|
-
*/
|
|
8
|
-
export async function npmAudit(workDir: string) {
|
|
9
|
-
const cmd = `npm audit --json`;
|
|
10
|
-
const jsonResult = await runCommand(cmd, workDir); // 在工作目录中执行命令
|
|
11
|
-
const auditData = JSON.parse(jsonResult) as AuditResult;
|
|
12
|
-
return auditData;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @Desc: 执行pnpm audit命令,返回审计结果
|
|
17
|
-
* @param {string} workDir
|
|
18
|
-
*/
|
|
19
|
-
export async function pnpmAudit(workDir: string) {
|
|
20
|
-
const cmd = `pnpm audit --json`;
|
|
21
|
-
const jsonResult = await runCommand(cmd, workDir); // 在工作目录中执行命令
|
|
22
|
-
const auditData = JSON.parse(jsonResult) as AuditResult;
|
|
23
|
-
return auditData;
|
|
24
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import type { AuditSeverity } from "../types.js";
|
|
2
|
-
import { remoteAudit } from "./remoteAudit.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 单个漏洞问题的详细信息
|
|
6
|
-
*/
|
|
7
|
-
interface Problem {
|
|
8
|
-
/** 漏洞 ID (Advisory ID) */
|
|
9
|
-
source: number;
|
|
10
|
-
|
|
11
|
-
/** 包名 */
|
|
12
|
-
name: string;
|
|
13
|
-
|
|
14
|
-
/** 依赖名 */
|
|
15
|
-
dependency: string;
|
|
16
|
-
|
|
17
|
-
/** 漏洞标题 */
|
|
18
|
-
title: string;
|
|
19
|
-
|
|
20
|
-
/** 漏洞详情 URL */
|
|
21
|
-
url: string;
|
|
22
|
-
|
|
23
|
-
/** 严重程度 */
|
|
24
|
-
severity: AuditSeverity;
|
|
25
|
-
|
|
26
|
-
/** CWE 列表 */
|
|
27
|
-
cwe: string[];
|
|
28
|
-
|
|
29
|
-
/** CVSS 评分数据 */
|
|
30
|
-
cvss: {
|
|
31
|
-
score: number;
|
|
32
|
-
vectorString: string;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/** 受影响的版本范围 */
|
|
36
|
-
range: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* currentAudit 函数返回的最终结果对象
|
|
41
|
-
*/
|
|
42
|
-
interface CurrentAuditResult {
|
|
43
|
-
/** 包名 */
|
|
44
|
-
name: string;
|
|
45
|
-
|
|
46
|
-
/** 版本/范围 */
|
|
47
|
-
range: string;
|
|
48
|
-
|
|
49
|
-
/** 节点路径,当前工程通常为根目录 '.' */
|
|
50
|
-
nodes: string[];
|
|
51
|
-
|
|
52
|
-
/** 依赖链,当前工程通常为空 */
|
|
53
|
-
depChains: any[]; // 如果 depChains 有具体结构,可以替换 any
|
|
54
|
-
|
|
55
|
-
/** 检测到的所有漏洞问题列表 */
|
|
56
|
-
problems: Problem[];
|
|
57
|
-
|
|
58
|
-
/** 当前包的最高严重程度 */
|
|
59
|
-
severity: AuditSeverity;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const severityLevelsMap: Record<AuditSeverity, number> = {
|
|
63
|
-
info: 0,
|
|
64
|
-
low: 1,
|
|
65
|
-
moderate: 2,
|
|
66
|
-
high: 3,
|
|
67
|
-
critical: 4,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @Desc: 添加当前工程的审计结果
|
|
72
|
-
* @return {*}
|
|
73
|
-
* @param {string} name
|
|
74
|
-
* @param {string} version
|
|
75
|
-
*/
|
|
76
|
-
export async function currentAudit(name: string, version: string) {
|
|
77
|
-
// 1. 调用 remoteAudit 函数获取审计结果
|
|
78
|
-
const auditResult = await remoteAudit(name, version);
|
|
79
|
-
// 2. 规格化审计结果
|
|
80
|
-
if (
|
|
81
|
-
!auditResult.advisories ||
|
|
82
|
-
Object.keys(auditResult.advisories).length === 0
|
|
83
|
-
) {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
const result: CurrentAuditResult = {
|
|
87
|
-
name,
|
|
88
|
-
range: version,
|
|
89
|
-
nodes: ["."],
|
|
90
|
-
depChains: [],
|
|
91
|
-
problems: [],
|
|
92
|
-
severity: "info",
|
|
93
|
-
};
|
|
94
|
-
const advisories = Object.values(auditResult.advisories);
|
|
95
|
-
let maxSeverity: AuditSeverity = "info";
|
|
96
|
-
result.problems = advisories.map((advisory) => {
|
|
97
|
-
const problem: Problem = {
|
|
98
|
-
source: advisory.id,
|
|
99
|
-
name,
|
|
100
|
-
dependency: name,
|
|
101
|
-
title: advisory.title,
|
|
102
|
-
url: advisory.url,
|
|
103
|
-
severity: advisory.severity,
|
|
104
|
-
cwe: advisory.cwe,
|
|
105
|
-
cvss: advisory.cvss,
|
|
106
|
-
range: advisory.vulnerable_versions,
|
|
107
|
-
};
|
|
108
|
-
// 更新最大严重性
|
|
109
|
-
if (severityLevelsMap[problem.severity] > severityLevelsMap[maxSeverity]) {
|
|
110
|
-
maxSeverity = problem.severity;
|
|
111
|
-
}
|
|
112
|
-
return problem;
|
|
113
|
-
});
|
|
114
|
-
result.severity = maxSeverity;
|
|
115
|
-
return result;
|
|
116
|
-
}
|
package/src/audit/getDepChain.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import type { VulnerabilityInfo } from "../types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 图的伸缩算法,用于获取从给定节点出发的所有依赖链条
|
|
5
|
-
* 给定图结构中的一个节点,获取从该节点的依赖节点出发一直走到终点,一共走出的所有链条
|
|
6
|
-
* 注意:图结构中可能存在环,遇到环时,环所在的节点直接作为终点即可
|
|
7
|
-
* @param {VulnerabilityInfo} vulnerabilityInfo - 给定的漏洞信息
|
|
8
|
-
* @param {Record<string, VulnerabilityInfo>} vulnerabilities - 所有漏洞信息的映射表,键为漏洞名称,值为漏洞信息
|
|
9
|
-
* @returns {Array<string[][]>} 返回所有依赖链,每个链是一个字符串数组,每个字符串是一个漏洞名称
|
|
10
|
-
* 返回结果示例:"depChains": [["@vue/cli-plugin-babel","@vue/cli-service","@intervolga/optimize-cssnano-plugin","postcss"],[
|
|
11
|
-
"@vue/cli-plugin-router",
|
|
12
|
-
"@vue/cli-service",
|
|
13
|
-
"@intervolga/optimize-cssnano-plugin",
|
|
14
|
-
"postcss"]]
|
|
15
|
-
*/
|
|
16
|
-
export function getDepChains(
|
|
17
|
-
vulnerabilityInfo: VulnerabilityInfo,
|
|
18
|
-
vulnerabilities: Record<string, VulnerabilityInfo>,
|
|
19
|
-
) {
|
|
20
|
-
// 存储所有找到的依赖链(存储最终结果:所有找到的完整路径)
|
|
21
|
-
const chains: string[][] = [];
|
|
22
|
-
|
|
23
|
-
// 当前DFS路径(用于检测环)(当前正在探索的路径栈(用于记录路径和检测环))
|
|
24
|
-
const currentPath: string[] = [];
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* 深度优先搜索函数
|
|
28
|
-
* @param {VulnerabilityInfo} currentVulnerabilityInfo - 当前处理的漏洞信息
|
|
29
|
-
*/
|
|
30
|
-
function dfs(currentVulnerabilityInfo?: VulnerabilityInfo) {
|
|
31
|
-
// 1. 健壮性检查
|
|
32
|
-
if (!currentVulnerabilityInfo) return;
|
|
33
|
-
|
|
34
|
-
// 2. 环检测
|
|
35
|
-
// 检查是否形成环(当前节点已在路径中)
|
|
36
|
-
// 如果当前节点的名字已经存在于当前路径中,说明我们遇到了一个环(A->B->C->A)。
|
|
37
|
-
// 将当前路径记录下来并停止该分支的搜索。
|
|
38
|
-
if (currentPath.includes(currentVulnerabilityInfo.name)) {
|
|
39
|
-
chains.push([...currentPath]); // 注意:这里并没有把重复的节点再次加入,而是截断
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// 3. 前进:将当前节点加入路径头部
|
|
44
|
-
// 使用 unshift 是为了让链条保持顺序:[起点, ..., 当前节点]
|
|
45
|
-
currentPath.unshift(currentVulnerabilityInfo.name);
|
|
46
|
-
|
|
47
|
-
// 4. 终点判断
|
|
48
|
-
// 如果没有依赖节点,说明到达终点
|
|
49
|
-
if (
|
|
50
|
-
!currentVulnerabilityInfo.effects ||
|
|
51
|
-
currentVulnerabilityInfo.effects.length === 0
|
|
52
|
-
) {
|
|
53
|
-
chains.push([...currentPath]);
|
|
54
|
-
} else {
|
|
55
|
-
// 5. 递归遍历
|
|
56
|
-
// 遍历当前节点的所有依赖项,对每一个依赖项递归调用 dfs
|
|
57
|
-
for (const effect of currentVulnerabilityInfo.effects) {
|
|
58
|
-
dfs(vulnerabilities[effect]);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// 6. 回溯
|
|
62
|
-
// 当递归返回(无论是找到了终点还是遇到了环),
|
|
63
|
-
// 必须将当前节点从路径中移除,以便探索下一条可能的路径。
|
|
64
|
-
currentPath.shift();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// 从给定节点开始DFS
|
|
68
|
-
dfs(vulnerabilityInfo);
|
|
69
|
-
|
|
70
|
-
return chains;
|
|
71
|
-
}
|
package/src/audit/index.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { join } from "path";
|
|
2
|
-
import type { RemoteWorkspaceInfo } from "../parseProject/parseWorkspace.js";
|
|
3
|
-
import type { PackageJsonInfo, PackageManager } from "../types.js";
|
|
4
|
-
import { npmAudit, pnpmAudit } from "./auditUtils.js";
|
|
5
|
-
import { currentAudit } from "./currentAudit.js";
|
|
6
|
-
import { normalizeAuditResult } from "./normalizeAuditResult.js";
|
|
7
|
-
|
|
8
|
-
interface AuditOptions {
|
|
9
|
-
workDir: string;
|
|
10
|
-
packageJson: PackageJsonInfo;
|
|
11
|
-
subPackageInfos: RemoteWorkspaceInfo | null;
|
|
12
|
-
currentPackageManager: PackageManager;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function audit(options: AuditOptions) {
|
|
16
|
-
const { subPackageInfos } = options;
|
|
17
|
-
if (subPackageInfos?.subPackageNames) {
|
|
18
|
-
return await monorepoAudit(options);
|
|
19
|
-
}
|
|
20
|
-
return await defaultAudit(options);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function defaultAudit(options: AuditOptions) {
|
|
24
|
-
const { workDir, packageJson, currentPackageManager } = options;
|
|
25
|
-
const auditFn = currentPackageManager === "npm" ? npmAudit : pnpmAudit;
|
|
26
|
-
// 调用 npmAudit 获取审计结果
|
|
27
|
-
const auditResult = await auditFn(workDir);
|
|
28
|
-
|
|
29
|
-
// 规范化审计结果
|
|
30
|
-
const normalizedResult = normalizeAuditResult(auditResult);
|
|
31
|
-
|
|
32
|
-
// 添加当前工程的审计结果
|
|
33
|
-
const current = await currentAudit(packageJson.name, packageJson.version);
|
|
34
|
-
if (current) {
|
|
35
|
-
normalizedResult.vulnerabilities[current.severity].unshift(current);
|
|
36
|
-
}
|
|
37
|
-
// 添加汇总信息
|
|
38
|
-
normalizedResult.summary = {
|
|
39
|
-
total: Object.values(normalizedResult.vulnerabilities).reduce(
|
|
40
|
-
(sum, arr) => sum + arr.length,
|
|
41
|
-
0,
|
|
42
|
-
),
|
|
43
|
-
critical: normalizedResult.vulnerabilities.critical.length,
|
|
44
|
-
high: normalizedResult.vulnerabilities.high.length,
|
|
45
|
-
moderate: normalizedResult.vulnerabilities.moderate.length,
|
|
46
|
-
low: normalizedResult.vulnerabilities.low.length,
|
|
47
|
-
info: normalizedResult.vulnerabilities.info.length,
|
|
48
|
-
};
|
|
49
|
-
return normalizedResult;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function monorepoAudit(options: AuditOptions) {
|
|
53
|
-
const { workDir, packageJson, subPackageInfos, currentPackageManager } =
|
|
54
|
-
options;
|
|
55
|
-
if (!subPackageInfos) {
|
|
56
|
-
throw new Error("monorepo工程必须包含子包信息");
|
|
57
|
-
}
|
|
58
|
-
const auditFn = currentPackageManager === "npm" ? npmAudit : pnpmAudit;
|
|
59
|
-
// 调用 npmAudit 获取审计结果
|
|
60
|
-
const auditResult = await auditFn(workDir);
|
|
61
|
-
// 得到所有子包的审计结果
|
|
62
|
-
const subPackageAuditResults = await Promise.all(
|
|
63
|
-
subPackageInfos.subPackageNames.map((subPackageName) =>
|
|
64
|
-
auditFn(join(workDir, subPackageName)),
|
|
65
|
-
),
|
|
66
|
-
);
|
|
67
|
-
const allAuditResults = [auditResult, ...subPackageAuditResults];
|
|
68
|
-
|
|
69
|
-
// 规范化审计结果
|
|
70
|
-
const normalizedResult = normalizeAuditResult(allAuditResults);
|
|
71
|
-
|
|
72
|
-
// 添加当前工程的审计结果
|
|
73
|
-
const current = await currentAudit(packageJson.name, packageJson.version);
|
|
74
|
-
if (current) {
|
|
75
|
-
normalizedResult.vulnerabilities[current.severity].unshift(current);
|
|
76
|
-
}
|
|
77
|
-
// 添加汇总信息
|
|
78
|
-
normalizedResult.summary = {
|
|
79
|
-
total: Object.values(normalizedResult.vulnerabilities).reduce(
|
|
80
|
-
(sum, arr) => sum + arr.length,
|
|
81
|
-
0,
|
|
82
|
-
),
|
|
83
|
-
critical: normalizedResult.vulnerabilities.critical.length,
|
|
84
|
-
high: normalizedResult.vulnerabilities.high.length,
|
|
85
|
-
moderate: normalizedResult.vulnerabilities.moderate.length,
|
|
86
|
-
low: normalizedResult.vulnerabilities.low.length,
|
|
87
|
-
info: normalizedResult.vulnerabilities.info.length,
|
|
88
|
-
};
|
|
89
|
-
return normalizedResult;
|
|
90
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AuditResult,
|
|
3
|
-
AuditSeverity,
|
|
4
|
-
NormalizedVulnerabilityInfo,
|
|
5
|
-
VulnerabilityInfo,
|
|
6
|
-
} from "../types.js";
|
|
7
|
-
import { getDepChains } from "./getDepChain.js";
|
|
8
|
-
|
|
9
|
-
export interface NormalizedResult {
|
|
10
|
-
vulnerabilities: Record<AuditSeverity, NormalizedVulnerabilityInfo[]>;
|
|
11
|
-
summary?: Record<AuditSeverity | "total", number>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function _normalizeVulnerabilities(auditResult: AuditResult) {
|
|
15
|
-
// 漏洞级别分类组别,用于后续统计漏洞数量
|
|
16
|
-
const result: Record<AuditSeverity, NormalizedVulnerabilityInfo[]> = {
|
|
17
|
-
critical: [],
|
|
18
|
-
high: [],
|
|
19
|
-
moderate: [],
|
|
20
|
-
low: [],
|
|
21
|
-
info: [],
|
|
22
|
-
};
|
|
23
|
-
for (const key in auditResult.vulnerabilities) {
|
|
24
|
-
// 获取当前漏洞的包信息
|
|
25
|
-
const packageInfo = auditResult.vulnerabilities[key];
|
|
26
|
-
const normalizedPackage = _normalizePackage(packageInfo);
|
|
27
|
-
if (normalizedPackage) {
|
|
28
|
-
result[normalizedPackage.severity].push(normalizedPackage);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return result;
|
|
32
|
-
|
|
33
|
-
function _normalizePackage(packageInfo?: VulnerabilityInfo) {
|
|
34
|
-
if (!packageInfo) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
const { via = [] } = packageInfo;
|
|
38
|
-
// 只需要记录自身有漏洞的包,而不是依赖的包
|
|
39
|
-
const validVia = via.filter((it) => typeof it === "object");
|
|
40
|
-
if (validVia.length === 0) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
// 规格化漏洞信息
|
|
44
|
-
const info: NormalizedVulnerabilityInfo = {
|
|
45
|
-
name: packageInfo.name,
|
|
46
|
-
severity: packageInfo.severity,
|
|
47
|
-
problems: validVia,
|
|
48
|
-
nodes: packageInfo.nodes || [],
|
|
49
|
-
};
|
|
50
|
-
info.depChains = getDepChains(packageInfo, auditResult.vulnerabilities);
|
|
51
|
-
// info.depChains = info.depChains.filter(
|
|
52
|
-
// (chain) => !isInvalidChain(chain, packageInfo.name)
|
|
53
|
-
// );
|
|
54
|
-
return info;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 处理 auditResult 是数组的情况,合并多个审计结果
|
|
60
|
-
* @param auditResults AuditResult 数组
|
|
61
|
-
* @returns 合并后的标准化结果
|
|
62
|
-
*/
|
|
63
|
-
export function normalizeAuditResults(auditResults: AuditResult[]) {
|
|
64
|
-
// 初始化结果对象
|
|
65
|
-
const result: Record<AuditSeverity, NormalizedVulnerabilityInfo[]> = {
|
|
66
|
-
critical: [],
|
|
67
|
-
high: [],
|
|
68
|
-
moderate: [],
|
|
69
|
-
low: [],
|
|
70
|
-
info: [],
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// 遍历所有审计结果
|
|
74
|
-
for (const auditResult of auditResults) {
|
|
75
|
-
const normalizedResult = _normalizeVulnerabilities(auditResult);
|
|
76
|
-
|
|
77
|
-
// 合并每个级别的漏洞
|
|
78
|
-
for (const severity in normalizedResult) {
|
|
79
|
-
const vulnerabilities = normalizedResult[severity as AuditSeverity];
|
|
80
|
-
result[severity as AuditSeverity].push(...vulnerabilities);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
vulnerabilities: result,
|
|
86
|
-
} as NormalizedResult;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function normalizeAuditResult(auditResult: AuditResult | AuditResult[]) {
|
|
90
|
-
if (Array.isArray(auditResult)) {
|
|
91
|
-
return {
|
|
92
|
-
vulnerabilities: normalizeAuditResults(auditResult).vulnerabilities,
|
|
93
|
-
} as NormalizedResult;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
vulnerabilities: _normalizeVulnerabilities(auditResult),
|
|
98
|
-
} as NormalizedResult;
|
|
99
|
-
}
|
package/src/audit/remoteAudit.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { NpmAuditResponse } from "../types.js";
|
|
2
|
-
|
|
3
|
-
const URL = "https://registry.npmjs.org/-/npm/v1/security/audits";
|
|
4
|
-
|
|
5
|
-
export async function remoteAudit(packageName: string, packageVersion: string) {
|
|
6
|
-
const body = {
|
|
7
|
-
name: "example-audit", // 项目名字随便写
|
|
8
|
-
version: "1.0.0", // 项目的版本,随便写
|
|
9
|
-
requires: {
|
|
10
|
-
[packageName]: packageVersion,
|
|
11
|
-
},
|
|
12
|
-
dependencies: {
|
|
13
|
-
[packageName]: {
|
|
14
|
-
version: packageVersion,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
const resp = await fetch(URL, {
|
|
19
|
-
method: "POST",
|
|
20
|
-
headers: {
|
|
21
|
-
"Content-Type": "application/json",
|
|
22
|
-
},
|
|
23
|
-
body: JSON.stringify(body),
|
|
24
|
-
});
|
|
25
|
-
return (await resp.json()) as NpmAuditResponse;
|
|
26
|
-
}
|