chore(frontend): introduce prettier + eslint and prune unused code
- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports) - Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier - Add root scripts: format, format:check, lint, lint:fix - Reformat 257 files across admin-web, ops-web, desktop-client, packages - Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters - Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex - Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,35 +1,35 @@
|
||||
function normalizeText(value: string | null | undefined): string {
|
||||
return value?.trim() ?? "";
|
||||
return value?.trim() ?? ''
|
||||
}
|
||||
|
||||
export function normalizeAccountPlatformUid(value: string | null | undefined): string {
|
||||
let normalized = normalizeText(value);
|
||||
while (normalized.toLowerCase().startsWith("platform:")) {
|
||||
normalized = normalized.slice("platform:".length).trim();
|
||||
let normalized = normalizeText(value)
|
||||
while (normalized.toLowerCase().startsWith('platform:')) {
|
||||
normalized = normalized.slice('platform:'.length).trim()
|
||||
}
|
||||
return normalized;
|
||||
return normalized
|
||||
}
|
||||
|
||||
export function sameAccountPlatformUid(
|
||||
left: string | null | undefined,
|
||||
right: string | null | undefined,
|
||||
): boolean {
|
||||
const normalizedLeft = normalizeAccountPlatformUid(left);
|
||||
const normalizedRight = normalizeAccountPlatformUid(right);
|
||||
return Boolean(normalizedLeft) && normalizedLeft === normalizedRight;
|
||||
const normalizedLeft = normalizeAccountPlatformUid(left)
|
||||
const normalizedRight = normalizeAccountPlatformUid(right)
|
||||
return Boolean(normalizedLeft) && normalizedLeft === normalizedRight
|
||||
}
|
||||
|
||||
export function buildAccountIdentityKey(input: {
|
||||
platform: string;
|
||||
platformUid?: string | null;
|
||||
displayName?: string | null;
|
||||
platform: string
|
||||
platformUid?: string | null
|
||||
displayName?: string | null
|
||||
}): string {
|
||||
const platform = normalizeText(input.platform).toLowerCase() || "unknown";
|
||||
const platformUid = normalizeAccountPlatformUid(input.platformUid);
|
||||
const platform = normalizeText(input.platform).toLowerCase() || 'unknown'
|
||||
const platformUid = normalizeAccountPlatformUid(input.platformUid)
|
||||
if (platformUid) {
|
||||
return `${platform}:${platformUid}`;
|
||||
return `${platform}:${platformUid}`
|
||||
}
|
||||
|
||||
const normalizedName = normalizeText(input.displayName).replace(/\s+/g, "").toLowerCase();
|
||||
return `${platform}:name:${normalizedName || "unknown"}`;
|
||||
const normalizedName = normalizeText(input.displayName).replace(/\s+/g, '').toLowerCase()
|
||||
return `${platform}:name:${normalizedName || 'unknown'}`
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
export type DesktopObservedRequestPhase = "request" | "response" | "close" | "error";
|
||||
export type DesktopObservedRequestPhase = 'request' | 'response' | 'close' | 'error'
|
||||
|
||||
export type DesktopObservedRequestKind = "http" | "sse" | "ws";
|
||||
export type DesktopObservedRequestKind = 'http' | 'sse' | 'ws'
|
||||
|
||||
export type DesktopObservedRequestSource = "session" | "main" | "transport";
|
||||
export type DesktopObservedRequestSource = 'session' | 'main' | 'transport'
|
||||
|
||||
export interface DesktopObservedRequest {
|
||||
id: string;
|
||||
at: number;
|
||||
phase: DesktopObservedRequestPhase;
|
||||
kind: DesktopObservedRequestKind;
|
||||
source: DesktopObservedRequestSource;
|
||||
label: string;
|
||||
method: string;
|
||||
url: string;
|
||||
partition: string | null;
|
||||
resourceType: string | null;
|
||||
status: number | null;
|
||||
durationMs: number | null;
|
||||
error: string | null;
|
||||
id: string
|
||||
at: number
|
||||
phase: DesktopObservedRequestPhase
|
||||
kind: DesktopObservedRequestKind
|
||||
source: DesktopObservedRequestSource
|
||||
label: string
|
||||
method: string
|
||||
url: string
|
||||
partition: string | null
|
||||
resourceType: string | null
|
||||
status: number | null
|
||||
durationMs: number | null
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export interface DesktopObservedRequestSnapshot {
|
||||
rendererAttached: boolean;
|
||||
activeCount: number;
|
||||
recent: DesktopObservedRequest[];
|
||||
rendererAttached: boolean
|
||||
activeCount: number
|
||||
recent: DesktopObservedRequest[]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import {
|
||||
PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE,
|
||||
@@ -13,73 +13,79 @@ import {
|
||||
normalizeQiehaoPublishErrorMessage,
|
||||
normalizeWangyihaoPublishErrorMessage,
|
||||
normalizeWeixinGzhPublishErrorMessage,
|
||||
} from "./publisher-errors";
|
||||
} from './publisher-errors'
|
||||
|
||||
describe("publisher error normalization", () => {
|
||||
it("normalizes Qiehao real-name authentication failures from raw platform text", () => {
|
||||
describe('publisher error normalization', () => {
|
||||
it('normalizes Qiehao real-name authentication failures from raw platform text', () => {
|
||||
expect(
|
||||
normalizePublisherErrorMessage("type:business, code:-5022, msg:user is not real name authentication"),
|
||||
).toBe(QIEHAO_REAL_NAME_AUTH_MESSAGE);
|
||||
});
|
||||
normalizePublisherErrorMessage(
|
||||
'type:business, code:-5022, msg:user is not real name authentication',
|
||||
),
|
||||
).toBe(QIEHAO_REAL_NAME_AUTH_MESSAGE)
|
||||
})
|
||||
|
||||
it("recognizes Qiehao real-name authentication failures by business code", () => {
|
||||
expect(isQiehaoRealNameAuthError("publish rejected", -5022)).toBe(true);
|
||||
expect(normalizeQiehaoPublishErrorMessage("publish rejected", -5022)).toBe(QIEHAO_REAL_NAME_AUTH_MESSAGE);
|
||||
});
|
||||
it('recognizes Qiehao real-name authentication failures by business code', () => {
|
||||
expect(isQiehaoRealNameAuthError('publish rejected', -5022)).toBe(true)
|
||||
expect(normalizeQiehaoPublishErrorMessage('publish rejected', -5022)).toBe(
|
||||
QIEHAO_REAL_NAME_AUTH_MESSAGE,
|
||||
)
|
||||
})
|
||||
|
||||
it("normalizes publisher login-state failures", () => {
|
||||
expect(normalizePublisherErrorMessage("wangyihao_not_logged_in")).toBe(
|
||||
"网易号账号登录态已失效,请重新登录该平台后再重试。",
|
||||
);
|
||||
expect(normalizePublisherErrorMessage("Error: weixin_gzh_not_logged_in")).toBe(
|
||||
"微信公众号账号登录态已失效,请重新登录该平台后再重试。",
|
||||
);
|
||||
expect(normalizePublisherErrorMessage("qiehao_cookie_missing")).toBe(
|
||||
"企鹅号账号登录态已失效,请重新登录该平台后再重试。",
|
||||
);
|
||||
});
|
||||
it('normalizes publisher login-state failures', () => {
|
||||
expect(normalizePublisherErrorMessage('wangyihao_not_logged_in')).toBe(
|
||||
'网易号账号登录态已失效,请重新登录该平台后再重试。',
|
||||
)
|
||||
expect(normalizePublisherErrorMessage('Error: weixin_gzh_not_logged_in')).toBe(
|
||||
'微信公众号账号登录态已失效,请重新登录该平台后再重试。',
|
||||
)
|
||||
expect(normalizePublisherErrorMessage('qiehao_cookie_missing')).toBe(
|
||||
'企鹅号账号登录态已失效,请重新登录该平台后再重试。',
|
||||
)
|
||||
})
|
||||
|
||||
it("uses a generic Chinese message for unknown publisher login-state failures", () => {
|
||||
expect(normalizePublisherLoginErrorMessage("unknown_platform_not_logged_in")).toBe(
|
||||
it('uses a generic Chinese message for unknown publisher login-state failures', () => {
|
||||
expect(normalizePublisherLoginErrorMessage('unknown_platform_not_logged_in')).toBe(
|
||||
PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE,
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it("normalizes Wangyihao token missing failures", () => {
|
||||
expect(normalizePublisherErrorMessage("wangyihao_token_missing")).toBe(WANGYIHAO_TOKEN_MISSING_MESSAGE);
|
||||
expect(normalizeWangyihaoPublishErrorMessage("Error: wangyihao_token_missing")).toBe(
|
||||
it('normalizes Wangyihao token missing failures', () => {
|
||||
expect(normalizePublisherErrorMessage('wangyihao_token_missing')).toBe(
|
||||
WANGYIHAO_TOKEN_MISSING_MESSAGE,
|
||||
);
|
||||
});
|
||||
)
|
||||
expect(normalizeWangyihaoPublishErrorMessage('Error: wangyihao_token_missing')).toBe(
|
||||
WANGYIHAO_TOKEN_MISSING_MESSAGE,
|
||||
)
|
||||
})
|
||||
|
||||
it("normalizes Wangyihao draft parameter failures", () => {
|
||||
expect(normalizePublisherErrorMessage("wangyihao_draft_save_failed:wangyihao_error_100002")).toBe(
|
||||
it('normalizes Wangyihao draft parameter failures', () => {
|
||||
expect(
|
||||
normalizePublisherErrorMessage('wangyihao_draft_save_failed:wangyihao_error_100002'),
|
||||
).toBe(WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE)
|
||||
expect(normalizeWangyihaoPublishErrorMessage('wangyihao_draft_save_failed:参数错误')).toBe(
|
||||
WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE,
|
||||
);
|
||||
expect(normalizeWangyihaoPublishErrorMessage("wangyihao_draft_save_failed:参数错误")).toBe(
|
||||
WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE,
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it("normalizes Wangyihao publish click failures", () => {
|
||||
expect(normalizePublisherErrorMessage("wangyihao_publish_click_failed")).toBe(
|
||||
it('normalizes Wangyihao publish click failures', () => {
|
||||
expect(normalizePublisherErrorMessage('wangyihao_publish_click_failed')).toBe(
|
||||
WANGYIHAO_PUBLISH_CLICK_MESSAGE,
|
||||
);
|
||||
expect(normalizeWangyihaoPublishErrorMessage("wangyihao_publish_click_failed:未找到发布按钮")).toBe(
|
||||
WANGYIHAO_PUBLISH_CLICK_MESSAGE,
|
||||
);
|
||||
});
|
||||
)
|
||||
expect(
|
||||
normalizeWangyihaoPublishErrorMessage('wangyihao_publish_click_failed:未找到发布按钮'),
|
||||
).toBe(WANGYIHAO_PUBLISH_CLICK_MESSAGE)
|
||||
})
|
||||
|
||||
it("normalizes Weixin GZH missing public URL failures", () => {
|
||||
expect(normalizePublisherErrorMessage("weixin_gzh_public_url_missing:100000093")).toBe(
|
||||
it('normalizes Weixin GZH missing public URL failures', () => {
|
||||
expect(normalizePublisherErrorMessage('weixin_gzh_public_url_missing:100000093')).toBe(
|
||||
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
);
|
||||
expect(normalizeWeixinGzhPublishErrorMessage("Error: weixin_gzh_public_url_missing")).toBe(
|
||||
)
|
||||
expect(normalizeWeixinGzhPublishErrorMessage('Error: weixin_gzh_public_url_missing')).toBe(
|
||||
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it("leaves unknown publisher errors unchanged", () => {
|
||||
expect(normalizePublisherErrorMessage("qiehao_publish_failed")).toBe("qiehao_publish_failed");
|
||||
});
|
||||
});
|
||||
it('leaves unknown publisher errors unchanged', () => {
|
||||
expect(normalizePublisherErrorMessage('qiehao_publish_failed')).toBe('qiehao_publish_failed')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,119 +1,132 @@
|
||||
export const QIEHAO_REAL_NAME_AUTH_MESSAGE = "企鹅号账号未完成实名认证,请先到企鹅号后台完成实名认证后再重试。";
|
||||
export const PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE = "发布账号登录态已失效,请重新打开平台后台完成登录后再重试。";
|
||||
export const WANGYIHAO_TOKEN_MISSING_MESSAGE = "网易号发布凭证获取失败,请重新打开网易号后台确认登录状态。";
|
||||
export const QIEHAO_REAL_NAME_AUTH_MESSAGE =
|
||||
'企鹅号账号未完成实名认证,请先到企鹅号后台完成实名认证后再重试。'
|
||||
export const PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE =
|
||||
'发布账号登录态已失效,请重新打开平台后台完成登录后再重试。'
|
||||
export const WANGYIHAO_TOKEN_MISSING_MESSAGE =
|
||||
'网易号发布凭证获取失败,请重新打开网易号后台确认登录状态。'
|
||||
export const WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE =
|
||||
"网易号草稿保存失败:参数错误。请检查标题、正文、封面或账号状态后重试。";
|
||||
'网易号草稿保存失败:参数错误。请检查标题、正文、封面或账号状态后重试。'
|
||||
export const WANGYIHAO_PUBLISH_CLICK_MESSAGE =
|
||||
"网易号草稿已保存,但自动发布未完成。请打开网易号后台确认草稿状态后重试。";
|
||||
'网易号草稿已保存,但自动发布未完成。请打开网易号后台确认草稿状态后重试。'
|
||||
export const WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE =
|
||||
"微信公众号可能已触发管理员/运营者授权发布,桌面端未能获取到文章外链。请打开公众号后台完成授权发布,并在发表记录中确认文章链接。";
|
||||
'微信公众号可能已触发管理员/运营者授权发布,桌面端未能获取到文章外链。请打开公众号后台完成授权发布,并在发表记录中确认文章链接。'
|
||||
|
||||
const PUBLISH_PLATFORM_LABELS: Record<string, string> = {
|
||||
baijiahao: "百家号",
|
||||
bilibili: "bilibili",
|
||||
dongchedi: "懂车帝",
|
||||
jianshu: "简书",
|
||||
juejin: "稀土掘金",
|
||||
qiehao: "企鹅号",
|
||||
smzdm: "什么值得买",
|
||||
sohuhao: "搜狐号",
|
||||
toutiaohao: "头条号",
|
||||
wangyihao: "网易号",
|
||||
weixin_gzh: "微信公众号",
|
||||
zhihu: "知乎",
|
||||
zol: "中关村在线",
|
||||
};
|
||||
baijiahao: '百家号',
|
||||
bilibili: 'bilibili',
|
||||
dongchedi: '懂车帝',
|
||||
jianshu: '简书',
|
||||
juejin: '稀土掘金',
|
||||
qiehao: '企鹅号',
|
||||
smzdm: '什么值得买',
|
||||
sohuhao: '搜狐号',
|
||||
toutiaohao: '头条号',
|
||||
wangyihao: '网易号',
|
||||
weixin_gzh: '微信公众号',
|
||||
zhihu: '知乎',
|
||||
zol: '中关村在线',
|
||||
}
|
||||
|
||||
function normalizeErrorText(value: string | null | undefined): string | null {
|
||||
const trimmed = value?.trim();
|
||||
return trimmed ? trimmed : null;
|
||||
const trimmed = value?.trim()
|
||||
return trimmed ? trimmed : null
|
||||
}
|
||||
|
||||
export function isQiehaoRealNameAuthError(
|
||||
message: string | null | undefined,
|
||||
code?: number | string | null,
|
||||
): boolean {
|
||||
const codeText = code == null ? "" : String(code).trim();
|
||||
if (codeText === "-5022" || codeText === "5022") {
|
||||
return true;
|
||||
const codeText = code == null ? '' : String(code).trim()
|
||||
if (codeText === '-5022' || codeText === '5022') {
|
||||
return true
|
||||
}
|
||||
|
||||
const normalized = normalizeErrorText(message);
|
||||
const normalized = normalizeErrorText(message)
|
||||
if (!normalized) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
return /^qiehao_real_name_auth_required\b/i.test(normalized)
|
||||
|| /\bcode\s*:\s*-?5022\b/i.test(normalized)
|
||||
|| /user\s+is\s+not\s+real\s+name\s+authentication/i.test(normalized)
|
||||
|| /(?:未|没有|尚未).{0,8}实名/.test(normalized)
|
||||
|| /请.{0,8}实名认证/.test(normalized);
|
||||
return (
|
||||
/^qiehao_real_name_auth_required\b/i.test(normalized) ||
|
||||
/\bcode\s*:\s*-?5022\b/i.test(normalized) ||
|
||||
/user\s+is\s+not\s+real\s+name\s+authentication/i.test(normalized) ||
|
||||
/(?:未|没有|尚未).{0,8}实名/.test(normalized) ||
|
||||
/请.{0,8}实名认证/.test(normalized)
|
||||
)
|
||||
}
|
||||
|
||||
export function normalizeQiehaoPublishErrorMessage(
|
||||
message: string | null | undefined,
|
||||
code?: number | string | null,
|
||||
): string | null {
|
||||
const normalized = normalizeErrorText(message);
|
||||
const normalized = normalizeErrorText(message)
|
||||
if (!normalized) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
return isQiehaoRealNameAuthError(normalized, code) ? QIEHAO_REAL_NAME_AUTH_MESSAGE : normalized;
|
||||
return isQiehaoRealNameAuthError(normalized, code) ? QIEHAO_REAL_NAME_AUTH_MESSAGE : normalized
|
||||
}
|
||||
|
||||
export function normalizePublisherLoginErrorMessage(message: string | null | undefined): string | null {
|
||||
const normalized = normalizeErrorText(message);
|
||||
export function normalizePublisherLoginErrorMessage(
|
||||
message: string | null | undefined,
|
||||
): string | null {
|
||||
const normalized = normalizeErrorText(message)
|
||||
if (!normalized) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
const match = normalized.match(
|
||||
/\b([a-z0-9_]+?)_(not_logged_in|token_missing|cookie_missing|csrf_missing)\b/i,
|
||||
);
|
||||
)
|
||||
if (!match) {
|
||||
return normalized;
|
||||
return normalized
|
||||
}
|
||||
|
||||
const platformLabel = PUBLISH_PLATFORM_LABELS[match[1]?.toLowerCase() ?? ""];
|
||||
return platformLabel ? `${platformLabel}账号登录态已失效,请重新登录该平台后再重试。` : PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE;
|
||||
const platformLabel = PUBLISH_PLATFORM_LABELS[match[1]?.toLowerCase() ?? '']
|
||||
return platformLabel
|
||||
? `${platformLabel}账号登录态已失效,请重新登录该平台后再重试。`
|
||||
: PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE
|
||||
}
|
||||
|
||||
export function normalizeWangyihaoPublishErrorMessage(message: string | null | undefined): string | null {
|
||||
const normalized = normalizeErrorText(message);
|
||||
export function normalizeWangyihaoPublishErrorMessage(
|
||||
message: string | null | undefined,
|
||||
): string | null {
|
||||
const normalized = normalizeErrorText(message)
|
||||
if (!normalized) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
if (/\bwangyihao_token_missing\b/i.test(normalized)) {
|
||||
return WANGYIHAO_TOKEN_MISSING_MESSAGE;
|
||||
return WANGYIHAO_TOKEN_MISSING_MESSAGE
|
||||
}
|
||||
if (
|
||||
/\bwangyihao_error_100002\b/i.test(normalized)
|
||||
|| /\bwangyihao_draft_save_failed:.*参数错误/i.test(normalized)
|
||||
/\bwangyihao_error_100002\b/i.test(normalized) ||
|
||||
/\bwangyihao_draft_save_failed:.*参数错误/i.test(normalized)
|
||||
) {
|
||||
return WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE;
|
||||
return WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE
|
||||
}
|
||||
if (/\bwangyihao_publish_click_failed\b/i.test(normalized)) {
|
||||
return WANGYIHAO_PUBLISH_CLICK_MESSAGE;
|
||||
return WANGYIHAO_PUBLISH_CLICK_MESSAGE
|
||||
}
|
||||
return normalized;
|
||||
return normalized
|
||||
}
|
||||
|
||||
export function normalizeWeixinGzhPublishErrorMessage(message: string | null | undefined): string | null {
|
||||
const normalized = normalizeErrorText(message);
|
||||
export function normalizeWeixinGzhPublishErrorMessage(
|
||||
message: string | null | undefined,
|
||||
): string | null {
|
||||
const normalized = normalizeErrorText(message)
|
||||
if (!normalized) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
if (/\bweixin_gzh_public_url_missing\b/i.test(normalized)) {
|
||||
return WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE;
|
||||
return WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE
|
||||
}
|
||||
return normalized;
|
||||
return normalized
|
||||
}
|
||||
|
||||
export function normalizePublisherErrorMessage(message: string | null | undefined): string | null {
|
||||
const qiehaoMessage = normalizeQiehaoPublishErrorMessage(message);
|
||||
const wangyihaoMessage = normalizeWangyihaoPublishErrorMessage(qiehaoMessage);
|
||||
const loginMessage = normalizePublisherLoginErrorMessage(wangyihaoMessage);
|
||||
return normalizeWeixinGzhPublishErrorMessage(loginMessage);
|
||||
const qiehaoMessage = normalizeQiehaoPublishErrorMessage(message)
|
||||
const wangyihaoMessage = normalizeWangyihaoPublishErrorMessage(qiehaoMessage)
|
||||
const loginMessage = normalizePublisherLoginErrorMessage(wangyihaoMessage)
|
||||
return normalizeWeixinGzhPublishErrorMessage(loginMessage)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user