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.
Files changed (152) hide show
  1. package/LICENSE +21 -0
  2. package/bin/fg-core.js +1238 -0
  3. package/bin/watch-mode.js +123 -0
  4. package/dist/engine/cache.d.ts +68 -0
  5. package/dist/engine/cache.d.ts.map +1 -0
  6. package/dist/engine/cache.js +164 -0
  7. package/dist/engine/cache.js.map +1 -0
  8. package/dist/engine/rule-engine.d.ts +135 -0
  9. package/dist/engine/rule-engine.d.ts.map +1 -0
  10. package/dist/engine/rule-engine.js +716 -0
  11. package/dist/engine/rule-engine.js.map +1 -0
  12. package/dist/formatters/github-annotation.d.ts +36 -0
  13. package/dist/formatters/github-annotation.d.ts.map +1 -0
  14. package/dist/formatters/github-annotation.js +122 -0
  15. package/dist/formatters/github-annotation.js.map +1 -0
  16. package/dist/formatters/pr-comment.d.ts +43 -0
  17. package/dist/formatters/pr-comment.d.ts.map +1 -0
  18. package/dist/formatters/pr-comment.js +171 -0
  19. package/dist/formatters/pr-comment.js.map +1 -0
  20. package/dist/formatters/sarif.d.ts +104 -0
  21. package/dist/formatters/sarif.d.ts.map +1 -0
  22. package/dist/formatters/sarif.js +130 -0
  23. package/dist/formatters/sarif.js.map +1 -0
  24. package/dist/index.d.ts +46 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +108 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/integrations/base.d.ts +44 -0
  29. package/dist/integrations/base.d.ts.map +1 -0
  30. package/dist/integrations/base.js +104 -0
  31. package/dist/integrations/base.js.map +1 -0
  32. package/dist/integrations/eslint.d.ts +8 -0
  33. package/dist/integrations/eslint.d.ts.map +1 -0
  34. package/dist/integrations/eslint.js +67 -0
  35. package/dist/integrations/eslint.js.map +1 -0
  36. package/dist/integrations/formatter.d.ts +35 -0
  37. package/dist/integrations/formatter.d.ts.map +1 -0
  38. package/dist/integrations/formatter.js +182 -0
  39. package/dist/integrations/formatter.js.map +1 -0
  40. package/dist/integrations/index.d.ts +17 -0
  41. package/dist/integrations/index.d.ts.map +1 -0
  42. package/dist/integrations/index.js +25 -0
  43. package/dist/integrations/index.js.map +1 -0
  44. package/dist/integrations/stylelint.d.ts +8 -0
  45. package/dist/integrations/stylelint.d.ts.map +1 -0
  46. package/dist/integrations/stylelint.js +59 -0
  47. package/dist/integrations/stylelint.js.map +1 -0
  48. package/dist/integrations/typescript.d.ts +8 -0
  49. package/dist/integrations/typescript.d.ts.map +1 -0
  50. package/dist/integrations/typescript.js +92 -0
  51. package/dist/integrations/typescript.js.map +1 -0
  52. package/dist/rules/registry.d.ts +83 -0
  53. package/dist/rules/registry.d.ts.map +1 -0
  54. package/dist/rules/registry.js +205 -0
  55. package/dist/rules/registry.js.map +1 -0
  56. package/dist/scanners/a11y-scanner.d.ts +14 -0
  57. package/dist/scanners/a11y-scanner.d.ts.map +1 -0
  58. package/dist/scanners/a11y-scanner.js +781 -0
  59. package/dist/scanners/a11y-scanner.js.map +1 -0
  60. package/dist/scanners/component-scanner.d.ts +12 -0
  61. package/dist/scanners/component-scanner.d.ts.map +1 -0
  62. package/dist/scanners/component-scanner.js +304 -0
  63. package/dist/scanners/component-scanner.js.map +1 -0
  64. package/dist/scanners/cross-file-scanner.d.ts +18 -0
  65. package/dist/scanners/cross-file-scanner.d.ts.map +1 -0
  66. package/dist/scanners/cross-file-scanner.js +684 -0
  67. package/dist/scanners/cross-file-scanner.js.map +1 -0
  68. package/dist/scanners/hooks-scanner.d.ts +15 -0
  69. package/dist/scanners/hooks-scanner.d.ts.map +1 -0
  70. package/dist/scanners/hooks-scanner.js +670 -0
  71. package/dist/scanners/hooks-scanner.js.map +1 -0
  72. package/dist/scanners/i18n-scanner.d.ts +13 -0
  73. package/dist/scanners/i18n-scanner.d.ts.map +1 -0
  74. package/dist/scanners/i18n-scanner.js +535 -0
  75. package/dist/scanners/i18n-scanner.js.map +1 -0
  76. package/dist/scanners/naming-scanner.d.ts +19 -0
  77. package/dist/scanners/naming-scanner.d.ts.map +1 -0
  78. package/dist/scanners/naming-scanner.js +746 -0
  79. package/dist/scanners/naming-scanner.js.map +1 -0
  80. package/dist/scanners/performance-scanner.d.ts +7 -0
  81. package/dist/scanners/performance-scanner.d.ts.map +1 -0
  82. package/dist/scanners/performance-scanner.js +402 -0
  83. package/dist/scanners/performance-scanner.js.map +1 -0
  84. package/dist/scanners/platform-scanner.d.ts +15 -0
  85. package/dist/scanners/platform-scanner.d.ts.map +1 -0
  86. package/dist/scanners/platform-scanner.js +320 -0
  87. package/dist/scanners/platform-scanner.js.map +1 -0
  88. package/dist/scanners/security-scanner.d.ts +7 -0
  89. package/dist/scanners/security-scanner.d.ts.map +1 -0
  90. package/dist/scanners/security-scanner.js +349 -0
  91. package/dist/scanners/security-scanner.js.map +1 -0
  92. package/dist/scanners/svelte-scanner.d.ts +14 -0
  93. package/dist/scanners/svelte-scanner.d.ts.map +1 -0
  94. package/dist/scanners/svelte-scanner.js +228 -0
  95. package/dist/scanners/svelte-scanner.js.map +1 -0
  96. package/dist/types.d.ts +343 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +6 -0
  99. package/dist/types.js.map +1 -0
  100. package/dist/utils/ast-parser.d.ts +21 -0
  101. package/dist/utils/ast-parser.d.ts.map +1 -0
  102. package/dist/utils/ast-parser.js +119 -0
  103. package/dist/utils/ast-parser.js.map +1 -0
  104. package/dist/utils/baseline.d.ts +89 -0
  105. package/dist/utils/baseline.d.ts.map +1 -0
  106. package/dist/utils/baseline.js +156 -0
  107. package/dist/utils/baseline.js.map +1 -0
  108. package/dist/utils/ci-generator.d.ts +34 -0
  109. package/dist/utils/ci-generator.d.ts.map +1 -0
  110. package/dist/utils/ci-generator.js +194 -0
  111. package/dist/utils/ci-generator.js.map +1 -0
  112. package/dist/utils/common.d.ts +8 -0
  113. package/dist/utils/common.d.ts.map +1 -0
  114. package/dist/utils/common.js +38 -0
  115. package/dist/utils/common.js.map +1 -0
  116. package/dist/utils/concurrent.d.ts +16 -0
  117. package/dist/utils/concurrent.d.ts.map +1 -0
  118. package/dist/utils/concurrent.js +49 -0
  119. package/dist/utils/concurrent.js.map +1 -0
  120. package/dist/utils/config-loader.d.ts +8 -0
  121. package/dist/utils/config-loader.d.ts.map +1 -0
  122. package/dist/utils/config-loader.js +154 -0
  123. package/dist/utils/config-loader.js.map +1 -0
  124. package/dist/utils/fix-bot.d.ts +36 -0
  125. package/dist/utils/fix-bot.d.ts.map +1 -0
  126. package/dist/utils/fix-bot.js +274 -0
  127. package/dist/utils/fix-bot.js.map +1 -0
  128. package/dist/utils/git-hooks.d.ts +55 -0
  129. package/dist/utils/git-hooks.d.ts.map +1 -0
  130. package/dist/utils/git-hooks.js +318 -0
  131. package/dist/utils/git-hooks.js.map +1 -0
  132. package/dist/utils/history-report.d.ts +72 -0
  133. package/dist/utils/history-report.d.ts.map +1 -0
  134. package/dist/utils/history-report.js +144 -0
  135. package/dist/utils/history-report.js.map +1 -0
  136. package/dist/utils/init-config.d.ts +23 -0
  137. package/dist/utils/init-config.d.ts.map +1 -0
  138. package/dist/utils/init-config.js +146 -0
  139. package/dist/utils/init-config.js.map +1 -0
  140. package/dist/utils/pr-publisher.d.ts +64 -0
  141. package/dist/utils/pr-publisher.d.ts.map +1 -0
  142. package/dist/utils/pr-publisher.js +265 -0
  143. package/dist/utils/pr-publisher.js.map +1 -0
  144. package/dist/utils/project-detector.d.ts +20 -0
  145. package/dist/utils/project-detector.d.ts.map +1 -0
  146. package/dist/utils/project-detector.js +342 -0
  147. package/dist/utils/project-detector.js.map +1 -0
  148. package/dist/utils/report-uploader.d.ts +35 -0
  149. package/dist/utils/report-uploader.d.ts.map +1 -0
  150. package/dist/utils/report-uploader.js +106 -0
  151. package/dist/utils/report-uploader.js.map +1 -0
  152. 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"}