mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-23 05:31:11 +00:00
177 lines
5.7 KiB
TypeScript
177 lines
5.7 KiB
TypeScript
import type { WorkboardCard } from "@openclaw/workboard-contract";
|
|
// Workboard Gateway methods that can persist workspace-bearing card metadata.
|
|
import type { OpenClawPluginApi } from "../api.js";
|
|
import {
|
|
readId,
|
|
readPatch,
|
|
resolveGatewayWorkboardWorkspaceAccess,
|
|
respondError,
|
|
type GatewayMethodContext,
|
|
} from "./gateway-helpers.js";
|
|
import type { WorkboardStore } from "./store.js";
|
|
import {
|
|
assertWorkboardWorkspaceMutationAccess,
|
|
canonicalizeWorkboardWorkspaceAccess,
|
|
containsWorkboardWorkspaceMutation,
|
|
withWorkboardDecomposeWorkspaceAccess,
|
|
withWorkboardWorkspaceAccess,
|
|
withoutWorkboardWorkspaceAccess,
|
|
type WorkboardWorkspaceAccess,
|
|
} from "./workspace-access.js";
|
|
|
|
const WRITE_SCOPE = "operator.write" as const;
|
|
|
|
async function resolveGatewayWorkspaceMutationAccess(
|
|
request: GatewayMethodContext,
|
|
value: unknown,
|
|
): Promise<WorkboardWorkspaceAccess> {
|
|
const access = await canonicalizeWorkboardWorkspaceAccess(
|
|
resolveGatewayWorkboardWorkspaceAccess({
|
|
context: request.context,
|
|
client: request.client,
|
|
}),
|
|
);
|
|
await assertWorkboardWorkspaceMutationAccess(value, access);
|
|
return access;
|
|
}
|
|
|
|
type WorkspaceGatewayMethodParams = {
|
|
api: OpenClawPluginApi;
|
|
store: WorkboardStore;
|
|
redactCard: (card: WorkboardCard) => WorkboardCard;
|
|
};
|
|
|
|
export function registerWorkboardWorkspaceCardMethods(params: WorkspaceGatewayMethodParams): void {
|
|
const { api, store, redactCard } = params;
|
|
api.registerGatewayMethod(
|
|
"workboard.cards.create",
|
|
async (request) => {
|
|
const { params: requestParams, respond } = request;
|
|
try {
|
|
const input = withoutWorkboardWorkspaceAccess(requestParams);
|
|
const access = await resolveGatewayWorkspaceMutationAccess(request, input);
|
|
respond(true, {
|
|
card: redactCard(await store.create(withWorkboardWorkspaceAccess(input, access))),
|
|
});
|
|
} catch (error) {
|
|
respondError(respond, error);
|
|
}
|
|
},
|
|
{ scope: WRITE_SCOPE },
|
|
);
|
|
|
|
api.registerGatewayMethod(
|
|
"workboard.cards.update",
|
|
async (request) => {
|
|
const { params: requestParams, respond } = request;
|
|
try {
|
|
const patch = withoutWorkboardWorkspaceAccess(readPatch(requestParams));
|
|
const access = await resolveGatewayWorkspaceMutationAccess(request, patch);
|
|
respond(true, {
|
|
card: redactCard(
|
|
await store.update(
|
|
readId(requestParams),
|
|
containsWorkboardWorkspaceMutation(patch)
|
|
? withWorkboardWorkspaceAccess(patch, access)
|
|
: patch,
|
|
),
|
|
),
|
|
});
|
|
} catch (error) {
|
|
respondError(respond, error);
|
|
}
|
|
},
|
|
{ scope: WRITE_SCOPE },
|
|
);
|
|
}
|
|
|
|
export function registerWorkboardWorkspaceBulkMethod(params: WorkspaceGatewayMethodParams): void {
|
|
const { api, store, redactCard } = params;
|
|
api.registerGatewayMethod(
|
|
"workboard.cards.bulk",
|
|
async (request) => {
|
|
const { params: requestParams, respond } = request;
|
|
try {
|
|
const sanitizedParams = withoutWorkboardWorkspaceAccess(requestParams);
|
|
const patch = withoutWorkboardWorkspaceAccess(readPatch(requestParams));
|
|
const access = await resolveGatewayWorkspaceMutationAccess(request, patch);
|
|
const result = await store.bulkUpdate({
|
|
...sanitizedParams,
|
|
patch: containsWorkboardWorkspaceMutation(patch)
|
|
? withWorkboardWorkspaceAccess(patch, access)
|
|
: patch,
|
|
});
|
|
respond(true, { cards: result.cards.map(redactCard) });
|
|
} catch (error) {
|
|
respondError(respond, error);
|
|
}
|
|
},
|
|
{ scope: WRITE_SCOPE },
|
|
);
|
|
}
|
|
|
|
export function registerWorkboardWorkspaceBoardMethod(params: WorkspaceGatewayMethodParams): void {
|
|
const { api, store } = params;
|
|
api.registerGatewayMethod(
|
|
"workboard.boards.upsert",
|
|
async (request) => {
|
|
const { params: requestParams, respond } = request;
|
|
try {
|
|
await resolveGatewayWorkspaceMutationAccess(request, requestParams);
|
|
respond(true, { board: await store.upsertBoard(requestParams) });
|
|
} catch (error) {
|
|
respondError(respond, error);
|
|
}
|
|
},
|
|
{ scope: WRITE_SCOPE },
|
|
);
|
|
}
|
|
|
|
export function registerWorkboardWorkspaceWorkflowMethods(
|
|
params: WorkspaceGatewayMethodParams,
|
|
): void {
|
|
const { api, store, redactCard } = params;
|
|
api.registerGatewayMethod(
|
|
"workboard.cards.specify",
|
|
async (request) => {
|
|
const { params: requestParams, respond } = request;
|
|
try {
|
|
const sanitizedParams = withoutWorkboardWorkspaceAccess(requestParams);
|
|
const access = await resolveGatewayWorkspaceMutationAccess(request, sanitizedParams);
|
|
const input = containsWorkboardWorkspaceMutation(sanitizedParams)
|
|
? withWorkboardWorkspaceAccess(sanitizedParams, access)
|
|
: sanitizedParams;
|
|
respond(true, {
|
|
card: redactCard(await store.specify(readId(requestParams), input, null)),
|
|
});
|
|
} catch (error) {
|
|
respondError(respond, error);
|
|
}
|
|
},
|
|
{ scope: WRITE_SCOPE },
|
|
);
|
|
|
|
api.registerGatewayMethod(
|
|
"workboard.cards.decompose",
|
|
async (request) => {
|
|
const { params: requestParams, respond } = request;
|
|
try {
|
|
const sanitizedParams = withoutWorkboardWorkspaceAccess(requestParams);
|
|
const access = await resolveGatewayWorkspaceMutationAccess(request, sanitizedParams);
|
|
const result = await store.decompose(
|
|
readId(requestParams),
|
|
withWorkboardDecomposeWorkspaceAccess(sanitizedParams, access),
|
|
null,
|
|
);
|
|
respond(true, {
|
|
parent: redactCard(result.parent),
|
|
children: result.children.map(redactCard),
|
|
});
|
|
} catch (error) {
|
|
respondError(respond, error);
|
|
}
|
|
},
|
|
{ scope: WRITE_SCOPE },
|
|
);
|
|
}
|