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
@@ -95,20 +95,20 @@ export async function transfer(
|
||||
const t = await resolveIn(d, body.target.root, body.target.path);
|
||||
if (!t.lst?.isDirectory() || t.isSymlink) throw new FilesError("bad_request", "目标必须是已存在的目录");
|
||||
if (!t.def.libraryRootId || !(await isWritableTarget(t.def, t.rootReal)))
|
||||
throw new FilesError("not_writable", `目标根 ${t.def.name} 不可写,只能选 managed 库根`);
|
||||
throw new FilesError("not_writable", `目标根 ${t.def.name} 不可写,只能选 managed 库根`);
|
||||
|
||||
const sources: Resolved[] = [];
|
||||
for (const it of body.items) {
|
||||
const s = await resolveIn(d, it.root, it.path);
|
||||
if (s.rel === "") throw new FilesError("bad_request", "根目录不能移动或复制");
|
||||
if (mode === "move" && !s.def.modifiable) throw new FilesError("not_writable", `源根 ${s.def.name} 只读,只能复制`);
|
||||
if (within(t.abs, s.abs)) throw new FilesError("bad_request", `目标在源目录之内: ${s.rel}`);
|
||||
if (dirname(s.abs) === t.abs) throw new FilesError("bad_request", `源已在目标目录中: ${s.rel}`);
|
||||
if (s.isSymlink) throw new FilesError("bad_request", `不能移动符号链接: ${s.rel}`);
|
||||
if (mode === "move" && !s.def.modifiable) throw new FilesError("not_writable", `源根 ${s.def.name} 只读,只能复制`);
|
||||
if (within(t.abs, s.abs)) throw new FilesError("bad_request", `目标在源目录之内:${s.rel}`);
|
||||
if (dirname(s.abs) === t.abs) throw new FilesError("bad_request", `源已在目标目录中:${s.rel}`);
|
||||
if (s.isSymlink) throw new FilesError("bad_request", `不能移动符号链接:${s.rel}`);
|
||||
sources.push(s);
|
||||
}
|
||||
const names = sources.map((s) => basename(s.abs));
|
||||
if (new Set(names).size !== names.length) throw new FilesError("bad_request", "多个源同名,会在目标目录冲突");
|
||||
if (new Set(names).size !== names.length) throw new FilesError("bad_request", "多个源同名,会在目标目录冲突");
|
||||
|
||||
const snaps = await Promise.all(sources.map((s, i) => snapshot(d, s, body.items[i]!.root)));
|
||||
const downloads = await managedDownloads(d);
|
||||
@@ -148,7 +148,7 @@ export async function transfer(
|
||||
const reason = planned.reason ?? "plan_failed";
|
||||
throw new FilesError(
|
||||
reason.startsWith("library_root_offline") ? "root_unavailable" : "bad_request",
|
||||
`无法生成计划:${reason}`,
|
||||
`无法生成计划:${reason}`,
|
||||
);
|
||||
}
|
||||
const planFiles = planned.plan.organize.files;
|
||||
@@ -189,9 +189,9 @@ export async function transfer(
|
||||
const allowCross = (await d.ctx.settings.get("organize")).allowCrossVolumeMove;
|
||||
const crossBlocked = mode === "move" && !allowCross && pairs.some((p) => p.crossDevice);
|
||||
const warnings: string[] = [];
|
||||
if (crossBlocked) warnings.push("未开启跨卷移动,执行会失败。改用复制,或在 设置 → 整理 中开启");
|
||||
if (conflictSrc.size > 0) warnings.push(`${conflictSrc.size} 个文件在目标已存在,不覆盖,执行时记为失败`);
|
||||
if (truncated) warnings.push("源文件数超过上限,分批操作");
|
||||
if (crossBlocked) warnings.push("未开启跨卷移动,执行会失败。改用复制,或在 设置 → 整理 中开启");
|
||||
if (conflictSrc.size > 0) warnings.push(`${conflictSrc.size} 个文件在目标已存在,不覆盖,执行时记为失败`);
|
||||
if (truncated) warnings.push("源文件数超过上限,分批操作");
|
||||
const base = { mode, pairs, totalBytes, freeBytes, spaceOk, hnrBlocks, truncated, warnings };
|
||||
|
||||
if (body.dryRun) {
|
||||
@@ -215,22 +215,22 @@ export async function transfer(
|
||||
for (const [i, s] of snaps.entries()) {
|
||||
const frozen = plan.content.sources[i];
|
||||
if (!frozen || frozen.abs !== s.abs || frozen.fingerprint !== s.fingerprint)
|
||||
throw new FilesError("plan_stale", `源在预览后发生变化(大小/修改时间/文件清单): ${s.rel}`);
|
||||
throw new FilesError("plan_stale", `源在预览后发生变化(大小/修改时间/文件清单):${s.rel}`);
|
||||
}
|
||||
if (plan.content.files && hashJson(plan.content.files) !== hashJson(filePairs))
|
||||
throw new FilesError("plan_stale", "目标已变化,与预览不一致。重新预览");
|
||||
if (truncated) throw new FilesError("bad_request", "源目录文件数超过上限,分批操作");
|
||||
if (!spaceOk) throw new FilesError("bad_request", `目标卷空间不足:需要 ${needBytes},可用 ${freeBytes}`);
|
||||
throw new FilesError("plan_stale", "目标已变化,与预览不一致。重新预览");
|
||||
if (truncated) throw new FilesError("bad_request", "源目录文件数超过上限,分批操作");
|
||||
if (!spaceOk) throw new FilesError("bad_request", `目标卷空间不足:需要 ${needBytes},可用 ${freeBytes}`);
|
||||
if (crossBlocked)
|
||||
throw new FilesError(
|
||||
"bad_request",
|
||||
"未开启跨卷移动(settings.organize.allowCrossVolumeMove)。改用复制,或开启后重试",
|
||||
"未开启跨卷移动(settings.organize.allowCrossVolumeMove)。改用复制,或开启后重试",
|
||||
);
|
||||
if (mode === "move") {
|
||||
if (hnrBlocks.length > 0)
|
||||
throw new FilesError(
|
||||
"download_active",
|
||||
`源属于下载任务 ${[...new Set(hnrBlocks.map((h) => h.taskId))].join(", ")},直接移动会让下载器丢失文件。改用整理入库,它会按做种义务决定能否移动`,
|
||||
`源属于下载任务 ${[...new Set(hnrBlocks.map((h) => h.taskId))].join(", ")},直接移动会让下载器丢失文件。改用整理入库,它会按做种义务决定能否移动`,
|
||||
);
|
||||
if (!isAdmin(principal)) {
|
||||
// 每个源按其(目录则为其下)已登记资产求作品集合,逐一核对授权;任一不覆盖 → 整体拒绝并列出未授权项
|
||||
@@ -272,7 +272,7 @@ export async function transfer(
|
||||
}
|
||||
if (!rec.recordId || rec.status === "failed") {
|
||||
await markTask(db, taskId, "failed", { error: rec.reason ?? rec.status });
|
||||
throw new FilesError("bad_request", `计划不可执行:${rec.reason ?? rec.status}`);
|
||||
throw new FilesError("bad_request", `计划不可执行:${rec.reason ?? rec.status}`);
|
||||
}
|
||||
const recordId = rec.recordId;
|
||||
await db.updateTable("organization_record").set({ task_id: taskId }).where("id", "=", recordId).execute();
|
||||
@@ -316,7 +316,7 @@ export async function transfer(
|
||||
failed.push({
|
||||
path: s.rel,
|
||||
code: err.code === "EEXIST" ? "exists" : (err.code ?? bad.status),
|
||||
message: `${err.message ?? bad.status}${mine.length > 1 ? `(${mine.filter((f) => f.status === "succeeded").length}/${mine.length} 个文件已完成)` : ""}`,
|
||||
message: `${err.message ?? bad.status}${mine.length > 1 ? `(${mine.filter((f) => f.status === "succeeded").length}/${mine.length} 个文件已完成)` : ""}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user