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,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 @@
|
|
|
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 @@
|
|
|
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"}
|