142 lines · 4.8 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 ReviewDiffFileContentsInput,  type ReviewDiffFileContentsResult,  type ReviewDiffPreviewError,  type ReviewDiffPreviewInput,  type ReviewDiffPreviewResult,} from "@t3tools/contracts"; import * as ServerConfig from "../config.ts";import * as GitVcsDriver from "../vcs/GitVcsDriver.ts";import * as VcsDriverRegistry from "../vcs/VcsDriverRegistry.ts"; export class ReviewService extends Context.Service<  ReviewService,  {    readonly getDiffPreview: (      input: ReviewDiffPreviewInput,    ) => Effect.Effect<ReviewDiffPreviewResult, ReviewDiffPreviewError>;    readonly getDiffFileContents: (      input: ReviewDiffFileContentsInput,    ) => Effect.Effect<ReviewDiffFileContentsResult, ReviewDiffPreviewError>;  }>()("t3/review/ReviewService") {} /** @public Service construction is part of the canonical Effect module API. */export const make = Effect.gen(function* () {  const config = yield* ServerConfig.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) => {    const resolvedPath = path.resolve(value);    return fileSystem.realPath(resolvedPath).pipe(      Effect.catchTags({        PlatformError: (cause) =>          cause.reason._tag === "NotFound"            ? Effect.succeed(resolvedPath)            : Effect.fail(                new VcsRepositoryDetectionError({                  operation: "ReviewService.assertWorkspaceBoundCwd.canonicalizePath",                  cwd: resolvedPath,                  detail: "Failed to resolve a path while validating the review workspace.",                  cause,                }),              ),      }),    );  };   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* (    operation: "ReviewService.getDiffPreview" | "ReviewService.getDiffFileContents",    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,      cwd,      detail:        operation === "ReviewService.getDiffPreview"          ? "Review diff preview cwd must stay within the configured workspace root."          : "Review diff file contents cwd must stay within the configured workspace root.",    });  });   const getDiffPreview: ReviewService["Service"]["getDiffPreview"] = Effect.fn(    "ReviewService.getDiffPreview",  )(function* (input) {    yield* assertWorkspaceBoundCwd("ReviewService.getDiffPreview", 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);  });   const getDiffFileContents: ReviewService["Service"]["getDiffFileContents"] = Effect.fn(    "ReviewService.getDiffFileContents",  )(function* (input) {    yield* assertWorkspaceBoundCwd("ReviewService.getDiffFileContents", input.cwd);     const handle = yield* vcsRegistry.detect({ cwd: input.cwd, requestedKind: "auto" });    if (handle?.kind !== "git") {      return yield* new VcsUnsupportedOperationError({        operation: "ReviewService.getDiffFileContents",        kind: handle?.kind ?? "unknown",        detail: "Unchanged diff expansion currently requires a Git repository.",      });    }     return yield* git.getReviewDiffFileContents(input);  });   return ReviewService.of({    getDiffPreview,    getDiffFileContents,  });}); export const layer = Layer.effect(ReviewService, make);