101 lines · 3.2 KB · TypeScript
RawDownload
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());