import * as Context from "effect/Context";import * as DateTime from "effect/DateTime";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Layer from "effect/Layer";import * as Path from "effect/Path"; import { VcsRepositoryDetectionError, VcsUnsupportedOperationError, type ReviewDiffPreviewError, type ReviewDiffPreviewInput, type ReviewDiffPreviewResult,} from "@t3tools/contracts"; import { ServerConfig } from "../config.ts";import * as GitVcsDriver from "../vcs/GitVcsDriver.ts";import * as VcsDriverRegistry from "../vcs/VcsDriverRegistry.ts"; export interface ReviewServiceShape { readonly getDiffPreview: ( input: ReviewDiffPreviewInput, ) => Effect.Effect<ReviewDiffPreviewResult, ReviewDiffPreviewError>;} export class ReviewService extends Context.Service<ReviewService, ReviewServiceShape>()( "t3/review/ReviewService",) {} export const make = Effect.fn("makeReviewService")(function* () { const config = yield* ServerConfig; const fileSystem = yield* FileSystem.FileSystem; const path = yield* Path.Path; const vcsRegistry = yield* VcsDriverRegistry.VcsDriverRegistry; const git = yield* GitVcsDriver.GitVcsDriver; const canonicalizePath = (value: string) => fileSystem .realPath(path.resolve(value)) .pipe(Effect.catch(() => Effect.succeed(path.resolve(value)))); const isWithinRoot = (candidate: string, root: string) => { const relative = path.relative(root, candidate); return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative)); }; const assertWorkspaceBoundCwd = Effect.fn("ReviewService.assertWorkspaceBoundCwd")(function* ( cwd: string, ) { const [candidate, workspaceRoot, worktreesRoot] = yield* Effect.all([ canonicalizePath(cwd), canonicalizePath(config.cwd), canonicalizePath(config.worktreesDir), ]); if (isWithinRoot(candidate, workspaceRoot) || isWithinRoot(candidate, worktreesRoot)) { return; } return yield* new VcsRepositoryDetectionError({ operation: "ReviewService.getDiffPreview", cwd, detail: "Review diff preview cwd must stay within the configured workspace root.", }); }); const getDiffPreview: ReviewServiceShape["getDiffPreview"] = Effect.fn( "ReviewService.getDiffPreview", )(function* (input) { yield* assertWorkspaceBoundCwd(input.cwd); const handle = yield* vcsRegistry.detect({ cwd: input.cwd, requestedKind: "auto" }); if (!handle) { return { cwd: input.cwd, generatedAt: yield* DateTime.now, sources: [], }; } const getDriverDiffPreview = handle.driver.getDiffPreview; if (!getDriverDiffPreview) { if (handle.kind === "git") { return yield* git.getReviewDiffPreview(input); } return yield* new VcsUnsupportedOperationError({ operation: "ReviewService.getDiffPreview", kind: handle.kind, detail: `The ${handle.kind} VCS driver does not support review diff previews.`, }); } return yield* getDriverDiffPreview(input); }); return ReviewService.of({ getDiffPreview, });}); export const layer = Layer.effect(ReviewService, make());
import * as Context from "effect/Context";
import * as DateTime from "effect/DateTime";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Path from "effect/Path";
import {
VcsRepositoryDetectionError,
VcsUnsupportedOperationError,
type ReviewDiffPreviewError,
type ReviewDiffPreviewInput,
type ReviewDiffPreviewResult,
} from "@t3tools/contracts";
import { ServerConfig } from "../config.ts";
import * as GitVcsDriver from "../vcs/GitVcsDriver.ts";
import * as VcsDriverRegistry from "../vcs/VcsDriverRegistry.ts";
export interface ReviewServiceShape {
readonly getDiffPreview: (
input: ReviewDiffPreviewInput,
) => Effect.Effect<ReviewDiffPreviewResult, ReviewDiffPreviewError>;
}
export class ReviewService extends Context.Service<ReviewService, ReviewServiceShape>()(
"t3/review/ReviewService",
) {}
export const make = Effect.fn("makeReviewService")(function* () {
const config = yield* ServerConfig;
const fileSystem = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const vcsRegistry = yield* VcsDriverRegistry.VcsDriverRegistry;
const git = yield* GitVcsDriver.GitVcsDriver;
const canonicalizePath = (value: string) =>
fileSystem
.realPath(path.resolve(value))
.pipe(Effect.catch(() => Effect.succeed(path.resolve(value))));
const isWithinRoot = (candidate: string, root: string) => {
const relative = path.relative(root, candidate);
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
};
const assertWorkspaceBoundCwd = Effect.fn("ReviewService.assertWorkspaceBoundCwd")(function* (
cwd: string,
) {
const [candidate, workspaceRoot, worktreesRoot] = yield* Effect.all([
canonicalizePath(cwd),
canonicalizePath(config.cwd),
canonicalizePath(config.worktreesDir),
]);
if (isWithinRoot(candidate, workspaceRoot) || isWithinRoot(candidate, worktreesRoot)) {
return;
}
return yield* new VcsRepositoryDetectionError({
operation: "ReviewService.getDiffPreview",
cwd,
detail: "Review diff preview cwd must stay within the configured workspace root.",
});
});
const getDiffPreview: ReviewServiceShape["getDiffPreview"] = Effect.fn(
"ReviewService.getDiffPreview",
)(function* (input) {
yield* assertWorkspaceBoundCwd(input.cwd);
const handle = yield* vcsRegistry.detect({ cwd: input.cwd, requestedKind: "auto" });
if (!handle) {
return {
cwd: input.cwd,
generatedAt: yield* DateTime.now,
sources: [],
};
}
const getDriverDiffPreview = handle.driver.getDiffPreview;
if (!getDriverDiffPreview) {
if (handle.kind === "git") {
return yield* git.getReviewDiffPreview(input);
}
return yield* new VcsUnsupportedOperationError({
operation: "ReviewService.getDiffPreview",
kind: handle.kind,
detail: `The ${handle.kind} VCS driver does not support review diff previews.`,
});
}
return yield* getDriverDiffPreview(input);
});
return ReviewService.of({
getDiffPreview,
});
});
export const layer = Layer.effect(ReviewService, make());