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,182 @@
1
+ "use strict";
2
+ /**
3
+ * Formatter Integration — 代码格式化器集成
4
+ *
5
+ * 功能:
6
+ * 1. 自动检测项目使用的格式化工具(Biome / Prettier)
7
+ * 2. 使用项目已有配置,无配置时回退到默认
8
+ * 3. 支持 --format 单独运行,或 --fix --format 修复后自动格式化
9
+ *
10
+ * 检测优先级:
11
+ * 1. biome.json / biome.jsonc → Biome
12
+ * 2. .prettierrc / prettier.config.* → Prettier
13
+ * 3. 无配置 → 默认 Biome(4空格/120字符/双引号)
14
+ */
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.detectFormatter = detectFormatter;
20
+ exports.runFormat = runFormat;
21
+ const node_fs_1 = require("node:fs");
22
+ const node_path_1 = require("node:path");
23
+ const picocolors_1 = __importDefault(require("picocolors"));
24
+ const base_js_1 = require("./base.js");
25
+ /** 检测项目使用的格式化器 */
26
+ function detectFormatter(projectDir) {
27
+ if (biomeFormatter.isAvailable(projectDir)) {
28
+ return biomeFormatter;
29
+ }
30
+ if (prettierFormatter.isAvailable(projectDir)) {
31
+ return prettierFormatter;
32
+ }
33
+ // 无配置时默认用 Biome
34
+ if (hasBiomeCli(projectDir)) {
35
+ return biomeFormatter;
36
+ }
37
+ return null;
38
+ }
39
+ /** 运行格式化 */
40
+ function runFormat(projectDir, files) {
41
+ const formatter = detectFormatter(projectDir);
42
+ if (!formatter) {
43
+ return {
44
+ formatter: "none",
45
+ formatted: 0,
46
+ unchanged: 0,
47
+ errors: ["未检测到可用的格式化工具(Biome 或 Prettier)"],
48
+ duration: 0,
49
+ };
50
+ }
51
+ return formatter.format(projectDir, files);
52
+ }
53
+ // ── Biome Formatter ────────────────────────────────────────────────────────
54
+ const biomeFormatter = {
55
+ name: "Biome",
56
+ isAvailable(projectDir) {
57
+ return ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, "biome.json")) ||
58
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, "biome.jsonc")) ||
59
+ hasBiomeCli(projectDir));
60
+ },
61
+ format(projectDir, files) {
62
+ const start = Date.now();
63
+ const errors = [];
64
+ let formatted = 0;
65
+ let unchanged = 0;
66
+ // 确保有配置文件
67
+ ensureBiomeConfig(projectDir);
68
+ const fileArgs = files && files.length > 0 ? files.join(" ") : ".";
69
+ const output = (0, base_js_1.runCommand)(`npx biome format --write ${fileArgs}`, projectDir, 120000);
70
+ if (output === null) {
71
+ errors.push("Biome format 执行失败");
72
+ }
73
+ else {
74
+ // Biome 输出格式: "Formatted 3 files in 12ms"
75
+ const match = output.match(/Formatted\s+(\d+)\s+file/i);
76
+ if (match) {
77
+ formatted = parseInt(match[1], 10);
78
+ }
79
+ // 检查 unchanged
80
+ const unchangedMatch = output.match(/unchanged\s+(\d+)/i);
81
+ if (unchangedMatch) {
82
+ unchanged = parseInt(unchangedMatch[1], 10);
83
+ }
84
+ // 如果没匹配到 formatted,可能全部未变更
85
+ if (!match && output.includes("unchanged")) {
86
+ const allMatch = output.match(/(\d+)\s+files?\s+unchanged/i);
87
+ if (allMatch) {
88
+ unchanged = parseInt(allMatch[1], 10);
89
+ }
90
+ }
91
+ }
92
+ return {
93
+ formatter: "Biome",
94
+ formatted,
95
+ unchanged,
96
+ errors,
97
+ duration: Date.now() - start,
98
+ };
99
+ },
100
+ };
101
+ // ── Prettier Formatter ─────────────────────────────────────────────────────
102
+ const prettierFormatter = {
103
+ name: "Prettier",
104
+ isAvailable(projectDir) {
105
+ return ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, ".prettierrc")) ||
106
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, ".prettierrc.json")) ||
107
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, ".prettierrc.js")) ||
108
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, ".prettierrc.mjs")) ||
109
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, ".prettierrc.cjs")) ||
110
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, ".prettierrc.yaml")) ||
111
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, ".prettierrc.yml")) ||
112
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, "prettier.config.js")) ||
113
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, "prettier.config.mjs")) ||
114
+ (0, node_fs_1.existsSync)((0, node_path_1.resolve)(projectDir, "prettier.config.cjs")) ||
115
+ hasPrettierCli(projectDir));
116
+ },
117
+ format(projectDir, files) {
118
+ const start = Date.now();
119
+ const errors = [];
120
+ let formatted = 0;
121
+ let unchanged = 0;
122
+ const fileArgs = files && files.length > 0 ? files.join(" ") : "**/*.{js,ts,jsx,tsx,vue,svelte,css,scss,less,json,md}";
123
+ const output = (0, base_js_1.runCommand)(`npx prettier --write --log-level warn ${fileArgs}`, projectDir, 120000);
124
+ if (output === null) {
125
+ errors.push("Prettier 执行失败");
126
+ }
127
+ else {
128
+ // Prettier 输出每行一个文件路径
129
+ const lines = output.split("\n").filter((l) => l.trim());
130
+ formatted = lines.length;
131
+ }
132
+ return {
133
+ formatter: "Prettier",
134
+ formatted,
135
+ unchanged,
136
+ errors,
137
+ duration: Date.now() - start,
138
+ };
139
+ },
140
+ };
141
+ // ── Helpers ────────────────────────────────────────────────────────────────
142
+ function hasBiomeCli(projectDir) {
143
+ const result = (0, base_js_1.runCommand)("npx biome --version 2>/dev/null || echo NOT_FOUND", projectDir, 5000);
144
+ return result !== null && !result.includes("NOT_FOUND");
145
+ }
146
+ function hasPrettierCli(projectDir) {
147
+ const result = (0, base_js_1.runCommand)("npx prettier --version 2>/dev/null || echo NOT_FOUND", projectDir, 5000);
148
+ return result !== null && !result.includes("NOT_FOUND");
149
+ }
150
+ /** 如果项目没有 biome.json,生成一个默认配置 */
151
+ function ensureBiomeConfig(projectDir) {
152
+ const configPath = (0, node_path_1.resolve)(projectDir, "biome.json");
153
+ if ((0, node_fs_1.existsSync)(configPath))
154
+ return;
155
+ const defaultConfig = {
156
+ "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
157
+ formatter: {
158
+ enabled: true,
159
+ indentStyle: "space",
160
+ indentWidth: 4,
161
+ lineWidth: 120,
162
+ },
163
+ javascript: {
164
+ formatter: {
165
+ quoteStyle: "double",
166
+ trailingCommas: "all",
167
+ },
168
+ },
169
+ files: {
170
+ ignore: ["node_modules", "dist", "build", ".git", "coverage"],
171
+ },
172
+ };
173
+ try {
174
+ const fs = require("node:fs");
175
+ fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 4), "utf-8");
176
+ console.log(picocolors_1.default.blue(` 📝 已生成默认 Biome 配置: ${configPath}`));
177
+ }
178
+ catch {
179
+ // 静默失败
180
+ }
181
+ }
182
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/integrations/formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 外部工具集成索引
3
+ * Phase 4: 覆盖全面化 — 集成 ESLint / TypeScript / Stylelint
4
+ */
5
+ export type { ExternalTool, ExternalToolResult } from "./base.js";
6
+ export { runAllExternalTools, runCommand, eslintSeverityToFg, hasPackage } from "./base.js";
7
+ import { eslintIntegration as _eslintIntegration } from "./eslint.js";
8
+ import { typescriptIntegration as _typescriptIntegration } from "./typescript.js";
9
+ import { stylelintIntegration as _stylelintIntegration } from "./stylelint.js";
10
+ export { _eslintIntegration as eslintIntegration };
11
+ export { _typescriptIntegration as typescriptIntegration };
12
+ export { _stylelintIntegration as stylelintIntegration };
13
+ /** 所有可用的外部工具列表 */
14
+ export declare const allExternalTools: import("./base.js").ExternalTool[];
15
+ export { detectFormatter, runFormat } from "./formatter.js";
16
+ export type { FormatResult, FormatterTool } from "./formatter.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5F,OAAO,EAAE,iBAAiB,IAAI,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,EAAE,kBAAkB,IAAI,iBAAiB,EAAE,CAAC;AACnD,OAAO,EAAE,sBAAsB,IAAI,qBAAqB,EAAE,CAAC;AAC3D,OAAO,EAAE,qBAAqB,IAAI,oBAAoB,EAAE,CAAC;AAEzD,kBAAkB;AAClB,eAAO,MAAM,gBAAgB,oCAAsE,CAAC;AAGpG,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * 外部工具集成索引
4
+ * Phase 4: 覆盖全面化 — 集成 ESLint / TypeScript / Stylelint
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.runFormat = exports.detectFormatter = exports.allExternalTools = exports.stylelintIntegration = exports.typescriptIntegration = exports.eslintIntegration = exports.hasPackage = exports.eslintSeverityToFg = exports.runCommand = exports.runAllExternalTools = void 0;
8
+ var base_js_1 = require("./base.js");
9
+ Object.defineProperty(exports, "runAllExternalTools", { enumerable: true, get: function () { return base_js_1.runAllExternalTools; } });
10
+ Object.defineProperty(exports, "runCommand", { enumerable: true, get: function () { return base_js_1.runCommand; } });
11
+ Object.defineProperty(exports, "eslintSeverityToFg", { enumerable: true, get: function () { return base_js_1.eslintSeverityToFg; } });
12
+ Object.defineProperty(exports, "hasPackage", { enumerable: true, get: function () { return base_js_1.hasPackage; } });
13
+ const eslint_js_1 = require("./eslint.js");
14
+ Object.defineProperty(exports, "eslintIntegration", { enumerable: true, get: function () { return eslint_js_1.eslintIntegration; } });
15
+ const typescript_js_1 = require("./typescript.js");
16
+ Object.defineProperty(exports, "typescriptIntegration", { enumerable: true, get: function () { return typescript_js_1.typescriptIntegration; } });
17
+ const stylelint_js_1 = require("./stylelint.js");
18
+ Object.defineProperty(exports, "stylelintIntegration", { enumerable: true, get: function () { return stylelint_js_1.stylelintIntegration; } });
19
+ /** 所有可用的外部工具列表 */
20
+ exports.allExternalTools = [eslint_js_1.eslintIntegration, typescript_js_1.typescriptIntegration, stylelint_js_1.stylelintIntegration];
21
+ // Phase 5+6: 格式化器集成
22
+ var formatter_js_1 = require("./formatter.js");
23
+ Object.defineProperty(exports, "detectFormatter", { enumerable: true, get: function () { return formatter_js_1.detectFormatter; } });
24
+ Object.defineProperty(exports, "runFormat", { enumerable: true, get: function () { return formatter_js_1.runFormat; } });
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,qCAA4F;AAAnF,8GAAA,mBAAmB,OAAA;AAAE,qGAAA,UAAU,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAAE,qGAAA,UAAU,OAAA;AAExE,2CAAsE;AAIvC,kGAJD,6BAAkB,OAIA;AAHhD,mDAAkF;AAI/C,sGAJD,qCAAsB,OAIA;AAHxD,iDAA+E;AAI7C,qGAJD,mCAAqB,OAIA;AAEtD,kBAAkB;AACL,QAAA,gBAAgB,GAAG,CAAC,6BAAkB,EAAE,qCAAsB,EAAE,mCAAqB,CAAC,CAAC;AAEpG,oBAAoB;AACpB,+CAA4D;AAAnD,+GAAA,eAAe,OAAA;AAAE,yGAAA,SAAS,OAAA"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Stylelint 集成
3
+ *
4
+ * 调用 npx stylelint --formatter json 并解析 CSS 规范问题为 Issue 格式
5
+ */
6
+ import type { ExternalTool } from "./base.js";
7
+ export declare const stylelintIntegration: ExternalTool;
8
+ //# sourceMappingURL=stylelint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stylelint.d.ts","sourceRoot":"","sources":["../../src/integrations/stylelint.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAgC9C,eAAO,MAAM,oBAAoB,EAAE,YA4ClC,CAAC"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /**
3
+ * Stylelint 集成
4
+ *
5
+ * 调用 npx stylelint --formatter json 并解析 CSS 规范问题为 Issue 格式
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.stylelintIntegration = void 0;
9
+ const base_js_1 = require("./base.js");
10
+ function slSeverityToFg(severity) {
11
+ switch (severity) {
12
+ case "error":
13
+ return "critical";
14
+ case "warning":
15
+ return "warning";
16
+ default:
17
+ return "suggestion";
18
+ }
19
+ }
20
+ exports.stylelintIntegration = {
21
+ name: "Stylelint",
22
+ isAvailable(projectDir) {
23
+ return (0, base_js_1.hasPackage)(projectDir, "stylelint");
24
+ },
25
+ run(projectDir, files) {
26
+ const patterns = files && files.length > 0 ? files.join(" ") : '"src/**/*.{css,scss,less,sass}"';
27
+ const stdout = (0, base_js_1.runCommand)(`npx stylelint ${patterns} --formatter json --allow-empty-input`, projectDir, 120000);
28
+ if (!stdout) {
29
+ return [];
30
+ }
31
+ let results;
32
+ try {
33
+ results = JSON.parse(stdout);
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ const issues = [];
39
+ for (const result of results) {
40
+ for (const warning of result.warnings) {
41
+ issues.push({
42
+ ruleId: `stylelint-${warning.rule}`,
43
+ title: warning.rule,
44
+ description: warning.text.replace(/\s*\(.*\)\s*$/, ""), // 去掉末尾的 URL 提示
45
+ severity: slSeverityToFg(warning.severity),
46
+ file: result.source,
47
+ line: warning.line,
48
+ column: warning.column,
49
+ meta: {
50
+ tool: "stylelint",
51
+ url: warning.url,
52
+ },
53
+ });
54
+ }
55
+ }
56
+ return issues;
57
+ },
58
+ };
59
+ //# sourceMappingURL=stylelint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stylelint.js","sourceRoot":"","sources":["../../src/integrations/stylelint.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH,uCAAmD;AAoBnD,SAAS,cAAc,CAAC,QAAgB;IACpC,QAAQ,QAAQ,EAAE,CAAC;QACf,KAAK,OAAO;YACR,OAAO,UAAU,CAAC;QACtB,KAAK,SAAS;YACV,OAAO,SAAS,CAAC;QACrB;YACI,OAAO,YAAY,CAAC;IAC5B,CAAC;AACL,CAAC;AAEY,QAAA,oBAAoB,GAAiB;IAC9C,IAAI,EAAE,WAAW;IAEjB,WAAW,CAAC,UAAkB;QAC1B,OAAO,IAAA,oBAAU,EAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,GAAG,CAAC,UAAkB,EAAE,KAAgB;QACpC,MAAM,QAAQ,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,iCAAiC,CAAC;QAEjG,MAAM,MAAM,GAAG,IAAA,oBAAU,EAAC,iBAAiB,QAAQ,uCAAuC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QAEhH,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,OAA0B,CAAC;QAC/B,IAAI,CAAC;YACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,EAAE,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC;oBACR,MAAM,EAAE,aAAa,OAAO,CAAC,IAAI,EAAE;oBACnC,KAAK,EAAE,OAAO,CAAC,IAAI;oBACnB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,EAAE,eAAe;oBACvE,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC;oBAC1C,IAAI,EAAE,MAAM,CAAC,MAAM;oBACnB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,IAAI,EAAE;wBACF,IAAI,EAAE,WAAW;wBACjB,GAAG,EAAE,OAAO,CAAC,GAAG;qBACnB;iBACJ,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * TypeScript 集成
3
+ *
4
+ * 调用 npx tsc --noEmit 并解析类型错误为 Issue 格式
5
+ */
6
+ import type { ExternalTool } from "./base.js";
7
+ export declare const typescriptIntegration: ExternalTool;
8
+ //# sourceMappingURL=typescript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/integrations/typescript.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAmC9C,eAAO,MAAM,qBAAqB,EAAE,YA0DnC,CAAC"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ /**
3
+ * TypeScript 集成
4
+ *
5
+ * 调用 npx tsc --noEmit 并解析类型错误为 Issue 格式
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.typescriptIntegration = void 0;
9
+ const base_js_1 = require("./base.js");
10
+ /** TSC 错误码分类:关键类型错误 */
11
+ const CRITICAL_CODES = new Set([
12
+ 2322, // Type 'X' is not assignable to type 'Y'
13
+ 2345, // Argument of type 'X' is not assignable to parameter of type 'Y'
14
+ 2321, // Excess property checks
15
+ 2531, // Object is possibly 'null'
16
+ 2532, // Object is possibly 'undefined'
17
+ 2533, // Object is possibly 'null' or 'undefined'
18
+ 2571, // Object is of type 'unknown'
19
+ 18046, // 'X' is of type 'unknown'
20
+ 18047, // 'X' is possibly 'null'
21
+ 18048, // 'X' is possibly 'undefined'
22
+ 7006, // Parameter 'X' implicitly has an 'any' type
23
+ 7008, // Member 'X' implicitly has an 'any' type
24
+ 7017, // Element implicitly has an 'any' type because index expression is not of type 'number'
25
+ 7019, // Element implicitly has an 'any' type because expression of type 'X' can't be used to index type 'Y'
26
+ ]);
27
+ const WARNING_CODES = new Set([
28
+ 6133, // 'X' is declared but its value is never read
29
+ 6196, // 'X' is declared but never used
30
+ 2578, // Unused '@ts-expect-error' directive
31
+ 7027, // Unreachable code detected
32
+ 7030, // Not all code paths return a value
33
+ ]);
34
+ function tscCodeToSeverity(code) {
35
+ if (CRITICAL_CODES.has(code))
36
+ return "critical";
37
+ if (WARNING_CODES.has(code))
38
+ return "warning";
39
+ return "suggestion";
40
+ }
41
+ exports.typescriptIntegration = {
42
+ name: "TypeScript",
43
+ isAvailable(projectDir) {
44
+ // 检查 tsconfig.json 是否存在
45
+ try {
46
+ const fs = require("node:fs");
47
+ return fs.existsSync(require("node:path").join(projectDir, "tsconfig.json"));
48
+ }
49
+ catch {
50
+ return false;
51
+ }
52
+ },
53
+ run(projectDir, files) {
54
+ // 如果指定了文件列表,只检查这些文件
55
+ const cmd = files && files.length > 0 ? `npx tsc --noEmit ${files.join(" ")}` : "npx tsc --noEmit";
56
+ const stdout = (0, base_js_1.runCommand)(cmd, projectDir, 180000);
57
+ if (!stdout) {
58
+ return [];
59
+ }
60
+ const issues = [];
61
+ const lines = stdout.split("\n");
62
+ // 解析 TSC 错误输出格式:
63
+ // src/file.ts(10,5): error TS2322: Type 'string' is not assignable to type 'number'.
64
+ const errorRegex = /^(.+)\((\d+),(\d+)\):\s+(error|warning)\s+TS(\d+):\s+(.+)$/;
65
+ for (const line of lines) {
66
+ const match = line.match(errorRegex);
67
+ if (!match)
68
+ continue;
69
+ const [, filePath, lineStr, colStr, category, codeStr, message] = match;
70
+ const code = parseInt(codeStr, 10);
71
+ const lineNum = parseInt(lineStr, 10);
72
+ const colNum = parseInt(colStr, 10);
73
+ const severity = tscCodeToSeverity(code);
74
+ issues.push({
75
+ ruleId: `tsc-TS${code}`,
76
+ title: `TS${code}: ${message.slice(0, 60)}`,
77
+ description: message,
78
+ severity,
79
+ file: filePath,
80
+ line: lineNum,
81
+ column: colNum,
82
+ meta: {
83
+ tool: "typescript",
84
+ code,
85
+ category,
86
+ },
87
+ });
88
+ }
89
+ return issues;
90
+ },
91
+ };
92
+ //# sourceMappingURL=typescript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../src/integrations/typescript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * RuleRegistry — 规则注册中心
3
+ *
4
+ * Phase 3 核心组件:
5
+ * 1. 统一管理内置规则 + 自定义规则
6
+ * 2. 支持配置驱动(启用/禁用/调整 severity/参数化)
7
+ * 3. 支持热加载用户自定义 JS 规则文件
8
+ * 4. 框架抽象:规则按 category 分组,引擎按需取用
9
+ */
10
+ import type { Rule, RuleConfig, RuleCategory } from "../types.js";
11
+ /** 规则注册中心 */
12
+ export declare class RuleRegistry {
13
+ /** 内置规则(原始定义,不可变) */
14
+ private builtInRules;
15
+ /** 自定义规则(从外部 JS 文件加载) */
16
+ private customRules;
17
+ /** 配置覆盖(id → RuleConfig) */
18
+ private configOverrides;
19
+ /** 注册单条规则 */
20
+ register(rule: Rule): this;
21
+ /** 批量注册规则 */
22
+ registerAll(rules: Rule[]): this;
23
+ /** 注销规则(仅对自定义规则有效,内置规则不可注销) */
24
+ unregister(ruleId: string): this;
25
+ /** 获取单条规则(原始定义,未应用配置) */
26
+ getRaw(ruleId: string): Rule | undefined;
27
+ /** 获取所有已注册规则 ID */
28
+ getRuleIds(): string[];
29
+ /** ───────────────────────────────────────────────────────────────────────── */
30
+ /** 配置驱动 */
31
+ /** ───────────────────────────────────────────────────────────────────────── */
32
+ /**
33
+ * 从配置加载规则覆盖
34
+ * @param configs 规则配置列表(来自 .frontend-guardian.yml 的 rules: 节点)
35
+ */
36
+ loadFromConfig(configs: RuleConfig[]): void;
37
+ /**
38
+ * 加载自定义规则文件
39
+ * @param filePath 规则文件路径(相对或绝对)
40
+ * @param projectDir 项目根目录(用于解析相对路径)
41
+ */
42
+ loadCustomRule(filePath: string, projectDir?: string): boolean;
43
+ /** 加载多个自定义规则文件 */
44
+ loadCustomRules(paths: string[], projectDir?: string): {
45
+ loaded: string[];
46
+ failed: string[];
47
+ };
48
+ /** ───────────────────────────────────────────────────────────────────────── */
49
+ /** 规则取用 */
50
+ /** ───────────────────────────────────────────────────────────────────────── */
51
+ /**
52
+ * 获取应用了配置覆盖后的规则
53
+ * @returns 规则副本(severity/params 已按配置调整)
54
+ */
55
+ getRule(ruleId: string): Rule | undefined;
56
+ /**
57
+ * 获取所有启用的规则
58
+ * @param category 可选:按分类过滤
59
+ */
60
+ getActiveRules(category?: RuleCategory): Rule[];
61
+ /**
62
+ * 按条件过滤规则(框架/平台/组件库)
63
+ * 与 RuleEngine.filterRules 保持一致
64
+ */
65
+ filterRules(options?: {
66
+ category?: string;
67
+ framework?: string;
68
+ platform?: string;
69
+ componentLib?: string;
70
+ }): Rule[];
71
+ /** 清除所有配置覆盖(重置为默认状态) */
72
+ clearOverrides(): void;
73
+ /** 清除所有自定义规则 */
74
+ clearCustomRules(): void;
75
+ /** ───────────────────────────────────────────────────────────────────────── */
76
+ /** 内部工具 */
77
+ /** ───────────────────────────────────────────────────────────────────────── */
78
+ /** 将配置覆盖应用到规则,返回新副本 */
79
+ private applyOverride;
80
+ }
81
+ /** 创建空的规则注册中心 */
82
+ export declare function createRegistry(): RuleRegistry;
83
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/rules/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAY,MAAM,YAAY,CAAC;AAG3E,aAAa;AACb,qBAAa,YAAY;IACrB,qBAAqB;IACrB,OAAO,CAAC,YAAY,CAA2B;IAC/C,yBAAyB;IACzB,OAAO,CAAC,WAAW,CAA2B;IAC9C,4BAA4B;IAC5B,OAAO,CAAC,eAAe,CAAiC;IAExD,aAAa;IACb,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAK1B,aAAa;IACb,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAOhC,+BAA+B;IAC/B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKhC,yBAAyB;IACzB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIxC,mBAAmB;IACnB,UAAU,IAAI,MAAM,EAAE;IAOtB,gFAAgF;IAChF,gFAAgF;IAChF,gFAAgF;IAEhF;;;OAGG;IACH,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI;IAU3C;;;;OAIG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO;IA6B9D,kBAAkB;IAClB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAe7F,gFAAgF;IAChF,gFAAgF;IAChF,gFAAgF;IAEhF;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAUzC;;;OAGG;IACH,cAAc,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,IAAI,EAAE;IAqB/C;;;OAGG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,EAAE;IAgBlH,wBAAwB;IACxB,cAAc,IAAI,IAAI;IAItB,gBAAgB;IAChB,gBAAgB,IAAI,IAAI;IAIxB,gFAAgF;IAChF,gFAAgF;IAChF,gFAAgF;IAEhF,uBAAuB;IACvB,OAAO,CAAC,aAAa;CAkBxB;AAED,iBAAiB;AACjB,wBAAgB,cAAc,IAAI,YAAY,CAE7C"}