prscan 1.0.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/.vscode/launch.json +14 -0
- package/README.MD +32 -0
- package/dist/bot/lark.d.ts +2 -0
- package/dist/bot/lark.d.ts.map +1 -0
- package/dist/bot/lark.js +156 -0
- package/dist/bot/lark.js.map +1 -0
- package/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +77 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/report/index.d.ts +7 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +45 -0
- package/dist/report/index.js.map +1 -0
- package/dist/tool/prscan.d.ts +72 -0
- package/dist/tool/prscan.d.ts.map +1 -0
- package/dist/tool/prscan.js +477 -0
- package/dist/tool/prscan.js.map +1 -0
- package/dist/util/analyze.d.ts +4 -0
- package/dist/util/analyze.d.ts.map +1 -0
- package/dist/util/analyze.js +213 -0
- package/dist/util/analyze.js.map +1 -0
- package/dist/util/archive.d.ts +34 -0
- package/dist/util/archive.d.ts.map +1 -0
- package/dist/util/archive.js +110 -0
- package/dist/util/archive.js.map +1 -0
- package/dist/util/memory-archive.d.ts +37 -0
- package/dist/util/memory-archive.d.ts.map +1 -0
- package/dist/util/memory-archive.js +128 -0
- package/dist/util/memory-archive.js.map +1 -0
- package/dist/util/npm.d.ts +46 -0
- package/dist/util/npm.d.ts.map +1 -0
- package/dist/util/npm.js +35 -0
- package/dist/util/npm.js.map +1 -0
- package/dist/util/parse.d.ts +18 -0
- package/dist/util/parse.d.ts.map +1 -0
- package/dist/util/parse.js +92 -0
- package/dist/util/parse.js.map +1 -0
- package/dist/util/proxy.d.ts +45 -0
- package/dist/util/proxy.d.ts.map +1 -0
- package/dist/util/proxy.js +143 -0
- package/dist/util/proxy.js.map +1 -0
- package/dist/util/repo.d.ts +103 -0
- package/dist/util/repo.d.ts.map +1 -0
- package/dist/util/repo.js +170 -0
- package/dist/util/repo.js.map +1 -0
- package/package.json +35 -0
- package/report.png +0 -0
- package/src/bot/lark.ts +184 -0
- package/src/cli/cli.ts +80 -0
- package/src/index.ts +67 -0
- package/src/report/index.ts +50 -0
- package/src/tool/prscan.ts +634 -0
- package/src/util/analyze.ts +248 -0
- package/src/util/memory-archive.ts +184 -0
- package/src/util/npm.ts +100 -0
- package/src/util/parse.ts +103 -0
- package/src/util/repo.ts +224 -0
- package/tsconfig.json +43 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare abstract class LockParser {
|
|
2
|
+
abstract getDependencies(): Record<string, string[]>;
|
|
3
|
+
constructor(content: string);
|
|
4
|
+
static deps2Set(deps: Record<string, string[]>): Set<string>;
|
|
5
|
+
}
|
|
6
|
+
export declare class PnpmLockParser extends LockParser {
|
|
7
|
+
private yaml;
|
|
8
|
+
constructor(content: string);
|
|
9
|
+
getDependencies(): Record<string, string[]>;
|
|
10
|
+
}
|
|
11
|
+
export declare class YarnLockParser extends LockParser {
|
|
12
|
+
private syml;
|
|
13
|
+
constructor(content: string);
|
|
14
|
+
private static getPackageName;
|
|
15
|
+
getDependencies(): Record<string, string[]>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/util/parse.ts"],"names":[],"mappings":"AAGA,uBAAe,UAAU;IACrB,QAAQ,CAAC,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBACxC,OAAO,EAAE,MAAM;WAEb,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;CAUtE;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC1C,OAAO,CAAC,IAAI,CAAM;gBACN,OAAO,EAAE,MAAM;IAKpB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAuCrD;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC1C,OAAO,CAAC,IAAI,CAAM;gBAEN,OAAO,EAAE,MAAM;IAI3B,OAAO,CAAC,MAAM,CAAC,cAAc;IAQtB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAoBrD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { parseSyml } from "@yarnpkg/parsers";
|
|
2
|
+
import * as yaml from "js-yaml";
|
|
3
|
+
class LockParser {
|
|
4
|
+
constructor(content) { }
|
|
5
|
+
static deps2Set(deps) {
|
|
6
|
+
const r = new Set();
|
|
7
|
+
for (const key in deps) {
|
|
8
|
+
const versions = deps[key];
|
|
9
|
+
for (let i = 0; i < versions.length; i++) {
|
|
10
|
+
r.add(`${key}@${versions[i]}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return r;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class PnpmLockParser extends LockParser {
|
|
17
|
+
yaml;
|
|
18
|
+
constructor(content) {
|
|
19
|
+
super(content);
|
|
20
|
+
this.yaml = yaml.load(content);
|
|
21
|
+
}
|
|
22
|
+
getDependencies() {
|
|
23
|
+
const r = Object.create(null);
|
|
24
|
+
if (!this.yaml.packages) {
|
|
25
|
+
return r;
|
|
26
|
+
}
|
|
27
|
+
Object.entries(this.yaml.packages).forEach(([pkgKey, pkgInfo]) => {
|
|
28
|
+
// 解析包键,格式如: "/lodash/4.17.21" 或 "lodash@4.17.21"
|
|
29
|
+
let name, version;
|
|
30
|
+
if (pkgKey.startsWith("/")) {
|
|
31
|
+
// 旧格式: /lodash/4.17.21
|
|
32
|
+
const parts = pkgKey.split("/");
|
|
33
|
+
name = parts[1];
|
|
34
|
+
version = parts[2];
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// 新格式: lodash@4.17.21
|
|
38
|
+
const match = pkgKey.match(/^(.+?)@(.+)$/);
|
|
39
|
+
if (match) {
|
|
40
|
+
name = match[1];
|
|
41
|
+
version = match[2];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (name && version) {
|
|
45
|
+
// 处理 peer dependency 后缀,如 "babel-jest@27.5.1(@babel/core@7.23.6)"
|
|
46
|
+
let cleanVersion = version.split("(")[0];
|
|
47
|
+
if (cleanVersion == null) {
|
|
48
|
+
cleanVersion = version;
|
|
49
|
+
}
|
|
50
|
+
if (!r[name]) {
|
|
51
|
+
r[name] = [];
|
|
52
|
+
}
|
|
53
|
+
if (r[name].indexOf(cleanVersion) === -1) {
|
|
54
|
+
r[name].push(cleanVersion);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return r;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export class YarnLockParser extends LockParser {
|
|
62
|
+
syml;
|
|
63
|
+
constructor(content) {
|
|
64
|
+
super(content);
|
|
65
|
+
this.syml = parseSyml(content);
|
|
66
|
+
}
|
|
67
|
+
static getPackageName(key) {
|
|
68
|
+
key = key.split(",")[0].trim();
|
|
69
|
+
key = key.split(":")[0].trim();
|
|
70
|
+
return key.lastIndexOf("@") > 0
|
|
71
|
+
? key.slice(0, key.lastIndexOf("@"))
|
|
72
|
+
: key;
|
|
73
|
+
}
|
|
74
|
+
getDependencies() {
|
|
75
|
+
const r = Object.create(null);
|
|
76
|
+
for (const key in this.syml) {
|
|
77
|
+
const entry = this.syml[key];
|
|
78
|
+
if (entry === "__metadata") {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const pkgName = YarnLockParser.getPackageName(key);
|
|
82
|
+
if (!r[pkgName]) {
|
|
83
|
+
r[pkgName] = [];
|
|
84
|
+
}
|
|
85
|
+
if (r[pkgName].indexOf(entry.version) === -1) {
|
|
86
|
+
r[pkgName].push(entry.version);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return r;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/util/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface ProxyConfig {
|
|
2
|
+
http?: string;
|
|
3
|
+
https?: string;
|
|
4
|
+
noProxy?: string[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 全局代理配置
|
|
8
|
+
*/
|
|
9
|
+
export declare class GlobalProxy {
|
|
10
|
+
private static httpAgent;
|
|
11
|
+
private static httpsAgent;
|
|
12
|
+
private static originalGlobalAgent;
|
|
13
|
+
/**
|
|
14
|
+
* 设置全局代理
|
|
15
|
+
*/
|
|
16
|
+
static setup(config: ProxyConfig): void;
|
|
17
|
+
/**
|
|
18
|
+
* 为fetch请求设置代理
|
|
19
|
+
*/
|
|
20
|
+
static setupFetch(config: ProxyConfig): void;
|
|
21
|
+
/**
|
|
22
|
+
* 检查URL是否应该使用代理
|
|
23
|
+
*/
|
|
24
|
+
private static shouldUseProxy;
|
|
25
|
+
/**
|
|
26
|
+
* 获取代理配置的Agent
|
|
27
|
+
*/
|
|
28
|
+
static getAgents(): {
|
|
29
|
+
httpAgent: any;
|
|
30
|
+
httpsAgent: any;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* 清除代理设置
|
|
34
|
+
*/
|
|
35
|
+
static clear(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 从环境变量读取代理配置
|
|
39
|
+
*/
|
|
40
|
+
export declare function getProxyFromEnv(): ProxyConfig;
|
|
41
|
+
/**
|
|
42
|
+
* 初始化代理设置
|
|
43
|
+
*/
|
|
44
|
+
export declare function initializeProxy(config?: ProxyConfig): void;
|
|
45
|
+
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/util/proxy.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,WAAW;IACpB,OAAO,CAAC,MAAM,CAAC,SAAS,CAAqC;IAC7D,OAAO,CAAC,MAAM,CAAC,UAAU,CAAsC;IAC/D,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAsC;IAExE;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW;IAmChC;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW;IA6BrC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAkB7B;;OAEG;IACH,MAAM,CAAC,SAAS;;;;IAOhB;;OAEG;IACH,MAAM,CAAC,KAAK;CAkBf;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,WAAW,CAM7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,WAAW,QAUnD"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Agent as HttpAgent } from 'http';
|
|
2
|
+
import { Agent as HttpsAgent } from 'https';
|
|
3
|
+
import { ProxyAgent } from 'proxy-agent';
|
|
4
|
+
/**
|
|
5
|
+
* 全局代理配置
|
|
6
|
+
*/
|
|
7
|
+
export class GlobalProxy {
|
|
8
|
+
static httpAgent;
|
|
9
|
+
static httpsAgent;
|
|
10
|
+
static originalGlobalAgent;
|
|
11
|
+
/**
|
|
12
|
+
* 设置全局代理
|
|
13
|
+
*/
|
|
14
|
+
static setup(config) {
|
|
15
|
+
// 方法1: 设置环境变量
|
|
16
|
+
if (config.http) {
|
|
17
|
+
process.env.HTTP_PROXY = config.http;
|
|
18
|
+
process.env.http_proxy = config.http;
|
|
19
|
+
}
|
|
20
|
+
if (config.https) {
|
|
21
|
+
process.env.HTTPS_PROXY = config.https;
|
|
22
|
+
process.env.https_proxy = config.https;
|
|
23
|
+
}
|
|
24
|
+
if (config.noProxy) {
|
|
25
|
+
process.env.NO_PROXY = config.noProxy.join(',');
|
|
26
|
+
process.env.no_proxy = config.noProxy.join(',');
|
|
27
|
+
}
|
|
28
|
+
// 方法2: 使用 proxy-agent (推荐)
|
|
29
|
+
if (config.http || config.https) {
|
|
30
|
+
const proxyUrl = config.https || config.http;
|
|
31
|
+
try {
|
|
32
|
+
this.httpAgent = new ProxyAgent(proxyUrl);
|
|
33
|
+
this.httpsAgent = new ProxyAgent(proxyUrl);
|
|
34
|
+
// 设置全局默认agent
|
|
35
|
+
globalThis.httpGlobalAgent = this.httpAgent;
|
|
36
|
+
globalThis.httpsGlobalAgent = this.httpsAgent;
|
|
37
|
+
console.log(`✅ Global proxy set to: ${proxyUrl}`);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error('❌ Failed to setup proxy agent:', error);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 为fetch请求设置代理
|
|
47
|
+
*/
|
|
48
|
+
static setupFetch(config) {
|
|
49
|
+
if (!config.http && !config.https)
|
|
50
|
+
return;
|
|
51
|
+
const proxyUrl = config.https || config.http;
|
|
52
|
+
// 保存原始fetch
|
|
53
|
+
this.originalGlobalAgent = globalThis.fetch;
|
|
54
|
+
// 创建代理agent
|
|
55
|
+
const agent = new ProxyAgent(proxyUrl);
|
|
56
|
+
// 重写全局fetch
|
|
57
|
+
globalThis.fetch = async (input, init) => {
|
|
58
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
|
|
59
|
+
// 检查是否需要代理
|
|
60
|
+
if (this.shouldUseProxy(url, config.noProxy)) {
|
|
61
|
+
const modifiedInit = {
|
|
62
|
+
...init,
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
agent: agent
|
|
65
|
+
};
|
|
66
|
+
return this.originalGlobalAgent(input, modifiedInit);
|
|
67
|
+
}
|
|
68
|
+
return this.originalGlobalAgent(input, init);
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 检查URL是否应该使用代理
|
|
73
|
+
*/
|
|
74
|
+
static shouldUseProxy(url, noProxy) {
|
|
75
|
+
if (!noProxy || noProxy.length === 0)
|
|
76
|
+
return true;
|
|
77
|
+
try {
|
|
78
|
+
const urlObj = new URL(url);
|
|
79
|
+
const hostname = urlObj.hostname;
|
|
80
|
+
return !noProxy.some(pattern => {
|
|
81
|
+
if (pattern.startsWith('.')) {
|
|
82
|
+
return hostname.endsWith(pattern);
|
|
83
|
+
}
|
|
84
|
+
return hostname === pattern || hostname.endsWith(`.${pattern}`);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 获取代理配置的Agent
|
|
93
|
+
*/
|
|
94
|
+
static getAgents() {
|
|
95
|
+
return {
|
|
96
|
+
httpAgent: this.httpAgent,
|
|
97
|
+
httpsAgent: this.httpsAgent
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 清除代理设置
|
|
102
|
+
*/
|
|
103
|
+
static clear() {
|
|
104
|
+
delete process.env.HTTP_PROXY;
|
|
105
|
+
delete process.env.http_proxy;
|
|
106
|
+
delete process.env.HTTPS_PROXY;
|
|
107
|
+
delete process.env.https_proxy;
|
|
108
|
+
delete process.env.NO_PROXY;
|
|
109
|
+
delete process.env.no_proxy;
|
|
110
|
+
if (this.originalGlobalAgent) {
|
|
111
|
+
globalThis.fetch = this.originalGlobalAgent;
|
|
112
|
+
}
|
|
113
|
+
this.httpAgent = undefined;
|
|
114
|
+
this.httpsAgent = undefined;
|
|
115
|
+
this.originalGlobalAgent = undefined;
|
|
116
|
+
console.log('🧹 Proxy settings cleared');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 从环境变量读取代理配置
|
|
121
|
+
*/
|
|
122
|
+
export function getProxyFromEnv() {
|
|
123
|
+
return {
|
|
124
|
+
http: process.env.HTTP_PROXY || process.env.http_proxy,
|
|
125
|
+
https: process.env.HTTPS_PROXY || process.env.https_proxy,
|
|
126
|
+
noProxy: (process.env.NO_PROXY || process.env.no_proxy)?.split(',')
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 初始化代理设置
|
|
131
|
+
*/
|
|
132
|
+
export function initializeProxy(config) {
|
|
133
|
+
const proxyConfig = config || getProxyFromEnv();
|
|
134
|
+
if (proxyConfig.http || proxyConfig.https) {
|
|
135
|
+
console.log('🔄 Initializing proxy settings...');
|
|
136
|
+
GlobalProxy.setup(proxyConfig);
|
|
137
|
+
GlobalProxy.setupFetch(proxyConfig);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.log('ℹ️ No proxy configuration found');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/util/proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export declare class GitHubRepo {
|
|
2
|
+
private octokit;
|
|
3
|
+
private maxRetries;
|
|
4
|
+
constructor(authToken?: string, maxRetries?: number);
|
|
5
|
+
getPRInfo(owner: string, repo: string, pull_number: number): Promise<{
|
|
6
|
+
url: string;
|
|
7
|
+
id: number;
|
|
8
|
+
node_id: string;
|
|
9
|
+
html_url: string;
|
|
10
|
+
diff_url: string;
|
|
11
|
+
patch_url: string;
|
|
12
|
+
issue_url: string;
|
|
13
|
+
commits_url: string;
|
|
14
|
+
review_comments_url: string;
|
|
15
|
+
review_comment_url: string;
|
|
16
|
+
comments_url: string;
|
|
17
|
+
statuses_url: string;
|
|
18
|
+
number: number;
|
|
19
|
+
state: "open" | "closed";
|
|
20
|
+
locked: boolean;
|
|
21
|
+
title: string;
|
|
22
|
+
user: import("@octokit/openapi-types").components["schemas"]["simple-user"];
|
|
23
|
+
body: string | null;
|
|
24
|
+
labels: {
|
|
25
|
+
id: number;
|
|
26
|
+
node_id: string;
|
|
27
|
+
url: string;
|
|
28
|
+
name: string;
|
|
29
|
+
description: string | null;
|
|
30
|
+
color: string;
|
|
31
|
+
default: boolean;
|
|
32
|
+
}[];
|
|
33
|
+
milestone: import("@octokit/openapi-types").components["schemas"]["nullable-milestone"];
|
|
34
|
+
active_lock_reason?: string | null;
|
|
35
|
+
created_at: string;
|
|
36
|
+
updated_at: string;
|
|
37
|
+
closed_at: string | null;
|
|
38
|
+
merged_at: string | null;
|
|
39
|
+
merge_commit_sha: string | null;
|
|
40
|
+
assignee: import("@octokit/openapi-types").components["schemas"]["nullable-simple-user"];
|
|
41
|
+
assignees?: import("@octokit/openapi-types").components["schemas"]["simple-user"][] | null;
|
|
42
|
+
requested_reviewers?: import("@octokit/openapi-types").components["schemas"]["simple-user"][] | null;
|
|
43
|
+
requested_teams?: import("@octokit/openapi-types").components["schemas"]["team-simple"][] | null;
|
|
44
|
+
head: {
|
|
45
|
+
label: string;
|
|
46
|
+
ref: string;
|
|
47
|
+
repo: import("@octokit/openapi-types").components["schemas"]["repository"];
|
|
48
|
+
sha: string;
|
|
49
|
+
user: import("@octokit/openapi-types").components["schemas"]["simple-user"];
|
|
50
|
+
};
|
|
51
|
+
base: {
|
|
52
|
+
label: string;
|
|
53
|
+
ref: string;
|
|
54
|
+
repo: import("@octokit/openapi-types").components["schemas"]["repository"];
|
|
55
|
+
sha: string;
|
|
56
|
+
user: import("@octokit/openapi-types").components["schemas"]["simple-user"];
|
|
57
|
+
};
|
|
58
|
+
_links: {
|
|
59
|
+
comments: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
60
|
+
commits: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
61
|
+
statuses: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
62
|
+
html: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
63
|
+
issue: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
64
|
+
review_comments: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
65
|
+
review_comment: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
66
|
+
self: import("@octokit/openapi-types").components["schemas"]["link"];
|
|
67
|
+
};
|
|
68
|
+
author_association: import("@octokit/openapi-types").components["schemas"]["author-association"];
|
|
69
|
+
auto_merge: import("@octokit/openapi-types").components["schemas"]["auto-merge"];
|
|
70
|
+
draft?: boolean;
|
|
71
|
+
merged: boolean;
|
|
72
|
+
mergeable: boolean | null;
|
|
73
|
+
rebaseable?: boolean | null;
|
|
74
|
+
mergeable_state: string;
|
|
75
|
+
merged_by: import("@octokit/openapi-types").components["schemas"]["nullable-simple-user"];
|
|
76
|
+
comments: number;
|
|
77
|
+
review_comments: number;
|
|
78
|
+
maintainer_can_modify: boolean;
|
|
79
|
+
commits: number;
|
|
80
|
+
additions: number;
|
|
81
|
+
deletions: number;
|
|
82
|
+
changed_files: number;
|
|
83
|
+
}>;
|
|
84
|
+
getPRChangedFiles(owner: string, repo: string, pull_number: number, per_page?: number): Promise<{
|
|
85
|
+
sha: string | null;
|
|
86
|
+
filename: string;
|
|
87
|
+
status: "added" | "removed" | "modified" | "renamed" | "copied" | "changed" | "unchanged";
|
|
88
|
+
additions: number;
|
|
89
|
+
deletions: number;
|
|
90
|
+
changes: number;
|
|
91
|
+
blob_url: string;
|
|
92
|
+
raw_url: string;
|
|
93
|
+
contents_url: string;
|
|
94
|
+
patch?: string;
|
|
95
|
+
previous_filename?: string;
|
|
96
|
+
}[]>;
|
|
97
|
+
getTextFileContent(owner: string, repo: string, path: string, ref: string): Promise<string | null>;
|
|
98
|
+
/**
|
|
99
|
+
* 在Git树中递归查找文件
|
|
100
|
+
*/
|
|
101
|
+
private findFileInTree;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/util/repo.ts"],"names":[],"mappings":"AAGA,qBAAa,UAAU;IACnB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAS;gBAEf,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,SAAI;IAKjC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;cAoNytrqC,sDAAsB;;;;;;;;;;;mBAAyV,sDAAsB;;;;;;;kBAAoqB,sDAAsB;oBAA2C,sDAAsB;8BAAqD,sDAAsB;0BAAiD,sDAAsB;;;;kBAAiG,sDAAsB;;kBAAkD,sDAAsB;;;;;kBAAiG,sDAAsB;;kBAAkD,sDAAsB;;;sBAA2D,sDAAsB;qBAA0B,sDAAsB;sBAA2B,sDAAsB;kBAAuB,sDAAsB;mBAAwB,sDAAsB;6BAAkC,sDAAsB;4BAAiC,sDAAsB;kBAAuB,sDAAsB;;4BAA4C,sDAAsB;oBAAyC,sDAAsB;;;;;;mBAA2X,sDAAsB;;;;;;;;;IAlM91wqC,iBAAiB,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAK;;;;;;;;;;;;;IAoCJ,kBAAkB,CAC3B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAoGzB;;OAEG;YACW,cAAc;CA6C/B"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Octokit } from "octokit";
|
|
2
|
+
import got from "got";
|
|
3
|
+
export class GitHubRepo {
|
|
4
|
+
octokit;
|
|
5
|
+
maxRetries;
|
|
6
|
+
constructor(authToken, maxRetries = 3) {
|
|
7
|
+
this.maxRetries = maxRetries;
|
|
8
|
+
this.octokit = new Octokit(authToken ? { auth: authToken } : {});
|
|
9
|
+
}
|
|
10
|
+
async getPRInfo(owner, repo, pull_number) {
|
|
11
|
+
for (let i = 0; i < this.maxRetries; i++) {
|
|
12
|
+
try {
|
|
13
|
+
console.info(`Fetching PR info ${owner}/${repo}#${pull_number}`);
|
|
14
|
+
const { data } = await this.octokit.rest.pulls.get({
|
|
15
|
+
owner,
|
|
16
|
+
repo,
|
|
17
|
+
pull_number,
|
|
18
|
+
});
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
catch (error) { }
|
|
22
|
+
}
|
|
23
|
+
throw new Error("读取PR信息失败");
|
|
24
|
+
}
|
|
25
|
+
async getPRChangedFiles(owner, repo, pull_number, per_page = 30) {
|
|
26
|
+
const files = [];
|
|
27
|
+
let page = 1;
|
|
28
|
+
while (true) {
|
|
29
|
+
let data;
|
|
30
|
+
for (let i = 0; i < this.maxRetries; i++) {
|
|
31
|
+
try {
|
|
32
|
+
console.info(`Fetching PR files ${owner}/${repo}#${pull_number} page ${page}`);
|
|
33
|
+
data = await this.octokit.rest.pulls.listFiles({
|
|
34
|
+
owner,
|
|
35
|
+
repo,
|
|
36
|
+
pull_number,
|
|
37
|
+
per_page,
|
|
38
|
+
page,
|
|
39
|
+
});
|
|
40
|
+
break; // 成功获取数据,跳出重试循环
|
|
41
|
+
}
|
|
42
|
+
catch (error) { }
|
|
43
|
+
}
|
|
44
|
+
if (data) {
|
|
45
|
+
files.push(...data.data);
|
|
46
|
+
page++;
|
|
47
|
+
if (data.data.length < per_page) {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
throw new Error("读取PR变更文件失败");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return files;
|
|
56
|
+
}
|
|
57
|
+
async getTextFileContent(owner, repo, path, ref) {
|
|
58
|
+
// 使用多种方式获取文件内容,解决原API经常超时的问题
|
|
59
|
+
try {
|
|
60
|
+
console.info(`Fetching ${owner}/${repo}/${path}@${ref} via Git Data API`);
|
|
61
|
+
// 先获取commit的tree
|
|
62
|
+
const { data: commit } = await this.octokit.rest.git.getCommit({
|
|
63
|
+
owner,
|
|
64
|
+
repo,
|
|
65
|
+
commit_sha: ref,
|
|
66
|
+
});
|
|
67
|
+
// 递归查找文件
|
|
68
|
+
const blob = await this.findFileInTree(owner, repo, commit.tree.sha, path);
|
|
69
|
+
if (blob) {
|
|
70
|
+
const { data: blobData } = await this.octokit.rest.git.getBlob({
|
|
71
|
+
owner,
|
|
72
|
+
repo,
|
|
73
|
+
file_sha: blob.sha,
|
|
74
|
+
});
|
|
75
|
+
if (blobData.encoding === "base64") {
|
|
76
|
+
return Buffer.from(blobData.content, "base64").toString("utf-8");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.warn(`Git Data API failed for ${path}:`, error);
|
|
82
|
+
}
|
|
83
|
+
for (let i = 0; i < this.maxRetries; i++) {
|
|
84
|
+
try {
|
|
85
|
+
console.info(`Fetching ${owner}/${repo}/${path}@${ref} via Contents API (attempt ${i + 1})`);
|
|
86
|
+
const { data } = await this.octokit.rest.repos.getContent({
|
|
87
|
+
owner,
|
|
88
|
+
repo,
|
|
89
|
+
path,
|
|
90
|
+
ref,
|
|
91
|
+
});
|
|
92
|
+
if ("content" in data && data.content) {
|
|
93
|
+
// 使用 Buffer 解码 base64 内容 (替代 atob,更可靠)
|
|
94
|
+
return Buffer.from(data.content, "base64").toString("utf-8");
|
|
95
|
+
}
|
|
96
|
+
else if ("download_url" in data && data.download_url) {
|
|
97
|
+
// 文件过大时:使用 download_url 获取原始内容
|
|
98
|
+
const response = await got(data.download_url);
|
|
99
|
+
if (response.statusCode === 200) {
|
|
100
|
+
return response.body;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
console.warn(`Contents API attempt ${i + 1} failed for ${path}:`, error);
|
|
106
|
+
if (i === this.maxRetries - 1) {
|
|
107
|
+
// 最后一次重试失败,尝试其他方法
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
// 等待一段时间再重试
|
|
111
|
+
await new Promise((resolve) => setTimeout(resolve, 200 * (i + 1)));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
console.info(`Fetching ${owner}/${repo}/${path}@${ref} via raw URL`);
|
|
116
|
+
const rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${path}`;
|
|
117
|
+
const response = await got(rawUrl);
|
|
118
|
+
if (response.statusCode === 200) {
|
|
119
|
+
return response.body;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.warn(`Raw URL failed for ${path}:`, error);
|
|
124
|
+
}
|
|
125
|
+
console.error(`All methods failed to fetch ${owner}/${repo}/${path}@${ref}`);
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 在Git树中递归查找文件
|
|
130
|
+
*/
|
|
131
|
+
async findFileInTree(owner, repo, treeSha, filePath) {
|
|
132
|
+
const pathParts = filePath.split("/");
|
|
133
|
+
let currentTreeSha = treeSha;
|
|
134
|
+
let currentPath = "";
|
|
135
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
136
|
+
const part = pathParts[i];
|
|
137
|
+
currentPath = currentPath ? `${currentPath}/${part}` : part;
|
|
138
|
+
try {
|
|
139
|
+
const { data: tree } = await this.octokit.rest.git.getTree({
|
|
140
|
+
owner,
|
|
141
|
+
repo,
|
|
142
|
+
tree_sha: currentTreeSha,
|
|
143
|
+
});
|
|
144
|
+
const item = tree.tree.find((item) => item.path === part);
|
|
145
|
+
if (!item) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
if (i === pathParts.length - 1) {
|
|
149
|
+
// 这是最后一个部分,应该是文件
|
|
150
|
+
return item.type === "blob" ? { sha: item.sha } : null;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// 这是一个目录,继续递归
|
|
154
|
+
if (item.type === "tree") {
|
|
155
|
+
currentTreeSha = item.sha;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.warn(`Failed to get tree ${currentTreeSha}:`, error);
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/util/repo.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prscan",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"author": "ru1n <113791864+ddddhm1234@users.noreply.github.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"bin": {
|
|
8
|
+
"prscan": "./dist/cli/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@babel/parser": "^7.28.4",
|
|
12
|
+
"@babel/traverse": "^7.28.4",
|
|
13
|
+
"@larksuiteoapi/node-sdk": "^1.55.0",
|
|
14
|
+
"@types/babel__traverse": "^7.28.0",
|
|
15
|
+
"@types/gunzip-maybe": "^1.4.2",
|
|
16
|
+
"@yarnpkg/parsers": "^3.0.3",
|
|
17
|
+
"commander": "^14.0.2",
|
|
18
|
+
"got": "^14.5.0",
|
|
19
|
+
"gunzip-maybe": "^1.4.2",
|
|
20
|
+
"js-yaml": "^4.1.1",
|
|
21
|
+
"octokit": "^5.0.3",
|
|
22
|
+
"semver": "^7.7.3",
|
|
23
|
+
"tar-stream": "^3.1.7",
|
|
24
|
+
"zustand": "^5.0.9"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@babel/types": "^7.28.4",
|
|
29
|
+
"@types/js-yaml": "^4.0.9",
|
|
30
|
+
"@types/node": "^24.7.2",
|
|
31
|
+
"@types/semver": "^7.7.1",
|
|
32
|
+
"@types/tar-stream": "^3.1.4",
|
|
33
|
+
"@types/yarnpkg__lockfile": "^1.1.9"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/report.png
ADDED
|
Binary file
|