1import { SourceControlProviderKind } from "@t3tools/contracts";
2import * as Schema from "effect/Schema";
3import * as Option from "effect/Option";
4import type { ChangeRequest } from "@t3tools/contracts";
5
6const Repository = Schema.Struct({
7 full_name: Schema.String,
8 owner: Schema.Struct({ login: Schema.String }),
9});
10const Branch = Schema.Struct({
11 ref: Schema.String,
12 sha: Schema.String,
13 repo: Schema.NullOr(Repository),
14});
15export const ForgejoPullRequestSchema = Schema.Struct({
16 number: Schema.Int,
17 title: Schema.String,
18 html_url: Schema.String,
19 state: Schema.String,
20 merged: Schema.Boolean,
21 draft: Schema.optional(Schema.Boolean),
22 base: Branch,
23 head: Branch,
24 closed_at: Schema.optional(Schema.NullOr(Schema.String)),
25 merged_at: Schema.optional(Schema.NullOr(Schema.String)),
26 updated_at: Schema.optional(Schema.OptionFromNullOr(Schema.DateTimeUtcFromString)),
27});
28export function toForgejoChangeRequest(raw: typeof ForgejoPullRequestSchema.Type): ChangeRequest {
29 return {
30 provider: SourceControlProviderKind.make("forgejo"),
31 number: raw.number,
32 title: raw.title,
33 url: raw.html_url,
34 state: raw.merged ? "merged" : raw.state === "closed" ? "closed" : "open",
35 isDraft: raw.draft ?? /^(?:\[WIP\]|WIP:)/i.test(raw.title),
36 baseRefName: raw.base.ref,
37 headRefName: raw.head.ref,
38 closedAt: raw.closed_at ?? null,
39 mergedAt: raw.merged_at ?? null,
40 updatedAt: raw.updated_at ?? Option.none(),
41 isCrossRepository:
42 raw.head.repo !== null &&
43 raw.base.repo !== null &&
44 raw.head.repo.full_name !== raw.base.repo.full_name,
45 headRepositoryNameWithOwner: raw.head.repo?.full_name ?? null,
46 headRepositoryOwnerLogin: raw.head.repo?.owner.login ?? null,
47 };
48}