1
0

chore: 强化代码质量与风格检查体系

ESLint 升级到 recommended-type-checked + stylistic-type-checked,
引入 perfectionist 导入排序和 import 插件导入验证。

Prettier 显式声明全部格式化参数,消除跨环境差异。
TypeScript 启用 noUnusedLocals 和 noPropertyAccessFromIndexSignature。
完善 ignore 列表,排除 .agents/、bun.lock、data/ 等。
引入 husky + lint-staged(pre-commit)+ commitlint(commit-msg)。
更新 DEVELOPMENT.md 代码质量章节。
修复所有新增规则检测到的类型和风格违规。
This commit is contained in:
2026-05-12 18:44:59 +08:00
parent ce8baae3d1
commit a5cf6065c2
83 changed files with 2654 additions and 1824 deletions

View File

@@ -1,11 +1,7 @@
import type {
DefaultsConfig,
ProbeConfig,
ResolvedTarget,
EngineRuntimeConfig,
TargetConfig,
} from "./types";
import { dirname, resolve } from "node:path";
import type { DefaultsConfig, EngineRuntimeConfig, ProbeConfig, ResolvedTarget, TargetConfig } from "./types";
import { checkerRegistry } from "./runner";
const DEFAULT_HOST = "127.0.0.1";
@@ -16,11 +12,11 @@ const DEFAULT_TIMEOUT = "10s";
const DEFAULT_MAX_CONCURRENT_CHECKS = 20;
export interface ResolvedConfig {
host: string;
port: number;
dataDir: string;
configDir: string;
dataDir: string;
host: string;
maxConcurrentChecks: number;
port: number;
targets: ResolvedTarget[];
}
@@ -32,7 +28,7 @@ export async function loadConfig(configPath: string): Promise<ResolvedConfig> {
}
const content = await file.text();
const raw = Bun.YAML.parse(content) as ProbeConfig | null;
const raw = Bun.YAML.parse(content) as null | ProbeConfig;
if (!raw) {
throw new Error("配置文件内容为空或格式无效");
@@ -61,21 +57,7 @@ export async function loadConfig(configPath: string): Promise<ResolvedConfig> {
resolveTarget(target, defaults, defaultIntervalMs, defaultTimeoutMs, configDir),
);
return { host, port, dataDir, configDir, maxConcurrentChecks, targets };
}
function validateRuntime(runtime: EngineRuntimeConfig): number {
if (runtime.maxConcurrentChecks === undefined) return DEFAULT_MAX_CONCURRENT_CHECKS;
if (
typeof runtime.maxConcurrentChecks !== "number" ||
!Number.isInteger(runtime.maxConcurrentChecks) ||
runtime.maxConcurrentChecks <= 0
) {
throw new Error("runtime.maxConcurrentChecks 必须为正整数");
}
return runtime.maxConcurrentChecks;
return { configDir, dataDir, host, maxConcurrentChecks, port, targets };
}
function resolveTarget(
@@ -89,7 +71,7 @@ function resolveTarget(
const timeoutMs = parseDuration(target.timeout ?? defaults.timeout ?? DEFAULT_TIMEOUT);
const checker = checkerRegistry.get(target.type);
const result = checker.resolve(target, { defaults, configDir, defaultIntervalMs, defaultTimeoutMs });
const result = checker.resolve(target, { configDir, defaultIntervalMs, defaults, defaultTimeoutMs });
result.intervalMs = intervalMs;
result.timeoutMs = timeoutMs;
@@ -109,7 +91,7 @@ function validateConfig(config: ProbeConfig): void {
const raw = config.targets[i] as unknown as Record<string, unknown>;
const name = raw["name"];
if (!name || typeof name !== "string" || (name as string).trim() === "") {
if (!name || typeof name !== "string" || name.trim() === "") {
throw new Error(`${i + 1} 个 target 缺少 name 字段`);
}
@@ -127,14 +109,28 @@ function validateConfig(config: ProbeConfig): void {
throw new Error(`target "${name}" 的 group 字段必须为字符串`);
}
if (names.has(name as string)) {
if (names.has(name)) {
throw new Error(`target name 重复: "${name}"`);
}
names.add(name as string);
names.add(name);
}
}
function validateRuntime(runtime: EngineRuntimeConfig): number {
if (runtime.maxConcurrentChecks === undefined) return DEFAULT_MAX_CONCURRENT_CHECKS;
if (
typeof runtime.maxConcurrentChecks !== "number" ||
!Number.isInteger(runtime.maxConcurrentChecks) ||
runtime.maxConcurrentChecks <= 0
) {
throw new Error("runtime.maxConcurrentChecks 必须为正整数");
}
return runtime.maxConcurrentChecks;
}
const DURATION_REGEX = /^(\d+(?:\.\d+)?)(ms|s|m)$/;
export function parseDuration(value: string): number {