diff --git a/httpd-client/index.ts b/httpd-client/index.ts index 828a0e72b..19d766235 100644 --- a/httpd-client/index.ts +++ b/httpd-client/index.ts @@ -11,8 +11,6 @@ import type { Commit, CommitHeader, Diff, - DiffAddedDeletedModifiedChangeset, - DiffCopiedMovedChangeset, HunkLine, } from "./lib/project/commit.js"; import type { Issue, IssueState } from "./lib/project/issue.js"; @@ -44,8 +42,6 @@ export type { Commit, CommitHeader, Diff, - DiffAddedDeletedModifiedChangeset, - DiffCopiedMovedChangeset, DiffResponse, HunkLine, Issue, diff --git a/httpd-client/lib/project/commit.ts b/httpd-client/lib/project/commit.ts index 07a687deb..3610a9610 100644 --- a/httpd-client/lib/project/commit.ts +++ b/httpd-client/lib/project/commit.ts @@ -1,171 +1,175 @@ -import type { ZodSchema } from "zod"; -import { array, literal, number, object, string, union } from "zod"; +import type { z } from "zod"; +import { array, literal, number, object, optional, string, union } from "zod"; -interface GitPerson { - name: string; - email: string; -} +export { commitHeaderSchema, diffSchema, commitSchema, commitsSchema }; + +export type { + Commits, + HunkLine, + Commit, + DiffFile, + Diff, + DiffCopiedChangeset, + DiffMovedChangeset, + CommitHeader, + DiffAddedChangeset, + DiffDeletedChangeset, + DiffModifiedChangeset, + DiffContent, +}; const gitPersonSchema = object({ name: string(), email: string(), -}) satisfies ZodSchema; +}); -export interface CommitHeader { - id: string; - author: GitPerson; - summary: string; - description: string; - parents: string[]; - committer: GitPerson & { time: number }; -} +type CommitHeader = z.infer; -export const commitHeaderSchema = object({ +const commitHeaderSchema = object({ id: string(), author: gitPersonSchema, summary: string(), description: string(), parents: array(string()), committer: gitPersonSchema.merge(object({ time: number() })), -}) satisfies ZodSchema; +}); -interface AdditionHunkLine { - line: string; - lineNo: number; - type: "addition"; -} +type AdditionHunkLine = z.infer; const additionHunkLineSchema = object({ line: string(), lineNo: number(), type: literal("addition"), -}) satisfies ZodSchema; +}); -interface DeletionHunkLine { - line: string; - lineNo: number; - type: "deletion"; -} +type DeletionHunkLine = z.infer; const deletionHunkLineSchema = object({ line: string(), lineNo: number(), type: literal("deletion"), -}) satisfies ZodSchema; +}); -interface ContextHunkLine { - line: string; - lineNoNew: number; - lineNoOld: number; - type: "context"; -} +type DiffFile = z.infer; + +const diffFileSchema = object({ + oid: string(), + mode: union([ + literal("blob"), + literal("blobExecutable"), + literal("tree"), + literal("link"), + literal("commit"), + ]), +}); + +type ContextHunkLine = z.infer; const contextHunkLineSchema = object({ line: string(), lineNoNew: number(), lineNoOld: number(), type: literal("context"), -}) satisfies ZodSchema; +}); -export type HunkLine = AdditionHunkLine | DeletionHunkLine | ContextHunkLine; +type HunkLine = AdditionHunkLine | DeletionHunkLine | ContextHunkLine; const hunkLineSchema = union([ additionHunkLineSchema, deletionHunkLineSchema, contextHunkLineSchema, -]) satisfies ZodSchema; - -interface ChangesetHunk { - header: string; - lines: HunkLine[]; -} +]); const changesetHunkSchema = object({ header: string(), lines: array(hunkLineSchema), -}) satisfies ZodSchema; +}); -export interface DiffAddedDeletedModifiedChangeset { - path: string; - diff: { - type: "plain" | "binary" | "empty"; - hunks: ChangesetHunk[]; - eof: "noneMissing" | "oldMissing" | "newMissing" | "bothMissing"; - }; -} +type DiffContent = z.infer; -const diffAddedDeletedModifiedChangesetSchema = object({ +const diffContentSchema = object({ + type: union([literal("plain"), literal("binary"), literal("empty")]), + hunks: array(changesetHunkSchema), + eof: union([ + literal("noneMissing"), + literal("oldMissing"), + literal("newMissing"), + literal("bothMissing"), + ]), +}); + +type DiffAddedChangeset = z.infer; + +const diffAddedChangesetSchema = object({ path: string(), - diff: object({ - type: union([literal("plain"), literal("binary"), literal("empty")]), - hunks: array(changesetHunkSchema), - eof: union([ - literal("noneMissing"), - literal("oldMissing"), - literal("newMissing"), - literal("bothMissing"), - ]), - }), -}) satisfies ZodSchema; + diff: diffContentSchema, + new: diffFileSchema, +}); -export interface DiffCopiedMovedChangeset { - newPath: string; - oldPath: string; -} +type DiffDeletedChangeset = z.infer; -const diffCopiedMovedChangesetSchema = object({ +const diffDeletedChangesetSchema = object({ + path: string(), + diff: diffContentSchema, + old: diffFileSchema, +}); + +type DiffModifiedChangeset = z.infer; + +const diffModifiedChangesetSchema = object({ + path: string(), + diff: diffContentSchema, + new: diffFileSchema, + old: diffFileSchema, +}); + +type DiffCopiedChangeset = z.infer; + +const diffCopiedChangesetSchema = object({ newPath: string(), oldPath: string(), -}) satisfies ZodSchema; +}); -export interface Diff { - added: DiffAddedDeletedModifiedChangeset[]; - deleted: DiffAddedDeletedModifiedChangeset[]; - moved: DiffCopiedMovedChangeset[]; - copied: DiffCopiedMovedChangeset[]; - modified: DiffAddedDeletedModifiedChangeset[]; - stats: { - filesChanged: number; - insertions: number; - deletions: number; - }; -} +type DiffMovedChangeset = z.infer; -export const diffSchema = object({ - added: array(diffAddedDeletedModifiedChangesetSchema), - deleted: array(diffAddedDeletedModifiedChangesetSchema), - moved: array(diffCopiedMovedChangesetSchema), - copied: array(diffCopiedMovedChangesetSchema), - modified: array(diffAddedDeletedModifiedChangesetSchema), +const diffMovedChangesetSchema = diffCopiedChangesetSchema.merge( + object({ + old: optional(diffFileSchema), + new: optional(diffFileSchema), + diff: optional(diffContentSchema), + }), +); + +type Diff = z.infer; + +const diffSchema = object({ + added: array(diffAddedChangesetSchema), + deleted: array(diffDeletedChangesetSchema), + modified: array(diffModifiedChangesetSchema), + moved: array(diffMovedChangesetSchema), + copied: array(diffCopiedChangesetSchema), stats: object({ filesChanged: number(), insertions: number(), deletions: number(), }), -}) satisfies ZodSchema; +}); -export interface Commit { - commit: CommitHeader; - diff: Diff; - branches: string[]; -} +type Commit = z.infer; -export const commitSchema = object({ +const commitSchema = object({ commit: commitHeaderSchema, diff: diffSchema, branches: array(string()), -}) satisfies ZodSchema; +}); -export interface Commits { - commits: Commit[]; - stats: { commits: number; branches: number; contributors: number }; -} +type Commits = z.infer; -export const commitsSchema = object({ +const commitsSchema = object({ commits: array(commitSchema), stats: object({ commits: number(), branches: number(), contributors: number(), }), -}) satisfies ZodSchema; +}); diff --git a/src/views/projects/Changeset.svelte b/src/views/projects/Changeset.svelte index 47f077358..eb175f519 100644 --- a/src/views/projects/Changeset.svelte +++ b/src/views/projects/Changeset.svelte @@ -72,25 +72,53 @@ {/each} {#each diff.deleted as file} {/each} {#each diff.modified as file} - + {/each} {#each diff.moved as file} - + {#if file.diff} + + {:else} + + {/if} {/each} {#each diff.copied as file} - + {/each} diff --git a/src/views/projects/Changeset/FileDiff.svelte b/src/views/projects/Changeset/FileDiff.svelte index aa900c74d..20cd99162 100644 --- a/src/views/projects/Changeset/FileDiff.svelte +++ b/src/views/projects/Changeset/FileDiff.svelte @@ -1,16 +1,14 @@