mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-14 10:00:38 +09:00
92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
|
|
import { definePlugin, runWorker } from "@paperclipai/plugin-sdk";
|
||
|
|
import { workspaceDiffQuerySchema } from "./contracts.js";
|
||
|
|
import { workspaceDiffService } from "./workspace-diff.js";
|
||
|
|
|
||
|
|
const PLUGIN_NAME = "workspace-diff";
|
||
|
|
|
||
|
|
function readString(value: unknown): string {
|
||
|
|
return typeof value === "string" ? value.trim() : "";
|
||
|
|
}
|
||
|
|
|
||
|
|
function readOptionalString(value: unknown): string | null {
|
||
|
|
const trimmed = readString(value);
|
||
|
|
return trimmed || null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function resolveDefaultBaseRef(input: {
|
||
|
|
workspaceBaseRef?: unknown;
|
||
|
|
projectWorkspaceDefaultRef?: unknown;
|
||
|
|
projectWorkspaceRepoRef?: unknown;
|
||
|
|
}): string | null {
|
||
|
|
return readOptionalString(input.workspaceBaseRef)
|
||
|
|
?? readOptionalString(input.projectWorkspaceDefaultRef)
|
||
|
|
?? readOptionalString(input.projectWorkspaceRepoRef);
|
||
|
|
}
|
||
|
|
|
||
|
|
const plugin = definePlugin({
|
||
|
|
async setup(ctx) {
|
||
|
|
ctx.logger.info(`${PLUGIN_NAME} plugin setup`);
|
||
|
|
const workspaceDiff = workspaceDiffService();
|
||
|
|
|
||
|
|
ctx.data.register("workspace-diff", async (params: Record<string, unknown>) => {
|
||
|
|
const workspaceId = readString(params.workspaceId);
|
||
|
|
const companyId = readString(params.companyId);
|
||
|
|
if (!workspaceId || !companyId) {
|
||
|
|
throw new Error("workspaceId and companyId are required");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (params.entityType === "project_workspace") {
|
||
|
|
const projectId = readString(params.projectId);
|
||
|
|
if (!projectId) {
|
||
|
|
throw new Error("projectId is required for project workspace diffs");
|
||
|
|
}
|
||
|
|
const workspaces = await ctx.projects.listWorkspaces(projectId, companyId);
|
||
|
|
const workspace = workspaces.find((candidate) => candidate.id === workspaceId);
|
||
|
|
if (!workspace) {
|
||
|
|
throw new Error("Workspace not found");
|
||
|
|
}
|
||
|
|
return workspaceDiff.getDiff({
|
||
|
|
id: workspace.id,
|
||
|
|
companyId,
|
||
|
|
cwd: workspace.path,
|
||
|
|
baseRef: resolveDefaultBaseRef({
|
||
|
|
projectWorkspaceDefaultRef: workspace.defaultRef,
|
||
|
|
projectWorkspaceRepoRef: workspace.repoRef,
|
||
|
|
}),
|
||
|
|
}, workspaceDiffQuerySchema.parse(params));
|
||
|
|
}
|
||
|
|
|
||
|
|
const workspace = await ctx.executionWorkspaces.get(workspaceId, companyId);
|
||
|
|
if (!workspace) {
|
||
|
|
throw new Error("Workspace not found");
|
||
|
|
}
|
||
|
|
let projectWorkspaceDefaultBaseRef: string | null = null;
|
||
|
|
if (!readOptionalString(workspace.baseRef) && workspace.projectWorkspaceId) {
|
||
|
|
const workspaces = await ctx.projects.listWorkspaces(workspace.projectId, companyId);
|
||
|
|
const projectWorkspace = workspaces.find((candidate) => candidate.id === workspace.projectWorkspaceId);
|
||
|
|
projectWorkspaceDefaultBaseRef = projectWorkspace
|
||
|
|
? resolveDefaultBaseRef({
|
||
|
|
projectWorkspaceDefaultRef: projectWorkspace.defaultRef,
|
||
|
|
projectWorkspaceRepoRef: projectWorkspace.repoRef,
|
||
|
|
})
|
||
|
|
: null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return workspaceDiff.getDiff({
|
||
|
|
...workspace,
|
||
|
|
baseRef: resolveDefaultBaseRef({
|
||
|
|
workspaceBaseRef: workspace.baseRef,
|
||
|
|
projectWorkspaceDefaultRef: projectWorkspaceDefaultBaseRef,
|
||
|
|
}),
|
||
|
|
}, workspaceDiffQuerySchema.parse(params));
|
||
|
|
});
|
||
|
|
},
|
||
|
|
|
||
|
|
async onHealth() {
|
||
|
|
return { status: "ok", message: `${PLUGIN_NAME} ready` };
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
export default plugin;
|
||
|
|
runWorker(plugin, import.meta.url);
|