style(copy): punctuation rules and site-wide fix with a CI check (QA U11)
- glossary: 10 punctuation rules (full-width in Chinese, CJK/Latin spacing, full-width parens around Chinese, single ellipsis, 「」 quotes, period rules) - scripts/check-copy-punctuation.mjs: checks string literals, templates and JSX text (not comments, types, keys, match/compare strings); --fix, --strict, --by-file; wired into deno task ci as check:copy in warn mode - --fix applied to web, server and contracts; files other lanes were editing (subscriptions, sites, browser, agent, auth/account, inventory) left for them - tests updated for the changed messages Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
9b017906cf
commit
52402864d6
143 files changed
+985
-606
No files matched your search
@@ -157,8 +157,8 @@ const BLOCK_ERR: Record<
|
||||
> = {
|
||||
download_active: ["download_active", "属于未完成或做种义务未满足的下载任务"],
|
||||
is_root: ["bad_request", "不能删除根目录或只读根下的内容"],
|
||||
needs_retire: ["needs_retire", "含已登记资产,需勾选“同时退役资产”"],
|
||||
needs_unbind: ["needs_unbind", "是作品/季的绑定目录,需勾选“解除绑定”"],
|
||||
needs_retire: ["needs_retire", "含已登记资产,需勾选「同时退役资产」"],
|
||||
needs_unbind: ["needs_unbind", "是作品/季的绑定目录,需勾选「解除绑定」"],
|
||||
root_unavailable: ["root_unavailable", "根不可用"],
|
||||
not_found: ["not_found", "不存在"],
|
||||
escape: ["path_escape", "路径指向根外"],
|
||||
@@ -276,8 +276,8 @@ export async function deleteFiles(
|
||||
for (const s of slots)
|
||||
await upsertDecision(d.ao, trx, {
|
||||
kind: "other",
|
||||
title: `版本目标的文件已删除:${s.name}`,
|
||||
summary: "满足该版本目标的资产已在文件管理中删除,版本目标改为需关注。确认是否重新获取",
|
||||
title: `版本目标的文件已删除:${s.name}`,
|
||||
summary: "满足该版本目标的资产已在文件管理中删除,版本目标改为需关注。确认是否重新获取",
|
||||
subjectType: "acquisition_slot",
|
||||
subjectId: s.id,
|
||||
dedupeKey: `files_delete_slot:${s.id}`,
|
||||
@@ -384,7 +384,7 @@ async function moveToTrash(
|
||||
try {
|
||||
await mkdir(dirname(trashPath), { recursive: true });
|
||||
const r = await moveSafe(abs, trashPath);
|
||||
if (r.status === "exists") throw new FilesError("exists", `回收站路径已存在: ${trashPath}`);
|
||||
if (r.status === "exists") throw new FilesError("exists", `回收站路径已存在:${trashPath}`);
|
||||
moved = r.status === "moved";
|
||||
} catch (e) {
|
||||
if (e instanceof FilesError) throw e;
|
||||
@@ -396,7 +396,7 @@ async function moveToTrash(
|
||||
if (check.size > d.options.trashCrossMaxBytes)
|
||||
throw new FilesError(
|
||||
"bad_request",
|
||||
`无法同卷移入回收站,且大小 ${check.size} 超过跨卷上限 ${d.options.trashCrossMaxBytes}。改用永久删除`,
|
||||
`无法同卷移入回收站,且大小 ${check.size} 超过跨卷上限 ${d.options.trashCrossMaxBytes}。改用永久删除`,
|
||||
);
|
||||
await rm(join(ctx.rootReal!, TRASH_DIR, stamp, id), { recursive: true, force: true }).catch(() => undefined);
|
||||
trashPath = join(resolve(d.options.dataDir), "trash", stamp, id, check.path);
|
||||
@@ -487,10 +487,10 @@ export async function mkdirWithin(rootReal: string, rel: string): Promise<void>
|
||||
throw e;
|
||||
});
|
||||
if (st?.isSymbolicLink())
|
||||
throw new FilesError("path_escape", `还原路径中的 ${relOfRoot(rootReal, cur)} 是符号链接,不能还原`);
|
||||
throw new FilesError("path_escape", `还原路径中的 ${relOfRoot(rootReal, cur)} 是符号链接,不能还原`);
|
||||
if (st && !st.isDirectory()) throw new FilesError("exists", `还原路径中的 ${relOfRoot(rootReal, cur)} 不是目录`);
|
||||
if (!st) await mkdir(cur);
|
||||
if (!within(await realpath(cur), rootReal)) throw new FilesError("path_escape", `还原路径指向根外: ${rel}`);
|
||||
if (!within(await realpath(cur), rootReal)) throw new FilesError("path_escape", `还原路径指向根外:${rel}`);
|
||||
}
|
||||
}
|
||||
const relOfRoot = (root: string, p: string) => (p === root ? "" : p.slice(root.length + 1));
|
||||
@@ -509,12 +509,12 @@ export async function restoreTrash(
|
||||
throw new FilesError("bad_request", "还原目标必须是已存在的目录");
|
||||
// "还原到…"只能进可写的 managed 库根(与 move/copy 的目标规则一致;register_only / 下载根拒绝,验收 07 S-5)
|
||||
if (target && !(await isWritableTarget(target.def, target.rootReal)))
|
||||
throw new FilesError("not_writable", `还原目标根 ${target.def.name} 不可写,只能选 managed 库根`);
|
||||
throw new FilesError("not_writable", `还原目标根 ${target.def.name} 不可写,只能选 managed 库根`);
|
||||
for (const id of body.ids) {
|
||||
try {
|
||||
const row = await d.ctx.db.selectFrom("trash_item").selectAll().where("id", "=", id).executeTakeFirst();
|
||||
if (!row) throw new FilesError("not_found", "回收站条目不存在");
|
||||
if (!trashPathSafe(d, row)) throw new FilesError("path_escape", "回收站路径异常,拒绝操作");
|
||||
if (!trashPathSafe(d, row)) throw new FilesError("path_escape", "回收站路径异常,拒绝操作");
|
||||
let rootId = row.root_id;
|
||||
let dst: string;
|
||||
let rootReal: string;
|
||||
@@ -537,7 +537,7 @@ export async function restoreTrash(
|
||||
);
|
||||
dst = parent.abs;
|
||||
}
|
||||
if (await lstat(dst).catch(() => null)) throw new FilesError("exists", "原位置已被占用,可选择“还原到…”");
|
||||
if (await lstat(dst).catch(() => null)) throw new FilesError("exists", "原位置已被占用,可选择「还原到…」");
|
||||
const r = await moveSafe(row.trash_path, dst);
|
||||
if (r.status === "exists") throw new FilesError("exists", "原位置已被占用");
|
||||
if (r.status === "exdev") {
|
||||
@@ -547,7 +547,7 @@ export async function restoreTrash(
|
||||
if (bytes > d.options.trashCrossMaxBytes)
|
||||
throw new FilesError(
|
||||
"too_large",
|
||||
`跨卷还原大小 ${bytes} 超过上限 ${d.options.trashCrossMaxBytes}。在同卷还原,或手工处理 ${row.trash_path}`,
|
||||
`跨卷还原大小 ${bytes} 超过上限 ${d.options.trashCrossMaxBytes}。在同卷还原,或手工处理 ${row.trash_path}`,
|
||||
);
|
||||
await copyTree(d, row.trash_path, dst, files);
|
||||
await rm(row.trash_path, { recursive: true });
|
||||
@@ -597,7 +597,7 @@ export async function purgeTrash(
|
||||
const failed: FilesTrashPurgeResult["failed"] = [];
|
||||
for (const row of rows) {
|
||||
try {
|
||||
if (!trashPathSafe(d, row)) throw new FilesError("path_escape", "回收站路径异常,拒绝清除");
|
||||
if (!trashPathSafe(d, row)) throw new FilesError("path_escape", "回收站路径异常,拒绝清除");
|
||||
const gone = await d.ctx.db.deleteFrom("trash_item").where("id", "=", row.id).returning("id").executeTakeFirst();
|
||||
if (!gone) continue;
|
||||
await rm(row.trash_path, { recursive: true, force: true });
|
||||
|
||||
Reference in new issue
Block a user