diff --git a/backend/src/services/orchestrator.test.ts b/backend/src/services/orchestrator.test.ts new file mode 100644 index 0000000..e8a5b6c --- /dev/null +++ b/backend/src/services/orchestrator.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, test } from "bun:test"; +import { runCommand } from "./orchestrator"; + +describe("runCommand", () => { + test("runs a command and returns stdout", async () => { + const result = await runCommand("echo", ["hello"]); + expect(result.stdout.trim()).toBe("hello"); + expect(result.exitCode).toBe(0); + }); + + test("returns non-zero exit code on failure", async () => { + const result = await runCommand("false", []); + expect(result.exitCode).not.toBe(0); + }); +}); diff --git a/backend/src/services/orchestrator.ts b/backend/src/services/orchestrator.ts new file mode 100644 index 0000000..380e847 --- /dev/null +++ b/backend/src/services/orchestrator.ts @@ -0,0 +1,34 @@ +export interface CommandResult { + stdout: string; + stderr: string; + exitCode: number; +} + +export async function runCommand(cmd: string, args: string[]): Promise { + const proc = Bun.spawn([cmd, ...args], { + stdout: "pipe", + stderr: "pipe", + }); + + const stdout = await new Response(proc.stdout).text(); + const stderr = await new Response(proc.stderr).text(); + const exitCode = await proc.exited; + + return { stdout, stderr, exitCode }; +} + +export async function syncMail(channelName: string): Promise { + return runCommand("mbsync", [channelName]); +} + +export async function indexMail(): Promise { + return runCommand("notmuch", ["new"]); +} + +export async function syncAndIndex(channelName: string): Promise { + const syncResult = await syncMail(channelName); + if (syncResult.exitCode !== 0) { + return syncResult; + } + return indexMail(); +}