Skip to content
Source
Sign inSign up

pullRequestReviewDrafts.ts

77 lines2.4 KB

1import type { PullRequestReviewCommentDraft } from "@t3tools/contracts";
2import * as Schema from "effect/Schema";
3import { PullRequestReviewCommentDraft as CommentSchema } from "@t3tools/contracts";
4import type { PullRequestParams } from "./usePullRequestDiff";
5​
6export type PendingReviewComment = PullRequestReviewCommentDraft & {
7 readonly id: string;
8 readonly headSha: string;
9 readonly code: string;
10};
11export type ReviewDraft = {
12 readonly summary: string;
13 readonly comment: string;
14 readonly comments: readonly PendingReviewComment[];
15};
16export const EMPTY_REVIEW_DRAFT: ReviewDraft = { summary: "", comment: "", comments: [] };
17export function pullRequestReviewKey(params: PullRequestParams) {
18 return JSON.stringify([
19 params.environmentId,
20 params.projectId,
21 params.host ?? "",
22 params.repository,
23 params.number,
24 ]);
26export const ReviewDraftDocument = Schema.Struct({
27 version: Schema.Literal(1),
28 drafts: Schema.Record(
29 Schema.String,
30 Schema.Struct({
31 summary: Schema.String,
32 comment: Schema.String,
33 comments: Schema.Array(
34 Schema.Struct({
35 ...CommentSchema.fields,
36 id: Schema.String,
37 headSha: Schema.String,
38 code: Schema.String,
39 }),
40 ),
41 }),
42 ),
43});
44export function clearSubmittedReview(current: ReviewDraft, submitted: ReviewDraft): ReviewDraft {
45 return {
46 ...current,
47 summary: current.summary === submitted.summary ? "" : current.summary,
48 comments: current.comments.filter(
49 (comment) =>
50 !submitted.comments.some(
51 (saved) =>
52 saved.id === comment.id &&
53 saved.body === comment.body &&
54 saved.headSha === comment.headSha &&
55 saved.path === comment.path &&
56 saved.oldPath === comment.oldPath &&
57 saved.code === comment.code &&
58 samePosition(saved.position, comment.position),
59 ),
60 ),
61 };
63​
64function samePosition(
65 left: PendingReviewComment["position"],
66 right: PendingReviewComment["position"],
67) {
68 if (left.kind === "added" && right.kind === "added") return left.newLine === right.newLine;
69 if (left.kind === "deleted" && right.kind === "deleted") return left.oldLine === right.oldLine;
70 return (
71 left.kind === "context" &&
72 right.kind === "context" &&
73 left.oldLine === right.oldLine &&
74 left.newLine === right.newLine &&
75 left.side === right.side
76 );