chore(deps): lock file maintenance npm dependencies (#6119)

* chore(deps): lock file maintenance npm dependencies

* chore: run pnpm update

* fix(components): satisfy ESLint destructuring and narrow unknown errors

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Slinetrac <realakayuki@gmail.com>
This commit is contained in:
renovate[bot]
2026-01-19 12:05:48 +08:00
committed by GitHub
parent 6dc8a2f232
commit 98f12a9c72
4 changed files with 959 additions and 951 deletions

View File

@@ -48,9 +48,9 @@
"@tanstack/react-virtual": "^3.13.18",
"@tauri-apps/api": "2.9.1",
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
"@tauri-apps/plugin-dialog": "^2.5.0",
"@tauri-apps/plugin-dialog": "^2.6.0",
"@tauri-apps/plugin-fs": "^2.4.5",
"@tauri-apps/plugin-http": "~2.5.5",
"@tauri-apps/plugin-http": "~2.5.6",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-shell": "2.3.4",
"@tauri-apps/plugin-updater": "2.9.0",
@@ -66,9 +66,9 @@
"nanoid": "^5.1.6",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-error-boundary": "6.0.3",
"react-hook-form": "^7.71.0",
"react-i18next": "16.5.2",
"react-error-boundary": "6.1.0",
"react-hook-form": "^7.71.1",
"react-i18next": "16.5.3",
"react-markdown": "10.1.0",
"react-router": "^7.12.0",
"react-virtuoso": "^4.18.1",
@@ -79,12 +79,12 @@
},
"devDependencies": {
"@actions/github": "^7.0.0",
"@eslint-react/eslint-plugin": "^2.5.5",
"@eslint-react/eslint-plugin": "^2.7.2",
"@eslint/js": "^9.39.2",
"@tauri-apps/cli": "2.9.6",
"@types/js-yaml": "^4.0.9",
"@types/lodash-es": "^4.17.12",
"@types/node": "^24.10.7",
"@types/node": "^24.10.9",
"@types/react": "19.2.8",
"@types/react-dom": "19.2.3",
"@vitejs/plugin-legacy": "^7.2.1",
@@ -97,7 +97,7 @@
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import-x": "^4.16.1",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-react-compiler": "19.1.0-rc.2",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.26",
@@ -109,12 +109,12 @@
"jiti": "^2.6.1",
"lint-staged": "^16.2.7",
"node-fetch": "^3.3.2",
"prettier": "^3.7.4",
"prettier": "^3.8.0",
"sass": "^1.97.2",
"tar": "^7.5.2",
"terser": "^5.44.1",
"tar": "^7.5.3",
"terser": "^5.46.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.52.0",
"typescript-eslint": "^8.53.0",
"vite": "^7.3.1",
"vite-plugin-svgr": "^4.5.0"
},

1582
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,15 +2,18 @@ import { ReactNode } from "react";
import { ErrorBoundary, FallbackProps } from "react-error-boundary";
function ErrorFallback({ error }: FallbackProps) {
const errorMessage = error instanceof Error ? error.message : String(error);
const errorStack = error instanceof Error ? error.stack : undefined;
return (
<div role="alert" style={{ padding: 16 }}>
<h4>Something went wrong:(</h4>
<pre>{error.message}</pre>
<pre>{errorMessage}</pre>
<details title="Error Stack">
<summary>Error Stack</summary>
<pre>{error.stack}</pre>
<pre>{errorStack}</pre>
</details>
</div>
);

View File

@@ -19,157 +19,162 @@ export interface TestViewerRef {
}
// create or edit the test item
export const TestViewer = forwardRef<TestViewerRef, Props>((props, ref) => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [openType, setOpenType] = useState<"new" | "edit">("new");
const [loading, setLoading] = useState(false);
const { verge, patchVerge } = useVerge();
const testList = verge?.test_list ?? [];
const { control, ...formIns } = useForm<IVergeTestItem>({
defaultValues: {
name: "",
icon: "",
url: "",
},
});
const patchTestList = async (uid: string, patch: Partial<IVergeTestItem>) => {
const newList = testList.map((x) => {
if (x.uid === uid) {
return { ...x, ...patch };
}
return x;
export const TestViewer = forwardRef<TestViewerRef, Props>(
({ onChange }, ref) => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [openType, setOpenType] = useState<"new" | "edit">("new");
const [loading, setLoading] = useState(false);
const { verge, patchVerge } = useVerge();
const testList = verge?.test_list ?? [];
const { control, ...formIns } = useForm<IVergeTestItem>({
defaultValues: {
name: "",
icon: "",
url: "",
},
});
await patchVerge({ test_list: newList });
};
useImperativeHandle(ref, () => ({
create: () => {
setOpenType("new");
setOpen(true);
},
edit: (item) => {
if (item) {
Object.entries(item).forEach(([key, value]) => {
formIns.setValue(key as any, value);
});
}
setOpenType("edit");
setOpen(true);
},
}));
const handleOk = useLockFn(
formIns.handleSubmit(async (form) => {
setLoading(true);
try {
if (!form.name) throw new Error("`Name` should not be null");
if (!form.url) throw new Error("`Url` should not be null");
let newList;
let uid;
if (form.icon && form.icon.startsWith("<svg")) {
// 移除 icon 中的注释
if (form.icon) {
form.icon = form.icon.replace(/<!--[\s\S]*?-->/g, "");
}
const doc = new DOMParser().parseFromString(
form.icon,
"image/svg+xml",
);
if (doc.querySelector("parsererror")) {
throw new Error("`Icon`svg format error");
}
const patchTestList = async (
uid: string,
patch: Partial<IVergeTestItem>,
) => {
const newList = testList.map((x) => {
if (x.uid === uid) {
return { ...x, ...patch };
}
return x;
});
await patchVerge({ test_list: newList });
};
if (openType === "new") {
uid = nanoid();
const item = { ...form, uid };
newList = [...testList, item];
await patchVerge({ test_list: newList });
props.onChange(uid);
} else {
if (!form.uid) throw new Error("UID not found");
uid = form.uid;
await patchTestList(uid, form);
props.onChange(uid, form);
useImperativeHandle(ref, () => ({
create: () => {
setOpenType("new");
setOpen(true);
},
edit: (item) => {
if (item) {
Object.entries(item).forEach(([key, value]) => {
formIns.setValue(key as any, value);
});
}
setOpen(false);
setLoading(false);
setTimeout(() => formIns.reset(), 500);
} catch (err: any) {
showNotice.error(err);
setLoading(false);
}
}),
);
setOpenType("edit");
setOpen(true);
},
}));
const handleClose = () => {
setOpen(false);
setTimeout(() => formIns.reset(), 500);
};
const handleOk = useLockFn(
formIns.handleSubmit(async (form) => {
setLoading(true);
try {
if (!form.name) throw new Error("`Name` should not be null");
if (!form.url) throw new Error("`Url` should not be null");
const text = {
fullWidth: true,
size: "small",
margin: "normal",
variant: "outlined",
autoComplete: "off",
autoCorrect: "off",
} as const;
let newList;
let uid;
return (
<BaseDialog
open={open}
title={
openType === "new"
? t("tests.modals.test.title.create")
: t("tests.modals.test.title.edit")
}
contentSx={{ width: 375, pb: 0, maxHeight: "80%" }}
okBtn={t("shared.actions.save")}
cancelBtn={t("shared.actions.cancel")}
onClose={handleClose}
onCancel={handleClose}
onOk={handleOk}
loading={loading}
>
<Controller
name="name"
control={control}
render={({ field }) => (
<TextField {...text} {...field} label={t("shared.labels.name")} />
)}
/>
<Controller
name="icon"
control={control}
render={({ field }) => (
<TextField
{...text}
{...field}
multiline
maxRows={5}
label={t("shared.labels.icon")}
/>
)}
/>
<Controller
name="url"
control={control}
render={({ field }) => (
<TextField
{...text}
{...field}
multiline
maxRows={3}
label={t("tests.modals.test.fields.url")}
/>
)}
/>
</BaseDialog>
);
});
if (form.icon && form.icon.startsWith("<svg")) {
// 移除 icon 中的注释
if (form.icon) {
form.icon = form.icon.replace(/<!--[\s\S]*?-->/g, "");
}
const doc = new DOMParser().parseFromString(
form.icon,
"image/svg+xml",
);
if (doc.querySelector("parsererror")) {
throw new Error("`Icon`svg format error");
}
}
if (openType === "new") {
uid = nanoid();
const item = { ...form, uid };
newList = [...testList, item];
await patchVerge({ test_list: newList });
onChange(uid);
} else {
if (!form.uid) throw new Error("UID not found");
uid = form.uid;
await patchTestList(uid, form);
onChange(uid, form);
}
setOpen(false);
setLoading(false);
setTimeout(() => formIns.reset(), 500);
} catch (err: any) {
showNotice.error(err);
setLoading(false);
}
}),
);
const handleClose = () => {
setOpen(false);
setTimeout(() => formIns.reset(), 500);
};
const text = {
fullWidth: true,
size: "small",
margin: "normal",
variant: "outlined",
autoComplete: "off",
autoCorrect: "off",
} as const;
return (
<BaseDialog
open={open}
title={
openType === "new"
? t("tests.modals.test.title.create")
: t("tests.modals.test.title.edit")
}
contentSx={{ width: 375, pb: 0, maxHeight: "80%" }}
okBtn={t("shared.actions.save")}
cancelBtn={t("shared.actions.cancel")}
onClose={handleClose}
onCancel={handleClose}
onOk={handleOk}
loading={loading}
>
<Controller
name="name"
control={control}
render={({ field }) => (
<TextField {...text} {...field} label={t("shared.labels.name")} />
)}
/>
<Controller
name="icon"
control={control}
render={({ field }) => (
<TextField
{...text}
{...field}
multiline
maxRows={5}
label={t("shared.labels.icon")}
/>
)}
/>
<Controller
name="url"
control={control}
render={({ field }) => (
<TextField
{...text}
{...field}
multiline
maxRows={3}
label={t("tests.modals.test.fields.url")}
/>
)}
/>
</BaseDialog>
);
},
);