4-10 树域 Rust 家族化
This commit is contained in:
@@ -20,7 +20,7 @@ describe("tree-command-client", () => {
|
||||
it("通过统一 client 发送 tree/document command 并返回结果", async () => {
|
||||
const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({ ok: true, success: true, items: [] }),
|
||||
json: async () => ({ ok: true, success: true, items: [], id: "doc_created", documentId: "doc_created" }),
|
||||
} as Response);
|
||||
|
||||
await createDocumentCommand(null);
|
||||
@@ -41,9 +41,9 @@ describe("tree-command-client", () => {
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledTimes(10);
|
||||
expect(fetchMock.mock.calls.map((call) => String(call[0]))).toEqual([
|
||||
"/api/documents/create",
|
||||
"/api/documents/title",
|
||||
"/api/documents/move",
|
||||
"/api/tree/commands",
|
||||
"/api/tree/commands",
|
||||
"/api/tree/commands",
|
||||
"/api/documents/delete",
|
||||
"/api/documents/restore",
|
||||
"/api/documents/purge",
|
||||
@@ -52,6 +52,24 @@ describe("tree-command-client", () => {
|
||||
"/api/documents/title",
|
||||
"/api/documents/options",
|
||||
]);
|
||||
|
||||
expect(JSON.parse(String(fetchMock.mock.calls[0]?.[1]?.body))).toEqual({
|
||||
action: "create",
|
||||
parentId: null,
|
||||
});
|
||||
expect(JSON.parse(String(fetchMock.mock.calls[1]?.[1]?.body))).toEqual({
|
||||
action: "rename",
|
||||
documentId: "doc_1",
|
||||
workspaceId: null,
|
||||
title: "新标题",
|
||||
});
|
||||
expect(JSON.parse(String(fetchMock.mock.calls[2]?.[1]?.body))).toEqual({
|
||||
action: "move",
|
||||
documentId: "doc_1",
|
||||
parentId: null,
|
||||
sortOrder: 0,
|
||||
workspaceId: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("在后端返回错误时抛出统一异常", async () => {
|
||||
|
||||
@@ -96,6 +96,8 @@ type MoveDocumentInput = {
|
||||
workspaceId?: string | null;
|
||||
};
|
||||
|
||||
type TreeCommandAction = "create" | "rename" | "move";
|
||||
|
||||
type DeleteDocumentInput = {
|
||||
documentId: string;
|
||||
workspaceId?: string | null;
|
||||
@@ -148,8 +150,56 @@ async function postDocumentCommand<TResult>(path: string, payload: unknown, fall
|
||||
return body as TResult;
|
||||
}
|
||||
|
||||
type TreeCommandResponse = {
|
||||
requestId?: string;
|
||||
traceId?: string;
|
||||
result?: {
|
||||
action?: TreeCommandAction;
|
||||
workspaceId?: string | null;
|
||||
documentId?: string;
|
||||
parentId?: string | null;
|
||||
title?: string | null;
|
||||
sortOrder?: number | null;
|
||||
updatedAt?: string | null;
|
||||
execution?: {
|
||||
access_scope?: "private" | "shared" | "public";
|
||||
is_template?: boolean;
|
||||
created_at?: string | null;
|
||||
updated_at?: string | null;
|
||||
} | null;
|
||||
} | null;
|
||||
};
|
||||
|
||||
async function postTreeCommand<TResult>(payload: unknown, fallbackMessage: string): Promise<TResult> {
|
||||
return postDocumentCommand<TResult>("/api/tree/commands", payload, fallbackMessage);
|
||||
}
|
||||
|
||||
export async function createDocumentCommand(parentId: string | null): Promise<DocumentCreateCommandResult> {
|
||||
return postDocumentCommand<DocumentCreateCommandResult>("/api/documents/create", { parentId }, "新建页面失败,请稍后再试");
|
||||
const response = await postTreeCommand<TreeCommandResponse>(
|
||||
{
|
||||
action: "create",
|
||||
parentId,
|
||||
},
|
||||
"新建页面失败,请稍后再试",
|
||||
);
|
||||
const result = response.result;
|
||||
|
||||
return {
|
||||
id: result?.documentId ?? "",
|
||||
title: result?.title ?? "无标题",
|
||||
parent_id: result?.parentId ?? parentId,
|
||||
sort_order: result?.sortOrder ?? null,
|
||||
workspace_id: result?.workspaceId ?? undefined,
|
||||
access_scope: result?.execution?.access_scope ?? "private",
|
||||
is_template: result?.execution?.is_template ?? false,
|
||||
created_at: result?.execution?.created_at ?? null,
|
||||
updated_at: result?.execution?.updated_at ?? result?.updatedAt ?? null,
|
||||
meta: {
|
||||
requestId: response.requestId,
|
||||
traceId: response.traceId,
|
||||
commandName: TREE_COMMAND_PROTOCOL.create.preferredCommandName,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function createChildDocumentCommand(
|
||||
@@ -163,15 +213,24 @@ export async function createChildDocumentCommand(
|
||||
}
|
||||
|
||||
export async function renameDocumentCommand(input: RenameDocumentInput): Promise<{ ok: true; meta?: DocumentCommandMeta }> {
|
||||
return postDocumentCommand<{ ok: true; meta?: DocumentCommandMeta }>(
|
||||
"/api/documents/title",
|
||||
const response = await postTreeCommand<TreeCommandResponse>(
|
||||
{
|
||||
action: "rename",
|
||||
documentId: input.documentId,
|
||||
workspaceId: input.workspaceId ?? null,
|
||||
title: input.title,
|
||||
},
|
||||
"重命名失败,请稍后再试",
|
||||
);
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
meta: {
|
||||
requestId: response.requestId,
|
||||
traceId: response.traceId,
|
||||
commandName: TREE_COMMAND_PROTOCOL.rename.preferredCommandName,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function updatePageTitleCommand(
|
||||
@@ -192,16 +251,25 @@ export async function updatePageOptionsCommand(
|
||||
}
|
||||
|
||||
export async function moveDocumentCommand(input: MoveDocumentInput): Promise<{ ok: true; meta?: DocumentCommandMeta }> {
|
||||
return postDocumentCommand<{ ok: true; meta?: DocumentCommandMeta }>(
|
||||
"/api/documents/move",
|
||||
const response = await postTreeCommand<TreeCommandResponse>(
|
||||
{
|
||||
action: "move",
|
||||
documentId: input.documentId,
|
||||
parentId: input.parentId ?? null,
|
||||
position: input.position,
|
||||
sortOrder: Number.isFinite(input.position) ? Math.floor(input.position) : 0,
|
||||
workspaceId: input.workspaceId ?? null,
|
||||
},
|
||||
"移动失败,请稍后再试",
|
||||
);
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
meta: {
|
||||
requestId: response.requestId,
|
||||
traceId: response.traceId,
|
||||
commandName: TREE_COMMAND_PROTOCOL.move.preferredCommandName,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function deleteDocumentCommand(
|
||||
|
||||
Reference in New Issue
Block a user