统一前后端代码格式化配置

This commit is contained in:
yml2213
2026-08-16 17:27:12 +08:00
parent 8705f6a6a1
commit 5c7c3e14e3
278 changed files with 6386 additions and 5500 deletions
+108 -115
View File
@@ -1,37 +1,40 @@
import type { Request, Response } from "express";
import { logError, logWarn } from "./logger.js";
import type { Request, Response } from 'express'
import { logError, logWarn } from './logger.js'
const RESPONSE_TIME_ZONE = "Asia/Shanghai";
const RESPONSE_TIME_ZONE = 'Asia/Shanghai'
export type HttpErrorLike = {
statusCode?: number;
errorCode?: string;
cause?: unknown;
context?: unknown;
[key: string]: unknown;
};
statusCode?: number
errorCode?: string
cause?: unknown
context?: unknown
[key: string]: unknown
}
type CreateHttpErrorOptions = {
statusCode?: number;
errorCode?: string;
cause?: unknown;
context?: unknown;
};
statusCode?: number
errorCode?: string
cause?: unknown
context?: unknown
}
export function buildSuccessPayload(data: unknown, msg: string = "ok") {
export function buildSuccessPayload(data: unknown, msg: string = 'ok') {
return {
code: 0,
msg,
time: Math.floor(Date.now() / 1000),
data: normalizeResponseDateTime(data),
};
}
}
export function buildErrorPayload(error: unknown, fallbackMessage: string) {
const classification = classifyRouteError(error);
const message = classification.statusCode >= 500
? fallbackMessage || "服务内部错误"
: error instanceof Error ? error.message : fallbackMessage;
const classification = classifyRouteError(error)
const message =
classification.statusCode >= 500
? fallbackMessage || '服务内部错误'
: error instanceof Error
? error.message
: fallbackMessage
return {
code: 1,
@@ -39,25 +42,23 @@ export function buildErrorPayload(error: unknown, fallbackMessage: string) {
errorCode: classification.errorCode,
time: Math.floor(Date.now() / 1000),
data: null as null,
};
}
}
export function sendRouteError(
res: Response,
error: unknown,
fallbackMessage = "服务内部错误",
scope = "[route]"
fallbackMessage = '服务内部错误',
scope = '[route]',
): void {
const classification = classifyRouteError(error);
const logger = classification.statusCode >= 500 ? logError : logWarn;
const classification = classifyRouteError(error)
const logger = classification.statusCode >= 500 ? logError : logWarn
logger(scope, fallbackMessage, {
statusCode: classification.statusCode,
errorCode: classification.errorCode,
error,
});
res
.status(classification.statusCode)
.json(buildErrorPayload(error, fallbackMessage));
})
res.status(classification.statusCode).json(buildErrorPayload(error, fallbackMessage))
}
export function buildNotFoundPayload(req: Request) {
@@ -66,201 +67,193 @@ export function buildNotFoundPayload(req: Request) {
msg: `未实现接口: ${req.method} ${req.originalUrl}`,
time: Math.floor(Date.now() / 1000),
data: null as null,
};
}
}
export function createHttpError(
message: string,
options: CreateHttpErrorOptions = {}
options: CreateHttpErrorOptions = {},
): Error & HttpErrorLike {
const { statusCode = 500, errorCode = "", cause, context } = options;
const error = new Error(message) as Error & HttpErrorLike;
error.statusCode = statusCode;
error.errorCode = errorCode || defaultErrorCodeForStatus(statusCode);
const { statusCode = 500, errorCode = '', cause, context } = options
const error = new Error(message) as Error & HttpErrorLike
error.statusCode = statusCode
error.errorCode = errorCode || defaultErrorCodeForStatus(statusCode)
if (typeof cause !== "undefined") {
error.cause = cause;
if (typeof cause !== 'undefined') {
error.cause = cause
}
if (typeof context !== "undefined") {
error.context = context;
if (typeof context !== 'undefined') {
error.context = context
}
return error;
return error
}
function classifyRouteError(error: unknown): {
statusCode: number;
errorCode: string;
statusCode: number
errorCode: string
} {
if (error && typeof error === "object") {
const currentError = error as HttpErrorLike;
const statusCode = Number(currentError.statusCode);
const errorCode = String(currentError.errorCode || "").trim();
if (error && typeof error === 'object') {
const currentError = error as HttpErrorLike
const statusCode = Number(currentError.statusCode)
const errorCode = String(currentError.errorCode || '').trim()
if (Number.isInteger(statusCode) && statusCode >= 400 && statusCode < 600) {
return {
statusCode,
errorCode: errorCode || defaultErrorCodeForStatus(statusCode),
};
}
}
}
const message = error instanceof Error ? error.message : String(error || "");
const message = error instanceof Error ? error.message : String(error || '')
if (
message.includes("缺少") ||
message.includes("无效") ||
message.includes("验签失败")
) {
return { statusCode: 400, errorCode: "invalid_request" };
if (message.includes('缺少') || message.includes('无效') || message.includes('验签失败')) {
return { statusCode: 400, errorCode: 'invalid_request' }
}
if (message.includes("不存在")) {
return { statusCode: 404, errorCode: "not_found" };
if (message.includes('不存在')) {
return { statusCode: 404, errorCode: 'not_found' }
}
if (message.includes("已关闭")) {
return { statusCode: 410, errorCode: "gone" };
if (message.includes('已关闭')) {
return { statusCode: 410, errorCode: 'gone' }
}
if (message.includes("不能") || message.includes("冲突")) {
return { statusCode: 409, errorCode: "conflict" };
if (message.includes('不能') || message.includes('冲突')) {
return { statusCode: 409, errorCode: 'conflict' }
}
return { statusCode: 500, errorCode: "internal_error" };
return { statusCode: 500, errorCode: 'internal_error' }
}
function defaultErrorCodeForStatus(statusCode: number): string {
if (statusCode === 400) {
return "invalid_request";
return 'invalid_request'
}
if (statusCode === 401) {
return "unauthorized";
return 'unauthorized'
}
if (statusCode === 403) {
return "forbidden";
return 'forbidden'
}
if (statusCode === 404) {
return "not_found";
return 'not_found'
}
if (statusCode === 409) {
return "conflict";
return 'conflict'
}
if (statusCode === 410) {
return "gone";
return 'gone'
}
if (statusCode === 503) {
return "dependency_unavailable";
return 'dependency_unavailable'
}
return "internal_error";
return 'internal_error'
}
function normalizeResponseDateTime(value: unknown): unknown {
if (value instanceof Date) {
return formatResponseDateTime(value.toISOString());
return formatResponseDateTime(value.toISOString())
}
if (Array.isArray(value)) {
return value.map((item) => normalizeResponseDateTime(item));
return value.map((item) => normalizeResponseDateTime(item))
}
if (value && typeof value === "object") {
if (value && typeof value === 'object') {
return Object.fromEntries(
Object.entries(value).map(([key, currentValue]) => [
key,
normalizeResponseDateTime(currentValue),
])
);
]),
)
}
if (isIsoDateTimeString(value)) {
return formatResponseDateTime(value as string);
return formatResponseDateTime(value as string)
}
return value;
return value
}
function isIsoDateTimeString(value: unknown): boolean {
return (
typeof value === "string" &&
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?$/.test(
value.trim()
)
);
typeof value === 'string' &&
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?$/.test(value.trim())
)
}
function formatResponseDateTime(value: string): string {
const date = new Date(value);
const date = new Date(value)
if (Number.isNaN(date.getTime())) {
return String(value || "")
.replace("T", " ")
.replace("Z", "");
return String(value || '')
.replace('T', ' ')
.replace('Z', '')
}
const parts = new Intl.DateTimeFormat("zh-CN", {
const parts = new Intl.DateTimeFormat('zh-CN', {
timeZone: RESPONSE_TIME_ZONE,
hour12: false,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}).formatToParts(date);
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
}).formatToParts(date)
const tokens = Object.fromEntries(
parts
.filter((item) => item.type !== "literal")
.map((item) => [item.type, item.value])
);
parts.filter((item) => item.type !== 'literal').map((item) => [item.type, item.value]),
)
return `${tokens.year}-${tokens.month}-${tokens.day} ${tokens.hour}:${tokens.minute}:${tokens.second}`;
return `${tokens.year}-${tokens.month}-${tokens.day} ${tokens.hour}:${tokens.minute}:${tokens.second}`
}
type RouteHandlerOptions = {
successMessage?: string;
errorMessage?: string;
scope?: string;
};
successMessage?: string
errorMessage?: string
scope?: string
}
type RouteFileHandlerOptions = {
errorMessage?: string;
scope?: string;
};
errorMessage?: string
scope?: string
}
export function createRouteHandler(
action: (req: Request, res: Response) => unknown | Promise<unknown>,
{ successMessage = "ok", errorMessage, scope }: RouteHandlerOptions = {}
{ successMessage = 'ok', errorMessage, scope }: RouteHandlerOptions = {},
) {
return async (req: Request, res: Response): Promise<void> => {
try {
const data = await action(req, res);
res.json(buildSuccessPayload(data, successMessage));
const data = await action(req, res)
res.json(buildSuccessPayload(data, successMessage))
} catch (error) {
sendRouteError(res, error, errorMessage, scope);
sendRouteError(res, error, errorMessage, scope)
}
};
}
}
export function createRouteFileHandler(
action: (req: Request, res: Response) => string | Promise<string>,
{ errorMessage, scope }: RouteFileHandlerOptions = {}
{ errorMessage, scope }: RouteFileHandlerOptions = {},
) {
return async (req: Request, res: Response): Promise<void> => {
try {
const filePath = await action(req, res);
res.sendFile(filePath);
const filePath = await action(req, res)
res.sendFile(filePath)
} catch (error) {
sendRouteError(res, error, errorMessage, scope);
sendRouteError(res, error, errorMessage, scope)
}
};
}
}
+7 -5
View File
@@ -175,9 +175,7 @@ function enqueueFileWrite(
sanitize: boolean,
jsonLine = false,
): void {
const line = jsonLine
? JSON.stringify(entry)
: formatLogEntry(entry, { color: false, sanitize })
const line = jsonLine ? JSON.stringify(entry) : formatLogEntry(entry, { color: false, sanitize })
const dateKey = extractLogDateKey(entry.time)
writeQueue = writeQueue
@@ -279,7 +277,9 @@ export function resolveLogFilePath(channel = 'app', time = new Date().toISOStrin
}
function normalizeLogChannelName(value: unknown): string {
const normalized = String(value || '').trim().toLowerCase()
const normalized = String(value || '')
.trim()
.toLowerCase()
if (!normalized) {
return 'app'
}
@@ -344,7 +344,9 @@ function normalizeLogValue(value: unknown, sanitize = true): unknown {
try {
return sanitize
? sanitizeLogValue(JSON.parse(JSON.stringify(value, (_key, current) => normalizeCurrent(current))))
? sanitizeLogValue(
JSON.parse(JSON.stringify(value, (_key, current) => normalizeCurrent(current))),
)
: JSON.parse(JSON.stringify(value, (_key, current) => normalizeCurrent(current)))
} catch {
return sanitize ? sanitizeLogString(String(value)) : String(value)
+2 -6
View File
@@ -21,14 +21,10 @@ export function parseJsonObject(value: unknown): JsonObject {
}
}
export function parseTaskContext(
task: { context_json?: unknown } | null | undefined,
): TaskContext {
export function parseTaskContext(task: { context_json?: unknown } | null | undefined): TaskContext {
return parseJsonObject(task?.context_json) as TaskContext
}
export function parseTaskState(
task: { state_json?: unknown } | null | undefined,
): JsonObject {
export function parseTaskState(task: { state_json?: unknown } | null | undefined): JsonObject {
return parseJsonObject(task?.state_json)
}