frontend-guardian-core 2.6.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/LICENSE +21 -0
- package/bin/fg-core.js +1238 -0
- package/bin/watch-mode.js +123 -0
- package/dist/engine/cache.d.ts +68 -0
- package/dist/engine/cache.d.ts.map +1 -0
- package/dist/engine/cache.js +164 -0
- package/dist/engine/cache.js.map +1 -0
- package/dist/engine/rule-engine.d.ts +135 -0
- package/dist/engine/rule-engine.d.ts.map +1 -0
- package/dist/engine/rule-engine.js +716 -0
- package/dist/engine/rule-engine.js.map +1 -0
- package/dist/formatters/github-annotation.d.ts +36 -0
- package/dist/formatters/github-annotation.d.ts.map +1 -0
- package/dist/formatters/github-annotation.js +122 -0
- package/dist/formatters/github-annotation.js.map +1 -0
- package/dist/formatters/pr-comment.d.ts +43 -0
- package/dist/formatters/pr-comment.d.ts.map +1 -0
- package/dist/formatters/pr-comment.js +171 -0
- package/dist/formatters/pr-comment.js.map +1 -0
- package/dist/formatters/sarif.d.ts +104 -0
- package/dist/formatters/sarif.d.ts.map +1 -0
- package/dist/formatters/sarif.js +130 -0
- package/dist/formatters/sarif.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/base.d.ts +44 -0
- package/dist/integrations/base.d.ts.map +1 -0
- package/dist/integrations/base.js +104 -0
- package/dist/integrations/base.js.map +1 -0
- package/dist/integrations/eslint.d.ts +8 -0
- package/dist/integrations/eslint.d.ts.map +1 -0
- package/dist/integrations/eslint.js +67 -0
- package/dist/integrations/eslint.js.map +1 -0
- package/dist/integrations/formatter.d.ts +35 -0
- package/dist/integrations/formatter.d.ts.map +1 -0
- package/dist/integrations/formatter.js +182 -0
- package/dist/integrations/formatter.js.map +1 -0
- package/dist/integrations/index.d.ts +17 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +25 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/stylelint.d.ts +8 -0
- package/dist/integrations/stylelint.d.ts.map +1 -0
- package/dist/integrations/stylelint.js +59 -0
- package/dist/integrations/stylelint.js.map +1 -0
- package/dist/integrations/typescript.d.ts +8 -0
- package/dist/integrations/typescript.d.ts.map +1 -0
- package/dist/integrations/typescript.js +92 -0
- package/dist/integrations/typescript.js.map +1 -0
- package/dist/rules/registry.d.ts +83 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +205 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/scanners/a11y-scanner.d.ts +14 -0
- package/dist/scanners/a11y-scanner.d.ts.map +1 -0
- package/dist/scanners/a11y-scanner.js +781 -0
- package/dist/scanners/a11y-scanner.js.map +1 -0
- package/dist/scanners/component-scanner.d.ts +12 -0
- package/dist/scanners/component-scanner.d.ts.map +1 -0
- package/dist/scanners/component-scanner.js +304 -0
- package/dist/scanners/component-scanner.js.map +1 -0
- package/dist/scanners/cross-file-scanner.d.ts +18 -0
- package/dist/scanners/cross-file-scanner.d.ts.map +1 -0
- package/dist/scanners/cross-file-scanner.js +684 -0
- package/dist/scanners/cross-file-scanner.js.map +1 -0
- package/dist/scanners/hooks-scanner.d.ts +15 -0
- package/dist/scanners/hooks-scanner.d.ts.map +1 -0
- package/dist/scanners/hooks-scanner.js +670 -0
- package/dist/scanners/hooks-scanner.js.map +1 -0
- package/dist/scanners/i18n-scanner.d.ts +13 -0
- package/dist/scanners/i18n-scanner.d.ts.map +1 -0
- package/dist/scanners/i18n-scanner.js +535 -0
- package/dist/scanners/i18n-scanner.js.map +1 -0
- package/dist/scanners/naming-scanner.d.ts +19 -0
- package/dist/scanners/naming-scanner.d.ts.map +1 -0
- package/dist/scanners/naming-scanner.js +746 -0
- package/dist/scanners/naming-scanner.js.map +1 -0
- package/dist/scanners/performance-scanner.d.ts +7 -0
- package/dist/scanners/performance-scanner.d.ts.map +1 -0
- package/dist/scanners/performance-scanner.js +402 -0
- package/dist/scanners/performance-scanner.js.map +1 -0
- package/dist/scanners/platform-scanner.d.ts +15 -0
- package/dist/scanners/platform-scanner.d.ts.map +1 -0
- package/dist/scanners/platform-scanner.js +320 -0
- package/dist/scanners/platform-scanner.js.map +1 -0
- package/dist/scanners/security-scanner.d.ts +7 -0
- package/dist/scanners/security-scanner.d.ts.map +1 -0
- package/dist/scanners/security-scanner.js +349 -0
- package/dist/scanners/security-scanner.js.map +1 -0
- package/dist/scanners/svelte-scanner.d.ts +14 -0
- package/dist/scanners/svelte-scanner.d.ts.map +1 -0
- package/dist/scanners/svelte-scanner.js +228 -0
- package/dist/scanners/svelte-scanner.js.map +1 -0
- package/dist/types.d.ts +343 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/ast-parser.d.ts +21 -0
- package/dist/utils/ast-parser.d.ts.map +1 -0
- package/dist/utils/ast-parser.js +119 -0
- package/dist/utils/ast-parser.js.map +1 -0
- package/dist/utils/baseline.d.ts +89 -0
- package/dist/utils/baseline.d.ts.map +1 -0
- package/dist/utils/baseline.js +156 -0
- package/dist/utils/baseline.js.map +1 -0
- package/dist/utils/ci-generator.d.ts +34 -0
- package/dist/utils/ci-generator.d.ts.map +1 -0
- package/dist/utils/ci-generator.js +194 -0
- package/dist/utils/ci-generator.js.map +1 -0
- package/dist/utils/common.d.ts +8 -0
- package/dist/utils/common.d.ts.map +1 -0
- package/dist/utils/common.js +38 -0
- package/dist/utils/common.js.map +1 -0
- package/dist/utils/concurrent.d.ts +16 -0
- package/dist/utils/concurrent.d.ts.map +1 -0
- package/dist/utils/concurrent.js +49 -0
- package/dist/utils/concurrent.js.map +1 -0
- package/dist/utils/config-loader.d.ts +8 -0
- package/dist/utils/config-loader.d.ts.map +1 -0
- package/dist/utils/config-loader.js +154 -0
- package/dist/utils/config-loader.js.map +1 -0
- package/dist/utils/fix-bot.d.ts +36 -0
- package/dist/utils/fix-bot.d.ts.map +1 -0
- package/dist/utils/fix-bot.js +274 -0
- package/dist/utils/fix-bot.js.map +1 -0
- package/dist/utils/git-hooks.d.ts +55 -0
- package/dist/utils/git-hooks.d.ts.map +1 -0
- package/dist/utils/git-hooks.js +318 -0
- package/dist/utils/git-hooks.js.map +1 -0
- package/dist/utils/history-report.d.ts +72 -0
- package/dist/utils/history-report.d.ts.map +1 -0
- package/dist/utils/history-report.js +144 -0
- package/dist/utils/history-report.js.map +1 -0
- package/dist/utils/init-config.d.ts +23 -0
- package/dist/utils/init-config.d.ts.map +1 -0
- package/dist/utils/init-config.js +146 -0
- package/dist/utils/init-config.js.map +1 -0
- package/dist/utils/pr-publisher.d.ts +64 -0
- package/dist/utils/pr-publisher.d.ts.map +1 -0
- package/dist/utils/pr-publisher.js +265 -0
- package/dist/utils/pr-publisher.js.map +1 -0
- package/dist/utils/project-detector.d.ts +20 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +342 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/dist/utils/report-uploader.d.ts +35 -0
- package/dist/utils/report-uploader.d.ts.map +1 -0
- package/dist/utils/report-uploader.js +106 -0
- package/dist/utils/report-uploader.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 配置文件初始化工具
|
|
4
|
+
* 一键生成 .frontend-guardian.yml 智能默认配置
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.generateDefaultConfig = generateDefaultConfig;
|
|
8
|
+
exports.initConfig = initConfig;
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
10
|
+
const node_path_1 = require("node:path");
|
|
11
|
+
/**
|
|
12
|
+
* 生成默认配置 YAML 内容
|
|
13
|
+
* 基于项目检测结果提供智能默认值
|
|
14
|
+
*/
|
|
15
|
+
function generateDefaultConfig(meta) {
|
|
16
|
+
const framework = meta?.framework;
|
|
17
|
+
const componentLib = meta?.componentLib;
|
|
18
|
+
const platforms = meta?.platforms ?? [];
|
|
19
|
+
const hasTs = meta?.hasTypeScript ?? true;
|
|
20
|
+
const hasI18n = meta?.hasI18n ?? false;
|
|
21
|
+
const i18nLib = meta?.i18nLib;
|
|
22
|
+
const lines = [
|
|
23
|
+
"# frontend-guardian 配置文件",
|
|
24
|
+
"# 文档: https://github.com/wzm111/frontend-guardian#configuration",
|
|
25
|
+
"",
|
|
26
|
+
"# ============================================================================",
|
|
27
|
+
"# 基础配置",
|
|
28
|
+
"# ============================================================================",
|
|
29
|
+
"",
|
|
30
|
+
"# 报告语言: zh | en",
|
|
31
|
+
"locale: zh",
|
|
32
|
+
"",
|
|
33
|
+
"# 最低输出严重级别: critical | warning | suggestion",
|
|
34
|
+
"severity: warning",
|
|
35
|
+
"",
|
|
36
|
+
];
|
|
37
|
+
// i18n 配置
|
|
38
|
+
if (hasI18n) {
|
|
39
|
+
lines.push("", "# ============================================================================", "# i18n 治理配置", "# ============================================================================", "i18n:", ` sourceLocale: ${getDefaultLocale(i18nLib)}`, " targetLocales:", " - en-US", " format: json", " keyPattern: '^[a-z][a-zA-Z0-9]*(\\.[a-z][a-zA-Z0-9]*)*$'", " extractPaths:", " - src/**", " ignorePaths:", ' - "**/*.test.*"', ' - "**/*.spec.*"', ' - "**/*.d.ts"', ' interpolationPattern: "\\{([^}]+)\\}"', " translateProvider: openai");
|
|
40
|
+
}
|
|
41
|
+
// 组件配置
|
|
42
|
+
if (framework && framework !== "flutter" && framework !== "react-native" && framework !== "harmony") {
|
|
43
|
+
lines.push("", "# ============================================================================", "# 组件医生配置", "# ============================================================================", "component:", ` library: ${componentLib ?? "auto"}`, " themeTokenPrefix: \"--\"", " maxSelectOptions: 100", " checkA11y: true", " checkPerf: true");
|
|
44
|
+
}
|
|
45
|
+
// Hooks 配置(React/Vue/Svelte 框架)
|
|
46
|
+
if (framework && ["react", "vue", "svelte", "solidjs", "nextjs", "nuxt", "uniapp", "taro"].includes(framework)) {
|
|
47
|
+
lines.push("", "# ============================================================================", "# Hooks / Composables 配置", "# ============================================================================", "hooks:", " maxEffectDeps: 5", " checkClosure: true", " checkCustomHookNaming: true", " checkVueComposables: " + (framework === "vue" || framework === "nuxt" ? "true" : "false"));
|
|
48
|
+
}
|
|
49
|
+
// 平台配置
|
|
50
|
+
if (platforms.length > 0) {
|
|
51
|
+
const mpPlatforms = platforms.filter((p) => ["wechat-mp", "alipay-mp", "douyin-mp"].includes(p));
|
|
52
|
+
const hasMobile = platforms.includes("h5") || platforms.includes("app");
|
|
53
|
+
const hasHarmony = platforms.includes("harmony");
|
|
54
|
+
if (mpPlatforms.length > 0 || hasMobile || hasHarmony) {
|
|
55
|
+
lines.push("", "# ============================================================================", "# 多端平台适配配置", "# ============================================================================", "platform:");
|
|
56
|
+
if (platforms.length > 0) {
|
|
57
|
+
lines.push(" targets:");
|
|
58
|
+
for (const p of platforms) {
|
|
59
|
+
lines.push(` - ${p}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (mpPlatforms.length > 0) {
|
|
63
|
+
lines.push(" mp:", ` type: ${getMpType(mpPlatforms[0])}`, " maxMainPackageSize: 2097152 # 2MB", " maxSubPackageSize: 2097152 # 2MB", " maxBase64ImageSize: 10240 # 10KB", " maxPageStack: 10");
|
|
64
|
+
}
|
|
65
|
+
if (hasMobile) {
|
|
66
|
+
lines.push(" mobile:", " minTouchTarget: 44", " checkSafeArea: true", " checkClickDelay: true", " checkKeyboard: true");
|
|
67
|
+
}
|
|
68
|
+
if (hasHarmony) {
|
|
69
|
+
lines.push(" harmony:", ' strictTypeCheck: true', ' arktsVersion: "1.1"');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// CI 门禁配置
|
|
74
|
+
lines.push("", "# ============================================================================", "# CI/CD 门禁配置", "# ============================================================================", "gate:", " enabled: true", " critical:", " max: 0", " warning:", " max: 10", " suggestion:", " max: 20", " blockPipeline: true");
|
|
75
|
+
// 扫描范围配置
|
|
76
|
+
const extensions = getDefaultExtensions(framework, hasTs);
|
|
77
|
+
lines.push("", "# ============================================================================", "# 扫描范围配置", "# ============================================================================", "scan:", " includeExtensions:");
|
|
78
|
+
for (const ext of extensions) {
|
|
79
|
+
lines.push(` - ${ext}`);
|
|
80
|
+
}
|
|
81
|
+
lines.push(" excludeDirs:", " - node_modules", " - dist", " - build", " - .git", " - coverage", " - .claude", " excludePatterns:", ' - "*.min.js"', ' - "*.test.*"', ' - "*.spec.*"', ' - "*.config.*"');
|
|
82
|
+
// 规则配置
|
|
83
|
+
lines.push("", "# ============================================================================", "# 规则配置(可选)", "# 可覆盖规则默认参数、调整严重级别、禁用特定规则", "# ============================================================================", "rules:", " # 示例:禁用某规则", " # - id: hooks-state-lifting", " # enabled: false", "", " # 示例:调整严重级别", " # - id: component-token", " # severity: warning", "", " # 示例:参数化规则", " # - id: hooks-effect-deps", " # severity: warning", " # params:", " # maxDeps: 7");
|
|
84
|
+
// 自定义规则
|
|
85
|
+
lines.push("", "# ============================================================================", "# 自定义规则(可选)", "# ============================================================================", "customRules:", " # - path: ./rules/my-company-rule.js");
|
|
86
|
+
return lines.join("\n");
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 初始化配置文件
|
|
90
|
+
* @param projectDir 项目根目录
|
|
91
|
+
* @param meta 项目元数据(可选,用于智能默认值)
|
|
92
|
+
* @param force 是否覆盖已存在的配置文件
|
|
93
|
+
* @returns 操作结果
|
|
94
|
+
*/
|
|
95
|
+
function initConfig(projectDir, meta, force = false) {
|
|
96
|
+
const configPath = (0, node_path_1.resolve)(projectDir, ".frontend-guardian.yml");
|
|
97
|
+
const existed = (0, node_fs_1.existsSync)(configPath);
|
|
98
|
+
if (existed && !force) {
|
|
99
|
+
return { created: false, path: configPath, existed: true };
|
|
100
|
+
}
|
|
101
|
+
const content = generateDefaultConfig(meta);
|
|
102
|
+
(0, node_fs_1.writeFileSync)(configPath, content, "utf-8");
|
|
103
|
+
return { created: true, path: configPath, existed };
|
|
104
|
+
}
|
|
105
|
+
// ── 辅助函数 ───────────────────────────────────────────────────────────────
|
|
106
|
+
function getDefaultLocale(i18nLib) {
|
|
107
|
+
if (i18nLib?.includes("zh") || i18nLib?.includes("cn"))
|
|
108
|
+
return "zh-CN";
|
|
109
|
+
return "zh-CN";
|
|
110
|
+
}
|
|
111
|
+
function getMpType(platform) {
|
|
112
|
+
switch (platform) {
|
|
113
|
+
case "wechat-mp":
|
|
114
|
+
return "wechat";
|
|
115
|
+
case "alipay-mp":
|
|
116
|
+
return "alipay";
|
|
117
|
+
case "douyin-mp":
|
|
118
|
+
return "douyin";
|
|
119
|
+
default:
|
|
120
|
+
return "wechat";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function getDefaultExtensions(framework, hasTs = true) {
|
|
124
|
+
const extensions = [];
|
|
125
|
+
if (hasTs) {
|
|
126
|
+
extensions.push(".ts", ".tsx");
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
extensions.push(".js", ".jsx");
|
|
130
|
+
}
|
|
131
|
+
if (framework === "vue" || framework === "nuxt" || framework === "uniapp") {
|
|
132
|
+
extensions.push(".vue");
|
|
133
|
+
}
|
|
134
|
+
if (framework === "svelte") {
|
|
135
|
+
extensions.push(".svelte");
|
|
136
|
+
}
|
|
137
|
+
if (framework === "solidjs" || framework === "astro") {
|
|
138
|
+
extensions.push(".tsx");
|
|
139
|
+
}
|
|
140
|
+
extensions.push(".css", ".scss", ".less", ".json");
|
|
141
|
+
if (framework === "harmony") {
|
|
142
|
+
extensions.push(".ets");
|
|
143
|
+
}
|
|
144
|
+
return [...new Set(extensions)];
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=init-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-config.js","sourceRoot":"","sources":["../../src/utils/init-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR/MR 评论发布器
|
|
3
|
+
*
|
|
4
|
+
* 支持 GitHub PR 和 GitLab MR 的评论发布/更新。
|
|
5
|
+
* 通过评论中的隐藏标记识别已有评论,实现同一 PR 多次扫描不重复发评论。
|
|
6
|
+
*/
|
|
7
|
+
/** 发布结果 */
|
|
8
|
+
export interface PublishResult {
|
|
9
|
+
/** 是否成功 */
|
|
10
|
+
success: boolean;
|
|
11
|
+
/** 发布的评论 URL */
|
|
12
|
+
commentUrl?: string;
|
|
13
|
+
/** 操作类型: created | updated */
|
|
14
|
+
action: "created" | "updated" | "none";
|
|
15
|
+
/** 错误信息 */
|
|
16
|
+
error?: string;
|
|
17
|
+
}
|
|
18
|
+
/** 发布器配置 */
|
|
19
|
+
export interface PublisherConfig {
|
|
20
|
+
/** 平台类型 */
|
|
21
|
+
provider: "github" | "gitlab";
|
|
22
|
+
/** API Token */
|
|
23
|
+
token: string;
|
|
24
|
+
/** 仓库所有者/名称 (GitHub: owner/repo, GitLab: project path or ID) */
|
|
25
|
+
repository: string;
|
|
26
|
+
/** PR/MR 编号 */
|
|
27
|
+
prNumber: number;
|
|
28
|
+
/** API 基础 URL(用于自托管) */
|
|
29
|
+
apiBaseUrl?: string;
|
|
30
|
+
}
|
|
31
|
+
/** PR/MR 评论发布器接口 */
|
|
32
|
+
export interface PRPublisher {
|
|
33
|
+
publish(body: string): Promise<PublishResult>;
|
|
34
|
+
}
|
|
35
|
+
export declare class GitHubPRPublisher implements PRPublisher {
|
|
36
|
+
private token;
|
|
37
|
+
private owner;
|
|
38
|
+
private repo;
|
|
39
|
+
private prNumber;
|
|
40
|
+
private apiBaseUrl;
|
|
41
|
+
constructor(config: PublisherConfig);
|
|
42
|
+
publish(body: string): Promise<PublishResult>;
|
|
43
|
+
/** 查找已有的 frontend-guardian 评论 ID */
|
|
44
|
+
private findExistingComment;
|
|
45
|
+
private headers;
|
|
46
|
+
}
|
|
47
|
+
export declare class GitLabMRPublisher implements PRPublisher {
|
|
48
|
+
private token;
|
|
49
|
+
private projectId;
|
|
50
|
+
private mrIid;
|
|
51
|
+
private apiBaseUrl;
|
|
52
|
+
constructor(config: PublisherConfig);
|
|
53
|
+
publish(body: string): Promise<PublishResult>;
|
|
54
|
+
/** 查找已有的 frontend-guardian MR 讨论 ID */
|
|
55
|
+
private findExistingNote;
|
|
56
|
+
private headers;
|
|
57
|
+
}
|
|
58
|
+
/** 从环境变量自动推断发布器配置 */
|
|
59
|
+
export declare function detectPublisherConfig(): PublisherConfig | null;
|
|
60
|
+
/** 创建发布器实例 */
|
|
61
|
+
export declare function createPublisher(config: PublisherConfig): PRPublisher;
|
|
62
|
+
/** 便捷函数:自动检测环境并发布评论 */
|
|
63
|
+
export declare function autoPublishComment(body: string): Promise<PublishResult>;
|
|
64
|
+
//# sourceMappingURL=pr-publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-publisher.d.ts","sourceRoot":"","sources":["../../src/utils/pr-publisher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,WAAW;AACX,MAAM,WAAW,aAAa;IAC1B,WAAW;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,WAAW;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,YAAY;AACZ,MAAM,WAAW,eAAe;IAC5B,WAAW;IACX,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC9B,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,oBAAoB;AACpB,MAAM,WAAW,WAAW;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACjD;AAMD,qBAAa,iBAAkB,YAAW,WAAW;IACjD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,eAAe;IAY7B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA2CnD,oCAAoC;YACtB,mBAAmB;IAiBjC,OAAO,CAAC,OAAO;CAQlB;AAMD,qBAAa,iBAAkB,YAAW,WAAW;IACjD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,eAAe;IAO7B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA2CnD,uCAAuC;YACzB,gBAAgB;IAuB9B,OAAO,CAAC,OAAO;CAMlB;AAMD,qBAAqB;AACrB,wBAAgB,qBAAqB,IAAI,eAAe,GAAG,IAAI,CAsC9D;AAgCD,cAAc;AACd,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAQpE;AAED,uBAAuB;AACvB,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAc7E"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PR/MR 评论发布器
|
|
4
|
+
*
|
|
5
|
+
* 支持 GitHub PR 和 GitLab MR 的评论发布/更新。
|
|
6
|
+
* 通过评论中的隐藏标记识别已有评论,实现同一 PR 多次扫描不重复发评论。
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.GitLabMRPublisher = exports.GitHubPRPublisher = void 0;
|
|
10
|
+
exports.detectPublisherConfig = detectPublisherConfig;
|
|
11
|
+
exports.createPublisher = createPublisher;
|
|
12
|
+
exports.autoPublishComment = autoPublishComment;
|
|
13
|
+
const pr_comment_js_1 = require("../formatters/pr-comment.js");
|
|
14
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
15
|
+
// GitHub PR 评论发布器
|
|
16
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
17
|
+
class GitHubPRPublisher {
|
|
18
|
+
token;
|
|
19
|
+
owner;
|
|
20
|
+
repo;
|
|
21
|
+
prNumber;
|
|
22
|
+
apiBaseUrl;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
const [owner, repo] = config.repository.split("/");
|
|
25
|
+
if (!owner || !repo) {
|
|
26
|
+
throw new Error(`Invalid GitHub repository format: ${config.repository} (expected: owner/repo)`);
|
|
27
|
+
}
|
|
28
|
+
this.token = config.token;
|
|
29
|
+
this.owner = owner;
|
|
30
|
+
this.repo = repo;
|
|
31
|
+
this.prNumber = config.prNumber;
|
|
32
|
+
this.apiBaseUrl = config.apiBaseUrl || "https://api.github.com";
|
|
33
|
+
}
|
|
34
|
+
async publish(body) {
|
|
35
|
+
try {
|
|
36
|
+
// 1. 查找已有的 guardian 评论
|
|
37
|
+
const existingCommentId = await this.findExistingComment();
|
|
38
|
+
if (existingCommentId) {
|
|
39
|
+
// 更新已有评论
|
|
40
|
+
const url = `${this.apiBaseUrl}/repos/${this.owner}/${this.repo}/issues/comments/${existingCommentId}`;
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
method: "PATCH",
|
|
43
|
+
headers: this.headers(),
|
|
44
|
+
body: JSON.stringify({ body }),
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
const errText = await response.text().catch(() => "Unknown error");
|
|
48
|
+
return { success: false, action: "none", error: `GitHub API error (${response.status}): ${errText}` };
|
|
49
|
+
}
|
|
50
|
+
const data = await response.json();
|
|
51
|
+
return { success: true, action: "updated", commentUrl: data.html_url };
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// 创建新评论
|
|
55
|
+
const url = `${this.apiBaseUrl}/repos/${this.owner}/${this.repo}/issues/${this.prNumber}/comments`;
|
|
56
|
+
const response = await fetch(url, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: this.headers(),
|
|
59
|
+
body: JSON.stringify({ body }),
|
|
60
|
+
});
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
const errText = await response.text().catch(() => "Unknown error");
|
|
63
|
+
return { success: false, action: "none", error: `GitHub API error (${response.status}): ${errText}` };
|
|
64
|
+
}
|
|
65
|
+
const data = await response.json();
|
|
66
|
+
return { success: true, action: "created", commentUrl: data.html_url };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
return { success: false, action: "none", error: String(err) };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** 查找已有的 frontend-guardian 评论 ID */
|
|
74
|
+
async findExistingComment() {
|
|
75
|
+
const url = `${this.apiBaseUrl}/repos/${this.owner}/${this.repo}/issues/${this.prNumber}/comments?per_page=100`;
|
|
76
|
+
const response = await fetch(url, { headers: this.headers() });
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const comments = await response.json();
|
|
81
|
+
for (const comment of comments) {
|
|
82
|
+
if ((0, pr_comment_js_1.isGuardianComment)(comment.body)) {
|
|
83
|
+
return comment.id;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
headers() {
|
|
89
|
+
return {
|
|
90
|
+
Authorization: `Bearer ${this.token}`,
|
|
91
|
+
Accept: "application/vnd.github+json",
|
|
92
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
93
|
+
"User-Agent": "frontend-guardian/2.5.0",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.GitHubPRPublisher = GitHubPRPublisher;
|
|
98
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
99
|
+
// GitLab MR 评论发布器
|
|
100
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
101
|
+
class GitLabMRPublisher {
|
|
102
|
+
token;
|
|
103
|
+
projectId;
|
|
104
|
+
mrIid;
|
|
105
|
+
apiBaseUrl;
|
|
106
|
+
constructor(config) {
|
|
107
|
+
this.token = config.token;
|
|
108
|
+
this.projectId = encodeURIComponent(config.repository);
|
|
109
|
+
this.mrIid = config.prNumber;
|
|
110
|
+
this.apiBaseUrl = config.apiBaseUrl || "https://gitlab.com";
|
|
111
|
+
}
|
|
112
|
+
async publish(body) {
|
|
113
|
+
try {
|
|
114
|
+
// 1. 查找已有的 guardian 评论
|
|
115
|
+
const existingNoteId = await this.findExistingNote();
|
|
116
|
+
if (existingNoteId) {
|
|
117
|
+
// 更新已有 MR 讨论
|
|
118
|
+
const url = `${this.apiBaseUrl}/api/v4/projects/${this.projectId}/merge_requests/${this.mrIid}/discussions/${existingNoteId}`;
|
|
119
|
+
const response = await fetch(url, {
|
|
120
|
+
method: "PUT",
|
|
121
|
+
headers: this.headers(),
|
|
122
|
+
body: new URLSearchParams({ body }),
|
|
123
|
+
});
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
const errText = await response.text().catch(() => "Unknown error");
|
|
126
|
+
return { success: false, action: "none", error: `GitLab API error (${response.status}): ${errText}` };
|
|
127
|
+
}
|
|
128
|
+
const data = await response.json();
|
|
129
|
+
return { success: true, action: "updated", commentUrl: data.web_url };
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// 创建新 MR 讨论(note)
|
|
133
|
+
const url = `${this.apiBaseUrl}/api/v4/projects/${this.projectId}/merge_requests/${this.mrIid}/discussions`;
|
|
134
|
+
const response = await fetch(url, {
|
|
135
|
+
method: "POST",
|
|
136
|
+
headers: this.headers(),
|
|
137
|
+
body: new URLSearchParams({ body }),
|
|
138
|
+
});
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
const errText = await response.text().catch(() => "Unknown error");
|
|
141
|
+
return { success: false, action: "none", error: `GitLab API error (${response.status}): ${errText}` };
|
|
142
|
+
}
|
|
143
|
+
const data = await response.json();
|
|
144
|
+
return { success: true, action: "created", commentUrl: data.web_url };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
return { success: false, action: "none", error: String(err) };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** 查找已有的 frontend-guardian MR 讨论 ID */
|
|
152
|
+
async findExistingNote() {
|
|
153
|
+
const url = `${this.apiBaseUrl}/api/v4/projects/${this.projectId}/merge_requests/${this.mrIid}/discussions?per_page=100`;
|
|
154
|
+
const response = await fetch(url, { headers: this.headers() });
|
|
155
|
+
if (!response.ok) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const discussions = await response.json();
|
|
159
|
+
for (const discussion of discussions) {
|
|
160
|
+
for (const note of discussion.notes) {
|
|
161
|
+
if ((0, pr_comment_js_1.isGuardianComment)(note.body)) {
|
|
162
|
+
return discussion.id;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
headers() {
|
|
169
|
+
return {
|
|
170
|
+
"PRIVATE-TOKEN": this.token,
|
|
171
|
+
"User-Agent": "frontend-guardian/2.5.0",
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.GitLabMRPublisher = GitLabMRPublisher;
|
|
176
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
177
|
+
// 环境自动检测与工厂函数
|
|
178
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
179
|
+
/** 从环境变量自动推断发布器配置 */
|
|
180
|
+
function detectPublisherConfig() {
|
|
181
|
+
// GitHub Actions
|
|
182
|
+
if (process.env.GITHUB_ACTIONS === "true") {
|
|
183
|
+
const token = process.env.GITHUB_TOKEN;
|
|
184
|
+
const repository = process.env.GITHUB_REPOSITORY;
|
|
185
|
+
const prNumber = detectGitHubPRNumber();
|
|
186
|
+
if (token && repository && prNumber) {
|
|
187
|
+
return {
|
|
188
|
+
provider: "github",
|
|
189
|
+
token,
|
|
190
|
+
repository,
|
|
191
|
+
prNumber,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// GitLab CI
|
|
196
|
+
if (process.env.GITLAB_CI === "true") {
|
|
197
|
+
const token = process.env.GITLAB_TOKEN || process.env.CI_JOB_TOKEN;
|
|
198
|
+
const projectId = process.env.CI_PROJECT_ID;
|
|
199
|
+
const mrIid = process.env.CI_MERGE_REQUEST_IID;
|
|
200
|
+
if (token && projectId && mrIid) {
|
|
201
|
+
const apiBaseUrl = process.env.CI_API_V4_URL
|
|
202
|
+
? process.env.CI_API_V4_URL.replace("/api/v4", "")
|
|
203
|
+
: undefined;
|
|
204
|
+
return {
|
|
205
|
+
provider: "gitlab",
|
|
206
|
+
token,
|
|
207
|
+
repository: projectId,
|
|
208
|
+
prNumber: parseInt(mrIid, 10),
|
|
209
|
+
apiBaseUrl,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
/** 检测 GitHub PR 编号 */
|
|
216
|
+
function detectGitHubPRNumber() {
|
|
217
|
+
// GITHUB_REF_NAME 在 PR 事件中为 "123/merge" 格式
|
|
218
|
+
const refName = process.env.GITHUB_REF_NAME;
|
|
219
|
+
if (refName) {
|
|
220
|
+
const match = refName.match(/^(\d+)\/merge$/);
|
|
221
|
+
if (match) {
|
|
222
|
+
return parseInt(match[1], 10);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// GITHUB_HEAD_REF 在 PR 事件中有值
|
|
226
|
+
const headRef = process.env.GITHUB_HEAD_REF;
|
|
227
|
+
if (headRef && process.env.GITHUB_REF) {
|
|
228
|
+
// GITHUB_REF 通常是 refs/pull/123/merge
|
|
229
|
+
const ref = process.env.GITHUB_REF;
|
|
230
|
+
const match = ref.match(/refs\/pull\/(\d+)\/merge/);
|
|
231
|
+
if (match) {
|
|
232
|
+
return parseInt(match[1], 10);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// 部分 runner 提供的专用变量
|
|
236
|
+
if (process.env.PR_NUMBER) {
|
|
237
|
+
return parseInt(process.env.PR_NUMBER, 10);
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
/** 创建发布器实例 */
|
|
242
|
+
function createPublisher(config) {
|
|
243
|
+
if (config.provider === "github") {
|
|
244
|
+
return new GitHubPRPublisher(config);
|
|
245
|
+
}
|
|
246
|
+
if (config.provider === "gitlab") {
|
|
247
|
+
return new GitLabMRPublisher(config);
|
|
248
|
+
}
|
|
249
|
+
throw new Error(`Unknown provider: ${config.provider}`);
|
|
250
|
+
}
|
|
251
|
+
/** 便捷函数:自动检测环境并发布评论 */
|
|
252
|
+
async function autoPublishComment(body) {
|
|
253
|
+
const config = detectPublisherConfig();
|
|
254
|
+
if (!config) {
|
|
255
|
+
return {
|
|
256
|
+
success: false,
|
|
257
|
+
action: "none",
|
|
258
|
+
error: "无法自动检测 CI 环境。请确保在 GitHub Actions (GITHUB_TOKEN + GITHUB_REPOSITORY) " +
|
|
259
|
+
"或 GitLab CI (GITLAB_TOKEN + CI_PROJECT_ID + CI_MERGE_REQUEST_IID) 中运行,或手动指定配置。",
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
const publisher = createPublisher(config);
|
|
263
|
+
return publisher.publish(body);
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=pr-publisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-publisher.js","sourceRoot":"","sources":["../../src/utils/pr-publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 项目元数据检测工具 (Phase 2: 智能化深度检测)
|
|
3
|
+
*
|
|
4
|
+
* 检测维度:
|
|
5
|
+
* 1. 框架 & 版本 (react@18.2, vue@3.3, nextjs, nuxt...)
|
|
6
|
+
* 2. 组件库 & 版本 (antd@5, element-plus, mui...)
|
|
7
|
+
* 3. 构建工具 / Bundler (vite, webpack, rsbuild, turbopack...)
|
|
8
|
+
* 4. 测试框架 (jest, vitest, cypress, playwright...)
|
|
9
|
+
* 5. 状态管理 (redux, zustand, pinia, jotai...)
|
|
10
|
+
* 6. 样式方案 (tailwind, styled-components, sass, less...)
|
|
11
|
+
* 7. 路由 (react-router, vue-router, tanstack-router...)
|
|
12
|
+
* 8. 包管理器 (npm/yarn/pnpm/bun — 通过 lockfile 推断)
|
|
13
|
+
* 9. Linter / Formatter (eslint, biome, prettier, stylelint...)
|
|
14
|
+
* 10. Monorepo 工具 (nx, turborepo, lerna, pnpm-workspace)
|
|
15
|
+
* 11. 平台 (pc, h5, 小程序, app, harmony...)
|
|
16
|
+
* 12. i18n (react-intl, vue-i18n, i18next...)
|
|
17
|
+
*/
|
|
18
|
+
import type { ProjectMeta, ProjectConfig } from "../types.js";
|
|
19
|
+
export declare function detectProjectMeta(projectDir: string, config?: ProjectConfig): ProjectMeta;
|
|
20
|
+
//# sourceMappingURL=project-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-detector.d.ts","sourceRoot":"","sources":["../../src/utils/project-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EACR,WAAW,EACX,aAAa,EAahB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,CAsCzF"}
|